/* * TMP144.c * * Created on: 23 Mar 2022 * Author: Jasper */ #include "TMP144.h" #include #include static const uint8_t TMP144_SEQ_RESET[] = {0x55, 0xB4}; static const uint8_t TMP144_SEQ_ADDR[] = {0x55, 0x8C, 0x90}; static const uint8_t TMP144_SEQ_READ_TEMPS[] = {0x55, 0xF1}; volatile uint16_t temperatures[N_SENSORS]; volatile uint16_t max_temp; static volatile TMP144Bus bus_busbar; static volatile TMP144Bus bus_other; #define CHECK_STATUS(s) \ { \ HAL_StatusTypeDef _s = s; \ if (_s != HAL_OK) \ return _s; \ } HAL_StatusTypeDef tmp144_init(UART_HandleTypeDef* busbar_side, UART_HandleTypeDef* other_side) { bus_busbar.handle = busbar_side; bus_other.handle = other_side; bus_busbar.state = TMP144_IDLE; bus_other.state = TMP144_IDLE; // TODO: Configure this in EEPROM bus_busbar.n_sensors = 16; bus_other.n_sensors = 16; CHECK_STATUS(tmp144_init_reset(&bus_busbar)); CHECK_STATUS(tmp144_init_reset(&bus_other)); return HAL_OK; } HAL_StatusTypeDef tmp144_init_reset(TMP144Bus* bus) { if (bus->state != TMP144_IDLE) { return HAL_ERROR; } bus->state = TMP144_RESETTING; CHECK_STATUS(HAL_UART_Receive_IT(bus->handle, bus->rxbuf, 2)); // Keep sending Global Software Reset until it echoes back (as per 7.5.2) int tries = 0; do { if (tries > 10) { return HAL_TIMEOUT; } CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_RESET, sizeof(TMP144_SEQ_RESET), 100)); HAL_Delay(100); tries++; } while (bus->state == TMP144_RESETTING); bus->state = TMP144_INITIALIZING; CHECK_STATUS(HAL_UART_Receive_IT(bus->handle, bus->rxbuf, 3)); CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_ADDR, sizeof(TMP144_SEQ_ADDR), 100)); return HAL_OK; } HAL_StatusTypeDef tmp144_init_post_reset(TMP144Bus* bus) { if (bus->state != TMP144_RESETTING || memcmp(bus->rxbuf, TMP144_SEQ_RESET, sizeof(TMP144_SEQ_RESET)) != 0) { return HAL_ERROR; } bus->state = TMP144_IDLE; return HAL_OK; } HAL_StatusTypeDef tmp144_init_post_addr(TMP144Bus* bus) { size_t idx_response = sizeof(TMP144_SEQ_ADDR) - 1; if (bus->state != TMP144_INITIALIZING || memcmp(bus->rxbuf, TMP144_SEQ_ADDR, idx_response) != 0) { return HAL_ERROR; } uint8_t n_sensors = bus->rxbuf[idx_response] - TMP144_SEQ_ADDR[idx_response]; if (n_sensors != bus->n_sensors) { return HAL_ERROR; } bus->state = TMP144_IDLE; return HAL_OK; } HAL_StatusTypeDef tmp144_read_temps() { CHECK_STATUS(tmp144_send_read_temps(&bus_busbar)); CHECK_STATUS(tmp144_send_read_temps(&bus_other)); return HAL_OK; } HAL_StatusTypeDef tmp144_send_read_temps(TMP144Bus* bus) { if (bus->state != TMP144_IDLE) { return HAL_ERROR; } bus->state = TMP144_READING_TEMP; // HAL_UART_Receive_IT(bus->handle, bus->rxbuf, // sizeof(TMP144_SEQ_READ_TEMPS) + 2 * bus->n_sensors); CHECK_STATUS( HAL_UART_Receive_IT(bus->handle, bus->rxbuf, sizeof(TMP144_SEQ_READ_TEMPS) + 2 * bus->n_sensors)); CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_READ_TEMPS, sizeof(TMP144_SEQ_READ_TEMPS), 100)); return HAL_OK; } HAL_StatusTypeDef tmp144_recv_temps(TMP144Bus* bus) { if (bus->state != TMP144_READING_TEMP) { return HAL_ERROR; } bus->state = TMP144_IDLE; size_t headerlen = sizeof(TMP144_SEQ_READ_TEMPS); if (memcmp(bus->rxbuf, TMP144_SEQ_READ_TEMPS, headerlen) != 0) { return HAL_ERROR; } size_t temperatures_offset = (bus == &bus_busbar) ? 0 : N_SENSORS / 2; for (size_t i = 0; i < bus->n_sensors; i++) { size_t buf_offset = headerlen + 2 * i; uint16_t temp = (bus->rxbuf[buf_offset] >> 4) | (bus->rxbuf[buf_offset + 1] << 4); temperatures[temperatures_offset + i] = temp; } uint16_t max = temperatures[0]; for (size_t i = 1; i < N_SENSORS; i++) { if (temperatures[i] > max) { max = temperatures[i]; } } max_temp = max; return HAL_OK; } void tmp144_handle_rx_cplt(UART_HandleTypeDef* handle) { TMP144Bus* bus; if (handle == bus_busbar.handle) { bus = &bus_busbar; } else if (handle == bus_other.handle) { bus = &bus_other; } else { // TODO Error_Handler(); } switch (bus->state) { case TMP144_IDLE: // TODO Error_Handler(); case TMP144_RESETTING: tmp144_init_post_reset(bus); break; case TMP144_INITIALIZING: tmp144_init_post_addr(bus); break; case TMP144_READING_TEMP: tmp144_recv_temps(bus); break; default: // TODO Error_Handler(); } }