1 | /*****************************************************************************
|
2 | * can.c: CAN module API file for NXP LPC17xx Family Microprocessors
|
3 | *
|
4 | * Copyright(C) 2009, NXP Semiconductor
|
5 | * All rights reserved.
|
6 | *
|
7 | * History
|
8 | * 2009.05.27 ver 1.00 Prelimnary version, first Release
|
9 | * 13.10.2010 ver 1.1 Änderung bezüglich CAN2
|
10 | *****************************************************************************/
|
11 | #include "lpc17xx.h"
|
12 | #include "type.h"
|
13 | #include "can.h"
|
14 |
|
15 | /* Receive Queue: one queue for each CAN port */
|
16 | extern CAN_MSG MsgBuf_RX1;
|
17 | extern volatile uint32_t CAN1RxDone;
|
18 | volatile uint32_t CANStatus;
|
19 | uint32_t CAN1RxCount = 0;
|
20 | uint32_t CAN1ErrCount = 0;
|
21 |
|
22 | /******************************************************************************
|
23 | ** Function name: CAN_ISR_Rx1
|
24 | **
|
25 | ** Descriptions: CAN Rx1 interrupt handler
|
26 | **
|
27 | ** parameters: None
|
28 | ** Returned value: None
|
29 | **
|
30 | ******************************************************************************/
|
31 | void CAN_ISR_Rx1( void )
|
32 | {
|
33 | uint32_t * pDest;
|
34 |
|
35 | /* initialize destination pointer */
|
36 | pDest = (uint32_t *)&MsgBuf_RX1;
|
37 | *pDest = LPC_CAN1->RFS; /* Frame */
|
38 |
|
39 | pDest++;
|
40 | *pDest = LPC_CAN1->RID; /* ID */
|
41 |
|
42 |
|
43 | pDest++;
|
44 | *pDest = LPC_CAN1->RDA; /* Data A */
|
45 |
|
46 |
|
47 | pDest++;
|
48 | *pDest = LPC_CAN1->RDB; /* Data B */
|
49 |
|
50 |
|
51 | CAN1RxDone = TRUE;
|
52 | LPC_CAN1->CMR = 0x04; /* release receive buffer */
|
53 | return;
|
54 | }
|
55 |
|
56 | /*****************************************************************************
|
57 | ** Function name: CAN_Handler
|
58 | **
|
59 | ** Descriptions: CAN interrupt handler
|
60 | **
|
61 | ** parameters: None
|
62 | ** Returned value: None
|
63 | **
|
64 | *****************************************************************************/
|
65 | void CAN_IRQHandler(void)
|
66 | {
|
67 |
|
68 | CANStatus = LPC_CANCR->CANRxSR;
|
69 | if ( CANStatus & (1 << 8) )
|
70 | {
|
71 | CAN1RxCount++;
|
72 | CAN_ISR_Rx1();
|
73 | }
|
74 |
|
75 | if ( LPC_CAN1->GSR & (1 << 6 ) )
|
76 | {
|
77 | /* The error count includes both TX and RX */
|
78 | CAN1ErrCount = LPC_CAN1->GSR >> 16;
|
79 | }
|
80 | return;
|
81 | }
|
82 |
|
83 | /******************************************************************************
|
84 | ** Function name: CAN_Init
|
85 | **
|
86 | ** Descriptions: Initialize CAN, install CAN interrupt handler
|
87 | **
|
88 | ** parameters: bitrate
|
89 | ** Returned value: true or false, false if initialization failed.
|
90 | **
|
91 | ******************************************************************************/
|
92 | uint32_t CAN_Init( uint32_t can_btr )
|
93 | {
|
94 | CAN1RxDone = FALSE;
|
95 |
|
96 | LPC_SC->PCONP |= ((1<<13)|(1<<14)); /* Enable CAN1 and CAN2 clock */
|
97 |
|
98 | LPC_PINCON->PINSEL0 &= ~0x0000000F; /* CAN1 is p0.0 and p0.1 */
|
99 | LPC_PINCON->PINSEL0 |= 0x00000005;
|
100 |
|
101 | LPC_CAN1->MOD = 1; /* Reset CAN */
|
102 | LPC_CAN1->IER = 0; /* Disable Receive Interrupt */
|
103 | LPC_CAN1->GSR = 0; /* Reset error counter when CANxMOD is in reset */
|
104 |
|
105 | LPC_CAN1->BTR = can_btr;
|
106 | LPC_CAN1->MOD = 0x0; /* CAN in normal operation mode */
|
107 |
|
108 | LPC_CAN1->IER = 0x01; /* Enable receive interrupts */
|
109 | return( TRUE );
|
110 | }
|
111 |
|
112 | /******************************************************************************
|
113 | ** Function name: CAN_SetACCF_Lookup
|
114 | **
|
115 | ** Descriptions: Initialize CAN, install CAN interrupt handler
|
116 | **
|
117 | ** parameters: bitrate
|
118 | ** Returned value: true or false, false if initialization failed.
|
119 | **
|
120 | ******************************************************************************/
|
121 | void CAN_SetACCF_Lookup( void )
|
122 | {
|
123 | uint32_t address = 0;
|
124 | uint32_t i;
|
125 | uint32_t ID_high, ID_low;
|
126 |
|
127 | /* Set explicit standard Frame */
|
128 | LPC_CANAF->SFF_sa = address;
|
129 | for ( i = 0; i < ACCF_IDEN_NUM; i += 2 )
|
130 | {
|
131 | ID_low = (i << 29) | (EXP_STD_ID << 16);
|
132 | ID_high = ((i+1) << 13) | (EXP_STD_ID << 0);
|
133 | *((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address)) = ID_low | ID_high;
|
134 | address += 4;
|
135 | }
|
136 |
|
137 | /* Set group standard Frame */
|
138 | LPC_CANAF->SFF_GRP_sa = address;
|
139 | for ( i = 0; i < ACCF_IDEN_NUM; i += 2 )
|
140 | {
|
141 | ID_low = (i << 29) | (GRP_STD_ID << 16);
|
142 | ID_high = ((i+1) << 13) | (GRP_STD_ID << 0);
|
143 | *((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address)) = ID_low | ID_high;
|
144 | address += 4;
|
145 | }
|
146 |
|
147 | /* Set explicit extended Frame */
|
148 | LPC_CANAF->EFF_sa = address;
|
149 | for ( i = 0; i < ACCF_IDEN_NUM; i++ )
|
150 | {
|
151 | ID_low = (i << 29) | (EXP_EXT_ID << 0);
|
152 | *((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address)) = ID_low;
|
153 | address += 4;
|
154 | }
|
155 |
|
156 | /* Set group extended Frame */
|
157 | LPC_CANAF->EFF_GRP_sa = address;
|
158 | for ( i = 0; i < ACCF_IDEN_NUM; i++ )
|
159 | {
|
160 | ID_low = (i << 29) | (GRP_EXT_ID << 0);
|
161 | *((volatile uint32_t *)(LPC_CANAF_RAM_BASE + address)) = ID_low;
|
162 | address += 4;
|
163 | }
|
164 |
|
165 | /* Set End of Table */
|
166 | LPC_CANAF->ENDofTable = address;
|
167 | return;
|
168 | }
|
169 |
|
170 | /******************************************************************************
|
171 | ** Function name: CAN_SetACCF
|
172 | **
|
173 | ** Descriptions: Set acceptance filter and SRAM associated with
|
174 | **
|
175 | ** parameters: ACMF mode
|
176 | ** Returned value: None
|
177 | **
|
178 | **
|
179 | ******************************************************************************/
|
180 | void CAN_SetACCF( uint32_t ACCFMode )
|
181 | {
|
182 | switch ( ACCFMode )
|
183 | {
|
184 | case ACCF_OFF:
|
185 | LPC_CANAF->AFMR = ACCFMode;
|
186 | LPC_CAN1->MOD = LPC_CAN2->MOD = 1; // Reset CAN
|
187 | LPC_CAN1->IER = LPC_CAN2->IER = 0; // Disable Receive Interrupt
|
188 | LPC_CAN1->GSR = LPC_CAN2->GSR = 0; // Reset error counter when CANxMOD is in reset
|
189 | break;
|
190 |
|
191 | case ACCF_BYPASS:
|
192 | LPC_CANAF->AFMR = ACCFMode;
|
193 | break;
|
194 |
|
195 | case ACCF_ON:
|
196 | case ACCF_FULLCAN:
|
197 | LPC_CANAF->AFMR = ACCF_OFF;
|
198 | CAN_SetACCF_Lookup();
|
199 | LPC_CANAF->AFMR = ACCFMode;
|
200 | break;
|
201 |
|
202 | default:
|
203 | break;
|
204 | }
|
205 | return;
|
206 | }
|
207 |
|
208 | /******************************************************************************
|
209 | ** Function name: CAN1_SendMessage
|
210 | **
|
211 | ** Descriptions: Send message block to CAN1
|
212 | **
|
213 | ** parameters: pointer to the CAN message
|
214 | ** Returned value: true or false, if message buffer is available,
|
215 | ** message can be sent successfully, return TRUE,
|
216 | ** otherwise, return FALSE.
|
217 | **
|
218 | ******************************************************************************/
|
219 | uint32_t CAN1_SendMessage( CAN_MSG *pTxBuf )
|
220 | {
|
221 | uint32_t CANStatus;
|
222 |
|
223 | CANStatus = LPC_CAN1->SR;
|
224 | if ( CANStatus & 0x00000004 )
|
225 | {
|
226 | LPC_CAN1->TFI1 = pTxBuf->Frame & 0xC00F0000;
|
227 | LPC_CAN1->TID1 = pTxBuf->MsgID;
|
228 | LPC_CAN1->TDA1 = pTxBuf->DataA;
|
229 | LPC_CAN1->TDB1 = pTxBuf->DataB;
|
230 | LPC_CAN1->CMR = 0x21;
|
231 | return ( TRUE );
|
232 | }
|
233 | else if ( CANStatus & 0x00000400 )
|
234 | {
|
235 | LPC_CAN1->TFI2 = pTxBuf->Frame & 0xC00F0000;
|
236 | LPC_CAN1->TID2 = pTxBuf->MsgID;
|
237 | LPC_CAN1->TDA2 = pTxBuf->DataA;
|
238 | LPC_CAN1->TDB2 = pTxBuf->DataB;
|
239 | LPC_CAN1->CMR = 0x41;
|
240 | return ( TRUE );
|
241 | }
|
242 | else if ( CANStatus & 0x00040000 )
|
243 | {
|
244 | LPC_CAN1->TFI3 = pTxBuf->Frame & 0xC00F0000;
|
245 | LPC_CAN1->TID3 = pTxBuf->MsgID;
|
246 | LPC_CAN1->TDA3 = pTxBuf->DataA;
|
247 | LPC_CAN1->TDB3 = pTxBuf->DataB;
|
248 | LPC_CAN1->CMR = 0x81;
|
249 | return ( TRUE );
|
250 | }
|
251 | return ( FALSE );
|
252 | }
|
253 |
|
254 | /******************************************************************************
|
255 | ** End Of File
|
256 | ******************************************************************************/
|
257 |
|
258 |
|
259 | und hier mein main Programm wobei ich weiß das dieses mit Sicherheit so nicht korrekt ist aber deshalb brauch ich ja eure Hilfe =)
|
260 |
|
261 | [c]
|
262 |
|
263 | /******************************Header Dateien einbinden***********************************/
|
264 | #include "lpc17xx.h"
|
265 | #include "type.h"
|
266 | #include "can.h"
|
267 |
|
268 | CAN_MSG MsgBuf_TX1, MsgBuf_TX2; /* TX and RX Buffers for CAN message */
|
269 | CAN_MSG MsgBuf_RX1, MsgBuf_RX2; /* TX and RX Buffers for CAN message */
|
270 |
|
271 | volatile uint32_t CAN1RxDone = FALSE, CAN2RxDone = FALSE;
|
272 |
|
273 |
|
274 | /*****************************************************************************
|
275 | ** Function name: main
|
276 | **
|
277 | ** Descriptions: main routine for CAN module test
|
278 | **
|
279 | ** parameters: None
|
280 | ** Returned value: int
|
281 | **
|
282 | *****************************************************************************/
|
283 | int main( void )
|
284 | {
|
285 |
|
286 | SystemInit();
|
287 | INOUT_Def();
|
288 |
|
289 | /* Please note, the bit timing is based on the setting of the
|
290 | PCLK, if different PCLK is used, please read can.h carefully
|
291 | and set your CAN bit timing accordingly. */
|
292 | //CAN_Init( BITRATE100K24MHZ );
|
293 | CAN_Init(BITRATE500K15MHZ);
|
294 | NVIC_EnableIRQ(CAN_IRQn);
|
295 | CAN_SetACCF(ACCF_BYPASS);
|
296 | CAN_SetACCF_Lookup();
|
297 | while(1)
|
298 | {
|
299 |
|
300 | if(!(LPC_CAN1->RID & 0x23))
|
301 | {
|
302 | LPC_GPIO2->FIOPIN &= ~(0x000000FF);
|
303 | }
|
304 |
|
305 | }
|
306 |
|
307 | }
|