Master_Interface/Core/Src/SPI_Communication.c

339 lines
12 KiB
C
Raw Normal View History

2022-07-03 17:33:09 +02:00
/*
* SPI_Communication.c
*
* Created on: Jun 16, 2022
* Author: max
*/
#include "SPI_Communication.h"
#include "stm32g4xx_hal.h"
#include "stm32g4xx_hal_spi.h"
2022-07-18 16:56:38 +02:00
#include <stdint.h>
2022-07-03 17:33:09 +02:00
#define GET_ERROR_RESPONSE_LEN 14
#define GET_TS_STATE_RESPONSE_LEN 23
static volatile int spi_transfer_state = 0;
uint8_t spitxbuf[1024];
uint8_t spirxbuf[1024];
SlaveHandler slaves[NUMBEROFSLAVES] = {0};
2022-07-18 16:56:38 +02:00
uint16_t min_voltage = 0, max_voltage = 0, min_temp = 0, max_temp = 0;
2022-07-03 17:33:09 +02:00
ErrorFlagHandler errorflags = {0};
TSHandler ctrltsstate = {0};
uint8_t spibusy = 0;
uint8_t actualTSState = 0;
SPI_HandleTypeDef* stmspi;
void InitSPI(SPI_HandleTypeDef* spi) {
stmspi = spi;
// HAL_SPI_DeInit(spi);
}
// uint8_t transmittoSlave(uint16_t length) {
// if (length > 1024)
// return 0xFE;
// if (waitforSlave() == 0) {
// HAL_StatusTypeDef status = HAL_SPI_Transmit(stmspi, spitxbuf, length,
// 10); return (uint8_t)status;
// }
// return 0xFF;
// }
// uint8_t receivefromSlave(uint16_t length) {
// if (length > 1024)
// return 0xFE;
// if (waitforSlave() == 0) {
// HAL_StatusTypeDef status = HAL_SPI_Receive(stmspi, spirxbuf, length, 10);
// return (uint8_t)status;
// }
// return 0xFF;
// }
// uint8_t slaveSendCommand(uint8_t command) {
// if (HAL_GPIO_ReadPin(InterSTM_IRQ_Line_GPIO_Port, InterSTM_IRQ_Line_Pin) ==
// 0x01)
// return 1;
// HAL_SPI_Transmit(stmspi, &command, 1, 10);
// return 0;
// }
// void sendShuntdata() {
// if (slaveSendCommand(SEND_SHUNTDATA) == 0) {
// spitxbuf[0] = (uint8_t)(shuntvoltage3 >> 24) & 0xFF;
// spitxbuf[1] = (uint8_t)(shuntvoltage3 >> 16) & 0xFF;
// spitxbuf[2] = (uint8_t)(shuntvoltage3 >> 8) & 0xFF;
// spitxbuf[3] = (uint8_t)(shuntvoltage3)&0xFF;
// spitxbuf[4] = (uint8_t)(shuntvoltage2 >> 24) & 0xFF;
// spitxbuf[5] = (uint8_t)(shuntvoltage2 >> 16) & 0xFF;
// spitxbuf[6] = (uint8_t)(shuntvoltage2 >> 8) & 0xFF;
// spitxbuf[7] = (uint8_t)(shuntvoltage2)&0xFF;
// spitxbuf[8] = (uint8_t)(shuntcurrent >> 24) & 0xFF;
// spitxbuf[9] = (uint8_t)(shuntcurrent >> 16) & 0xFF;
// spitxbuf[10] = (uint8_t)(shuntcurrent >> 8) & 0xFF;
// spitxbuf[11] = (uint8_t)(shuntcurrent)&0xFF;
// transmittoSlave(12);
// }
// }
// void sendTSstate(uint8_t targetstate) {
// if (slaveSendCommand(SET_TSSTATE) == 0) {
// spitxbuf[0] = targetstate;
// transmittoSlave(1);
// }
// }
// void getTSstate() {
// if (slaveSendCommand(GET_TSSTATE)) {
// if (receivefromSlave(20) == HAL_OK) {
// ctrltsstate.currentTSState = spirxbuf[0];
// ctrltsstate.targetTSState = spirxbuf[1];
// ctrltsstate.relaisSupplyVoltage = spirxbuf[2] << 8 | spirxbuf[3];
// ctrltsstate.shutdownCircuitVoltage = spirxbuf[4] << 8 | spirxbuf[5];
// ctrltsstate.negativeAIRCurrent = spirxbuf[6] << 8 | spirxbuf[7];
// ctrltsstate.positiveAIRCurrent = spirxbuf[8] << 8 | spirxbuf[9];
// ctrltsstate.preChargeAIRCurrent = spirxbuf[10] << 8 | spirxbuf[11];
// ctrltsstate.CtrlBatteryVoltageBatterySide =
// (spirxbuf[12] << 24) | (spirxbuf[13] << 16) | (spirxbuf[14] << 8) |
// (spirxbuf[15]);
// ctrltsstate.CtrlBatteryVoltageVehicleSide =
// (spirxbuf[16] << 24) | (spirxbuf[17] << 16) | (spirxbuf[18] << 8) |
// (spirxbuf[19]);
// }
// }
// }
// void getError() {
// if (slaveSendCommand(GET_ERROR) == 0) {
// if (receivefromSlave(12) == HAL_OK) {
// errorflags.errorcode = spirxbuf[0];
// errorflags.errorargs[0] = spirxbuf[1];
// errorflags.errorargs[1] = spirxbuf[2];
// errorflags.errorargs[2] = spirxbuf[3];
// errorflags.errorargs[3] = spirxbuf[4];
// errorflags.errorargs[4] = spirxbuf[5];
// errorflags.errorargs[5] = spirxbuf[6];
// errorflags.errorargs[6] = spirxbuf[7];
// errorflags.errorargs[7] = spirxbuf[8];
// errorflags.AMS_ERROR_LED = (spirxbuf[9] >> 7) & 0x01;
// errorflags.IMD_ERROR_LED = (spirxbuf[9] >> 6) & 0x01;
// errorflags.IMD_ERROR = (spirxbuf[9] >> 5) & 0x01;
// errorflags.HV_Inactive = (spirxbuf[9] >> 4) & 0x01;
// errorflags.TS_no_voltage_error = (spirxbuf[9] >> 3) & 0x01;
// errorflags.negative_AIR_error = (spirxbuf[9] >> 2) & 0x01;
// errorflags.positive_AIR_or_PC_error = (spirxbuf[9] >> 1) & 0x01;
// errorflags.positive_AIR_and_PC_open = spirxbuf[9] & 0x01;
// errorflags.negative_AIR_open = spirxbuf[10] & 0x01;
// }
// }
// }
// void getMeasurements() {
// if (slaveSendCommand(GET_MEASUREMENTS) == 0) {
// if (receivefromSlave(NUMBEROFSLAVES * 89) == HAL_OK) {
// for (int n = 0; n < NUMBEROFSLAVES; n++) {
// slaves[n].slaveID = spirxbuf[n * 89];
// slaves[n].timestamp =
// (spirxbuf[n * 89 + 1] << 24) | (spirxbuf[n * 89 + 2] << 16) |
// (spirxbuf[n * 89 + 3] << 8) | (spirxbuf[n * 89 + 4]);
// for (int i = 0; i < NUMBEROFCELLS; i++) {
// slaves[n].cellVoltages[i] =
// ((uint16_t)spirxbuf[n * 89 + 5 + 2 * i] << 8) |
// spirxbuf[n * 89 + 6 + 2 * i];
// }
// for (int i = 0; i < NUMBEROFTEMPS; i++) {
// slaves[n].cellTemps[i] =
// ((uint16_t)spirxbuf[n * 89 + 25 + 2 * i] << 8) |
// spirxbuf[n * 89 + 26 + 2 * i];
// }
// }
// }
// }
// }
// void toggleSlaveStatusLED() { slaveSendCommand(TOGGLE_STATUS_LED); }
uint8_t waitforSlave() {
uint32_t starttime = HAL_GetTick();
while ((starttime + SLAVE_TIMEOUT) > HAL_GetTick()) {
if (HAL_GPIO_ReadPin(InterSTM_IRQ_Line_GPIO_Port, InterSTM_IRQ_Line_Pin) ==
GPIO_PIN_SET) {
return 0;
}
}
HAL_GPIO_WritePin(InterSTM_SPI_CS_GPIO_Port, InterSTM_SPI_CS_Pin,
GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(InterSTM_SPI_CS_GPIO_Port, InterSTM_SPI_CS_Pin,
GPIO_PIN_RESET);
return 1;
}
void InterSTMFrame(uint8_t targettsstate) {
spitxbuf[0] = (uint8_t)(shuntvoltage3 >> 24) & 0xFF;
spitxbuf[1] = (uint8_t)(shuntvoltage3 >> 16) & 0xFF;
spitxbuf[2] = (uint8_t)(shuntvoltage3 >> 8) & 0xFF;
spitxbuf[3] = (uint8_t)(shuntvoltage3)&0xFF;
spitxbuf[4] = (uint8_t)(shuntvoltage2 >> 24) & 0xFF;
spitxbuf[5] = (uint8_t)(shuntvoltage2 >> 16) & 0xFF;
spitxbuf[6] = (uint8_t)(shuntvoltage2 >> 8) & 0xFF;
spitxbuf[7] = (uint8_t)(shuntvoltage2)&0xFF;
spitxbuf[8] = (uint8_t)(shuntcurrent >> 24) & 0xFF;
spitxbuf[9] = (uint8_t)(shuntcurrent >> 16) & 0xFF;
spitxbuf[10] = (uint8_t)(shuntcurrent >> 8) & 0xFF;
spitxbuf[11] = (uint8_t)(shuntcurrent)&0xFF;
spitxbuf[12] = targettsstate;
if (HAL_GPIO_ReadPin(InterSTM_IRQ_Line_GPIO_Port, InterSTM_IRQ_Line_Pin) ==
GPIO_PIN_SET) {
return;
}
uint8_t dummiebuf[4] = {0xFF, 0xFF, 0xFF, 0xFF};
HAL_SPI_Transmit(stmspi, dummiebuf, 4, 10);
// HAL_SPI_DeInit(stmspi);
// HAL_SPI_Init(stmspi);
HAL_SPIEx_FlushRxFifo(stmspi);
HAL_GPIO_WritePin(InterSTM_SPI_CS_GPIO_Port, InterSTM_SPI_CS_Pin,
GPIO_PIN_SET);
if (waitforSlave() != 0) {
return;
}
HAL_Delay(10);
spi_transfer_state = 0;
HAL_SPI_Transmit_IT(stmspi, spitxbuf, 13);
uint32_t timeout = HAL_GetTick() + 100;
while (spi_transfer_state == 0 && HAL_GetTick() < timeout) {
}
if (spi_transfer_state == 1) {
HAL_Delay(10);
HAL_SPI_Receive_IT(stmspi, spirxbuf, NUMBEROFSLAVES * 89 + 33);
timeout = HAL_GetTick() + 200;
while (spi_transfer_state == 1 && HAL_GetTick() < timeout) {
}
}
HAL_GPIO_WritePin(InterSTM_SPI_CS_GPIO_Port, InterSTM_SPI_CS_Pin,
GPIO_PIN_RESET);
if (spi_transfer_state != 2) {
return;
}
2022-07-18 16:56:38 +02:00
uint16_t min_v = 0xFFFF;
uint16_t max_v = 0;
uint16_t min_t = 0xFFFF;
uint16_t max_t = 0;
2022-07-03 17:33:09 +02:00
for (int n = 0; n < NUMBEROFSLAVES; n++) {
slaves[n].slaveID = spirxbuf[n * 89];
slaves[n].timestamp = (spirxbuf[n * 89 + 1] << 24) |
(spirxbuf[n * 89 + 2] << 16) |
(spirxbuf[n * 89 + 3] << 8) | (spirxbuf[n * 89 + 4]);
2022-07-03 23:47:14 +02:00
for (int i = 0; i < N_CELLS_SERIES; i++) {
2022-07-18 16:56:38 +02:00
uint16_t v = ((uint16_t)spirxbuf[n * 89 + 5 + 2 * i] << 8) |
spirxbuf[n * 89 + 6 + 2 * i];
slaves[n].cellVoltages[i] = v;
if (v < min_v) {
min_v = v;
}
if (v > max_v) {
max_v = v;
}
2022-07-03 17:33:09 +02:00
}
for (int i = 0; i < NUMBEROFTEMPS; i++) {
2022-07-18 16:56:38 +02:00
uint16_t t = ((uint16_t)spirxbuf[n * 89 + 25 + 2 * i] << 8) |
spirxbuf[n * 89 + 26 + 2 * i];
slaves[n].cellTemps[i] = t;
if (t < min_t) {
min_t = t;
}
if (t > max_t) {
max_t = t;
}
2022-07-03 17:33:09 +02:00
}
}
2022-07-18 16:56:38 +02:00
min_voltage = min_v;
max_voltage = max_v;
min_temp = min_t;
max_temp = max_t;
2022-07-03 17:33:09 +02:00
uint16_t errorflagbaseaddress = NUMBEROFSLAVES * 89 + 1;
errorflags.errorcode = spirxbuf[errorflagbaseaddress];
errorflags.errorargs[0] = spirxbuf[errorflagbaseaddress + 1];
errorflags.errorargs[1] = spirxbuf[errorflagbaseaddress + 2];
errorflags.errorargs[2] = spirxbuf[errorflagbaseaddress + 3];
errorflags.errorargs[3] = spirxbuf[errorflagbaseaddress + 4];
errorflags.errorargs[4] = spirxbuf[errorflagbaseaddress + 5];
errorflags.errorargs[5] = spirxbuf[errorflagbaseaddress + 6];
errorflags.errorargs[6] = spirxbuf[errorflagbaseaddress + 7];
errorflags.errorargs[7] = spirxbuf[errorflagbaseaddress + 8];
errorflags.AMS_ERROR_LED = (spirxbuf[errorflagbaseaddress + 9] >> 7) & 0x01;
errorflags.IMD_ERROR_LED = (spirxbuf[errorflagbaseaddress + 9] >> 6) & 0x01;
errorflags.IMD_ERROR = (spirxbuf[errorflagbaseaddress + 9] >> 5) & 0x01;
errorflags.HV_Inactive = (spirxbuf[errorflagbaseaddress + 9] >> 4) & 0x01;
errorflags.TS_no_voltage_error =
(spirxbuf[errorflagbaseaddress + 9] >> 3) & 0x01;
errorflags.negative_AIR_error =
(spirxbuf[errorflagbaseaddress + 9] >> 2) & 0x01;
errorflags.positive_AIR_or_PC_error =
(spirxbuf[errorflagbaseaddress + 9] >> 1) & 0x01;
errorflags.positive_AIR_and_PC_open =
spirxbuf[errorflagbaseaddress + 9] & 0x01;
errorflags.negative_AIR_open = spirxbuf[errorflagbaseaddress + 10] & 0x01;
uint16_t tsstatebaseaddress = errorflagbaseaddress + 12;
ctrltsstate.currentTSState = spirxbuf[tsstatebaseaddress + 0];
ctrltsstate.targetTSState = spirxbuf[tsstatebaseaddress + 1];
ctrltsstate.relaisSupplyVoltage =
spirxbuf[tsstatebaseaddress + 2] << 8 | spirxbuf[tsstatebaseaddress + 3];
ctrltsstate.shutdownCircuitVoltage =
spirxbuf[tsstatebaseaddress + 4] << 8 | spirxbuf[tsstatebaseaddress + 5];
ctrltsstate.negativeAIRCurrent =
spirxbuf[tsstatebaseaddress + 6] << 8 | spirxbuf[tsstatebaseaddress + 7];
ctrltsstate.positiveAIRCurrent =
spirxbuf[tsstatebaseaddress + 8] << 8 | spirxbuf[tsstatebaseaddress + 9];
ctrltsstate.preChargeAIRCurrent = spirxbuf[tsstatebaseaddress + 10] << 8 |
spirxbuf[tsstatebaseaddress + 11];
ctrltsstate.CtrlBatteryVoltageBatterySide =
(spirxbuf[tsstatebaseaddress + 12] << 24) |
(spirxbuf[tsstatebaseaddress + 13] << 16) |
(spirxbuf[tsstatebaseaddress + 14] << 8) |
(spirxbuf[tsstatebaseaddress + 15]);
ctrltsstate.CtrlBatteryVoltageVehicleSide =
(spirxbuf[tsstatebaseaddress + 16] << 24) |
(spirxbuf[tsstatebaseaddress + 17] << 16) |
(spirxbuf[tsstatebaseaddress + 18] << 8) |
(spirxbuf[tsstatebaseaddress + 19]);
}
uint8_t calculatechecksum(uint8_t* data, uint8_t datalen) {
uint8_t checksum = 0xFF;
for (int i = 0; i < datalen; i++) {
checksum ^= data[i];
}
return checksum;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi) { spi_transfer_state = 1; }
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef* hspi) { spi_transfer_state = 2; }