/** * @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; }