Skip to content

Commit

Permalink
ADS1115 (#1474)
Browse files Browse the repository at this point in the history
* test1

* tryyy

* uint

* end

* fx

* channeld

* fx

* split to file

* test

* split

* split

* w

* fx

* an

* DRV_I2C_Shutdown

* Update drv_i2c_ads1115.c

* rewrite

* fx

* defines
  • Loading branch information
openshwprojects authored Dec 23, 2024
1 parent ba3e171 commit 6152fec
Show file tree
Hide file tree
Showing 11 changed files with 475 additions and 281 deletions.
2 changes: 1 addition & 1 deletion src/driver/drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static driver_t g_drivers[] = {
//drvdetail:"title":"TODO",
//drvdetail:"descr":"Generic I2C, not used for LED drivers, but may be useful for displays or port expanders. Supports both hardware and software I2C.",
//drvdetail:"requires":""}
{ "I2C", DRV_I2C_Init, DRV_I2C_EverySecond, NULL, NULL, NULL, NULL, false },
{ "I2C", DRV_I2C_Init, DRV_I2C_EverySecond, NULL, NULL, DRV_I2C_Shutdown, NULL, false },
#endif
#if ENABLE_DRIVER_BL0942
//drvdetail:{"name":"RN8209",
Expand Down
126 changes: 126 additions & 0 deletions src/i2c/drv_i2c_ads1115.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include "../new_common.h"
#include "../new_pins.h"
#include "../new_cfg.h"
// Commands register, execution API and cmd tokenizer
#include "../cmnds/cmd_public.h"
#include "../logging/logging.h"
#include "drv_i2c_local.h"
// addresses, banks, etc, defines
#include "drv_i2c_ads1115.h"

#define CONFIG_REGISTER 0x01
#define CONVERSION_REGISTER 0x00
// default config for 16-bit resolution, single-ended, channels AIN0, AIN1, AIN2, AIN3
#define CONFIG_DEFAULT 0xC183 // 16-bit, AIN0, single-ended


typedef struct i2cDevice_ADS1115_s {
i2cDevice_t base;
byte channels[4];
} i2cDevice_ADS1115_t;



/*
// set SoftSDA and SoftSCL pins
startDriver I2C
// use adr here from scanI2C, I'm assuming 0x48
addI2CDevice_ADS1115 Soft 0x48 0 1 2 3
// Btw, if you are only using input 0, you can also do
// addI2CDevice_ADS1115 Soft 0x48 0
// Others will not be read.
// You can also use 0xff to mark skip input
// addI2CDevice_ADS1115 Soft 0x48 0 0xff 2 3
*/
void ADS1115_WriteConfig(i2cDevice_ADS1115_t *ads, uint16_t config) {
byte payload[3];
payload[0] = CONFIG_REGISTER;
payload[1] = (config >> 8) & 0xFF;
payload[2] = config & 0xFF;
DRV_I2C_Begin(ads->base.addr, ads->base.busType);
DRV_I2C_WriteBytesSingle(payload, 3);
DRV_I2C_Close();
}
int ADS1115_ReadChannel(i2cDevice_ADS1115_t *ads, int channel)
{
uint16_t config = CONFIG_DEFAULT | (channel << 12);
ADS1115_WriteConfig(ads, config);

delay_ms(8);

byte dat[2];
DRV_I2C_Begin(ads->base.addr, ads->base.busType);
DRV_I2C_ReadBytes(CONVERSION_REGISTER, dat, 2);
DRV_I2C_Close();
int res = (dat[0] << 8) | dat[1];
// DeDaMrAz hack?
if (res > 60000) {
res = 0;
}

addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "ADS adr %i AN%i is %i", ads->base.addr, channel, (int)res);
return res;
}
void DRV_I2C_ADS1115_RunDevice(i2cDevice_t *dev)
{
i2cDevice_ADS1115_t *ads;

ads = (i2cDevice_ADS1115_t*)dev;

for (int i = 0; i < 4; i++) {
if (ads->channels[i] != 0xff) {
int res = ADS1115_ReadChannel(dev, i);
CHANNEL_Set(ads->channels[i], res, 0);
}
}
}


void DRV_I2C_AddDevice_ADS1115_Internal(int busType, int address, byte channels[4]) {
i2cDevice_ADS1115_t *dev;

dev = malloc(sizeof(i2cDevice_ADS1115_t));

dev->base.addr = address;
dev->base.busType = busType;
dev->base.type = I2CDEV_ADS1115;
dev->base.next = 0;
dev->base.runFrame = DRV_I2C_ADS1115_RunDevice;
dev->base.channelChange = 0;
memcpy(dev->channels, channels, sizeof(dev->channels));

DRV_I2C_AddNextDevice((i2cDevice_t*)dev);
}
//
commandResult_t DRV_I2C_AddDevice_ADS1115(const void *context, const char *cmd, const char *args, int cmdFlags) {
const char *i2cModuleStr;
int address;
i2cBusType_t busType;
byte channels[4];

Tokenizer_TokenizeString(args, 0);
i2cModuleStr = Tokenizer_GetArg(0);
address = Tokenizer_GetArgInteger(1);

busType = DRV_I2C_ParseBusType(i2cModuleStr);

if (DRV_I2C_FindDevice(busType, address)) {
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_ADS1115: there is already some device on this bus with such addr\n");
return CMD_RES_BAD_ARGUMENT;
}
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_ADS1115: module %s, address %i\n", i2cModuleStr, address);

for (int i = 0; i < 4; i++) {
channels[i] = Tokenizer_GetArgIntegerDefault(2 + i, 0xff);
}

DRV_I2C_AddDevice_ADS1115_Internal(busType, address, channels);

return CMD_RES_OK;
}
void DRV_I2C_ADS1115_PreInit() {

CMD_RegisterCommand("addI2CDevice_ADS1115", DRV_I2C_AddDevice_ADS1115, NULL);
}

Empty file added src/i2c/drv_i2c_ads1115.h
Empty file.
77 changes: 76 additions & 1 deletion src/i2c/drv_i2c_lcd_pcf8574t.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
#define LCD_PIC_LINE_3_ADDRESS 0x14
#define LCD_PIC_LINE_4_ADDRESS 0x54

typedef struct i2cDevice_PCF8574_s {
i2cDevice_t base;
// private PCF8574T variables
byte lcd_cols, lcd_rows, charsize;
byte LCD_BL_Status; // 1 for POSITIVE control, 0 for NEGATIVE control
byte pin_E;// = I2C_BYTE.2
byte pin_RW;// = I2C_BYTE.1
byte pin_RS;// = I2C_BYTE.0
byte pin_D4;// = I2C_BYTE.4
byte pin_D5;// = I2C_BYTE.5
byte pin_D6;// = I2C_BYTE.6
byte pin_D7;// = I2C_BYTE.7
byte pin_BL;// = I2C_BYTE.3
} i2cDevice_PCF8574_t;

static byte PCF8574_LCD_Build_Byte(i2cDevice_PCF8574_t *lcd)
{
byte ret = 0x00;
Expand Down Expand Up @@ -412,8 +427,9 @@ void DRV_I2C_Commands_Init() {

// addRepeatingEvent 2 -1 backlog addChannel 12 1; lcd_goto Soft 0x23 1 1; lcd_printFloat Soft 0x23 $CH12
// addRepeatingEvent 2 -1 backlog addChannel 12 1; lcd_goto Soft 0x23 1 1; lcd_printFloat Soft 0x23 $CH12 2; lcd_print Soft 0x23 " C"

int c = 0;


void DRV_I2C_LCD_PCF8574_RunDevice(i2cDevice_t *dev)
{
i2cDevice_PCF8574_t *lcd;
Expand Down Expand Up @@ -442,3 +458,62 @@ void DRV_I2C_LCD_PCF8574_RunDevice(i2cDevice_t *dev)

}


void DRV_I2C_AddDevice_PCF8574_Internal(int busType, int address, byte lcd_cols, byte lcd_rows, byte charsize) {
i2cDevice_PCF8574_t *dev;

dev = malloc(sizeof(i2cDevice_PCF8574_t));

dev->base.addr = address;
dev->base.busType = busType;
dev->base.type = I2CDEV_LCD_PCF8574;
dev->base.next = 0;
dev->base.channelChange = 0;
dev->base.runFrame = DRV_I2C_LCD_PCF8574_RunDevice;
dev->lcd_cols = lcd_cols;
dev->lcd_rows = lcd_rows;
dev->charsize = charsize;
dev->LCD_BL_Status = 1;

DRV_I2C_AddNextDevice((i2cDevice_t*)dev);
}

//
commandResult_t DRV_I2C_AddDevice_PCF8574(const void *context, const char *cmd, const char *args, int cmdFlags) {
const char *i2cModuleStr;
int address;
i2cBusType_t busType;
byte lcd_cols, lcd_rows, charsize;

Tokenizer_TokenizeString(args, 0);
i2cModuleStr = Tokenizer_GetArg(0);
address = Tokenizer_GetArgInteger(1);

busType = DRV_I2C_ParseBusType(i2cModuleStr);

if (DRV_I2C_FindDevice(busType, address)) {
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_PCF8574: there is already some device on this bus with such addr\n");
return CMD_RES_BAD_ARGUMENT;
}
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_PCF8574: module %s, address %i\n", i2cModuleStr, address);

lcd_cols = Tokenizer_GetArgInteger(2);
lcd_rows = Tokenizer_GetArgInteger(3);
charsize = Tokenizer_GetArgInteger(4);
// DRV_I2C_AddDevice_LCM1602_Internal(busType,address);

DRV_I2C_AddDevice_PCF8574_Internal(busType, address, lcd_cols, lcd_rows, charsize);

return CMD_RES_OK;
}


void DRV_I2C_LCD_PCF8574_PreInit() {

//cmddetail:{"name":"addI2CDevice_LCD_PCF8574","args":"",
//cmddetail:"descr":"Adds a new I2C device - PCF8574",
//cmddetail:"fn":"DRV_I2C_AddDevice_PCF8574","file":"i2c/drv_i2c_main.c","requires":"",
//cmddetail:"examples":""}
CMD_RegisterCommand("addI2CDevice_LCD_PCF8574", DRV_I2C_AddDevice_PCF8574, NULL);
}

40 changes: 40 additions & 0 deletions src/i2c/drv_i2c_lcm1602.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "../new_common.h"
#include "../new_pins.h"
#include "../new_cfg.h"
// Commands register, execution API and cmd tokenizer
#include "../cmnds/cmd_public.h"
#include "../logging/logging.h"
#include "drv_i2c_local.h"



commandResult_t DRV_I2C_AddDevice_LCM1602(const void *context, const char *cmd, const char *args, int cmdFlags) {
const char *i2cModuleStr;
int address;
i2cBusType_t busType;

Tokenizer_TokenizeString(args, 0);
i2cModuleStr = Tokenizer_GetArg(0);
address = Tokenizer_GetArgInteger(1);

busType = DRV_I2C_ParseBusType(i2cModuleStr);

if (DRV_I2C_FindDevice(busType, address)) {
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_LCM1602: there is already some device on this bus with such addr\n");
return CMD_RES_BAD_ARGUMENT;
}
addLogAdv(LOG_INFO, LOG_FEATURE_I2C, "DRV_I2C_AddDevice_LCM1602: module %s, address %i\n", i2cModuleStr, address);

// DRV_I2C_AddDevice_LCM1602_Internal(busType,address);

return CMD_RES_OK;
}
void DRV_I2C_LCM1602_PreInit() {
//cmddetail:{"name":"addI2CDevice_LCM1602","args":"",
//cmddetail:"descr":"Adds a new I2C device - LCM1602",
//cmddetail:"fn":"DRV_I2C_AddDevice_LCM1602","file":"i2c/drv_i2c_main.c","requires":"",
//cmddetail:"examples":""}
CMD_RegisterCommand("addI2CDevice_LCM1602", DRV_I2C_AddDevice_LCM1602, NULL);


}
63 changes: 12 additions & 51 deletions src/i2c/drv_i2c_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ enum i2cDeviceType_e {
I2CDEV_TC74,
I2CDEV_MCP23017,
I2CDEV_LCD_PCF8574,
};
I2CDEV_ADS1115,
};

typedef enum i2cBusType_e {
I2C_BUS_ERROR,
Expand All @@ -21,54 +22,11 @@ typedef struct i2cDevice_s {
int busType;
int addr;
int type;
void(*runFrame)(struct i2cDevice_s *ptr);
void(*channelChange)(struct i2cDevice_s *dev, int channel, int iVal);
struct i2cDevice_s *next;
} i2cDevice_t;

typedef struct i2cDevice_TC74_s {
i2cDevice_t base;
// private TC74 variables
// Our channel index to save the result temp
int targetChannel;
} i2cDevice_TC74_t;

// https://www.elektroda.pl/rtvforum/viewtopic.php?t=3880540&highlight=
//typedef struct i2cDevice_SM2135_s {
// i2cDevice_t base;
// // private SM2135 variables
// // Input channel indices.
// // Device will listen to changes in those channels and update accordingly.
// int sourceChannel_R;
// int sourceChannel_G;
// int sourceChannel_B;
// int sourceChannel_C;
// int sourceChannel_W;
//} i2cDevice_SM2135_t;

// Right now, MCP23017 port expander supports only output mode
// (map channel to MCP23017 output)
typedef struct i2cDevice_MCP23017_s {
i2cDevice_t base;
// private MCP23017 variables
// Channel indices (0xff = none)
byte pinMapping[16];
// is pin an output or input?
//int pinDirections;
} i2cDevice_MCP23017_t;

typedef struct i2cDevice_PCF8574_s {
i2cDevice_t base;
// private PCF8574T variables
byte lcd_cols, lcd_rows, charsize;
byte LCD_BL_Status; // 1 for POSITIVE control, 0 for NEGATIVE control
byte pin_E;// = I2C_BYTE.2
byte pin_RW;// = I2C_BYTE.1
byte pin_RS;// = I2C_BYTE.0
byte pin_D4;// = I2C_BYTE.4
byte pin_D5;// = I2C_BYTE.5
byte pin_D6;// = I2C_BYTE.6
byte pin_D7;// = I2C_BYTE.7
byte pin_BL;// = I2C_BYTE.3
} i2cDevice_PCF8574_t;

void DRV_I2C_Write(byte addr, byte data);
void DRV_I2C_WriteBytes(byte addr, byte *data, int len);
Expand All @@ -79,17 +37,20 @@ void DRV_I2C_Close();
i2cBusType_t DRV_I2C_ParseBusType(const char *s);
i2cDevice_t *DRV_I2C_FindDevice(int busType,int address);
i2cDevice_t *DRV_I2C_FindDeviceExt(int busType,int address, int devType);
void DRV_I2C_AddNextDevice(i2cDevice_t *t);


// drv_i2c_mcp23017.c
void DRV_I2C_MCP23017_RunDevice(i2cDevice_t *dev);
commandResult_t DRV_I2C_MCP23017_MapPinToChannel(const void *context, const char *cmd, const char *args, int cmdFlags);
void DRV_I2C_MCP23017_OnChannelChanged(i2cDevice_t *dev, int channel, int iVal);
void DRV_I2C_MCP23017_PreInit();

// drv_i2c_tc74.c
void DRV_I2C_TC74_RunDevice(i2cDevice_t *dev);
void DRV_I2C_TC74_PreInit();

// drv_i2c_lcd_pcf8574t.c
void DRV_I2C_LCD_PCF8574_RunDevice(i2cDevice_t *dev);
void DRV_I2C_LCD_PCF8574_PreInit();

void DRV_I2C_ADS1115_PreInit();

void DRV_I2C_LCM1602_PreInit();

#endif // __DRV_I2C_LOCAL_H__
Loading

0 comments on commit 6152fec

Please sign in to comment.