Fixes:
CAN RX: ID conversion was incorrect
This commit is contained in:
parent
162522b3b2
commit
93007d20d9
@ -478,7 +478,7 @@ LGPL License Terms @ref lgpl_license
|
|||||||
/* 15:10 Reserved, forced by hardware to 0 */
|
/* 15:10 Reserved, forced by hardware to 0 */
|
||||||
|
|
||||||
/* BRP[9:0]: Baud rate prescaler */
|
/* BRP[9:0]: Baud rate prescaler */
|
||||||
#define CAN_BTR_BRP_MASK (0x1FF << 0)
|
#define CAN_BTR_BRP_MASK (0x1FFUL << 0)
|
||||||
|
|
||||||
/* --- CAN_TIxR values ------------------------------------------------------ */
|
/* --- CAN_TIxR values ------------------------------------------------------ */
|
||||||
|
|
||||||
@ -533,11 +533,11 @@ LGPL License Terms @ref lgpl_license
|
|||||||
/* --- CAN_RIxR values ------------------------------------------------------ */
|
/* --- CAN_RIxR values ------------------------------------------------------ */
|
||||||
|
|
||||||
/* STID[10:0]: Standard identifier */
|
/* STID[10:0]: Standard identifier */
|
||||||
#define CAN_RIxR_STID_MASK (0x3FF << 21)
|
#define CAN_RIxR_STID_MASK (0x7FF)
|
||||||
#define CAN_RIxR_STID_SHIFT 21
|
#define CAN_RIxR_STID_SHIFT 21
|
||||||
|
|
||||||
/* EXID[15:0]: Extended identifier */
|
/* EXID[15:0]: Extended identifier */
|
||||||
#define CAN_RIxR_EXID_MASK (0x1FFFFFF << 3)
|
#define CAN_RIxR_EXID_MASK (0x1FFFFFFF)
|
||||||
#define CAN_RIxR_EXID_SHIFT 3
|
#define CAN_RIxR_EXID_SHIFT 3
|
||||||
|
|
||||||
/* IDE: Identifier extension */
|
/* IDE: Identifier extension */
|
||||||
|
114
lib/stm32/can.c
114
lib/stm32/can.c
@ -47,6 +47,18 @@ LGPL License Terms @ref lgpl_license
|
|||||||
# error "stm32 family not defined."
|
# error "stm32 family not defined."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Timeout for CAN INIT acknowledge
|
||||||
|
* this value is difficult to define.
|
||||||
|
* INIT is set latest after finishing the current transfer.
|
||||||
|
* Assuming the lowest CAN speed of 100kbps one CAN frame may take about 1.6ms
|
||||||
|
* WAIT loop timeout varies on compiler switches, optimization, CPU architecture
|
||||||
|
* and CPU speed
|
||||||
|
*
|
||||||
|
* The same timeout value is used for leaving INIT where the longest time is
|
||||||
|
* 11 bits(110 us on 100 kbps).
|
||||||
|
*/
|
||||||
|
#define CAN_MSR_INAK_TIMEOUT 0x0000FFFF
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/** @brief CAN Reset
|
/** @brief CAN Reset
|
||||||
|
|
||||||
@ -88,8 +100,7 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
|
|||||||
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp,
|
bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp,
|
||||||
bool loopback, bool silent)
|
bool loopback, bool silent)
|
||||||
{
|
{
|
||||||
u32 wait_ack = 0x00000000;
|
volatile u32 wait_ack;
|
||||||
u32 can_msr_inak_timeout = 0x0000FFFF;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Exit from sleep mode. */
|
/* Exit from sleep mode. */
|
||||||
@ -99,76 +110,93 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
|
|||||||
CAN_MCR(canport) |= CAN_MCR_INRQ;
|
CAN_MCR(canport) |= CAN_MCR_INRQ;
|
||||||
|
|
||||||
/* Wait for acknowledge. */
|
/* Wait for acknowledge. */
|
||||||
while ((wait_ack != can_msr_inak_timeout) &&
|
wait_ack = CAN_MSR_INAK_TIMEOUT;
|
||||||
|
while ((--wait_ack) &&
|
||||||
((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) {
|
((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) {
|
||||||
wait_ack++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the acknowledge. */
|
/* Check the acknowledge. */
|
||||||
if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)
|
if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK){
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* clear can timing bits */
|
/* clear can timing bits */
|
||||||
CAN_BTR(canport) = 0;
|
CAN_BTR(canport) = 0;
|
||||||
|
|
||||||
/* Set the automatic bus-off management. */
|
/* Set the automatic bus-off management. */
|
||||||
if (ttcm)
|
if (ttcm) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_TTCM;
|
CAN_MCR(canport) |= CAN_MCR_TTCM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_TTCM;
|
CAN_MCR(canport) &= ~CAN_MCR_TTCM;
|
||||||
|
}
|
||||||
|
|
||||||
if (abom)
|
if (abom) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_ABOM;
|
CAN_MCR(canport) |= CAN_MCR_ABOM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_ABOM;
|
CAN_MCR(canport) &= ~CAN_MCR_ABOM;
|
||||||
|
}
|
||||||
|
|
||||||
if (awum)
|
if (awum) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_AWUM;
|
CAN_MCR(canport) |= CAN_MCR_AWUM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_AWUM;
|
CAN_MCR(canport) &= ~CAN_MCR_AWUM;
|
||||||
|
}
|
||||||
|
|
||||||
if (nart)
|
if (nart) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_NART;
|
CAN_MCR(canport) |= CAN_MCR_NART;
|
||||||
else
|
}
|
||||||
|
else{
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_NART;
|
CAN_MCR(canport) &= ~CAN_MCR_NART;
|
||||||
|
}
|
||||||
|
|
||||||
if (rflm)
|
if (rflm) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_RFLM;
|
CAN_MCR(canport) |= CAN_MCR_RFLM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_RFLM;
|
CAN_MCR(canport) &= ~CAN_MCR_RFLM;
|
||||||
|
}
|
||||||
|
|
||||||
if (txfp)
|
if (txfp) {
|
||||||
CAN_MCR(canport) |= CAN_MCR_TXFP;
|
CAN_MCR(canport) |= CAN_MCR_TXFP;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_TXFP;
|
CAN_MCR(canport) &= ~CAN_MCR_TXFP;
|
||||||
|
}
|
||||||
|
|
||||||
if (silent)
|
if (silent) {
|
||||||
CAN_BTR(canport) |= CAN_BTR_SILM;
|
CAN_BTR(canport) |= CAN_BTR_SILM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_BTR(canport) &= ~CAN_BTR_SILM;
|
CAN_BTR(canport) &= ~CAN_BTR_SILM;
|
||||||
|
}
|
||||||
|
|
||||||
if (loopback)
|
if (loopback) {
|
||||||
CAN_BTR(canport) |= CAN_BTR_LBKM;
|
CAN_BTR(canport) |= CAN_BTR_LBKM;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_BTR(canport) &= ~CAN_BTR_LBKM;
|
CAN_BTR(canport) &= ~CAN_BTR_LBKM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set bit timings. */
|
/* Set bit timings. */
|
||||||
CAN_BTR(canport) |= sjw | ts2 | ts1 |
|
CAN_BTR(canport) |= sjw | ts2 | ts1 |
|
||||||
(u32)(CAN_BTR_BRP_MASK & (brp - 1));
|
((brp - 1ul) & CAN_BTR_BRP_MASK);
|
||||||
|
|
||||||
/* Request initialization "leave". */
|
/* Request initialization "leave". */
|
||||||
CAN_MCR(canport) &= ~CAN_MCR_INRQ;
|
CAN_MCR(canport) &= ~CAN_MCR_INRQ;
|
||||||
|
|
||||||
/* Wait for acknowledge. */
|
/* Wait for acknowledge. */
|
||||||
wait_ack = 0x00000000;
|
wait_ack = CAN_MSR_INAK_TIMEOUT;
|
||||||
while ((wait_ack != can_msr_inak_timeout) &&
|
while ((--wait_ack) &&
|
||||||
((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) {
|
((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) {
|
||||||
wait_ack++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)
|
if ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -221,13 +249,15 @@ void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
|
|||||||
CAN_FiR2(canport, nr) = fr2;
|
CAN_FiR2(canport, nr) = fr2;
|
||||||
|
|
||||||
/* Select FIFO0 or FIFO1 as filter assignement. */
|
/* Select FIFO0 or FIFO1 as filter assignement. */
|
||||||
if (fifo)
|
if (fifo) {
|
||||||
CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */
|
CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */
|
CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */
|
||||||
|
}
|
||||||
if (enable)
|
if (enable) {
|
||||||
CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */
|
CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Request initialization "leave". */
|
/* Request initialization "leave". */
|
||||||
CAN_FMR(canport) &= ~CAN_FMR_FINIT;
|
CAN_FMR(canport) &= ~CAN_FMR_FINIT;
|
||||||
@ -431,10 +461,12 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
|
|||||||
*/
|
*/
|
||||||
void can_fifo_release(u32 canport, u8 fifo)
|
void can_fifo_release(u32 canport, u8 fifo)
|
||||||
{
|
{
|
||||||
if (fifo == 0)
|
if (fifo == 0) {
|
||||||
CAN_RF0R(canport) |= CAN_RF1R_RFOM1;
|
CAN_RF0R(canport) |= CAN_RF1R_RFOM1;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
CAN_RF1R(canport) |= CAN_RF1R_RFOM1;
|
CAN_RF1R(canport) |= CAN_RF1R_RFOM1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
@ -466,22 +498,18 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
|
|||||||
if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) {
|
if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) {
|
||||||
*ext = true;
|
*ext = true;
|
||||||
/* Get extended CAN ID. */
|
/* Get extended CAN ID. */
|
||||||
*id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_EXID_MASK) >>
|
*id = (CAN_RIxR(canport, fifo_id) >> CAN_RIxR_EXID_SHIFT) & CAN_RIxR_EXID_MASK;
|
||||||
CAN_RIxR_EXID_SHIFT);
|
|
||||||
} else {
|
} else {
|
||||||
*ext = false;
|
*ext = false;
|
||||||
/* Get standard CAN ID. */
|
/* Get standard CAN ID. */
|
||||||
*id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_STID_MASK) >>
|
*id = (CAN_RIxR(canport, fifo_id) >> CAN_RIxR_STID_SHIFT) & CAN_RIxR_STID_MASK;
|
||||||
CAN_RIxR_STID_SHIFT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get remote transmit flag. */
|
/* Get remote transmit flag. */
|
||||||
if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_RTR)
|
if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_RTR) {
|
||||||
{
|
|
||||||
*rtr = true;
|
*rtr = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
*rtr = false;
|
*rtr = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,11 +528,11 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
|
|||||||
/* Get data.
|
/* Get data.
|
||||||
* Byte wise copy is needed because we do not know the alignment
|
* Byte wise copy is needed because we do not know the alignment
|
||||||
* of the input buffer.
|
* of the input buffer.
|
||||||
* Here copying 8 bytes each is faster than using loop
|
* Here copying 8 bytes unconditionally is faster than using loop
|
||||||
*
|
*
|
||||||
* It is OK to copy all 8 bytes because the upper layer must be
|
* It is OK to copy all 8 bytes because the upper layer must be
|
||||||
* prepared that the data length of the CAN frame is bigger
|
* prepared for data length bigger expected.
|
||||||
* than expected. In contrary the driver has no clue what is expected.
|
* In contrary the driver has no information about the intended size.
|
||||||
* This could be different if the max length would be handed over
|
* This could be different if the max length would be handed over
|
||||||
* to the function, but it is not the case
|
* to the function, but it is not the case
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user