stm32: Support passing through RTR and EFF canbus frames
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
913c6a913d
commit
3f7d05dd18
|
@ -16,6 +16,9 @@ struct canbus_msg {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CANMSG_ID_RTR (1<<30)
|
||||||
|
#define CANMSG_ID_EFF (1<<31)
|
||||||
|
|
||||||
#define CANMSG_DATA_LEN(msg) ((msg)->dlc > 8 ? 8 : (msg)->dlc)
|
#define CANMSG_DATA_LEN(msg) ((msg)->dlc > 8 ? 8 : (msg)->dlc)
|
||||||
|
|
||||||
// callbacks provided by board specific code
|
// callbacks provided by board specific code
|
||||||
|
|
|
@ -118,6 +118,12 @@ canbus_send(struct canbus_msg *msg)
|
||||||
mb->TDHR = msg->data32[1];
|
mb->TDHR = msg->data32[1];
|
||||||
|
|
||||||
/* Request transmission */
|
/* Request transmission */
|
||||||
|
uint32_t tir;
|
||||||
|
if (msg->id & CANMSG_ID_EFF)
|
||||||
|
tir = ((msg->id & 0x1fffffff) << CAN_TI0R_EXID_Pos) | CAN_TI0R_IDE;
|
||||||
|
else
|
||||||
|
tir = (msg->id & 0x7ff) << CAN_TI0R_STID_Pos;
|
||||||
|
tir |= msg->id & CANMSG_ID_RTR ? CAN_TI0R_RTR : 0;
|
||||||
mb->TIR = (msg->id << CAN_TI0R_STID_Pos) | CAN_TI0R_TXRQ;
|
mb->TIR = (msg->id << CAN_TI0R_STID_Pos) | CAN_TI0R_TXRQ;
|
||||||
return CANMSG_DATA_LEN(msg);
|
return CANMSG_DATA_LEN(msg);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +137,7 @@ canbus_set_filter(uint32_t id)
|
||||||
/* Initialisation mode for the filter */
|
/* Initialisation mode for the filter */
|
||||||
SOC_CAN->FA1R = 0;
|
SOC_CAN->FA1R = 0;
|
||||||
|
|
||||||
uint32_t mask = CAN_RI0R_STID | CAN_TI0R_IDE | CAN_TI0R_RTR;
|
uint32_t mask = CAN_TI0R_STID | CAN_TI0R_IDE | CAN_TI0R_RTR;
|
||||||
SOC_CAN->sFilterRegister[0].FR1 = CANBUS_ID_ADMIN << CAN_RI0R_STID_Pos;
|
SOC_CAN->sFilterRegister[0].FR1 = CANBUS_ID_ADMIN << CAN_RI0R_STID_Pos;
|
||||||
SOC_CAN->sFilterRegister[0].FR2 = mask;
|
SOC_CAN->sFilterRegister[0].FR2 = mask;
|
||||||
SOC_CAN->sFilterRegister[1].FR1 = (id + 1) << CAN_RI0R_STID_Pos;
|
SOC_CAN->sFilterRegister[1].FR1 = (id + 1) << CAN_RI0R_STID_Pos;
|
||||||
|
@ -155,8 +161,13 @@ CAN_IRQHandler(void)
|
||||||
if (SOC_CAN->RF0R & CAN_RF0R_FMP0) {
|
if (SOC_CAN->RF0R & CAN_RF0R_FMP0) {
|
||||||
// Read and ack data packet
|
// Read and ack data packet
|
||||||
CAN_FIFOMailBox_TypeDef *mb = &SOC_CAN->sFIFOMailBox[0];
|
CAN_FIFOMailBox_TypeDef *mb = &SOC_CAN->sFIFOMailBox[0];
|
||||||
|
uint32_t rir = mb->RIR;
|
||||||
struct canbus_msg msg;
|
struct canbus_msg msg;
|
||||||
msg.id = (mb->RIR >> CAN_RI0R_STID_Pos) & 0x7FF;
|
if (rir & CAN_RI0R_IDE)
|
||||||
|
msg.id = ((rir >> CAN_RI0R_EXID_Pos) & 0x1fffffff) | CANMSG_ID_EFF;
|
||||||
|
else
|
||||||
|
msg.id = (rir >> CAN_RI0R_STID_Pos) & 0x7ff;
|
||||||
|
msg.id |= rir & CAN_RI0R_RTR ? CANMSG_ID_RTR : 0;
|
||||||
msg.dlc = mb->RDTR & CAN_RDT0R_DLC;
|
msg.dlc = mb->RDTR & CAN_RDT0R_DLC;
|
||||||
msg.data32[0] = mb->RDLR;
|
msg.data32[0] = mb->RDLR;
|
||||||
msg.data32[1] = mb->RDHR;
|
msg.data32[1] = mb->RDHR;
|
||||||
|
|
|
@ -17,38 +17,24 @@
|
||||||
#include "internal.h" // enable_pclock
|
#include "internal.h" // enable_pclock
|
||||||
#include "sched.h" // DECL_INIT
|
#include "sched.h" // DECL_INIT
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t RESERVED0 : 18;
|
|
||||||
__IO uint32_t ID : 11;
|
|
||||||
__IO uint32_t RTR : 1;
|
|
||||||
__IO uint32_t XTD : 1;
|
|
||||||
__IO uint32_t ESI : 1;
|
|
||||||
__IO uint32_t RXTS : 16;
|
|
||||||
__IO uint32_t DLC : 4;
|
|
||||||
__IO uint32_t BRS : 1;
|
|
||||||
__IO uint32_t FDF : 1;
|
|
||||||
uint32_t RESERVED1 : 2;
|
|
||||||
__IO uint32_t FIDX : 7;
|
|
||||||
__IO uint32_t ANMF : 1;
|
|
||||||
__IO uint32_t data[64 / 4];
|
|
||||||
}FDCAN_RX_FIFO_TypeDef;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
__IO uint32_t id_section;
|
__IO uint32_t id_section;
|
||||||
__IO uint32_t dlc_section;
|
__IO uint32_t dlc_section;
|
||||||
__IO uint32_t data[64 / 4];
|
__IO uint32_t data[64 / 4];
|
||||||
}FDCAN_TX_FIFO_TypeDef;
|
}FDCAN_FIFO_TypeDef;
|
||||||
|
|
||||||
|
#define FDCAN_XTD (1<<30)
|
||||||
|
#define FDCAN_RTR (1<<29)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
__IO uint32_t FLS[28]; // Filter list standard
|
__IO uint32_t FLS[28]; // Filter list standard
|
||||||
__IO uint32_t FLE[16]; // Filter list extended
|
__IO uint32_t FLE[16]; // Filter list extended
|
||||||
FDCAN_RX_FIFO_TypeDef RXF0[3];
|
FDCAN_FIFO_TypeDef RXF0[3];
|
||||||
FDCAN_RX_FIFO_TypeDef RXF1[3];
|
FDCAN_FIFO_TypeDef RXF1[3];
|
||||||
__IO uint32_t TEF[6]; // Tx event FIFO
|
__IO uint32_t TEF[6]; // Tx event FIFO
|
||||||
FDCAN_TX_FIFO_TypeDef TXFIFO[3];
|
FDCAN_FIFO_TypeDef TXFIFO[3];
|
||||||
}FDCAN_MSG_RAM_TypeDef;
|
}FDCAN_MSG_RAM_TypeDef;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -100,8 +86,14 @@ canbus_send(struct canbus_msg *msg)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint32_t w_index = ((txfqs & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
|
uint32_t w_index = ((txfqs & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
|
||||||
FDCAN_TX_FIFO_TypeDef *txfifo = &MSG_RAM.TXFIFO[w_index];
|
FDCAN_FIFO_TypeDef *txfifo = &MSG_RAM.TXFIFO[w_index];
|
||||||
txfifo->id_section = (msg->id & 0x1fffffff) << 18;
|
uint32_t ids;
|
||||||
|
if (msg->id & CANMSG_ID_EFF)
|
||||||
|
ids = (msg->id & 0x1fffffff) | FDCAN_XTD;
|
||||||
|
else
|
||||||
|
ids = (msg->id & 0x7ff) << 18;
|
||||||
|
ids |= msg->id & CANMSG_ID_RTR ? FDCAN_RTR : 0;
|
||||||
|
txfifo->id_section = ids;
|
||||||
txfifo->dlc_section = (msg->dlc & 0x0f) << 16;
|
txfifo->dlc_section = (msg->dlc & 0x0f) << 16;
|
||||||
txfifo->data[0] = msg->data32[0];
|
txfifo->data[0] = msg->data32[0];
|
||||||
txfifo->data[1] = msg->data32[1];
|
txfifo->data[1] = msg->data32[1];
|
||||||
|
@ -155,10 +147,15 @@ CAN_IRQHandler(void)
|
||||||
if (rxf0s & FDCAN_RXF0S_F0FL) {
|
if (rxf0s & FDCAN_RXF0S_F0FL) {
|
||||||
// Read and ack data packet
|
// Read and ack data packet
|
||||||
uint32_t idx = (rxf0s & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos;
|
uint32_t idx = (rxf0s & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos;
|
||||||
FDCAN_RX_FIFO_TypeDef *rxf0 = &MSG_RAM.RXF0[idx];
|
FDCAN_FIFO_TypeDef *rxf0 = &MSG_RAM.RXF0[idx];
|
||||||
|
uint32_t ids = rxf0->id_section;
|
||||||
struct canbus_msg msg;
|
struct canbus_msg msg;
|
||||||
msg.id = rxf0->ID;
|
if (ids & FDCAN_XTD)
|
||||||
msg.dlc = rxf0->DLC;
|
msg.id = (ids & 0x1fffffff) | CANMSG_ID_EFF;
|
||||||
|
else
|
||||||
|
msg.id = (ids >> 18) & 0x7ff;
|
||||||
|
msg.id |= ids & FDCAN_RTR ? CANMSG_ID_RTR : 0;
|
||||||
|
msg.dlc = (rxf0->dlc_section >> 16) & 0x0f;
|
||||||
msg.data32[0] = rxf0->data[0];
|
msg.data32[0] = rxf0->data[0];
|
||||||
msg.data32[1] = rxf0->data[1];
|
msg.data32[1] = rxf0->data[1];
|
||||||
SOC_CAN->RXF0A = idx;
|
SOC_CAN->RXF0A = idx;
|
||||||
|
|
Loading…
Reference in New Issue