1 #include "can/lpc17xx_can.h"
3 static void CAN_configPin();
4 static void CAN_setBusTiming(uint32_t baudrate);
6 //------------------------------------------
8 static void CAN_configPin(){
10 // CAN1 - select P0.0 as RD1. P0.1 as TD1
15 uint8_t pinsel0_val = 1;
16 uint8_t pinmode0_val = 0;
17 uint8_t pinmode_od0_val = 0;
21 pinsel0 &= ~CAN1_RX_MASK;
22 pinsel0 &= ~CAN1_TX_MASK;
23 pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
24 pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
28 pinmode0 &= ~CAN1_RX_MASK;
29 pinmode0 &= ~CAN1_TX_MASK;
30 pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
31 pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
34 pinmode_od0 = PINMODE_OD0;
36 pinmode_od0 |= CAN1_RX_BIT;
37 pinmode_od0 |= CAN1_TX_BIT;
40 pinmode_od0 &= ~CAN1_RX_BIT;
41 pinmode_od0 &= ~CAN1_TX_BIT;
43 PINMODE_OD0 = pinmode_od0;
48 void CAN_send(canmsg_t* msg){
53 // check status of TB1
54 while (!(CAN1SR & (1<<2))){}
56 CAN1TFI1 &= ~0x000F0000;
57 CAN1TFI1 |= (msg->length)<<16;
60 if(msg->flags & MSG_EXT)
66 if(msg->flags & MSG_RTR)
74 // write first 4 data bytes
78 data |= (msg->data[i])<<(i*8);
82 // write second 4 data bytes
86 data |= (msg->data[i])<<((i-4)*8);
89 // write transmission request
94 void CAN_setBusTiming(uint32_t baudrate){
99 uint8_t tq_numb; // number of time quantum
100 uint8_t TSEG1, TSEG2;
106 // 0 = the bus is sampled once
109 // the Synchronization Jump Width (this value plus one)
112 // get clock divide for CAN1
113 div = __mfld2val(PCLK_CAN1_MASK, PCLKSEL0);
125 // only for CAN, for other peripherials '11' value means div=8
131 PCLK_CAN = system_frequency / div;
133 res = PCLK_CAN / baudrate;
136 // calculation of tq_numb - number of time quantum (must be in <8,25>)
137 // tq_numb = TSEG1 + TSEG2 + 3
139 for(tq_numb=25; tq_numb>=8; tq_numb--){
141 if ((res%tq_numb)==0){
143 // Baud Rate Prescaler. The PCLK clock is divided by (this value plus one) to produce the CAN clock.
144 BRP = (res / tq_numb) - 1;
146 // sync. segment allways 1 tq
149 // number of tq from the sample point to the next nominal Sync. point (this value plus one)
150 TSEG2 = (tq_numb/3) - 1;
152 // number of tq from Sync. point to the sample point (this value plus one)
153 TSEG1 = tq_numb - (tq_numb/3) - 1;
159 CAN1BTR = ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0));
163 void CAN_init(uint32_t baudrate)
170 // configure CAN1 pins
173 // turn on power and clock for CAN1
176 // set clock divide for CAN1
178 val = 0x00; // 00 PCLK_peripheral = CCLK/4
180 pclksel0 &= ~PCLK_CAN1_MASK;
181 pclksel0 &= ~PCLK_CAN2_MASK;
182 pclksel0 &= ~PCLK_ACF_MASK;
183 pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
184 pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
185 pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
191 // disable all CAN interrupts
194 // reset value of Global Status Register (global controller status and error counters)
197 // request command to release Rx, Tx buffer and clear data overrun
198 CAN1CMR = (1<<1)|(1<<2)|(1<<3);
200 // read to clear interrupt pending in Interrupt Capture Register
204 CAN_setBusTiming(baudrate);
206 // return to normal operating