CAN: Cosmetics and coding-style fixes.

This commit is contained in:
Uwe Hermann 2010-12-26 00:30:05 +01:00
parent e7d765ea90
commit 06d1a5ca80
4 changed files with 174 additions and 235 deletions

View File

@ -17,6 +17,6 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>. ## along with this program. If not, see <http://www.gnu.org/licenses/>.
## ##
BINARY = can BINARY = can
include ../../Makefile.include include ../../Makefile.include

View File

@ -51,6 +51,7 @@ void gpio_setup(void)
{ {
/* Enable GPIOA clock. */ /* Enable GPIOA clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
/* Enable GPIOB clock. */ /* Enable GPIOB clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
@ -72,7 +73,7 @@ void gpio_setup(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); GPIO_CNF_OUTPUT_PUSHPULL, GPIO1);
} }
void systick_setup() void systick_setup(void)
{ {
/* 72MHz / 8 => 9000000 counts per second */ /* 72MHz / 8 => 9000000 counts per second */
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8); systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
@ -82,35 +83,34 @@ void systick_setup()
systick_interrupt_enable(); systick_interrupt_enable();
/* start counting */ /* Start counting. */
systick_counter_enable(); systick_counter_enable();
} }
void can_setup() void can_setup(void)
{ {
/* Enable peripheral clocks. */
/* Enable peripheral clocks */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN);
/* Configure CAN pin: RX (input pull-up) */ /* Configure CAN pin: RX (input pull-up). */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN_RX); GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN_RX);
gpio_set(GPIOA, GPIO_CAN_RX); gpio_set(GPIOA, GPIO_CAN_RX);
/* Configure CAN pin: TX */ /* Configure CAN pin: TX. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN_TX); GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN_TX);
/* NVIC setup */ /* NVIC setup. */
nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ);
nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1);
/* reset CAN */ /* Reset CAN. */
can_reset(CAN1); can_reset(CAN1);
/* CAN cell init */ /* CAN cell init. */
if (can_init(CAN1, if (can_init(CAN1,
false, /* TTCM: Time triggered comm mode? */ false, /* TTCM: Time triggered comm mode? */
true, /* ABOM: Automatic bus-off management? */ true, /* ABOM: Automatic bus-off management? */
@ -121,107 +121,97 @@ void can_setup()
CAN_BTR_SJW_1TQ, CAN_BTR_SJW_1TQ,
CAN_BTR_TS1_3TQ, CAN_BTR_TS1_3TQ,
CAN_BTR_TS2_4TQ, CAN_BTR_TS2_4TQ,
12)) { /* BRP+1: Baud rate prescaler */ 12)) /* BRP+1: Baud rate prescaler */
{
gpio_set(GPIOA, GPIO6); /* LED0 off */ gpio_set(GPIOA, GPIO6); /* LED0 off */
gpio_set(GPIOA, GPIO7); /* LED1 off */ gpio_set(GPIOA, GPIO7); /* LED1 off */
gpio_set(GPIOB, GPIO0); /* LED2 off */ gpio_set(GPIOB, GPIO0); /* LED2 off */
gpio_clear(GPIOB, GPIO1); /* LED3 on */ gpio_clear(GPIOB, GPIO1); /* LED3 on */
/* die because we failed to initialize */ /* Die because we failed to initialize. */
while(1){ while (1)
__asm("nop"); __asm__("nop");
}
} }
/* --- CAN filter 0 init -------------------------------------------- */ /* CAN filter 0 init. */
can_filter_id_mask_32bit_init(CAN1, can_filter_id_mask_32bit_init(CAN1,
0, /* Filter id */ 0, /* Filter ID */
0, /* CAN id */ 0, /* CAN ID */
0, /* CAN id mask */ 0, /* CAN ID mask */
0, /* FIFO assignement (in this case FIFO0) */ 0, /* FIFO assignment (here: FIFO0) */
true); /* Enable the filter */ true); /* Enable the filter. */
/* --- Enable CAN rx interrupt -------------------------------------- */
/* Enable CAN RX interrupt. */
can_enable_irq(CAN1, CAN_IER_FMPIE0); can_enable_irq(CAN1, CAN_IER_FMPIE0);
} }
void sys_tick_handler() void sys_tick_handler(void)
{ {
static int temp32 = 0; static int temp32 = 0;
static u8 data[8] = {0,1,2,0,0,0,0,0}; static u8 data[8] = {0, 1, 2, 0, 0, 0, 0, 0};
temp32++; temp32++;
/* we call this handler every 1ms so 1000ms = 1s on/off */ /* We call this handler every 1ms so 1000ms = 1s on/off. */
if (temp32 == 1000) { if (temp32 == 1000) {
temp32 = 0; temp32 = 0;
/* --- Transmit CAN frame ----------------------------------- */ /* Transmit CAN frame. */
data[0]++; data[0]++;
if(can_transmit(CAN1, if (can_transmit(CAN1,
0, /* (EX/ST)ID: CAN id */ 0, /* (EX/ST)ID: CAN ID */
false, /* IDE: CAN id extended? */ false, /* IDE: CAN ID extended? */
false, /* RTR: Request Transmit? */ false, /* RTR: Request transmit? */
8, /* DLC: Data Length */ 8, /* DLC: Data length */
data) == -1) { data) == -1)
{
gpio_set(GPIOA, GPIO6); /* LED0 off */ gpio_set(GPIOA, GPIO6); /* LED0 off */
gpio_set(GPIOA, GPIO7); /* LED1 off */ gpio_set(GPIOA, GPIO7); /* LED1 off */
gpio_clear(GPIOB, GPIO0); /* LED2 on */ gpio_clear(GPIOB, GPIO0); /* LED2 on */
gpio_set(GPIOB, GPIO1); /* LED3 off */ gpio_set(GPIOB, GPIO1); /* LED3 off */
} }
} }
} }
void usb_lp_can_rx0_isr(void) void usb_lp_can_rx0_isr(void)
{ {
u32 id; u32 id, fmi;
bool ext; bool ext, rtr;
bool rtr; u8 length, data[8];
u32 fmi;
u8 length;
u8 data[8];
can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data); can_receive(CAN1, 0, false, &id, &ext, &rtr, &fmi, &length, data);
if (data[0] & 1) { if (data[0] & 1)
gpio_clear(GPIOA, GPIO6); gpio_clear(GPIOA, GPIO6);
} else { else
gpio_set(GPIOA, GPIO6); gpio_set(GPIOA, GPIO6);
}
if (data[0] & 2) { if (data[0] & 2)
gpio_clear(GPIOA, GPIO7); gpio_clear(GPIOA, GPIO7);
} else { else
gpio_set(GPIOA, GPIO7); gpio_set(GPIOA, GPIO7);
}
if (data[0] & 4) { if (data[0] & 4)
gpio_clear(GPIOB, GPIO0); gpio_clear(GPIOB, GPIO0);
} else { else
gpio_set(GPIOB, GPIO0); gpio_set(GPIOB, GPIO0);
}
if (data[0] & 8) { if (data[0] & 8)
gpio_clear(GPIOB, GPIO1); gpio_clear(GPIOB, GPIO1);
} else { else
gpio_set(GPIOB, GPIO1); gpio_set(GPIOB, GPIO1);
}
can_fifo_release(CAN1, 0); can_fifo_release(CAN1, 0);
} }
int main(void) int main(void)
{ {
rcc_clock_setup_in_hse_8mhz_out_72mhz(); rcc_clock_setup_in_hse_8mhz_out_72mhz();
gpio_setup(); gpio_setup();
can_setup(); can_setup();
systick_setup(); systick_setup();
while(1); /* Halt. */ while (1); /* Halt. */
return 0; return 0;
} }

View File

@ -50,11 +50,11 @@
/* CAN bit timing register (CAN_BTR) */ /* CAN bit timing register (CAN_BTR) */
#define CAN_BTR(can_base) MMIO32(can_base + 0x01C) #define CAN_BTR(can_base) MMIO32(can_base + 0x01C)
/* Registers in the offset range 0x020 to 0x17F are reserved */ /* Registers in the offset range 0x020 to 0x17F are reserved. */
/* --- CAN mailbox registers ----------------------------------------------- */ /* --- CAN mailbox registers ----------------------------------------------- */
/* CAN mailbox / fifo register offsets */ /* CAN mailbox / FIFO register offsets */
#define CAN_MBOX0 0x180 #define CAN_MBOX0 0x180
#define CAN_MBOX1 0x190 #define CAN_MBOX1 0x190
#define CAN_MBOX2 0x1A0 #define CAN_MBOX2 0x1A0
@ -90,7 +90,7 @@
#define CAN_RI0R(can_base) CAN_RIxR(can_base, CAN_FIFO0) #define CAN_RI0R(can_base) CAN_RIxR(can_base, CAN_FIFO0)
#define CAN_RI1R(can_base) CAN_RIxR(can_base, CAN_FIFO1) #define CAN_RI1R(can_base) CAN_RIxR(can_base, CAN_FIFO1)
/* CAN RX FIFO mailbox data length control and time stamp register (CAN_RDTxR) */ /* CAN RX FIFO mailbox data length control & time stamp register (CAN_RDTxR) */
#define CAN_RDTxR(can_base, fifo) MMIO32(can_base + fifo + 0x4) #define CAN_RDTxR(can_base, fifo) MMIO32(can_base + fifo + 0x4)
#define CAN_RDT0R(can_base) CAN_RDTxR(can_base, CAN_FIFO0) #define CAN_RDT0R(can_base) CAN_RDTxR(can_base, CAN_FIFO0)
#define CAN_RDT1R(can_base) CAN_RDTxR(can_base, CAN_FIFO1) #define CAN_RDT1R(can_base) CAN_RDTxR(can_base, CAN_FIFO1)
@ -113,28 +113,29 @@
/* CAN filter mode register (CAN_FM1R) */ /* CAN filter mode register (CAN_FM1R) */
#define CAN_FM1R(can_base) MMIO32(can_base + 0x204) #define CAN_FM1R(can_base) MMIO32(can_base + 0x204)
/* Register offset 0x208 reserved */ /* Register offset 0x208 is reserved. */
/* CAN filter scale register (CAN_FS1R) */ /* CAN filter scale register (CAN_FS1R) */
#define CAN_FS1R(can_base) MMIO32(can_base + 0x20C) #define CAN_FS1R(can_base) MMIO32(can_base + 0x20C)
/* Register offset 0x210 reserved */ /* Register offset 0x210 is reserved. */
/* CAN filter FIFO assignement register (CAN_FFA1R) */ /* CAN filter FIFO assignement register (CAN_FFA1R) */
#define CAN_FFA1R(can_base) MMIO32(can_base + 0x214) #define CAN_FFA1R(can_base) MMIO32(can_base + 0x214)
/* Register offset 0x218 reserved */ /* Register offset 0x218 is reserved. */
/* CAN filter activation register (CAN_FA1R) */ /* CAN filter activation register (CAN_FA1R) */
#define CAN_FA1R(can_base) MMIO32(can_base + 0x21C) #define CAN_FA1R(can_base) MMIO32(can_base + 0x21C)
/* Register offset 0x220 reserved */ /* Register offset 0x220 is reserved. */
/* Registers with offset 0x224 to 0x23F reserved */ /* Registers with offset 0x224 to 0x23F are reserved. */
/* CAN filter bank registers (CAN_FiRx) */ /* CAN filter bank registers (CAN_FiRx) */
/* Connectivity line devices have 28 banks so the bank id spans 0..27 /*
* all other devices have 14 banks so the bank id spans 0..13 * Connectivity line devices have 28 banks so the bank ID spans 0..27
* all other devices have 14 banks so the bank ID spans 0..13.
*/ */
#define CAN_FiR1(can_base, bank) MMIO32(can_base + 0x240 + (bank * 0x8) + 0x0) #define CAN_FiR1(can_base, bank) MMIO32(can_base + 0x240 + (bank * 0x8) + 0x0)
#define CAN_FiR2(can_base, bank) MMIO32(can_base + 0x240 + (bank * 0x8) + 0x4) #define CAN_FiR2(can_base, bank) MMIO32(can_base + 0x240 + (bank * 0x8) + 0x4)
@ -556,8 +557,10 @@
/* 31:14 Reserved, forced to reset value */ /* 31:14 Reserved, forced to reset value */
/* CAN2SB[5:0]: CAN2 start bank /*
* (only on connectivity line devices otherwise reserved) */ * CAN2SB[5:0]: CAN2 start bank
* (only on connectivity line devices otherwise reserved)
*/
#define CAN_FMR_CAN2SB_MASK (0x3F << 8) #define CAN_FMR_CAN2SB_MASK (0x3F << 8)
#define CAN_FMR_CAN2SB_SHIFT 15 #define CAN_FMR_CAN2SB_SHIFT 15
@ -570,7 +573,8 @@
/* 31:28 Reserved, forced by hardware to 0 */ /* 31:28 Reserved, forced by hardware to 0 */
/* FBMx: Filter mode /*
* FBMx: Filter mode
* x is 0..27 should be calculated by a helper function making so many macros * x is 0..27 should be calculated by a helper function making so many macros
* seems like an overkill? * seems like an overkill?
*/ */
@ -579,7 +583,8 @@
/* 31:28 Reserved, forced by hardware to 0 */ /* 31:28 Reserved, forced by hardware to 0 */
/* FSCx: Filter scale configuration /*
* FSCx: Filter scale configuration
* x is 0..27 should be calculated by a helper function making so many macros * x is 0..27 should be calculated by a helper function making so many macros
* seems like an overkill? * seems like an overkill?
*/ */
@ -588,7 +593,8 @@
/* 31:28 Reserved, forced by hardware to 0 */ /* 31:28 Reserved, forced by hardware to 0 */
/* FFAx: Filter scale configuration /*
* FFAx: Filter scale configuration
* x is 0..27 should be calculated by a helper function making so many macros * x is 0..27 should be calculated by a helper function making so many macros
* seems like an overkill? * seems like an overkill?
*/ */
@ -597,7 +603,8 @@
/* 31:28 Reserved, forced by hardware to 0 */ /* 31:28 Reserved, forced by hardware to 0 */
/* FACTx: Filter active /*
* FACTx: Filter active
* x is 0..27 should be calculated by a helper function making so many macros * x is 0..27 should be calculated by a helper function making so many macros
* seems like an overkill? * seems like an overkill?
*/ */
@ -609,39 +616,27 @@
/* --- CAN functions -------------------------------------------------------- */ /* --- CAN functions -------------------------------------------------------- */
void can_reset(u32 canport); void can_reset(u32 canport);
int can_init(u32 canport, int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart,
bool ttcm, bool abom, bool awum, bool nart, bool rflm, bool txfp, bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp);
u32 sjw, u32 ts1, u32 ts2, u32 brp);
void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
u32 fr1, u32 fr2, u32 fr1, u32 fr2, u32 fifo, bool enable);
u32 fifo, bool enable); void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1,
u16 id2, u16 mask2, u32 fifo, bool enable);
void can_filter_id_mask_16bit_init(u32 canport, u32 nr, void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask,
u16 id1, u16 mask1,
u16 id2, u16 mask2,
u32 fifo, bool enable); u32 fifo, bool enable);
void can_filter_id_mask_32bit_init(u32 canport, u32 nr, void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2,
u32 id, u32 mask, u16 id3, u16 id4, u32 fifo, bool enable);
u32 fifo, bool enable); void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2,
void can_filter_id_list_16bit_init(u32 canport, u32 nr,
u16 id1, u16 id2,
u16 id3, u16 id4,
u32 fifo, bool enable);
void can_filter_id_list_32bit_init(u32 canport, u32 nr,
u32 id1, u32 id2,
u32 fifo, bool enable); u32 fifo, bool enable);
void can_enable_irq(u32 canport, u32 irq); void can_enable_irq(u32 canport, u32 irq);
void can_disable_irq(u32 canport, u32 irq); void can_disable_irq(u32 canport, u32 irq);
int can_transmit(u32 canport, u32 id, int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data);
bool ext, bool rtr, void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
u8 length, u8 *data); bool *rtr, u32 *fmi, u8 *length, u8 *data);
void can_receive(u32 canport, u8 fifo, bool release,
u32 *id, bool *ext, bool *rtr, u32 *fmi,
u8 *length, u8 *data);
void can_fifo_release(u32 canport, u8 fifo); void can_fifo_release(u32 canport, u8 fifo);
#endif /* LIBOPENSTM32_CAN_H */ #endif

226
lib/can.c
View File

@ -18,15 +18,14 @@
*/ */
#include <libopenstm32/can.h> #include <libopenstm32/can.h>
#include <libopenstm32/rcc.h> #include <libopenstm32/rcc.h>
void can_reset(u32 canport) void can_reset(u32 canport)
{ {
if(canport == CAN1){ if (canport == CAN1) {
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST);
}else{ } else {
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST);
} }
@ -40,197 +39,162 @@ int can_init(u32 canport,
u32 can_msr_inak_timeout = 0x0000FFFF; u32 can_msr_inak_timeout = 0x0000FFFF;
int ret = 0; int ret = 0;
/* Exit from sleep mode */ /* Exit from sleep mode. */
CAN_MCR(canport) &= ~CAN_MCR_SLEEP; CAN_MCR(canport) &= ~CAN_MCR_SLEEP;
/* Request initialization "enter" */ /* Request initialization "enter". */
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) && while ((wait_ack != can_msr_inak_timeout) &&
((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) { ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) {
wait_ack++; 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) {
ret = 1; ret = 1;
} else { } else {
/* 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;
}
/* Set bit timings */ /* Set bit timings. */
CAN_BTR(canport) = sjw | CAN_BTR(canport) = sjw | ts2 | ts1 |
ts2 |
ts1 |
(u32)(CAN_BTR_BRP_MASK & (brp - 1)); (u32)(CAN_BTR_BRP_MASK & (brp - 1));
/* 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 = 0x00000000;
while ((wait_ack != can_msr_inak_timeout) && while ((wait_ack != can_msr_inak_timeout) &&
((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) { ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) {
wait_ack++; 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;
} }
void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode,
u32 fr1, u32 fr2, u32 fr1, u32 fr2, u32 fifo, bool enable)
u32 fifo, bool enable)
{ {
u32 filter_select_bit = 0x00000001 << nr; u32 filter_select_bit = 0x00000001 << nr;
/* Request initialization "enter" */ /* Request initialization "enter". */
CAN_FMR(canport) |= CAN_FMR_FINIT; CAN_FMR(canport) |= CAN_FMR_FINIT;
/* Deactivate the filter */ /* Deactivate the filter. */
CAN_FA1R(canport) &= ~filter_select_bit; CAN_FA1R(canport) &= ~filter_select_bit;
if (scale_32bit) { if (scale_32bit) {
/* Set 32-bit scale for the filter */ /* Set 32-bit scale for the filter. */
CAN_FS1R(canport) |= filter_select_bit; CAN_FS1R(canport) |= filter_select_bit;
} else { } else {
/* Set 16-bit scale for the filter */ /* Set 16-bit scale for the filter. */
CAN_FS1R(canport) &= ~filter_select_bit; CAN_FS1R(canport) &= ~filter_select_bit;
} }
if (id_list_mode) { if (id_list_mode) {
/* Set filter mode to id list mode */ /* Set filter mode to ID list mode. */
CAN_FM1R(canport) |= filter_select_bit; CAN_FM1R(canport) |= filter_select_bit;
} else { } else {
/* Set filter mode to id/mask mode */ /* Set filter mode to id/mask mode. */
CAN_FM1R(canport) &= ~filter_select_bit; CAN_FM1R(canport) &= ~filter_select_bit;
} }
/* Set the first filter register */ /* Set the first filter register. */
CAN_FiR1(canport, nr) = fr1; CAN_FiR1(canport, nr) = fr1;
/* Set the second filter register */ /* Set the second filter register. */
CAN_FiR2(canport, nr) = fr2; CAN_FiR2(canport, nr) = fr2;
if (fifo) { /* Select FIFO0 or FIFO1 as filter assignement. */
/* Select FIFO1 as filter assignement */ if (fifo)
CAN_FFA1R(canport) |= filter_select_bit; CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */
} else { else
/* Select FIFO0 as filter assignement */ CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */
CAN_FFA1R(canport) &= ~filter_select_bit;
}
if (enable) { if (enable)
/* Activate the filter */ CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */
CAN_FA1R(canport) |= filter_select_bit;
}
/* Request initialization "leave" */ /* Request initialization "leave". */
CAN_FMR(canport) &= ~CAN_FMR_FINIT; CAN_FMR(canport) &= ~CAN_FMR_FINIT;
} }
void can_filter_id_mask_16bit_init(u32 canport, u32 nr, void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1,
u16 id1, u16 mask1, u16 id2, u16 mask2, u32 fifo, bool enable)
u16 id2, u16 mask2,
u32 fifo, bool enable)
{ {
can_filter_init(canport, nr, false, false, can_filter_init(canport, nr, false, false,
((u32)id1 << 16) | (u32)mask1, ((u32)id1 << 16) | (u32)mask1,
((u32)id2 << 16) | (u32)mask2, ((u32)id2 << 16) | (u32)mask2, fifo, enable);
fifo, enable);
} }
void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask,
void can_filter_id_mask_32bit_init(u32 canport, u32 nr,
u32 id, u32 mask,
u32 fifo, bool enable) u32 fifo, bool enable)
{ {
can_filter_init(canport, nr, true, false, can_filter_init(canport, nr, true, false, id, mask, fifo, enable);
id, mask,
fifo, enable);
} }
void can_filter_id_list_16bit_init(u32 canport, u32 nr, void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2,
u16 id1, u16 id2, u16 id3, u16 id4, u32 fifo, bool enable)
u16 id3, u16 id4,
u32 fifo, bool enable)
{ {
can_filter_init(canport, nr, false, true, can_filter_init(canport, nr, false, true,
((u32)id1 << 16) | (u32)id2, ((u32)id1 << 16) | (u32)id2,
((u32)id3 << 16) | (u32)id4, ((u32)id3 << 16) | (u32)id4, fifo, enable);
fifo, enable);
} }
void can_filter_id_list_32bit_init(u32 canport, u32 nr, void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2,
u32 id1, u32 id2,
u32 fifo, bool enable) u32 fifo, bool enable)
{ {
can_filter_init(canport, nr, true, true, can_filter_init(canport, nr, true, true, id1, id2, fifo, enable);
id1, id2,
fifo, enable);
} }
void can_enable_irq(u32 canport, u32 irq) void can_enable_irq(u32 canport, u32 irq)
{ {
CAN_IER(canport) |= irq; CAN_IER(canport) |= irq;
} }
void can_disable_irq(u32 canport, u32 irq) void can_disable_irq(u32 canport, u32 irq)
{ {
CAN_IER(canport) &= ~irq; CAN_IER(canport) &= ~irq;
} }
int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
{ {
int ret = 0; int ret = 0, i;
u32 mailbox = 0; u32 mailbox = 0;
int i;
if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) { if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) {
ret = 0; ret = 0;
@ -245,42 +209,39 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
ret = -1; ret = -1;
} }
if (ret != -1) { /* check if we have an empty mailbox */ if (ret != -1) { /* Check if we have an empty mailbox. */
if (ext) { if (ext) {
/* Set extended id */ /* Set extended ID. */
CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_EXID_SHIFT; CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_EXID_SHIFT;
/* Set extended id indicator bit */ /* Set extended ID indicator bit. */
CAN_TIxR(canport, mailbox) |= CAN_TIxR_IDE; CAN_TIxR(canport, mailbox) |= CAN_TIxR_IDE;
} else { } else {
/* Set standard id */ /* Set standard ID. */
CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_STID_SHIFT; CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_STID_SHIFT;
/* Unset extended id indicator bit */ /* Unset extended ID indicator bit. */
CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_IDE; CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_IDE;
} }
if (rtr) { /* Set/clear remote transmission request bit. */
/* Set remote transmission request bit */ if (rtr)
CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; /* Set */
} else { else
/* Unset remote transmission request bit */ CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_RTR; /* Clear */
CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_RTR;
}
/* Set the DLC */ /* Set the DLC. */
CAN_TDTxR(canport, mailbox) &= 0xFFFFFFFF0; CAN_TDTxR(canport, mailbox) &= 0xFFFFFFFF0;
CAN_TDTxR(canport, mailbox) |= length & CAN_TDTxR_DLC_MASK; CAN_TDTxR(canport, mailbox) |= length & CAN_TDTxR_DLC_MASK;
/* Set the data */ /* Set the data. */
CAN_TDLxR(canport, mailbox) = 0; CAN_TDLxR(canport, mailbox) = 0;
CAN_TDHxR(canport, mailbox) = 0; CAN_TDHxR(canport, mailbox) = 0;
for (i = 0; (i < 4) && (i < length); i++) { for (i = 0; (i < 4) && (i < length); i++)
CAN_TDLxR(canport, mailbox) |= (u32)data[i] << (8 * i); CAN_TDLxR(canport, mailbox) |= (u32)data[i] << (8 * i);
} for (i = 4; (i < 8) && (i < length); i++)
for (i = 4; (i < 8) && (i < length); i++) { CAN_TDHxR(canport, mailbox)
CAN_TDHxR(canport, mailbox) |= (u32)data[i] << (8 * (i-4)); |= (u32)data[i] << (8 * (i - 4));
}
/* Request transmission */ /* Request transmission. */
CAN_TIxR(canport, mailbox) |= CAN_TIxR_TXRQ; CAN_TIxR(canport, mailbox) |= CAN_TIxR_TXRQ;
} }
@ -289,64 +250,57 @@ 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;
}
} }
void can_receive(u32 canport, u8 fifo, bool release, void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
u32 *id, bool *ext, bool *rtr, u32 *fmi, bool *rtr, u32 *fmi, u8 *length, u8 *data)
u8 *length, u8 *data)
{ {
u32 fifo_id = 0; u32 fifo_id = 0;
int i; int i;
if (fifo == 0) { if (fifo == 0)
fifo_id = CAN_FIFO0; fifo_id = CAN_FIFO0;
} else { else
fifo_id = CAN_FIFO1; fifo_id = CAN_FIFO1;
}
/* get type of CAN id and CAN id */ /* Get type of CAN ID and CAN ID. */
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_MASK) >
CAN_RIxR_EXID_SHIFT); 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_MASK) >
CAN_RIxR_STID_SHIFT); CAN_RIxR_STID_SHIFT);
} }
/* get request transmit flag */ /* Get request 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;
}
/* get filter match id */ /* Get filter match ID. */
*fmi = ((CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_FMI_MASK) > *fmi = ((CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_FMI_MASK) >
CAN_RDTxR_FMI_SHIFT); CAN_RDTxR_FMI_SHIFT);
/* get data length */ /* Get data length. */
*length = CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_DLC_MASK; *length = CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_DLC_MASK;
/* get data */ /* Get data. */
for (i=0; (i < 4) && (i < *length); i++) { for (i = 0; (i < 4) && (i < *length); i++)
data[i] = (CAN_RDLxR(canport, fifo_id) >> (8 * i)) & 0xFF; data[i] = (CAN_RDLxR(canport, fifo_id) >> (8 * i)) & 0xFF;
}
for (i=4; (i < 8) && (i < *length); i++) { for (i = 4; (i < 8) && (i < *length); i++)
data[i] = (CAN_RDHxR(canport, fifo_id) >> (8 * (i - 4))) & 0xFF; data[i] = (CAN_RDHxR(canport, fifo_id) >> (8 * (i - 4))) & 0xFF;
}
/* release the fifo */ /* Release the FIFO. */
if (release) { if (release)
can_fifo_release(CAN1, 0); can_fifo_release(CAN1, 0);
}
} }