211 lines
5.8 KiB
C
211 lines
5.8 KiB
C
/*
|
|
* TMP144.c
|
|
*
|
|
* Created on: 23 Mar 2022
|
|
* Author: Jasper
|
|
*/
|
|
|
|
#include "TMP144.h"
|
|
|
|
#include <string.h>
|
|
|
|
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_CELLS];
|
|
|
|
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 = 11;
|
|
bus_busbar.sensor_mappings[0] = 8;
|
|
bus_busbar.sensor_mappings[1] = 8;
|
|
bus_busbar.sensor_mappings[2] = 8;
|
|
bus_busbar.sensor_mappings[3] = 6;
|
|
bus_busbar.sensor_mappings[4] = 6;
|
|
bus_busbar.sensor_mappings[5] = 4;
|
|
bus_busbar.sensor_mappings[6] = 4;
|
|
bus_busbar.sensor_mappings[7] = 4;
|
|
bus_busbar.sensor_mappings[8] = 2;
|
|
bus_busbar.sensor_mappings[9] = 2;
|
|
bus_busbar.sensor_mappings[10] = 2;
|
|
bus_other.n_sensors = 13;
|
|
bus_other.sensor_mappings[0] = 1;
|
|
bus_other.sensor_mappings[1] = 1;
|
|
bus_other.sensor_mappings[2] = 1;
|
|
bus_other.sensor_mappings[3] = 3;
|
|
bus_other.sensor_mappings[4] = 3;
|
|
bus_other.sensor_mappings[5] = 5;
|
|
bus_other.sensor_mappings[6] = 5;
|
|
bus_other.sensor_mappings[7] = 5;
|
|
bus_other.sensor_mappings[8] = 5;
|
|
bus_other.sensor_mappings[9] = 7;
|
|
bus_other.sensor_mappings[10] = 7;
|
|
bus_other.sensor_mappings[11] = 9;
|
|
bus_other.sensor_mappings[12] = 9;
|
|
|
|
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;
|
|
}
|
|
|
|
// Find max temperature for each cell
|
|
uint8_t current_cell = bus->sensor_mappings[0];
|
|
uint16_t max_temp = 0;
|
|
for (size_t i = 0; i < bus->n_sensors; i++) {
|
|
uint8_t cell = bus->sensor_mappings[i];
|
|
if (cell != current_cell) {
|
|
temperatures[current_cell] = max_temp;
|
|
current_cell = cell;
|
|
max_temp = 0;
|
|
}
|
|
|
|
size_t buf_offset = headerlen + 2 * i;
|
|
uint16_t temp =
|
|
(bus->rxbuf[buf_offset] >> 4) | (bus->rxbuf[buf_offset + 1] << 4);
|
|
if (temp > max_temp) {
|
|
max_temp = temp;
|
|
}
|
|
}
|
|
temperatures[current_cell] = max_temp;
|
|
|
|
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();
|
|
}
|
|
}
|