-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* init pca9539 * get rid of super bad enums lol * make it way simpler and no bools * get rid of extra shifts * misc fixes * fix buf * misc fixes needed * reverse the bits * no reverse bits --------- Co-authored-by: Scott A <[email protected]>
- Loading branch information
Showing
2 changed files
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#ifndef PCA9539_H | ||
#define PCA9539_H | ||
|
||
#include "stm32f4xx_hal.h" | ||
#include <stdint.h> | ||
|
||
/* | ||
PCA 9539 16 bit GPIO expander. Datasheet: https://www.ti.com/lit/ds/symlink/pca9539.pdf?ts=1716785085909 | ||
*/ | ||
|
||
/// Possible I2C addresses, see comment below | ||
/// A0 A1 | ||
/// PCA_I2C_ADDR_0 0x74, L L | ||
/// PCA_I2C_ADDR_1 0x75, L H | ||
/// PCA_I2C_ADDR_2 0x76, H L | ||
/// PCA_I2C_ADDR_3 0x77, H H | ||
#define PCA_I2C_ADDR_0 0x74 | ||
#define PCA_I2C_ADDR_1 0x75 | ||
#define PCA_I2C_ADDR_2 0x76 | ||
#define PCA_I2C_ADDR_3 0x77 | ||
|
||
/// What to write/read to/from | ||
/// 0 is for pins 0X, 1 is for pins 1X | ||
/// INPUT: The incoming logic level (read only) Result: 1=H 0=L | ||
/// OUTPUT: The outgoing logic level (write only) Set: 1=H 0=L | ||
/// POLARITY: Inversion state, 1=Inverted 0=Uninverted | ||
/// DIRECTION: Input/Output selection 1=Input 0=Output | ||
|
||
#define PCA_INPUT_0_REG 0x00 | ||
#define PCA_INPUT_1_REG 0x01 | ||
#define PCA_OUTPUT_0_REG 0x02 | ||
#define PCA_OUTPUT_1_REG 0x03 | ||
#define PCA_POLARITY_0_REG 0x04 | ||
#define PCA_POLARITY_1_REG 0x05 | ||
#define PCA_DIRECTION_0_REG 0x06 | ||
#define PCA_DIRECTION_1_REG 0x07 | ||
|
||
typedef struct | ||
{ | ||
I2C_HandleTypeDef *i2c_handle; | ||
uint16_t dev_addr; | ||
} pca9539_t; | ||
|
||
/// Init PCA9539, a 16 bit I2C GPIO expander | ||
void pca9539_init(pca9539_t *pca, I2C_HandleTypeDef *i2c_handle, uint8_t dev_addr); | ||
|
||
/// @brief Read all pins on a bus, for example using reg_type input to get incoming logic level | ||
HAL_StatusTypeDef pca9539_read_reg(pca9539_t *pca, uint8_t reg_type, | ||
uint8_t *buf); | ||
/// @brief Read a specific pin on a bus, do not iterate over this, use read_pins instead | ||
HAL_StatusTypeDef pca9539_read_pin(pca9539_t *pca, uint8_t reg_type, | ||
uint8_t pin, uint8_t *buf); | ||
|
||
/// @brief Write all pins on a bus, for example using reg_type OUTPUT to set logic level or DIRECTION to set as | ||
/// output | ||
HAL_StatusTypeDef pca9539_write_reg(pca9539_t *pca, uint8_t reg_type, uint8_t buf); | ||
/// @brief Write a specific pin on a bus, do not iterate over this, use write_pins instead | ||
HAL_StatusTypeDef pca9539_write_pin(pca9539_t *pca, uint8_t reg_type, uint8_t pin, | ||
uint8_t buf); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "pca9539.h" | ||
|
||
#include "../../middleware/include/c_utils.h" | ||
|
||
#define REG_SIZE_BITS 8 | ||
|
||
HAL_StatusTypeDef pca_write_reg(pca9539_t* pca, uint16_t address, uint8_t* data) | ||
{ | ||
// ensure shifting left one, HAL adds the write bit | ||
return HAL_I2C_Mem_Write(pca->i2c_handle, pca->dev_addr, address, I2C_MEMADD_SIZE_8BIT, data, 1, | ||
HAL_MAX_DELAY); | ||
} | ||
|
||
HAL_StatusTypeDef pca_read_reg(pca9539_t* pca, uint16_t address, uint8_t* data) | ||
{ | ||
|
||
return HAL_I2C_Mem_Read(pca->i2c_handle, pca->dev_addr, address, I2C_MEMADD_SIZE_8BIT, data, 1, | ||
HAL_MAX_DELAY); | ||
} | ||
|
||
void pca9539_init(pca9539_t* pca, I2C_HandleTypeDef* i2c_handle, uint8_t dev_addr) | ||
{ | ||
pca->i2c_handle = i2c_handle; | ||
pca->dev_addr = dev_addr << 1u; /* shifted one to the left cuz STM says so */ | ||
} | ||
|
||
HAL_StatusTypeDef pca9539_read_reg(pca9539_t* pca, uint8_t reg_type, uint8_t* buf) | ||
{ | ||
|
||
HAL_StatusTypeDef status = pca_read_reg(pca, reg_type, buf); | ||
if (status) { | ||
return status; | ||
} | ||
|
||
return status; | ||
} | ||
|
||
HAL_StatusTypeDef pca9539_read_pin(pca9539_t* pca, uint8_t reg_type, uint8_t pin, uint8_t* buf) | ||
{ | ||
uint8_t data; | ||
HAL_StatusTypeDef status = pca_read_reg(pca, reg_type, &data); | ||
if (status) { | ||
return status; | ||
} | ||
|
||
*buf = (data & (1 << pin)) > 0; | ||
|
||
return status; | ||
} | ||
|
||
HAL_StatusTypeDef pca9539_write_reg(pca9539_t* pca, uint8_t reg_type, uint8_t buf) | ||
{ | ||
|
||
return pca_write_reg(pca, reg_type, &buf); | ||
} | ||
|
||
HAL_StatusTypeDef pca9539_write_pin(pca9539_t* pca, uint8_t reg_type, uint8_t pin, uint8_t buf) | ||
{ | ||
|
||
uint8_t data; | ||
uint8_t data_new; | ||
|
||
HAL_StatusTypeDef status = pca_read_reg(pca, reg_type, &data); | ||
if (status) { | ||
return status; | ||
} | ||
|
||
data_new = (data & ~(1u << pin)) | (buf << pin); | ||
|
||
return pca_write_reg(pca, reg_type, &data_new); | ||
} |