Files
GbTModuleEV/Core/Src/j1939.c

198 lines
5.3 KiB
C
Executable File

/*
* j1939.c
*
* Created on: May 3, 2024
* Author: colorbass
*/
#include "main.h"
#include "j1939.h"
#include "charger_gbt.h"
#include "string.h"
#include "can.h"
#include "edcan.h"
extern GBT_BCL_t GBT_ReqPower;
extern GBT_BCL_t GBT_CurrPower;
j_receive_t j_rx;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8] = {0,};
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
{
if((RxHeader.ExtId & 0x00FFFF) == ((J_ID_SE << 8) | J_ID_EV)){ // SA, DA match
switch ((RxHeader.ExtId>>8) & 0x00FF00){
case 0xEC00: //PGN Connection Management Message
if(RxData[0] == 16){ //Request to Send
/* Set the RTS values */
j_rx.size = RxData[1] | (RxData[2]<<8);
j_rx.packet = 1;
j_rx.packets = RxData[3];
j_rx.step = 2; //TODO
j_rx.step_cts_remain = j_rx.step;
j_rx.PGN = (RxData[7] << 16) | (RxData[6] << 8) | RxData[5];
if(j_rx.size<256) { //TODO: valid check
J_SendCTS(j_rx);
j_rx.state = 1;
}
}
if(RxData[0] == 255){ //Connection Abort
j_rx.state = 0;
}
//if(RxData[0] == 32){}//Broadcast Announce Message
/*
* 1CEC56F4 10 31 00 07 07 00 02 00
* 1CECF456 11 02 01 FF FF 00 02 00
* 1CEB56F4 01 01 01 00 03 46 05 40
* 1CEC56F4 FF FF FF FF FF 00 00 00
*/
break;
case 0xEB00: //PGN Data Message
if(j_rx.state != 1) break;
if((RxData[0]>0) && (RxData[0]<35)){ //Array limit check
if(j_rx.packet == RxData[0]){ //step check
memcpy (&j_rx.data[(RxData[0]-1)*7], &RxData[1],7);
j_rx.packet++;
if(j_rx.packet > j_rx.packets){
//End of transmission
J_SendACK(j_rx);
j_rx.state = 2;
}else{
if(j_rx.step_cts_remain > 0) j_rx.step_cts_remain--;
if(j_rx.step_cts_remain == 0){
J_SendCTS(j_rx);
j_rx.step_cts_remain = 2;
}
}
}
}
break;
case 0x1E00: //PGN BEM (ERROR)
//Error force stop
// --> Suspend EV
EDCAN_printf(LOG_WARN, "BEM Received, force stopping...\n");
EDCAN_printf(LOG_WARN, "BEM: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
EDCAN_printf(LOG_WARN, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
GBT_ForceStop();
break;
case 0x1900: //PGN BST (STOP)
//Normal stop
// --> Suspend EV
EDCAN_printf(LOG_WARN, "BST Received, stopping...\n");
EDCAN_printf(LOG_WARN, "BST: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
EDCAN_printf(LOG_WARN, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
break;
default:
if(j_rx.state == 0){//TODO protections
//Short packet
j_rx.size = RxHeader.DLC;
j_rx.packet = 1;
j_rx.packets = 1;
j_rx.step = 1;
j_rx.step_cts_remain = 0;
j_rx.PGN = (RxHeader.ExtId>>8) & 0x00FF00;
j_rx.state = 2;
memcpy (j_rx.data, RxData, j_rx.size);
}
}
}
}
}
void GBT_CAN_ReInit(){
HAL_CAN_Stop(&hcan1);
MX_CAN1_Init();
HAL_CAN_Start(&hcan1);
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
GBT_CAN_FilterInit();
}
void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data){
CAN_TxHeaderTypeDef tx_header;
uint32_t tx_mailbox;
tx_header.ExtId = (pri << 26) | (PGN << 8) | (J_ID_EV << 8) | J_ID_SE;
tx_header.RTR = CAN_RTR_DATA;
tx_header.IDE = CAN_ID_EXT;
tx_header.DLC = DLC;
//TODO buffer wait
HAL_CAN_AddTxMessage(&hcan1, &tx_header, data, &tx_mailbox);
//HAL_Delay(2);
}
//void J_SendPacketLong(){
// //TODO (no need)
//}
// J1939 sequence Clear To Send packet
void J_SendCTS(j_receive_t rx){
//if(rx.packets <= rx.packet) return; TODO
uint8_t data[8];
data[0] = 17; //CONTROL_BYTE_TP_CM_CTS
data[1] = rx.step;//total_number_of_packages_transmitted
if (rx.step > (rx.packets - rx.packet+1)) data[1] = rx.packets - rx.packet+1;
data[2] = rx.packet;//next_packet_number_transmitted
data[3] = 0xFF; /* Reserved */
data[4] = 0xFF;
data[5] = rx.PGN;
data[6] = rx.PGN >> 8;
data[7] = rx.PGN >> 16;
J_SendPacket(0x00EC00, 7, 8, data);
}
// J1939 sequence ACK packet
void J_SendACK(j_receive_t rx){//uint32_t PGN, uint8_t step, uint8_t packet){
uint8_t data[8];
data[0] = 19; //CONTROL_BYTE_TP_CM_ACK
data[1] = j_rx.size;
data[2] = j_rx.size>>8;
data[3] = j_rx.packets;
data[4] = 0xFF;//TODO
data[5] = rx.PGN;
data[6] = rx.PGN >> 8;
data[7] = rx.PGN >> 16;
J_SendPacket(0x00EC00, 7, 8, data);
}
void GBT_CAN_FilterInit(){
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
//sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}