/* * 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 #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); // }