drivers/ecos_lpc2138_sja1000/canOpenDriver.c
changeset 93 16c8ceea8f18
parent 92 0d84d95790d9
child 94 bdf4c86be6b2
equal deleted inserted replaced
92:0d84d95790d9 93:16c8ceea8f18
     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 	return iat_init();
       
   159 }
       
   160 
       
   161 
       
   162 void nvram_close(void)
       
   163 {
       
   164 	iat_end();
       
   165 }
       
   166 
       
   167 
       
   168 void nvram_set_pos(UNS32 pos)
       
   169 /* set the current position in the NVRAM to pos */
       
   170 {
       
   171 }
       
   172 
       
   173 
       
   174 void nvram_new_firmware()
       
   175 {
       
   176 /*
       
   177 	this function is called whenever a new firmware is about
       
   178 	to be written in the NVRAM
       
   179 */
       
   180 	data_addr = regs_page[1] + regs_page[4]*NVRAM_BLOCK_SIZE;
       
   181 	if (data_addr > NVRAM_MAX_SIZE)
       
   182 		data_addr = NVRAM_BLOCK_SIZE;
       
   183 }
       
   184 
       
   185 int _get_data_len(int type)
       
   186 {
       
   187 	int len = 0; /* number of bytes */
       
   188 	switch(type)
       
   189 	{
       
   190 		case  boolean:
       
   191 			len = 1;
       
   192 			break;
       
   193 
       
   194 		case  int8:
       
   195 		case  uint8:
       
   196 			len = 1;
       
   197 			break;
       
   198 		case  int16:
       
   199 		case  uint16:
       
   200 			len = 2;
       
   201 			break;
       
   202 		case  int24:
       
   203 		case  uint24:
       
   204 			len = 3;
       
   205 			break;
       
   206 		case  int32:
       
   207 		case  uint32:
       
   208 		case  real32:
       
   209 			len = 4;
       
   210 			break;
       
   211 		case  int40:
       
   212 		case  uint40:
       
   213 			len = 5;
       
   214 			break;
       
   215 		case  int48:
       
   216 		case  uint48:
       
   217 			len = 6;
       
   218 			break;
       
   219 		case  int56:
       
   220 		case  uint56:
       
   221 			len = 7;
       
   222 			break;
       
   223 		case  int64:
       
   224 		case  uint64:
       
   225 		case  real64:
       
   226 			len = 8;
       
   227 			break;
       
   228 #if 0
       
   229 /* TO DO */
       
   230 		case  visible_string:
       
   231 		case  octet_string:
       
   232 		case  unicode_string:
       
   233 		case  time_of_day:
       
   234 		case  time_difference:
       
   235 #endif
       
   236 	}
       
   237 
       
   238 	return len;
       
   239 }
       
   240 
       
   241 
       
   242 char nvram_write_data(int type, int access_attr, void *data)
       
   243 /* return 0 if successfull */
       
   244 {
       
   245 	int len = _get_data_len(type);
       
   246 
       
   247 	if (data_len+len > NVRAM_BLOCK_SIZE)
       
   248 	{
       
   249 		iat_flash_write_page(data_addr);
       
   250 		data_len = 0;
       
   251 		data_addr += NVRAM_BLOCK_SIZE; 
       
   252 
       
   253 		/* wrap-around address pointer */
       
   254 		if (data_addr > NVRAM_MAX_SIZE)
       
   255 			data_addr = NVRAM_BLOCK_SIZE;
       
   256 
       
   257 		data_num_pages++;
       
   258 	}
       
   259 		
       
   260 	memcpy(((char *)data_page)+data_len, data, len);
       
   261 
       
   262 	data_len += len;
       
   263 
       
   264 	return 0;
       
   265 }
       
   266 
       
   267 
       
   268 char nvram_read_data(int type, int access_attr, void *data)
       
   269 /* return 0 if successful */
       
   270 {
       
   271 	int len = _get_data_len(type);
       
   272 
       
   273 	if (data_len+len > NVRAM_BLOCK_SIZE)
       
   274 	{
       
   275 		data_addr += NVRAM_BLOCK_SIZE;
       
   276 
       
   277 		/* wrap-around address pointer */
       
   278 		if (data_addr > NVRAM_MAX_SIZE)
       
   279 			data_addr = NVRAM_BLOCK_SIZE;
       
   280 
       
   281 		iat_flash_read_page(data_addr);
       
   282 		data_len = 0;		
       
   283 	}
       
   284 
       
   285 	memcpy(data, ((char *)data_page)+data_len, len);
       
   286 
       
   287 	data_len += len;
       
   288 
       
   289 	return 0;
       
   290 }
       
   291 
       
   292 /*
       
   293 	NVRAM registers at block 0
       
   294 	pos        description
       
   295 	0          version of the current dictionnary
       
   296 	1          starting address for data block
       
   297 	2          date of last writing
       
   298 	3          address of the previous dictionnary          
       
   299 	4          size in pages of the current dict
       
   300 */
       
   301 void nvram_write_reg(UNS32 reg, UNS16 pos)
       
   302 /* write reg at the position in the data block 0 */
       
   303 {
       
   304 	regs_page[pos] = reg;
       
   305 }
       
   306 
       
   307 UNS32 nvram_read_reg(UNS16 pos)
       
   308 /* read reg at the position in the data block 0 */
       
   309 {
       
   310 	return regs_page[pos];
       
   311 }
       
   312 
       
   313 
       
   314 /*
       
   315 	LED
       
   316 */
       
   317 
       
   318 void led_set_redgreen(UNS8 bits)
       
   319 /* bits : each bit of this uns8 is assigned a led 
       
   320           0=off, 1=on
       
   321 */
       
   322 {
       
   323 	lpc2138_redgreenled_set(bits);
       
   324 }
       
   325