Преглед на файлове

Merge pull request #430 from StefanKrupop/aw9523_expander

Add support for AW9523 GPIO expander
philippe44 преди 6 месеца
родител
ревизия
ffaff5ac27
променени са 2 файла, в които са добавени 29 реда и са изтрити 2 реда
  1. 1 1
      README.md
  2. 28 1
      components/services/gpio_exp.c

+ 1 - 1
README.md

@@ -308,7 +308,7 @@ The parameter "gpio_exp_config" is a semicolon (;) separated list with following
 ```
 model=<model>,addr=<addr>,[,port=system|dac][,base=<n>][,count=<n>][,intr=<gpio>][,cs=<gpio>][,speed=<Hz>]
 ```	
-- model: pca9535, pca85xx, mcp23017 and mcp23s17 (SPI version)
+- model: pca9535, pca85xx, mcp23017, aw9523 and mcp23s17 (SPI version)
 - addr: chip i2c/spi address (decimal)
 - port (I2C): use either "system" port (shared with display for example) or "dac" port (system is default)
 - cs (SPI): gpio used for Chip Select

+ 28 - 1
components/services/gpio_exp.c

@@ -83,6 +83,10 @@ static void      mcp23s17_set_direction(gpio_exp_t* self);
 static uint32_t  mcp23s17_read(gpio_exp_t* self);
 static void      mcp23s17_write(gpio_exp_t* self);
 
+static void 	aw9523_set_direction(gpio_exp_t* self);
+static uint32_t aw9523_read(gpio_exp_t* self);
+static void 	aw9523_write(gpio_exp_t* self);
+
 static void   service_handler(void *arg);
 static void   debounce_handler( TimerHandle_t xTimer );
 
@@ -130,6 +134,11 @@ static const struct gpio_exp_model_s {
 	  .set_pull_mode = mcp23s17_set_pull_mode,
 	  .read = mcp23s17_read,
 	  .write = mcp23s17_write, },
+	{ .model = "aw9523",
+	  .trigger = GPIO_INTR_LOW_LEVEL,
+	  .set_direction = aw9523_set_direction,
+	  .read = aw9523_read,
+	  .write = aw9523_write, },
 };
 
 static EXT_RAM_ATTR uint8_t n_expanders;
@@ -671,6 +680,24 @@ static void mcp23s17_write(gpio_exp_t* self) {
 	spi_write(self->spi_handle, self->phy.addr, 0x12, self->shadow, 2);
 }
 
+/****************************************************************************************
+ * AW9523 family : direction, read and write
+ */
+static void aw9523_set_direction(gpio_exp_t* self) {
+	i2c_write(self->phy.port, self->phy.addr, 0x04, self->r_mask, 2);
+	i2c_write(self->phy.port, self->phy.addr, 0x06, ~self->r_mask, 2);
+}
+
+static uint32_t aw9523_read(gpio_exp_t* self) {
+	// Reading both registers in one go does not seem to reset IRQ correctly
+	uint8_t port1 = i2c_read(self->phy.port, self->phy.addr, 0x00, 1);
+	return (i2c_read(self->phy.port, self->phy.addr, 0x01, 1) << 8) | port1;
+}
+
+static void aw9523_write(gpio_exp_t* self) {
+	i2c_write(self->phy.port, self->phy.addr, 0x02, self->shadow, 2);
+}
+
 /***************************************************************************************
                                      I2C low level                                   
 ***************************************************************************************/
@@ -793,4 +820,4 @@ static uint32_t spi_read(spi_device_handle_t handle, uint8_t addr, uint8_t reg,
 	free(transaction);
 
 	return data;
-}
+}