Master_Control/Core/Src/SPI_Slave_Communication.c
2022-07-30 22:25:09 +02:00

369 lines
13 KiB
C

/*
* SPI_Slave_Communication.c
*
* Created on: Jun 16, 2022
* Author: max
*/
#include "SPI_Slave_Communication.h"
#include "stm32g4xx_hal.h"
#include "stm32g4xx_hal_crc.h"
#include "stm32g4xx_hal_def.h"
#include "stm32g4xx_hal_spi.h"
#include "stm32g4xx_hal_spi_ex.h"
#include <stdint.h>
#define SPI_BUFFER_SIZE 1024
#define DUMMYBYTES 2
#define SPI_TIMEOUT 10
SPI_HandleTypeDef* spibus;
extern ErrorFlags errorflags;
uint8_t spirxbuf[SPI_BUFFER_SIZE];
uint8_t spitxbuf[SPI_BUFFER_SIZE];
static volatile int spi_transfer_complete;
uint8_t command;
AIRStateHandler* spi_airstates;
AMSErrorHandle* spierrorinfo;
void set_SPI_errorInfo(AMSErrorHandle* errorinfo) { spierrorinfo = errorinfo; }
void spi_communication_init(SPI_HandleTypeDef* spi,
AIRStateHandler* airstatemaschine) {
spibus = spi;
spi_airstates = airstatemaschine;
command = 0xFF;
HAL_SPI_DeInit(spi);
// HAL_SPI_Receive_IT(spibus, &command, 1);
}
// void setShuntdata() {
// uint8_t status = receiveData(12);
// if (status == HAL_OK) {
// spi_airstates->BatteryVoltageBatterySide =
// spirxbuf[0] << 24 | spirxbuf[1] << 16 | spirxbuf[2] << 8 |
// spirxbuf[3];
// spi_airstates->BatteryVoltageVehicleSide =
// spirxbuf[4] << 24 | spirxbuf[5] << 16 | spirxbuf[6] << 8 |
// spirxbuf[7];
// uint32_t current = spirxbuf[8] << 24 | spirxbuf[9] << 16 |
// spirxbuf[10] << 8 | spirxbuf[11];
// }
// }
// void setTSState() {
// uint8_t status = receiveData(1);
// if (status == HAL_OK) {
// spi_airstates->targetTSState = spirxbuf[0];
// }
// }
// void getTSState() {
// spitxbuf[0] = spi_airstates->currentTSState;
// spitxbuf[1] = (uint8_t)(spi_airstates->targetTSState);
// spitxbuf[2] = (uint8_t)(spi_airstates->RelaisSupplyVoltage >> 8) & 0xFF;
// spitxbuf[3] = (uint8_t)(spi_airstates->RelaisSupplyVoltage & 0xFF);
// spitxbuf[4] = (uint8_t)((spi_airstates->ShutdownCircuitVoltage >> 8) &
// 0xFF); spitxbuf[5] = (uint8_t)(spi_airstates->ShutdownCircuitVoltage &
// 0xFF); spitxbuf[6] = (uint8_t)((spi_airstates->AIRNegativeCurrent >> 8) &
// 0xFF); spitxbuf[7] = (uint8_t)(spi_airstates->AIRNegativeCurrent & 0xFF);
// spitxbuf[8] = (uint8_t)((spi_airstates->AIRPositiveCurrent >> 8) & 0xFF);
// spitxbuf[9] = (uint8_t)((spi_airstates->AIRPositiveCurrent) & 0xFF);
// spitxbuf[10] = (uint8_t)((spi_airstates->AIRPrechargeCurrent >> 8) & 0xFF);
// spitxbuf[11] = (uint8_t)((spi_airstates->AIRPrechargeCurrent) & 0xFF);
// spitxbuf[12] =
// (uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 24) & 0xFF);
// spitxbuf[13] =
// (uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 16) & 0xFF);
// spitxbuf[14] =
// (uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 8) & 0xFF);
// spitxbuf[15] =
// (uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 0) & 0xFF);
// spitxbuf[16] =
// (uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 24) & 0xFF);
// spitxbuf[17] =
// (uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 16) & 0xFF);
// spitxbuf[18] =
// (uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 8) & 0xFF);
// spitxbuf[19] =
// (uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 0) & 0xFF);
// transmitData(20);
// }
// void getError() {
// spitxbuf[0] = spierrorinfo->errorcode;
// spitxbuf[1] = spierrorinfo->errorarg[0];
// spitxbuf[2] = spierrorinfo->errorarg[1];
// spitxbuf[3] = spierrorinfo->errorarg[2];
// spitxbuf[4] = spierrorinfo->errorarg[3];
// spitxbuf[5] = spierrorinfo->errorarg[4];
// spitxbuf[6] = spierrorinfo->errorarg[5];
// spitxbuf[7] = spierrorinfo->errorarg[6];
// spitxbuf[8] = spierrorinfo->errorarg[7];
// spitxbuf[9] = (errorflags.AMS_ERROR_LED << 7) |
// (errorflags.IMD_ERROR_LED << 6) | (errorflags.IMD_ERROR << 5)
// | (errorflags.HV_inactive << 4) |
// (errorflags.TS_no_voltage_error << 3) |
// (errorflags.negative_AIR_error << 2) |
// (errorflags.positive_AIR_or_PC_error << 1) |
// (errorflags.positive_AIR_and_PC_open);
// spitxbuf[10] = (errorflags.negative_AIR_open);
// spitxbuf[11] = calculateChecksum(spitxbuf, 10);
// transmitData(12);
// }
// void togglestatusLED() {
// HAL_GPIO_TogglePin(Status_LED_GPIO_Port, Status_LED_Pin);
// }
// void getMeasurements() {
// for (int n = 0; n < NUMBEROFSLAVES; n++) {
// spitxbuf[n * 89] = slaves[n].slaveID;
// spitxbuf[n * 89 + 1] = (uint8_t)((slaves[n].timestamp >> 24) & 0xFF);
// spitxbuf[n * 89 + 2] = (uint8_t)((slaves[n].timestamp >> 16) & 0xFF);
// spitxbuf[n * 89 + 3] = (uint8_t)((slaves[n].timestamp >> 8) & 0xFF);
// spitxbuf[n * 89 + 4] = (uint8_t)((slaves[n].timestamp >> 0) & 0xFF);
// for (int i = 0; i < NUMBEROFCELLS; i++) {
// spitxbuf[n * 89 + 5 + 2 * i] =
// (uint8_t)((slaves[n].cellVoltages[i] >> 8) & 0xFF);
// spitxbuf[n * 89 + 6 + 2 * i] =
// (uint8_t)((slaves[n].cellVoltages[i]) & 0xFF);
// }
// for (int i = 0; i < NUMBEROFTEMPS; i++) {
// spitxbuf[n * 89 + 25 + 2 * i] =
// (uint8_t)((slaves[n].cellTemps[i] >> 8) & 0xFF);
// spitxbuf[n * 89 + 26 + 2 * i] =
// (uint8_t)((slaves[n].cellTemps[i]) & 0xFF);
// }
// }
// transmitData(NUMBEROFSLAVES * 89);
// }
// uint8_t receiveData(uint16_t length) {
// if (length > 1024)
// return 0xFF;
// HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin,
// GPIO_PIN_SET); HAL_StatusTypeDef status =
// HAL_SPI_Receive(spibus, spirxbuf, length, SPI_TIMEOUT);
// HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin,
// GPIO_PIN_RESET); return (uint8_t)status;
// }
// uint8_t transmitData(uint16_t length) {
// if (length > 1024)
// return 0xFF;
// HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin,
// GPIO_PIN_SET); HAL_StatusTypeDef status =
// HAL_SPI_Transmit(spibus, spitxbuf, length, SPI_TIMEOUT);
// HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin,
// GPIO_PIN_RESET); return (uint8_t)status;
// }
void checkSPI() {
/*
if(commandreceived)
{
commandreceived = 0;
switch(command)
{
case SET_SHUNTDATA:
setShuntdata();
break;
case SET_TSSTATE:
setTSState();
break;
case GET_TSSTATE:
getTSState();
break;
case GET_ERROR:
getError();
break;
case TOGGLE_STATUS_LED:
togglestatusLED();
break;
case GET_MEASUREMENTS:
getMeasurements();
break;
default:
break;
}
HAL_SPI_Receive_IT(spibus, &command, 1);
}
else
{
if(spibus->State == HAL_SPI_STATE_READY)
{
HAL_SPI_Receive_IT(spibus, &command, 1);
}
}
*/
InterSTMFrame();
}
// uint8_t checkXor(uint8_t *buf, uint8_t len) {
// uint8_t checksum = 0xFF;
// for (int i = 0; i < len; i++) {
// checksum ^= buf[i];
// }
// if (checksum == buf[len]) {
// return 0;
// } else {
// return 1;
// }
// }
uint8_t calculateChecksum(uint8_t* buf, uint8_t len) {
uint8_t checksum = 0xFF;
for (int i = 0; i < len; i++) {
checksum ^= buf[i];
}
return checksum;
}
void InterSTMFrame() {
HAL_GPIO_TogglePin(Status_LED_GPIO_Port, Status_LED_Pin);
if (HAL_GPIO_ReadPin(Inter_STM_CS_GPIO_Port, Inter_STM_CS_Pin) ==
GPIO_PIN_RESET) {
return;
}
for (int n = 0; n < NUMBEROFSLAVES; n++) {
spitxbuf[n * 89] = slaves[n].slaveID;
spitxbuf[n * 89 + 1] = (uint8_t)((slaves[n].timestamp >> 24) & 0xFF);
spitxbuf[n * 89 + 2] = (uint8_t)((slaves[n].timestamp >> 16) & 0xFF);
spitxbuf[n * 89 + 3] = (uint8_t)((slaves[n].timestamp >> 8) & 0xFF);
spitxbuf[n * 89 + 4] = (uint8_t)((slaves[n].timestamp >> 0) & 0xFF);
for (int i = 0; i < NUMBEROFCELLS; i++) {
spitxbuf[n * 89 + 5 + 2 * i] =
(uint8_t)((slaves[n].cellVoltages[i] >> 8) & 0xFF);
spitxbuf[n * 89 + 6 + 2 * i] =
(uint8_t)((slaves[n].cellVoltages[i]) & 0xFF);
}
for (int i = 0; i < NUMBEROFTEMPS; i++) {
spitxbuf[n * 89 + 25 + 2 * i] =
(uint8_t)((slaves[n].cellTemps[i] >> 8) & 0xFF);
spitxbuf[n * 89 + 26 + 2 * i] =
(uint8_t)((slaves[n].cellTemps[i]) & 0xFF);
}
}
uint16_t errorcodebaseaddress = NUMBEROFSLAVES * 89 + 1;
spitxbuf[errorcodebaseaddress + 0] = spierrorinfo->errorcode;
spitxbuf[errorcodebaseaddress + 1] = spierrorinfo->errorarg[0];
spitxbuf[errorcodebaseaddress + 2] = spierrorinfo->errorarg[1];
spitxbuf[errorcodebaseaddress + 3] = spierrorinfo->errorarg[2];
spitxbuf[errorcodebaseaddress + 4] = spierrorinfo->errorarg[3];
spitxbuf[errorcodebaseaddress + 5] = spierrorinfo->errorarg[4];
spitxbuf[errorcodebaseaddress + 6] = spierrorinfo->errorarg[5];
spitxbuf[errorcodebaseaddress + 7] = spierrorinfo->errorarg[6];
spitxbuf[errorcodebaseaddress + 8] = spierrorinfo->errorarg[7];
spitxbuf[errorcodebaseaddress + 9] =
(errorflags.AMS_ERROR_LED << 7) | (errorflags.IMD_ERROR_LED << 6) |
(errorflags.IMD_ERROR << 5) | (errorflags.HV_inactive << 4) |
(errorflags.TS_no_voltage_error << 3) |
(errorflags.negative_AIR_error << 2) |
(errorflags.positive_AIR_or_PC_error << 1) |
(errorflags.positive_AIR_and_PC_open);
spitxbuf[errorcodebaseaddress + 10] = (errorflags.negative_AIR_open);
spitxbuf[errorcodebaseaddress + 11] = calculateChecksum(spitxbuf, 10);
uint16_t tsstatebaseaddress = errorcodebaseaddress + 12;
spitxbuf[tsstatebaseaddress + 0] = spi_airstates->currentTSState;
spitxbuf[tsstatebaseaddress + 1] = (uint8_t)(spi_airstates->targetTSState);
spitxbuf[tsstatebaseaddress + 2] = (uint8_t)(0) & 0xFF;
spitxbuf[tsstatebaseaddress + 3] = (uint8_t)(0);
spitxbuf[tsstatebaseaddress + 4] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 5] = (uint8_t)(0);
spitxbuf[tsstatebaseaddress + 6] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 7] = (uint8_t)(0);
spitxbuf[tsstatebaseaddress + 8] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 9] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 10] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 11] = (uint8_t)((0) & 0xFF);
spitxbuf[tsstatebaseaddress + 12] =
(uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 24) & 0xFF);
spitxbuf[tsstatebaseaddress + 13] =
(uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 16) & 0xFF);
spitxbuf[tsstatebaseaddress + 14] =
(uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 8) & 0xFF);
spitxbuf[tsstatebaseaddress + 15] =
(uint8_t)((spi_airstates->BatteryVoltageBatterySide >> 0) & 0xFF);
spitxbuf[tsstatebaseaddress + 16] =
(uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 24) & 0xFF);
spitxbuf[tsstatebaseaddress + 17] =
(uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 16) & 0xFF);
spitxbuf[tsstatebaseaddress + 18] =
(uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 8) & 0xFF);
spitxbuf[tsstatebaseaddress + 19] =
(uint8_t)((spi_airstates->BatteryVoltageVehicleSide >> 0) & 0xFF);
uint32_t spitimeoutcounter = HAL_GetTick();
HAL_SPI_DeInit(spibus);
HAL_SPI_Init(spibus);
HAL_SPIEx_FlushRxFifo(spibus);
spi_transfer_complete = 0;
HAL_SPI_Receive_IT(spibus, spirxbuf, 13);
HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin, GPIO_PIN_SET);
uint32_t timeout = HAL_GetTick() + SPI_FRAME_TIMEOUT;
while (!spi_transfer_complete && HAL_GetTick() < timeout) {
}
HAL_GPIO_WritePin(Inter_STM_IRQ_GPIO_Port, Inter_STM_IRQ_Pin, GPIO_PIN_RESET);
if (!spi_transfer_complete) {
HAL_SPI_Abort(spibus);
return;
}
spi_airstates->BatteryVoltageBatterySide =
spirxbuf[0] << 24 | spirxbuf[1] << 16 | spirxbuf[2] << 8 | spirxbuf[3];
spi_airstates->BatteryVoltageVehicleSide =
spirxbuf[4] << 24 | spirxbuf[5] << 16 | spirxbuf[6] << 8 | spirxbuf[7];
uint32_t current =
spirxbuf[8] << 24 | spirxbuf[9] << 16 | spirxbuf[10] << 8 | spirxbuf[11];
spi_airstates->targetTSState = spirxbuf[12];
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef* hspi) {
HAL_SPI_Transmit_IT(spibus, spitxbuf, NUMBEROFSLAVES * 89 + 33);
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi) {
spi_transfer_complete = 1;
}
// void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) {
// __HAL_SPI_CLEAR_OVRFLAG(hspi);
// // HAL_SPI_Receive_IT(spibus, &command, 1);
// HAL_SPIEx_FlushRxFifo(hspi);
// }