2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Author: Christian Fortin (canfestival@canopencanada.ca)
6 See COPYING file for copyrights details.
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.
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.
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
28 #include <cyg/kernel/kapi.h>
29 #include <cyg/hal/hal_arch.h>
35 #include <can_driver.h>
36 #include <objdictdef.h>
39 #include "lpc2138_pinout.h"
40 #include "lpc2138_defs.h"
45 #include "time_slicer.h"
51 CAN_HANDLE canOpen(s_BOARD *board)
56 /***************************************************************************/
57 int canClose(CAN_HANDLE fd0)
62 UNS8 canReceive(CAN_HANDLE fd0, Message *m)
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)
73 Fill the structure "Message" with data from the CAN receive buffer
79 the sja1000 must be set to the PeliCAN mode
81 m->cob_id.w = sja1000_read(16) + (sja1000_read(17)<<8); // IO_PORTS_16(CAN0 + CANRCVID) >> 5
83 m->rtr = (sja1000_read(17) >> 4) & 0x01; // (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01;
85 m->len = sja1000_read(18);
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);
96 sja1000_write(CMR, 1<<RRB ); // release fifo
102 UNS8 canSend(CAN_HANDLE fd0, Message *m)
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
113 Send the content of the structure "Message" to the CAN transmit buffer
115 return : 0 if OK, 1 if error
118 unsigned char rec_buf;
122 rec_buf = sja1000_read(SR);
124 while ( (rec_buf & (1<<TBS))==0); // loop until TBS high
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);
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
139 sja1000_write(CMR,( (0<<SRR) | (0<<CDO) | (0<<RRB) | (0<<AT) | (1<<TR)));
142 rec_buf = sja1000_read(SR);
144 while ( (rec_buf & (1<<TBS))==0); // loop until TBS high
151 SEQUENTIAL I/O TO FLASH
152 those functions are for continous writing and read
158 int n = NVRAM_BLOCK_SIZE / sizeof(unsigned int);
160 /* some actions to initialise the flash */
164 data_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
165 memset(data_page, 0, sizeof(unsigned int)*n);
167 if (data_page == NULL)
170 regs_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
171 memset(regs_page, 0, sizeof(unsigned int)*n);
172 if (regs_page == NULL)
175 iat_flash_read_regs();
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];
182 data_addr = NVRAM_BLOCK_SIZE; /* let start at block 1 */
188 void nvram_close(void)
190 /* write the last page before closing */
191 iat_flash_write_page(data_addr);
193 /* some actions to end accessing the flash */
196 regs_page[4] = data_num_pages;
197 /* write the registers to the NVRAM before closing */
198 iat_flash_write_regs();
203 void nvram_set_pos(UNS32 pos)
204 /* set the current position in the NVRAM to pos */
209 void nvram_new_firmwave()
212 this function is called whenever a new firmware is about
213 to be written in the NVRAM
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;
220 int _get_data_len(int type)
222 int len = 0; /* number of bytes */
269 case time_difference:
277 char nvram_write_data(int type, int access_attr, void *data)
278 /* return 0 if successfull */
280 int len = _get_data_len(type);
282 if (data_len+len > NVRAM_BLOCK_SIZE)
284 iat_flash_write_page(data_addr);
286 data_addr += NVRAM_BLOCK_SIZE;
288 /* wrap-around address pointer */
289 if (data_addr > NVRAM_MAX_SIZE)
290 data_addr = NVRAM_BLOCK_SIZE;
295 memcpy(((char *)data_page)+data_len, data, len);
303 char nvram_read_data(int type, int access_attr, void *data)
304 /* return 0 if successful */
306 int len = _get_data_len(type);
308 if (data_len+len > NVRAM_BLOCK_SIZE)
310 data_addr += NVRAM_BLOCK_SIZE;
312 /* wrap-around address pointer */
313 if (data_addr > NVRAM_MAX_SIZE)
314 data_addr = NVRAM_BLOCK_SIZE;
316 iat_flash_read_page(data_addr);
320 memcpy(data, ((char *)data_page)+data_len, len);
328 NVRAM registers at block 0
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
336 void nvram_write_reg(UNS32 reg, UNS16 pos)
337 /* write reg at the position in the data block 0 */
339 regs_page[pos] = reg;
342 UNS32 nvram_read_reg(UNS16 pos)
343 /* read reg at the position in the data block 0 */
345 return regs_page[pos];
353 void led_set_redgreen(UNS8 bits)
354 /* bits : each bit of this uns8 is assigned a led
358 lpc2138_redgreenled_set(bits);