]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/ecos_lpc2138_sja1000/canOpenDriver.c
ADDED LED to TESTMASTERSLAVE. It looks nice!
[CanFestival-3.git] / drivers / ecos_lpc2138_sja1000 / canOpenDriver.c
1 /*
2 This file is part of CanFestival, a library implementing CanOpen Stack.
3
4  Author: Christian Fortin (canfestival@canopencanada.ca)
5
6 See COPYING file for copyrights details.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22
23 #include <stdlib.h>
24
25 #include <sys/time.h>
26 #include <signal.h>
27
28 #include <cyg/kernel/kapi.h>
29 #include <cyg/hal/hal_arch.h>
30
31 #include "applicfg.h"
32 #include <data.h>
33 #include <def.h>
34 #include <can.h>
35 #include <can_driver.h>
36 #include <objdictdef.h>
37 #include <objacces.h>
38
39 #include "lpc2138_pinout.h"
40 #include "lpc2138_defs.h"
41 #include "lpc2138.h"
42
43 #include "sja1000.h"
44
45 #include "time_slicer.h"
46
47
48 /*
49         SEND/RECEIVE
50 */
51 CAN_HANDLE canOpen(s_BOARD *board)
52 {
53         return NULL;
54 }
55
56 /***************************************************************************/
57 int canClose(CAN_HANDLE fd0)
58 {
59         return 0;
60 }
61
62 UNS8 canReceive(CAN_HANDLE fd0, Message *m)
63 /*
64 Message *m :
65         typedef struct {
66           SHORT_CAN cob_id;     // l'ID du mesg
67           UNS8 rtr;             // remote transmission request. 0 if not rtr,
68                                 // 1 for a rtr message
69           UNS8 len;             // message length (0 to 8)
70           UNS8 data[8];         // data
71         } Message;
72
73 Fill the structure "Message" with data from the CAN receive buffer
74
75 return : 0
76 */
77 {
78 /*
79         the sja1000 must be set to the PeliCAN mode
80 */
81     m->cob_id.w = sja1000_read(16) + (sja1000_read(17)<<8); // IO_PORTS_16(CAN0 + CANRCVID) >> 5
82
83     m->rtr = (sja1000_read(17) >> 4) & 0x01; // (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01; 
84
85     m->len = sja1000_read(18);
86
87     m->data[0] = sja1000_read(19);
88     m->data[1] = sja1000_read(20);
89     m->data[2] = sja1000_read(21);
90     m->data[3] = sja1000_read(22);
91     m->data[4] = sja1000_read(23);
92     m->data[5] = sja1000_read(24);
93     m->data[6] = sja1000_read(25);
94     m->data[7] = sja1000_read(26);
95
96     sja1000_write(CMR, 1<<RRB );        // release fifo
97
98     return 0;
99 }
100
101
102 UNS8 canSend(CAN_HANDLE fd0, Message *m)
103 /*
104 Message *m :
105         typedef struct {
106           SHORT_CAN cob_id;     // l'ID du mesg
107           UNS8 rtr;                     // remote transmission request. 0 if not rtr,
108                                         // 1 for a rtr message
109           UNS8 len;                     // message length (0 to 8)
110           UNS8 data[8];         // data
111         } Message;
112
113 Send the content of the structure "Message" to the CAN transmit buffer
114
115 return : 0 if OK, 1 if error
116 */
117 {
118     unsigned char rec_buf;
119
120     do
121     {
122         rec_buf = sja1000_read(SR);
123     }
124     while ( (rec_buf & (1<<TBS))==0);           // loop until TBS high
125
126     sja1000_write(16, m->cob_id.w & 0xff); 
127     sja1000_write(17, (m->cob_id.w >> 8) & 0xff);
128     sja1000_write(18, m->len);
129
130     sja1000_write(19, m->data[0]); // tx data 1
131     sja1000_write(20, m->data[1]); // tx data 2
132     sja1000_write(21, m->data[2]); // tx data 3
133     sja1000_write(22, m->data[3]); // tx data 4
134     sja1000_write(23, m->data[4]); // tx data 5
135     sja1000_write(24, m->data[5]); // tx data 6
136     sja1000_write(25, m->data[6]); // tx data 7
137     sja1000_write(26, m->data[7]); // tx data 8
138
139     sja1000_write(CMR,( (0<<SRR) | (0<<CDO) | (0<<RRB) | (0<<AT) | (1<<TR)));
140     do
141     {
142         rec_buf = sja1000_read(SR);
143     }
144     while ( (rec_buf & (1<<TBS))==0);           // loop until TBS high
145
146     return 0;
147 }
148
149
150 /*
151         SEQUENTIAL I/O TO FLASH
152         those functions are for continous writing and read
153 */
154
155
156 int nvram_open(void)
157 {
158         int n = NVRAM_BLOCK_SIZE / sizeof(unsigned int);
159
160         /* some actions to initialise the flash */
161         data_len = 0;
162         data_num_pages = 0;
163
164         data_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
165         memset(data_page, 0, sizeof(unsigned int)*n);
166
167         if (data_page == NULL)
168                 return -1;
169
170         regs_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
171         memset(regs_page, 0, sizeof(unsigned int)*n);
172         if (regs_page == NULL)
173                 return -2;
174
175         iat_flash_read_regs();
176
177         /* start the data at the location specified in the registers */ 
178         if (0) /* for now it is 0, but put here a test to know whether
179                   or not the NVRAM has been written before */
180                 data_addr = regs_page[1];
181         else
182                 data_addr = NVRAM_BLOCK_SIZE; /* let start at block 1 */
183
184         return 0;
185 }
186
187
188 void nvram_close(void)
189 {
190         /* write the last page before closing */
191         iat_flash_write_page(data_addr);
192
193         /* some actions to end accessing the flash */
194         free(data_page);
195
196         regs_page[4] = data_num_pages;
197         /* write the registers to the NVRAM before closing */
198         iat_flash_write_regs();
199         free(regs_page);
200 }
201
202
203 void nvram_set_pos(UNS32 pos)
204 /* set the current position in the NVRAM to pos */
205 {
206 }
207
208
209 void nvram_new_firmwave()
210 {
211 /*
212         this function is called whenever a new firmware is about
213         to be written in the NVRAM
214 */
215         data_addr = regs_page[1] + regs_page[4]*NVRAM_BLOCK_SIZE;
216         if (data_addr > NVRAM_MAX_SIZE)
217                 data_addr = NVRAM_BLOCK_SIZE;
218 }
219
220 int _get_data_len(int type)
221 {
222         int len = 0; /* number of bytes */
223         switch(type)
224         {
225                 case  boolean:
226                         len = 1;
227                         break;
228
229                 case  int8:
230                 case  uint8:
231                         len = 1;
232                         break;
233                 case  int16:
234                 case  uint16:
235                         len = 2;
236                         break;
237                 case  int24:
238                 case  uint24:
239                         len = 3;
240                         break;
241                 case  int32:
242                 case  uint32:
243                 case  real32:
244                         len = 4;
245                         break;
246                 case  int40:
247                 case  uint40:
248                         len = 5;
249                         break;
250                 case  int48:
251                 case  uint48:
252                         len = 6;
253                         break;
254                 case  int56:
255                 case  uint56:
256                         len = 7;
257                         break;
258                 case  int64:
259                 case  uint64:
260                 case  real64:
261                         len = 8;
262                         break;
263 #if 0
264 /* TO DO */
265                 case  visible_string:
266                 case  octet_string:
267                 case  unicode_string:
268                 case  time_of_day:
269                 case  time_difference:
270 #endif
271         }
272
273         return len;
274 }
275
276
277 char nvram_write_data(int type, int access_attr, void *data)
278 /* return 0 if successfull */
279 {
280         int len = _get_data_len(type);
281
282         if (data_len+len > NVRAM_BLOCK_SIZE)
283         {
284                 iat_flash_write_page(data_addr);
285                 data_len = 0;
286                 data_addr += NVRAM_BLOCK_SIZE; 
287
288                 /* wrap-around address pointer */
289                 if (data_addr > NVRAM_MAX_SIZE)
290                         data_addr = NVRAM_BLOCK_SIZE;
291
292                 data_num_pages++;
293         }
294                 
295         memcpy(((char *)data_page)+data_len, data, len);
296
297         data_len += len;
298
299         return 0;
300 }
301
302
303 char nvram_read_data(int type, int access_attr, void *data)
304 /* return 0 if successful */
305 {
306         int len = _get_data_len(type);
307
308         if (data_len+len > NVRAM_BLOCK_SIZE)
309         {
310                 data_addr += NVRAM_BLOCK_SIZE;
311
312                 /* wrap-around address pointer */
313                 if (data_addr > NVRAM_MAX_SIZE)
314                         data_addr = NVRAM_BLOCK_SIZE;
315
316                 iat_flash_read_page(data_addr);
317                 data_len = 0;           
318         }
319
320         memcpy(data, ((char *)data_page)+data_len, len);
321
322         data_len += len;
323
324         return 0;
325 }
326
327 /*
328         NVRAM registers at block 0
329         pos        description
330         0          version of the current dictionnary
331         1          starting address for data block
332         2          date of last writing
333         3          address of the previous dictionnary          
334         4          size in pages of the current dict
335 */
336 void nvram_write_reg(UNS32 reg, UNS16 pos)
337 /* write reg at the position in the data block 0 */
338 {
339         regs_page[pos] = reg;
340 }
341
342 UNS32 nvram_read_reg(UNS16 pos)
343 /* read reg at the position in the data block 0 */
344 {
345         return regs_page[pos];
346 }
347
348
349 /*
350         LED
351 */
352
353 void led_set_redgreen(UNS8 bits)
354 /* bits : each bit of this uns8 is assigned a led 
355           0=off, 1=on
356 */
357 {
358         lpc2138_redgreenled_set(bits);
359 }
360