/**************************************************************************/ /*! @file AW9523B.cpp Author: Michi License: MIT (see LICENSE) */ /**************************************************************************/ #ifdef STM32 #include "stm32l4xx_hal.h" #else #include #include #include "driver/i2c.h" #define I2C_MASTER_TIMEOUT_MS 1000 #endif #include "AW9523B.hpp" //#include //#include #define _REG(port, reg) (port == P0 ? reg : reg + 1) AW9523B *i2c_gpio; uint8_t AW9523B::readI2C(uint8_t reg) { //AW9523B_REG_ID uint8_t gelesen = 0; uint16_t MemAddress; MemAddress = reg; //HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) #ifdef STM32 HAL_StatusTypeDef ret; ret = HAL_I2C_Mem_Read( &(this->i2c_handle), _addr, MemAddress, 1, &gelesen, 1, HAL_MAX_DELAY); if (ret != HAL_OK) #else esp_err_t res1; printf("I2C read I2C-Bus:%d Addr:%d Register: %d BEGIN \n", this->i2c_num, _addr, reg ); //res1 = i2c_master_read_from_device(this->i2c_num, _addr, /*i2c_buf*/&gelesen, 1, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); res1 = i2c_master_write_read_device(this->i2c_num, _addr, ®, 1, &gelesen, 2, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); printf(" --> gelesen Byte: %d \n", gelesen ); if (res1 != ESP_OK) #endif { printf("ERROR I2C read I2C -------------------------- \n"); ESP_ERROR_CHECK_WITHOUT_ABORT(res1); return 0; } else { printf(" I2C read I2C-Bus OK \n"); return gelesen; } } //bool i2c_write(uint16_t MemAddress, uint8_t *pData) uint8_t AW9523B::writeI2C(uint8_t reg, uint8_t val) { //AW9523B_REG_ID uint16_t MemAddress; MemAddress = reg; //HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, //uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) #ifdef STM32 HAL_StatusTypeDef ret; ret = HAL_I2C_Mem_Write( &(this->i2c_handle), _addr, MemAddress, 1, &val, 1, HAL_MAX_DELAY); if (ret != HAL_OK) #else uint8_t I2C_buf[3]; esp_err_t res1 = ESP_OK; I2C_buf[0] = reg; //0x02; // write to register 0x02 I2C_buf[1] = 255; I2C_buf[2] = 255; //res1 = i2c_master_write_to_device(I2C_MASTER_NUM, I2C_PORTEXP1, I2C_buf, 3, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); //ESP_ERROR_CHECK(res1 ); if (res1 != ESP_OK) #endif { printf("ERROR I2C write I2C -------------------------- \n"); ESP_ERROR_CHECK_WITHOUT_ABORT(res1); return false; } else { printf(" I2C write I2C OK \n"); return true; } } #ifdef STM32 AW9523B::AW9523B(uint8_t address, I2C_HandleTypeDef _i2c_handle) //AD[1:0] address offset { i2c_handle = _i2c_handle; _addr = AW9523B_I2C_ADDRESS + (address & 0x03); #else AW9523B::AW9523B(uint8_t address, int _i2c_num) //AD[1:0] address offset { i2c_num = _i2c_num; //I2C number, 0 or 1 on ESP32 _addr = 0x58;/*AW9523B_I2C_ADDRESS; 0x58 for first AW9523, 0x58 for the second */ #endif } bool AW9523B::begin() { // Wire.begin(); // return readI2C(AW9523B_REG_ID) == AW9523B_ID; #ifdef STM32 HAL_StatusTypeDef ret; ret = HAL_I2C_IsDeviceReady (&i2c_handle, _addr, 1, 1000); if (ret == HAL_OK) #else uint8_t I2C_buf[3]; esp_err_t res1 = ESP_OK, res2 = ESP_OK; I2C_buf[0] = 0x7F; // write to soft-RESET register on AW9523 I2C_buf[1] = 0x00; // write 0 to reset the AW9523 // res1 = i2c_master_write_to_device(I2C_MASTER_NUM, I2C_PORTEXP1, I2C_buf, 2, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); // res2 = i2c_master_write_to_device(I2C_MASTER_NUM, I2C_PORTEXP2, I2C_buf, 2, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS); printf("\nMaster wrote %d %d %02X\n", res1,res2,I2C_buf[0]); if ( readI2C(AW9523B_REG_ID) == AW9523B_ID ) #endif { return true; } else { return false; } } void AW9523B::scanAllAddress(void) { esp_err_t res1; uint8_t gelesen = 0; uint8_t reg_addr = AW9523B_REG_ID; printf("Scanning I2C bus for devices:\n"); fflush(stdout); for (int i=0; i<255; i++) { //i2c_master_write_read_device(I2C_MASTER_NUM, slave_addr, ®_addr, 1, data, 2, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); //res1 = i2c_master_read_from_device(0, i, AW9523B_REG_ID, 1, &gelesen, 1, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); res1 = i2c_master_write_read_device(0, i, ®_addr, 1, &gelesen, 1, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); if (res1 == ESP_OK) { printf("\ndevice found on I2C-address %d, read value: %d AW9523=16 \n", i, gelesen); } else { printf("."); } fflush(stdout); gelesen = 0; } printf("\nfinish I2C Bus scan\n"); } void AW9523B::configInOut(AW9523BPort port, uint8_t inout) { writeI2C(_REG(port, AW9523B_P0_CONF_STATE), inout); } void AW9523B::configLedGPIO(AW9523BPort port, uint8_t ledGpio) { writeI2C(_REG(port, AW9523B_P0_LED_MODE), ledGpio); } void AW9523B::setPort0Mode(AW9523BPortMode mode) { writeI2C(AW9523B_REG_GLOB_CTR, mode | ledsDim); } void AW9523B::setLedsDim(AW9523BLedsDim dim) { writeI2C(AW9523B_REG_GLOB_CTR, dim | portMode); } void AW9523B::setLed(AW9523BLedDimCtrl led, uint8_t value) { writeI2C(led, value); } void AW9523B::portIn(AW9523BPort port) { _portIn = _REG(port, AW9523B_P0_IN_STATE); } void AW9523B::portOut(AW9523BPort port) { _portOut = _REG(port, AW9523B_P0_OUT_STATE); } uint8_t AW9523B::read() { return readI2C(_portIn); } uint8_t AW9523B::read(AW9523BPort port) { return readI2C(AW9523B_P0_IN_STATE + port); } uint8_t AW9523B::write(uint8_t data) { return writeI2C(_portOut, data); } uint8_t AW9523B::write(AW9523BPort port, uint8_t data) { return writeI2C(AW9523B_P0_OUT_STATE + port, data); } void AW9523B::reset() { writeI2C(AW9523B_REG_SOFT_RST, 0); } #ifdef STM32 extern "C" bool AW9523B_init(uint8_t address, I2C_HandleTypeDef _i2c_handle) { i2c_gpio = new AW9523B(address, _i2c_handle); if (!i2c_gpio->begin() ) { //Serial.println("Error: AW9523B not found!"); return false; } else { i2c_gpio->reset(); i2c_gpio->setPort0Mode(PUSH_PULL); return true; } } extern "C" void AW9523B_destroy(void) { delete i2c_gpio; } extern "C" void AW9523B_setAllOutputHigh(void) { i2c_gpio->write(P0, 255); i2c_gpio->write(P1, 255); } #endif