etisserant@0: /* etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@0: etisserant@0: Author: Christian Fortin (canfestival@canopencanada.ca) etisserant@0: etisserant@0: See COPYING file for copyrights details. etisserant@0: etisserant@0: This library is free software; you can redistribute it and/or etisserant@0: modify it under the terms of the GNU Lesser General Public etisserant@0: License as published by the Free Software Foundation; either etisserant@0: version 2.1 of the License, or (at your option) any later version. etisserant@0: etisserant@0: This library is distributed in the hope that it will be useful, etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: Lesser General Public License for more details. etisserant@0: etisserant@0: You should have received a copy of the GNU Lesser General Public etisserant@0: License along with this library; if not, write to the Free Software etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: */ etisserant@0: etisserant@0: #include etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include "applicfg.h" etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include "lpc2138_pinout.h" etisserant@0: #include "lpc2138_defs.h" etisserant@0: #include "lpc2138.h" etisserant@0: etisserant@0: #include "sja1000.h" etisserant@0: etisserant@0: #include "time_slicer.h" etisserant@0: etisserant@0: etisserant@0: /* etisserant@0: SEND/RECEIVE etisserant@0: */ etisserant@0: CAN_HANDLE canOpen(s_BOARD *board) etisserant@0: { etisserant@0: return NULL; etisserant@0: } etisserant@0: etisserant@0: /***************************************************************************/ etisserant@0: int canClose(CAN_HANDLE fd0) etisserant@0: { etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: UNS8 canReceive(CAN_HANDLE fd0, Message *m) etisserant@0: /* etisserant@0: Message *m : etisserant@0: typedef struct { etisserant@0: SHORT_CAN cob_id; // l'ID du mesg etisserant@0: UNS8 rtr; // remote transmission request. 0 if not rtr, etisserant@0: // 1 for a rtr message etisserant@0: UNS8 len; // message length (0 to 8) etisserant@0: UNS8 data[8]; // data etisserant@0: } Message; etisserant@0: etisserant@0: Fill the structure "Message" with data from the CAN receive buffer etisserant@0: etisserant@0: return : 0 etisserant@0: */ etisserant@0: { etisserant@0: /* etisserant@0: the sja1000 must be set to the PeliCAN mode etisserant@0: */ etisserant@0: m->cob_id.w = sja1000_read(16) + (sja1000_read(17)<<8); // IO_PORTS_16(CAN0 + CANRCVID) >> 5 etisserant@0: etisserant@0: m->rtr = (sja1000_read(17) >> 4) & 0x01; // (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01; etisserant@0: etisserant@0: m->len = sja1000_read(18); etisserant@0: etisserant@0: m->data[0] = sja1000_read(19); etisserant@0: m->data[1] = sja1000_read(20); etisserant@0: m->data[2] = sja1000_read(21); etisserant@0: m->data[3] = sja1000_read(22); etisserant@0: m->data[4] = sja1000_read(23); etisserant@0: m->data[5] = sja1000_read(24); etisserant@0: m->data[6] = sja1000_read(25); etisserant@0: m->data[7] = sja1000_read(26); etisserant@0: etisserant@0: sja1000_write(CMR, 1<cob_id.w & 0xff); etisserant@0: sja1000_write(17, (m->cob_id.w >> 8) & 0xff); etisserant@0: sja1000_write(18, m->len); etisserant@0: etisserant@0: sja1000_write(19, m->data[0]); // tx data 1 etisserant@0: sja1000_write(20, m->data[1]); // tx data 2 etisserant@0: sja1000_write(21, m->data[2]); // tx data 3 etisserant@0: sja1000_write(22, m->data[3]); // tx data 4 etisserant@0: sja1000_write(23, m->data[4]); // tx data 5 etisserant@0: sja1000_write(24, m->data[5]); // tx data 6 etisserant@0: sja1000_write(25, m->data[6]); // tx data 7 etisserant@0: sja1000_write(26, m->data[7]); // tx data 8 etisserant@0: etisserant@0: sja1000_write(CMR,( (0< NVRAM_MAX_SIZE) oremeq@3: data_addr = NVRAM_BLOCK_SIZE; etisserant@0: } etisserant@0: etisserant@0: int _get_data_len(int type) etisserant@0: { etisserant@0: int len = 0; /* number of bytes */ etisserant@0: switch(type) etisserant@0: { etisserant@0: case boolean: etisserant@0: len = 1; etisserant@0: break; etisserant@0: etisserant@0: case int8: etisserant@0: case uint8: etisserant@0: len = 1; etisserant@0: break; etisserant@0: case int16: etisserant@0: case uint16: etisserant@0: len = 2; etisserant@0: break; etisserant@0: case int24: etisserant@0: case uint24: etisserant@0: len = 3; etisserant@0: break; etisserant@0: case int32: etisserant@0: case uint32: etisserant@0: case real32: etisserant@0: len = 4; etisserant@0: break; etisserant@0: case int40: etisserant@0: case uint40: etisserant@0: len = 5; etisserant@0: break; etisserant@0: case int48: etisserant@0: case uint48: etisserant@0: len = 6; etisserant@0: break; etisserant@0: case int56: etisserant@0: case uint56: etisserant@0: len = 7; etisserant@0: break; etisserant@0: case int64: etisserant@0: case uint64: etisserant@0: case real64: etisserant@0: len = 8; etisserant@0: break; etisserant@0: #if 0 etisserant@0: /* TO DO */ etisserant@0: case visible_string: etisserant@0: case octet_string: etisserant@0: case unicode_string: etisserant@0: case time_of_day: etisserant@0: case time_difference: etisserant@0: #endif etisserant@0: } etisserant@0: etisserant@0: return len; etisserant@0: } etisserant@0: etisserant@0: oremeq@3: char nvram_write_data(int type, int access_attr, void *data) etisserant@0: /* return 0 if successfull */ etisserant@0: { etisserant@0: int len = _get_data_len(type); etisserant@0: oremeq@3: if (data_len+len > NVRAM_BLOCK_SIZE) etisserant@0: { etisserant@0: iat_flash_write_page(data_addr); etisserant@0: data_len = 0; oremeq@3: data_addr += NVRAM_BLOCK_SIZE; oremeq@3: oremeq@3: /* wrap-around address pointer */ oremeq@3: if (data_addr > NVRAM_MAX_SIZE) oremeq@3: data_addr = NVRAM_BLOCK_SIZE; oremeq@3: oremeq@3: data_num_pages++; etisserant@0: } etisserant@0: etisserant@0: memcpy(((char *)data_page)+data_len, data, len); etisserant@0: etisserant@0: data_len += len; etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: oremeq@3: char nvram_read_data(int type, int access_attr, void *data) etisserant@0: /* return 0 if successful */ etisserant@0: { etisserant@0: int len = _get_data_len(type); etisserant@0: oremeq@3: if (data_len+len > NVRAM_BLOCK_SIZE) etisserant@0: { oremeq@3: data_addr += NVRAM_BLOCK_SIZE; oremeq@3: oremeq@3: /* wrap-around address pointer */ oremeq@3: if (data_addr > NVRAM_MAX_SIZE) oremeq@3: data_addr = NVRAM_BLOCK_SIZE; oremeq@3: etisserant@0: iat_flash_read_page(data_addr); etisserant@0: data_len = 0; etisserant@0: } etisserant@0: etisserant@0: memcpy(data, ((char *)data_page)+data_len, len); etisserant@0: etisserant@0: data_len += len; etisserant@0: etisserant@0: return 0; etisserant@0: } etisserant@0: oremeq@3: /* oremeq@3: NVRAM registers at block 0 oremeq@3: pos description oremeq@3: 0 version of the current dictionnary oremeq@3: 1 starting address for data block oremeq@3: 2 date of last writing oremeq@3: 3 address of the previous dictionnary oremeq@3: 4 size in pages of the current dict oremeq@3: */ oremeq@3: void nvram_write_reg(UNS32 reg, UNS16 pos) oremeq@3: /* write reg at the position in the data block 0 */ oremeq@3: { oremeq@3: regs_page[pos] = reg; oremeq@3: } oremeq@3: oremeq@3: UNS32 nvram_read_reg(UNS16 pos) oremeq@3: /* read reg at the position in the data block 0 */ oremeq@3: { oremeq@3: return regs_page[pos]; oremeq@3: } oremeq@3: etisserant@0: etisserant@0: /* etisserant@0: LED etisserant@0: */ etisserant@0: oremeq@3: void led_set_redgreen(UNS8 bits) oremeq@3: /* bits : each bit of this uns8 is assigned a led oremeq@3: 0=off, 1=on oremeq@3: */ etisserant@0: { etisserant@0: lpc2138_redgreenled_set(bits); etisserant@0: } etisserant@0: