369 lines
13 KiB
C
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];
|
|
spi_airstates->shuntCurrent =
|
|
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);
|
|
// }
|