PDU_Code/Core/Src/PCA9535D_Driver.c

168 lines
5.1 KiB
C

/**
* @file PCA9535D_Driver.c
*
* Driver Software for the PCA9535D Port exteneder Peripheral
*
* @author Maximilian Mönikes
*/
#include "PCA9535D_Driver.h"
static I2C_HandleTypeDef* pcai2c;
static uint8_t deviceadr = 0;
static uint8_t gpioa_shadow_reg_out = 0;
static uint8_t gpiob_shadow_reg_out = 0;
static uint8_t gpioa_shadow_reg_dir = 0xFF;
static uint8_t gpiob_shadow_reg_dir = 0xFF;
static uint8_t gpioa_shadow_reg_inv = 0;
static uint8_t gpiob_shadow_reg_inv = 0;
/**@brief Initalize the PCA9535 Port extender
*
* All GPIOs are Initialized as Inputs with normal Polarity
*
* @param hi2c Pointer to I2C Handle struct for the peripheral in
* @param subaddress of the port expander
* @retval none
*/
void PCA9535_init(I2C_HandleTypeDef* hi2c, uint8_t subadr) {
pcai2c = hi2c;
deviceadr = PCA_I2C_BASE_ADDRESS | (subadr << 1);
uint8_t initalizationconfig[7] = {0x02, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, initalizationconfig, 7, 1000);
}
void PCA9535_setGPIOPinDirection(uint8_t Port, uint8_t pin, uint8_t state) {
if (Port == PC9535_PORTA) {
if (state)
gpioa_shadow_reg_dir |= (1 << pin);
else
gpioa_shadow_reg_dir &= ~(1 << pin);
uint8_t data[2] = {CONFIGURATION_REG_BASE_ADDRESS, gpioa_shadow_reg_dir};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
} else if (Port == PC9535_PORTB) {
if (state)
gpiob_shadow_reg_dir |= (1 << pin);
else
gpiob_shadow_reg_dir &= ~(1 << pin);
uint8_t data[2] = {CONFIGURATION_REG_BASE_ADDRESS | 1,
gpiob_shadow_reg_dir};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
}
}
void PCA9535_setGPIOPinOutput(uint8_t Port, uint8_t pin, uint8_t state) {
if (Port == PC9535_PORTA) {
if (state)
gpioa_shadow_reg_out |= (1 << pin);
else
gpioa_shadow_reg_out &= ~(1 << pin);
uint8_t data[2] = {OUTPUT_REG_BASE_ADDRESS, gpioa_shadow_reg_out};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
} else if (Port == PC9535_PORTB) {
if (state)
gpiob_shadow_reg_out |= (1 << pin);
else
gpiob_shadow_reg_out &= ~(1 << pin);
uint8_t data[2] = {OUTPUT_REG_BASE_ADDRESS | 1, gpiob_shadow_reg_out};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
}
}
void PCA9535_invertGPIOPinPolarity(uint8_t Port, uint8_t pin, uint8_t state) {
if (Port == PC9535_PORTA) {
if (state)
gpioa_shadow_reg_inv |= (1 << pin);
else
gpioa_shadow_reg_inv &= ~(1 << pin);
uint8_t data[2] = {INPUT_POLARITY_INVERSION_REG_BASE_ADDRESS,
gpioa_shadow_reg_inv};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
} else if (Port == PC9535_PORTB) {
if (state)
gpiob_shadow_reg_inv |= (1 << pin);
else
gpiob_shadow_reg_inv &= ~(1 << pin);
uint8_t data[2] = {INPUT_POLARITY_INVERSION_REG_BASE_ADDRESS | 1,
gpiob_shadow_reg_inv};
HAL_I2C_Master_Transmit(pcai2c, deviceadr, data, 2, 1000);
}
}
uint8_t PCA9535_readGPIOPinInput(uint8_t Port, uint8_t pin) {
if (Port == PC9535_PORTA) {
uint8_t command = INPUT_REG_BASE_ADDRESS;
HAL_I2C_Master_Transmit(pcai2c, deviceadr, &command, 1, 1000);
} else if (Port == PC9535_PORTB) {
uint8_t command = INPUT_REG_BASE_ADDRESS | 1;
HAL_I2C_Master_Transmit(pcai2c, deviceadr, &command, 1, 1000);
}
uint8_t reval = 0;
HAL_I2C_Master_Receive(pcai2c, deviceadr, &reval, 1, 1000);
reval &= (1 << pin);
reval = reval >> (pin);
return reval;
}
void PCA9535_setGPIOPortDirection(uint8_t Port, uint8_t bitmask) {
uint8_t command[2] = {0x00, bitmask};
if (Port == PC9535_PORTA) {
gpioa_shadow_reg_dir = bitmask;
command[0] = CONFIGURATION_REG_BASE_ADDRESS;
} else if (Port == PC9535_PORTB) {
gpiob_shadow_reg_dir = bitmask;
command[0] = CONFIGURATION_REG_BASE_ADDRESS | 1;
}
HAL_I2C_Master_Transmit(pcai2c, deviceadr, command, 2, 1000);
}
void PCA9535_setGPIOPortOutput(uint8_t Port, uint8_t bitmask) {
uint8_t command[2] = {0x00, bitmask};
if (Port == PC9535_PORTA) {
gpioa_shadow_reg_out = bitmask;
command[0] = OUTPUT_REG_BASE_ADDRESS;
} else if (Port == PC9535_PORTB) {
gpiob_shadow_reg_out = bitmask;
command[0] = OUTPUT_REG_BASE_ADDRESS | 1;
}
HAL_I2C_Master_Transmit(pcai2c, deviceadr, command, 2, 1000);
}
void PCA9535_invertGPIOPortPolarity(uint8_t Port, uint8_t bitmask) {
uint8_t command[2] = {0x00, bitmask};
if (Port == PC9535_PORTA) {
gpioa_shadow_reg_inv = bitmask;
command[0] = INPUT_POLARITY_INVERSION_REG_BASE_ADDRESS;
} else if (Port == PC9535_PORTB) {
gpiob_shadow_reg_inv = bitmask;
command[0] = INPUT_POLARITY_INVERSION_REG_BASE_ADDRESS | 1;
}
HAL_I2C_Master_Transmit(pcai2c, deviceadr, command, 2, 1000);
}
uint8_t PCA9535_readGPIOPortInput(uint8_t Port) {
uint8_t command = 0;
if (Port == PC9535_PORTB)
command |= INPUT_REG_BASE_ADDRESS;
else if (Port == PC9535_PORTA)
command |= INPUT_REG_BASE_ADDRESS | 1;
HAL_I2C_Master_Transmit(pcai2c, deviceadr, &command, 1, 1000);
uint8_t reval = 0;
HAL_I2C_Master_Receive(pcai2c, deviceadr, &reval, 1, 1000);
return reval;
}