/** * @file HTPA_32x32d.c * @brief Library for HTPA 32x32d infrared array sensor * @author Tim-Erik Düntzsch t.duentzsch@fasttube.de * * @date 25.03.2023 - first implementation (untested) * * @todo finish HTPA_ReadBlock function * @todo add calibration function * @todo add temperature conversion function * * @test communication and readout * * @version 0.1 */ #include #include "main.h" #include "HTPA_32x32d.h" // I2C address #define HTPA_SENSOR_ADDRESS 0x1A #define HTPA_EEPROM_ADDRESS 0x50 // Sensor configuration registers (write only) #define HTPA_SENSOR_CONFIG 0x01 // Configuration register #define HTPA_SENSOR_TRIM_1 0x03 // Amplification and ADC resolution #define HTPA_SENSOR_TRIM_2 0x04 // Bias current of Top ADC #define HTPA_SENSOR_TRIM_3 0x05 // Bias current of Bot ADC #define HTPA_SENSOR_TRIM_4 0x06 // Clock frequency #define HTPA_SENSOR_TRIM_5 0x07 // Common mode voltage preamplifier top #define HTPA_SENSOR_TRIM_6 0x08 // Common mode voltage preamplifier bot #define HTPA_SENSOR_TRIM_7 0x09 // Interal pull-ups SDA, SCL // Sensor read only registers #define HTPA_SENSOR_STATUS 0x02 // Status register #define HTPA_SENSOR_READTOP 0x0A // Read top half #define HTPA_SENSOR_READBOT 0x0B // Read bot half // I2C transmit delay #define I2C_MAX_DELAY 0xFFFFFFFF I2C_HandleTypeDef* i2c_handle; // pointer to i2c handle HAL_StatusTypeDef i2c_return; // error handling maybe? uint8_t data_topBlock[256]; uint8_t data_botBlock[256]; uint8_t htpa_statusReg; /** * @brief Initialization of HTPA Sensor * * Sets the wakeup bit in the status register and writes the desired sensor * configuration to the respective registers. * Afterwards the sensor is in idle and ready for conversion. * * @param *hi2c: Pointer to I2C Handle */ void HTPA_Init(I2C_HandleTypeDef *hi2c){ i2c_handle = hi2c; // Berechnung für clk / sample aus I2C parametern? HTPA_WriteRegister(HTPA_SENSOR_CONFIG, 0x01); // wakeup HTPA_WriteRegister(HTPA_SENSOR_TRIM_1, 0x0C); HTPA_WriteRegister(HTPA_SENSOR_TRIM_2, 0x0C); HTPA_WriteRegister(HTPA_SENSOR_TRIM_3, 0x0C); HTPA_WriteRegister(HTPA_SENSOR_TRIM_4, 0x14); HTPA_WriteRegister(HTPA_SENSOR_TRIM_5, 0x0C); HTPA_WriteRegister(HTPA_SENSOR_TRIM_6, 0x0C); HTPA_WriteRegister(HTPA_SENSOR_TRIM_7, 0x88); HTPA_WriteRegister(HTPA_SENSOR_CONFIG, 0x09); // start sensor } /** * @brief Read data of one block in one array half * * Block selection gets written to the config register and conversion is started. * After selected block of upper and lower half are converted, the selected half * is read and the data stored in the passed array. * * @param array_half: select top or bottom half of array * @param block: select block of array half (0-3) * @param *pData[128]: pointer to 128 word array for read data */ void HTPA_ReadBlock(uint8_t array_half, uint8_t block, uint8_t blockData[256]){ uint8_t config = 0; uint8_t statusReg = 0; //config = (block << 4); // bit 5,4 block config |= 0x09; // bit 3 start | bit 1 wakeup HTPA_WriteRegister(HTPA_SENSOR_CONFIG, config); HAL_Delay(1000); // dauer??? // read status register: statusReg = HTPA_ReadRegister(HTPA_SENSOR_STATUS); HAL_Delay(100); // tbc } /** * @brief Write to selected sensor register * * description * * @param register_address: address of register * @param byte: byte to be written to register */ void HTPA_WriteRegister(uint8_t register_address, uint8_t byte){ uint8_t i2c_data = register_address; uint8_t i2c_address = (HTPA_SENSOR_ADDRESS << 1); i2c_address &= 0xFE; // set read/write bit to write (0) HAL_I2C_Master_Transmit(i2c_handle, i2c_address, &i2c_data, 1, I2C_MAX_DELAY); i2c_data = byte; HAL_I2C_Master_Transmit(i2c_handle, i2c_address, &i2c_data, 1, I2C_MAX_DELAY); } /** * @brief Read single register * * description * * @param register_address: address of register * @return */ uint8_t HTPA_ReadRegister(uint8_t register_address){ uint8_t i2c_data = register_address; uint8_t i2c_address = (HTPA_SENSOR_ADDRESS << 1); uint8_t i2c_rx = 0; i2c_address &= 0xFE; // set read/write bit to write (0) HAL_I2C_Master_Transmit(i2c_handle, i2c_address, &i2c_data, 1, I2C_MAX_DELAY); i2c_address |= 0x01; // set read/write bit to write (1) HAL_I2C_Master_Receive(i2c_handle, i2c_address, &i2c_rx, 1, I2C_MAX_DELAY); return i2c_rx; } /** * @brief Get status of sensor * * Reads the sensors status register and stores the information in * the HTPA_Statsu structure. * * @return HTPA_Status: status register struct */ HTPA_Status HTPA_GetStatus(void){ HAL_StatusTypeDef i2c_status; HTPA_Status status_return; uint8_t i2c_data = HTPA_SENSOR_STATUS; uint8_t i2c_address = (HTPA_SENSOR_ADDRESS << 1); uint8_t i2c_readData = 0; i2c_address &= 0xFE; // set read/write bit 0 to write (0) HAL_I2C_Master_Transmit(i2c_handle, i2c_address, &i2c_data, 1, I2C_MAX_DELAY); i2c_address |= 0x01; // set read/write bit 0 to read (1) i2c_status = HAL_I2C_Master_Receive(i2c_handle, i2c_address, &i2c_readData, 1, I2C_MAX_DELAY); status_return.block = (i2c_readData >> 4) && 0xFC; status_return.vdd_meas = (i2c_readData >> 2) && 0xFE; status_return.blind = (i2c_readData >> 1) && 0xFE; status_return.eoc = i2c_readData && 0xFE; return status_return; }