Support for MCP3021 I2C ADC from Microchip
This commit is contained in:
parent
e14fa1c471
commit
5e50ad79fe
|
@ -0,0 +1,103 @@
|
|||
/****************************************************************************
|
||||
* extdrv/mcp3021_adc_i2c.c
|
||||
*
|
||||
*
|
||||
* Copyright 2021 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
|
||||
#include "core/system.h"
|
||||
#include "lib/errno.h"
|
||||
#include "lib/utils.h"
|
||||
#include "drivers/i2c.h"
|
||||
#include "extdrv/mcp3021_adc_i2c.h"
|
||||
|
||||
|
||||
/***************************************************************************** */
|
||||
/* Support for MCP3021 I2C ADC from Microchip */
|
||||
/***************************************************************************** */
|
||||
|
||||
/* The MCP3021 has no internal registers.
|
||||
* Data sampling is triggered by reading from the device
|
||||
* (triggering occurs on the R/W bit of the address byte set to Read)
|
||||
* Continuous sampling is triggered by continuous reading.
|
||||
* Samples are received on two contiguous bytes, with the four upper bits on the
|
||||
* four lower bits of the first byte and the six lower bits on the six upper
|
||||
* bits of the second byte.
|
||||
*/
|
||||
|
||||
|
||||
/* Check the sensor presence, return 1 if sensor was found.
|
||||
* This is a basic check, it could be anything with the same address ...
|
||||
* This check can be made either by trying to write nothing, or by reading a sample.
|
||||
*/
|
||||
int mcp3021_probe(struct mcp3021_config* conf)
|
||||
{
|
||||
char cmd_buf = (conf->addr | I2C_WRITE_BIT);
|
||||
|
||||
/* Did we already probe the sensor ? */
|
||||
if (conf->probe_ok != 1) {
|
||||
conf->probe_ok = i2c_write(conf->bus_num, &cmd_buf, 1, NULL);
|
||||
}
|
||||
return conf->probe_ok;
|
||||
}
|
||||
|
||||
/* ADC Read
|
||||
* Read _len_ samples from the ADC, put the shifted samples into _values_
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns the number of samples read.
|
||||
* On error, returns a negative integer equivalent to errors from glibc.
|
||||
*/
|
||||
#define CMD_BUF_SIZE 1
|
||||
int mcp3021_read(struct mcp3021_config* conf, uint16_t* values, int len)
|
||||
{
|
||||
int ret = 0, i = 0;
|
||||
char cmd_buf[CMD_BUF_SIZE] = { (conf->addr | I2C_READ_BIT), };
|
||||
char ctrl_buf[CMD_BUF_SIZE] = { I2C_CONT, };
|
||||
|
||||
if (mcp3021_probe(conf) != 1) {
|
||||
return -ENODEV;
|
||||
}
|
||||
if (values == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read the requested data */
|
||||
ret = i2c_read(conf->bus_num, cmd_buf, CMD_BUF_SIZE, ctrl_buf, (char*)values, (len * 2));
|
||||
|
||||
if (ret != (len * 2)) {
|
||||
conf->probe_ok = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Shift all values */
|
||||
for (i = 0; i < len; i++) {
|
||||
values[i] = ntohs(values[i]) >> 2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int mcp3021_config(struct mcp3021_config* conf)
|
||||
{
|
||||
if (mcp3021_probe(conf) != 1) {
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0; /* Config success */
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
* extdrv/mcp3021_adc_i2c.h
|
||||
*
|
||||
*
|
||||
* Copyright 2021 Nathael Pajani <nathael.pajani@ed3l.fr>
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
#ifndef MCP3021_ADC_H
|
||||
#define MCP3021_ADC_H
|
||||
|
||||
|
||||
/***************************************************************************** */
|
||||
/* Support for MCP3021 I2C ADC from Microchip */
|
||||
/***************************************************************************** */
|
||||
|
||||
/* The MCP3021 has no internal registers.
|
||||
* Data sampling is triggered by reading from the device
|
||||
* (triggering occurs on the R/W bit of the address byte set to Read)
|
||||
* Continuous sampling is triggered by continuous reading.
|
||||
* Samples are received on two contiguous bytes, with the four upper bits on the
|
||||
* four lower bits of the first byte and the six lower bits on the six upper
|
||||
* bits of the second byte.
|
||||
*/
|
||||
|
||||
struct mcp3021_config {
|
||||
uint8_t bus_num;
|
||||
uint8_t addr;
|
||||
uint8_t probe_ok;
|
||||
};
|
||||
|
||||
/* ADC Read
|
||||
* Read _len_ samples from the ADC, put the shifted samples into _values_
|
||||
* Return value(s):
|
||||
* Upon successfull completion, returns the number of samples read.
|
||||
* On error, returns a negative integer equivalent to errors from glibc.
|
||||
*/
|
||||
int mcp3021_read(struct mcp3021_config* conf, uint16_t* values, int len);
|
||||
|
||||
int mcp3021_config(struct mcp3021_config* conf);
|
||||
|
||||
|
||||
#endif /* MCP3021_ADC_H */
|
||||
|
Loading…
Reference in New Issue