Program Listing for File si8900.c¶
↰ Return to documentation for file (mainboard/Src/peripherals/si8900.c
)
#include "peripherals/si8900.h"
#include "error/error.h"
#include "mainboard_config.h"
#include "usart.h"
#include <stdlib.h>
#include <string.h>
bool si8900_ready = false;
bool si8900_init(UART_HandleTypeDef *huart, GPIO_TypeDef *reset_gpio, uint16_t reset_pin) {
uint8_t recv = 0;
uint8_t tx = 0xAA;
bool timeout = false;
bool code_receive = false;
bool code_confirm = false;
HAL_GPIO_WritePin(ADC_SIN_GPIO_Port, ADC_SIN_Pin, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(ADC_SIN_GPIO_Port, ADC_SIN_Pin, GPIO_PIN_RESET);
uint32_t time = HAL_GetTick();
HAL_UART_Transmit(huart, &tx, 1, 10);
while ((!code_receive || !code_confirm) && !timeout) {
HAL_UART_Receive(huart, &recv, 1, 10);
if (recv == 0x55) {
if (code_receive) {
code_confirm = true;
si8900_ready = true;
}
code_receive = true;
} else {
code_receive = false;
code_confirm = false;
}
HAL_UART_Transmit(huart, &tx, 1, 10);
timeout = (HAL_GetTick() - time) >= SI8900_INIT_TIMEOUT;
}
if (timeout) {
error_set(ERROR_ADC_INIT, 0, HAL_GetTick());
return false;
}
error_reset(ERROR_ADC_INIT, 0);
return true;
}
bool si8900_read_channel(UART_HandleTypeDef *huart, SI8900_CHANNEL ch, uint16_t *voltage) {
if (si8900_ready) {
uint8_t conf = si8900_cnfg_0 | (ch << 4);
HAL_UART_Transmit(huart, &conf, 1, 1);
uint8_t recv, count = 0;
while (recv != conf) {
HAL_UART_Receive(huart, &recv, 1, 1);
if (count++ > 5) {
error_set(ERROR_ADC_TIMEOUT, 0, HAL_GetTick());
return false;
}
}
uint8_t data[2] = {0};
HAL_UART_Receive(huart, data, 2, 1);
*voltage = si8900_convert_voltage(data);
error_reset(ERROR_ADC_TIMEOUT, 0);
return true;
}
return false;
}
uint16_t si8900_convert_voltage(uint8_t adc_hl[2]) {
// MSB | LSB
uint16_t dig = ((adc_hl[0] & 0b00001111) << 6) | ((adc_hl[1] & 0b01111110) >> 1);
return ((SI8900_VREF * (float)dig) / 1024) * 100;
}