119 lines
3.0 KiB
C
119 lines
3.0 KiB
C
#include "rpi.h"
|
|
#include "main.h"
|
|
#include "state.h"
|
|
#include "stm32g4xx_hal_def.h"
|
|
#include "stm32g4xx_hal_gpio.h"
|
|
#include "stm32g4xx_hal_i2c.h"
|
|
#include <stdint.h>
|
|
|
|
uint8_t i2c_rx_buf[I2C_RX_BUF_SIZE];
|
|
uint8_t i2c_tx_buf[I2C_TX_BUF_MAX_SIZE];
|
|
uint8_t i2c_tx_len;
|
|
RPiI2CState rpi_i2c_state;
|
|
size_t rpi_num_polls;
|
|
|
|
static I2C_HandleTypeDef *bus;
|
|
static uint8_t current_command;
|
|
|
|
void rpi_init(I2C_HandleTypeDef *handle) {
|
|
bus = handle;
|
|
rpi_i2c_state = RPI_I2C_IDLE;
|
|
rpi_num_polls = 0;
|
|
if (HAL_I2C_EnableListen_IT(bus) != HAL_OK) {
|
|
Error_Handler();
|
|
}
|
|
|
|
i2c_tx_len = I2C_TX_BUF_MAX_SIZE;
|
|
for (int i = 0; i < I2C_TX_BUF_MAX_SIZE; i++) {
|
|
i2c_tx_buf[i] = i;
|
|
}
|
|
}
|
|
|
|
void rpi_update_tx_buffer() {
|
|
i2c_tx_buf[0] = stw_state.view;
|
|
switch (stw_state.view) {
|
|
case VIEW_MISSION_SELECT:
|
|
rpi_update_tx_buffer_mission_select();
|
|
break;
|
|
default:
|
|
Error_Handler();
|
|
}
|
|
}
|
|
void rpi_update_tx_buffer_mission_select() {
|
|
i2c_tx_buf[1] = stw_state.view_state.mission_select.selection;
|
|
}
|
|
|
|
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *handle) {
|
|
switch (rpi_i2c_state) {
|
|
case RPI_I2C_SENDING_DATA_SIZE:
|
|
if (HAL_I2C_Slave_Seq_Transmit_IT(bus, i2c_tx_buf, i2c_tx_len,
|
|
I2C_LAST_FRAME) != HAL_OK) {
|
|
Error_Handler();
|
|
}
|
|
rpi_i2c_state = RPI_I2C_SENDING_DATA;
|
|
break;
|
|
case RPI_I2C_SENDING_DATA:
|
|
rpi_i2c_state = RPI_I2C_IDLE;
|
|
rpi_num_polls++;
|
|
break;
|
|
default:
|
|
// TODO: How do we handle this?
|
|
return;
|
|
}
|
|
}
|
|
|
|
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *handle) {
|
|
if (rpi_i2c_state != RPI_I2C_WAITING_FOR_COMMAND) {
|
|
// TODO: How do we handle this?
|
|
return;
|
|
}
|
|
|
|
// TODO: Check comm byte
|
|
current_command = i2c_rx_buf[0];
|
|
rpi_i2c_state = RPI_I2C_WAITING_FOR_MASTER_RECEIVE;
|
|
}
|
|
|
|
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *handle, uint8_t TransferDirection,
|
|
uint16_t AddrMatchCode) {
|
|
if (handle != bus) {
|
|
HAL_GPIO_WritePin(LED_SER_GPIO_Port, LED_SER_Pin, GPIO_PIN_RESET);
|
|
return;
|
|
}
|
|
|
|
// TransferDirection is from master POV, so we need to receive when the
|
|
// direction is transmit
|
|
if (TransferDirection == I2C_DIRECTION_TRANSMIT) {
|
|
if (rpi_i2c_state != RPI_I2C_IDLE) {
|
|
// TODO: How do we handle this?
|
|
return;
|
|
}
|
|
|
|
if (HAL_I2C_Slave_Seq_Receive_IT(bus, i2c_rx_buf, I2C_RX_BUF_SIZE,
|
|
I2C_FIRST_FRAME) != HAL_OK) {
|
|
Error_Handler();
|
|
}
|
|
rpi_i2c_state = RPI_I2C_WAITING_FOR_COMMAND;
|
|
} else {
|
|
if (rpi_i2c_state != RPI_I2C_WAITING_FOR_MASTER_RECEIVE) {
|
|
// TODO: How do we handle this?
|
|
return;
|
|
}
|
|
|
|
if (HAL_I2C_Slave_Seq_Transmit_IT(bus, &i2c_tx_len, 1, I2C_NEXT_FRAME) !=
|
|
HAL_OK) {
|
|
Error_Handler();
|
|
}
|
|
rpi_i2c_state = RPI_I2C_SENDING_DATA_SIZE;
|
|
rpi_update_tx_buffer();
|
|
}
|
|
}
|
|
|
|
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *handle) {
|
|
if (handle != bus) {
|
|
return;
|
|
}
|
|
|
|
if (rpi_i2c_state == RPI_I2C_IDLE) {
|
|
HAL_I2C_EnableListen_IT(bus);
|
|
}
|
|
} |