test
This commit is contained in:
281
Test2/Core/Src/can.c
Normal file
281
Test2/Core/Src/can.c
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* CAN.c
|
||||
|
||||
*
|
||||
* Created on: Dec 04, 2018
|
||||
* Author: v0stap
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "can.h"
|
||||
|
||||
can_msg_typedef CAN_TX_Msg; // CAN message for transmit
|
||||
can_msg_typedef CAN_RX_Msg; // CAN received message
|
||||
uint8_t CAN_TX_Rdy = 0; // CAN hardware ready to transmit a message
|
||||
uint8_t CAN_RX_Rdy = 0; // CAN hardware message received
|
||||
uint32_t CAN_Speed = CAN_500KBS; // CAN Speed / CAN BTR register
|
||||
can_buffer_typedef CAN_TX_Buffer, CAN_RX_Buffer;
|
||||
uint8_t CAN_Filter_Idx = 0; // CAN filter index
|
||||
|
||||
void CAN_Init(void) {
|
||||
CAN_TX_Buffer.todo = 0;
|
||||
CAN_TX_Buffer.corent = 0;
|
||||
CAN_TX_Buffer.done = 0;
|
||||
CAN_RX_Buffer.todo = 0;
|
||||
CAN_RX_Buffer.corent = 0;
|
||||
CAN_RX_Buffer.done = 0;
|
||||
CAN_Setup(CAN_1000KBS);
|
||||
CAN_Write_Filter(0x101, EXTD_FORMAT);
|
||||
CAN_Write_Filter(0x2D0, EXTD_FORMAT);
|
||||
CAN_Write_Filter(0x2D2, EXTD_FORMAT);
|
||||
//CAN_Write_Filter(0x630, STD_FORMAT);
|
||||
//CAN_Write_Filter(0x240, STD_FORMAT);
|
||||
CAN_Start();
|
||||
CAN_Wait_Ready();
|
||||
}
|
||||
/*----------------------------------------------------------------------------
|
||||
setup CAN interface
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CAN_Setup(uint32_t speed) {
|
||||
|
||||
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CANEN;
|
||||
GPIOB->MODER &= ~((3 << (8 * 2)) | (3 << (9 * 2)));
|
||||
GPIOB->MODER |= ((2 << (8 * 2)) | (2 << (9 * 2)));
|
||||
GPIOB->OTYPER &= ~((1 << 8) | (1 << 9));
|
||||
GPIOB->OSPEEDR &= ~((3 << (8 * 2)) | (3 << (9 * 2)));
|
||||
GPIOB->PUPDR &= ~((3 << (8 * 2)) | (3 << (9 * 2)));
|
||||
GPIOB->AFR[1] &= ~((15 << (0 * 4)) | (15 << (1 * 4)));
|
||||
GPIOB->AFR[1] |= ((4 << 0) | (4 << (1 * 4)));
|
||||
CAN->MCR |= CAN_MCR_INRQ;
|
||||
while ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
|
||||
//some code
|
||||
}
|
||||
CAN->MCR &= ~ CAN_MCR_SLEEP;
|
||||
CAN->BTR &= ~(((0x03) << 24) | ((0x07) << 20) | ((0x0F) << 16) | (0x1FF));
|
||||
CAN->BTR |= speed;
|
||||
NVIC_EnableIRQ(CEC_CAN_IRQn);
|
||||
CAN->IER |= CAN_IER_FMPIE0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
leave initialisation mode
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CAN_Start(void) {
|
||||
CAN->MCR &= ~CAN_MCR_INRQ;
|
||||
while ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
check if transmit mailbox is empty
|
||||
*----------------------------------------------------------------------------*/
|
||||
void CAN_Wait_Ready(void) {
|
||||
while ((CAN->TSR & CAN_TSR_TME0) == 0) { // Transmit mailbox 0 is empty
|
||||
|
||||
}
|
||||
CAN_TX_Rdy = 1;
|
||||
}
|
||||
|
||||
// CAN send data
|
||||
void CAN_Send_Msg(can_msg_typedef *msg) {
|
||||
CAN_TX_Rdy = 0;
|
||||
CAN->sTxMailBox[0].TIR = (uint32_t) 0;
|
||||
if (msg->format == STD_FORMAT) {
|
||||
CAN->sTxMailBox[0].TIR |= (uint32_t) (msg->id << 21) | CAN_ID_STD;
|
||||
} else {
|
||||
CAN->sTxMailBox[0].TIR |= (uint32_t) (msg->id << 3) | CAN_ID_EXT;
|
||||
}
|
||||
if (msg->frame == DATA_FRAME) {
|
||||
CAN->sTxMailBox[0].TIR |= CAN_RTR_DATA;
|
||||
} else {
|
||||
CAN->sTxMailBox[0].TIR |= CAN_RTR_REMOTE;
|
||||
}
|
||||
CAN->sTxMailBox[0].TDLR = (((uint32_t) msg->data[3] << 24)
|
||||
| ((uint32_t) msg->data[2] << 16) | ((uint32_t) msg->data[1] << 8)
|
||||
| ((uint32_t) msg->data[0]));
|
||||
CAN->sTxMailBox[0].TDHR = (((uint32_t) msg->data[7] << 24)
|
||||
| ((uint32_t) msg->data[6] << 16) | ((uint32_t) msg->data[5] << 8)
|
||||
| ((uint32_t) msg->data[4]));
|
||||
CAN->sTxMailBox[0].TDTR &= ~CAN_TDT0R_DLC;
|
||||
CAN->sTxMailBox[0].TDTR |= (msg->lenght & CAN_TDT0R_DLC);
|
||||
CAN->IER |= CAN_IER_TMEIE;
|
||||
CAN->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;
|
||||
}
|
||||
// Read CAN message
|
||||
void CAN_Read_Msg(can_msg_typedef *msg) {
|
||||
if ((CAN->sFIFOMailBox[0].RIR & CAN_ID_EXT) == 0) {
|
||||
msg->format = STD_FORMAT;
|
||||
msg->id = (uint32_t) 0x000007FF & (CAN->sFIFOMailBox[0].RIR >> 21);
|
||||
} else {
|
||||
msg->format = EXTD_FORMAT;
|
||||
msg->id = (uint32_t) 0x0003FFFF & (CAN->sFIFOMailBox[0].RIR >> 3);
|
||||
}
|
||||
if ((CAN->sFIFOMailBox[0].RIR & CAN_RTR_REMOTE) == 0) {
|
||||
msg->frame = DATA_FRAME;
|
||||
} else {
|
||||
msg->frame = REMOTE_FRAME;
|
||||
}
|
||||
msg->lenght = (uint8_t) 0x0000000F & CAN->sFIFOMailBox[0].RDTR;
|
||||
msg->data[0] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDLR);
|
||||
msg->data[1] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 8);
|
||||
msg->data[2] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 16);
|
||||
msg->data[3] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDLR >> 24);
|
||||
msg->data[4] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDHR);
|
||||
msg->data[5] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 8);
|
||||
msg->data[6] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 16);
|
||||
msg->data[7] = (uint32_t) 0x000000FF & (CAN->sFIFOMailBox[0].RDHR >> 24);
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
|
||||
CAN_RX_Rdy = 0;
|
||||
// if (msg->id == 0x643)
|
||||
// printf(
|
||||
// "CAN ID: 0x%X%X Data: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n",
|
||||
// (uint16_t) (msg->id >> 16), (uint16_t) msg->id, msg->data[0],
|
||||
// msg->data[1], msg->data[2], msg->data[3], msg->data[4],
|
||||
// msg->data[5], msg->data[6], msg->data[7]);
|
||||
// //(&canRxMsg); //TO DO not realy working
|
||||
}
|
||||
//Write CAN Filter
|
||||
void CAN_Write_Filter(uint32_t id, uint8_t format) {
|
||||
uint32_t CAN_msg_typedefId = 0;
|
||||
if (CAN_Filter_Idx > 13) {
|
||||
return;
|
||||
}
|
||||
if (format == STD_FORMAT) {
|
||||
CAN_msg_typedefId |= (uint32_t) (id << 21) | CAN_ID_STD;
|
||||
} else {
|
||||
CAN_msg_typedefId |= (uint32_t) (id << 3) | CAN_ID_EXT;
|
||||
}
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
CAN->FA1R &= ~(uint32_t) (1 << CAN_Filter_Idx);
|
||||
CAN->FS1R |= (uint32_t) (1 << CAN_Filter_Idx);
|
||||
CAN->FM1R |= (uint32_t) (1 << CAN_Filter_Idx);
|
||||
//Comment next to lines for no filter
|
||||
if (id != 0) {
|
||||
CAN->sFilterRegister[CAN_Filter_Idx].FR1 = CAN_msg_typedefId;
|
||||
CAN->sFilterRegister[CAN_Filter_Idx].FR2 = CAN_msg_typedefId;
|
||||
//Uncomment next to line for no filter
|
||||
} else {
|
||||
CAN->sFilterRegister[CAN_Filter_Idx].FR1 = 0; // 32-bit identifier
|
||||
CAN->sFilterRegister[CAN_Filter_Idx].FR2 = 0; // 32-bit identifier
|
||||
}
|
||||
CAN->FFA1R &= ~(uint32_t) (1 << CAN_Filter_Idx);
|
||||
CAN->FA1R |= (uint32_t) (1 << CAN_Filter_Idx);
|
||||
CAN->FMR &= ~CAN_FMR_FINIT;
|
||||
CAN_Filter_Idx++;
|
||||
}
|
||||
//CAN recive/transmit irq handler
|
||||
void CEC_CAN_IRQHandler(void) {
|
||||
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
CAN->TSR |= CAN_TSR_RQCP0;
|
||||
CAN->IER &= ~CAN_IER_TMEIE;
|
||||
CAN_TX_Rdy = 1;
|
||||
}
|
||||
if ((CAN->RF0R & CAN_RF0R_FMP0) != 0) {
|
||||
//CAN_Add_RX_Buffer();
|
||||
// TO DO
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
CAN_RX_Rdy = 1;
|
||||
}
|
||||
}
|
||||
void CAN_Send_TX_Buffer(void) {
|
||||
|
||||
if (CAN_TX_Rdy) {
|
||||
//HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
|
||||
if (CAN_TX_Buffer.todo > 0) {
|
||||
CAN_TX_Buffer.todo--;
|
||||
//HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
|
||||
CAN_Send_Msg(&CAN_TX_Buffer.data[CAN_TX_Buffer.done]);
|
||||
if ((CAN_TX_Buffer.done++) > 14) {
|
||||
CAN_TX_Buffer.done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void CAN_Add_TX_Buffer(can_msg_typedef *data) {
|
||||
if ((CAN_TX_Buffer.todo++) < 15) {
|
||||
if ((CAN_TX_Buffer.corent++) > 14) {
|
||||
CAN_TX_Buffer.corent = 0;
|
||||
}
|
||||
//memcpy((void*) &canTX_buffer.data[canTX_buffer.corent], (void*) &data, sizeof(CAN_msg_typedef));
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].id = data->id;
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].format = data->format;
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].frame = data->frame;
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].lenght = data->lenght;
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[0] = data->data[0];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[1] = data->data[1];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[2] = data->data[2];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[3] = data->data[3];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[4] = data->data[4];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[5] = data->data[5];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[6] = data->data[6];
|
||||
CAN_TX_Buffer.data[CAN_TX_Buffer.corent].data[7] = data->data[7];
|
||||
}
|
||||
}
|
||||
void CAN_Add_RX_Buffer(void) {
|
||||
if ((CAN_RX_Buffer.todo) < 16) {
|
||||
CAN_RX_Buffer.todo++;
|
||||
if ((CAN->sFIFOMailBox[0].RIR & CAN_ID_EXT) == 0) {
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].format = STD_FORMAT;
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].id = (uint32_t) 0x000007FF
|
||||
& (CAN->sFIFOMailBox[0].RIR >> 21);
|
||||
} else {
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].format = EXTD_FORMAT;
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].id = (uint32_t) 0x0003FFFF
|
||||
& (CAN->sFIFOMailBox[0].RIR >> 3);
|
||||
}
|
||||
if ((CAN->sFIFOMailBox[0].RIR & CAN_RTR_REMOTE) == 0) {
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].frame = DATA_FRAME;
|
||||
} else {
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].frame = REMOTE_FRAME;
|
||||
}
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].lenght = (uint8_t) 0x0000000F
|
||||
& CAN->sFIFOMailBox[0].RDTR;
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[0] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDLR);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[1] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDLR >> 8);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[2] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDLR >> 16);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[3] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDLR >> 24);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[4] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDHR);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[5] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDHR >> 8);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[6] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDHR >> 16);
|
||||
CAN_RX_Buffer.data[CAN_RX_Buffer.corent].data[7] = (uint32_t) 0x000000FF
|
||||
& (CAN->sFIFOMailBox[0].RDHR >> 24);
|
||||
if ((CAN_RX_Buffer.corent++) > 15) {
|
||||
CAN_RX_Buffer.corent = 0;
|
||||
}
|
||||
|
||||
//canAddRXBuffer(&canRxMsg); //TO DO not realy working
|
||||
}
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
void CAN_Read_RX_Buffer(can_msg_typedef *data) {
|
||||
if (CAN_RX_Buffer.todo > 0) {
|
||||
//memcpy((void*) &data, (void*) &canRX_buffer.data[canRX_buffer.done], sizeof(CAN_msg_typedef));
|
||||
data->id = CAN_RX_Buffer.data[CAN_RX_Buffer.done].id;
|
||||
data->format = CAN_RX_Buffer.data[CAN_RX_Buffer.done].format;
|
||||
data->frame = CAN_RX_Buffer.data[CAN_RX_Buffer.done].frame;
|
||||
data->lenght = CAN_RX_Buffer.data[CAN_RX_Buffer.done].lenght;
|
||||
data->data[0] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[0];
|
||||
data->data[1] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[1];
|
||||
data->data[2] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[2];
|
||||
data->data[3] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[3];
|
||||
data->data[4] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[4];
|
||||
data->data[5] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[5];
|
||||
data->data[6] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[6];
|
||||
data->data[7] = CAN_RX_Buffer.data[CAN_RX_Buffer.done].data[7];
|
||||
if ((CAN_RX_Buffer.done++) > 15) {
|
||||
CAN_RX_Buffer.done = 0;
|
||||
}
|
||||
CAN_RX_Buffer.todo--;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user