ADDED LED to TESTMASTERSLAVE. It looks nice!
Some code for the NVRAM support
--- a/drivers/Makefile.in Thu May 11 13:52:43 2006 +0200
+++ b/drivers/Makefile.in Fri May 12 22:14:03 2006 +0200
@@ -24,6 +24,7 @@
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
+LED_ENABLE = SUB_LED_ENABLE
all: driver
--- a/drivers/can_virtual/Makefile.in Thu May 11 13:52:43 2006 +0200
+++ b/drivers/can_virtual/Makefile.in Fri May 12 22:14:03 2006 +0200
@@ -33,6 +33,7 @@
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
+LED_ENABLE = SUB_LED_ENABLE
INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
--- a/drivers/can_virtual/led_virtual.c Thu May 11 13:52:43 2006 +0200
+++ b/drivers/can_virtual/led_virtual.c Fri May 12 22:14:03 2006 +0200
@@ -1,20 +1,18 @@
/***************************************************************************/
+#include <data.h>
#include <led.h>
-void led_set_redgreen(CO_Data *d, int state)
+void led_set_redgreen(CO_Data *d, unsigned char state)
{
+ if (state & 0x01)
+ printf("\e[41m ERROR LED ON \e[m ");
+ else
+ printf("\e[31m error led off \e[m ");
- printf("LEDS %d\n",bits);
-
- if (bits & 0x01)
- printf("\e[41m ERROR LED ON \e[m\n");
- else
- printf("error led off\n");
-
- if (bits & 0x02)
+ if (state & 0x02)
printf("\e[34;42m RUN LED ON \e[m\n");
else
- printf("run led off\n");
+ printf("\e[32m run led off \e[m\n");
}
--- a/drivers/ecos_lpc2138_sja1000/canOpenDriver.c Thu May 11 13:52:43 2006 +0200
+++ b/drivers/ecos_lpc2138_sja1000/canOpenDriver.c Fri May 12 22:14:03 2006 +0200
@@ -155,25 +155,66 @@
int nvram_open(void)
{
+ int n = NVRAM_BLOCK_SIZE / sizeof(unsigned int);
+
/* some actions to initialise the flash */
data_len = 0;
-
- data_addr = 0;
-
- data_page = (unsigned int *)malloc(sizeof(unsigned int) * 64);
- memset(data_page, 0, sizeof(unsigned int)*64);
+ data_num_pages = 0;
+
+ data_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
+ memset(data_page, 0, sizeof(unsigned int)*n);
if (data_page == NULL)
return -1;
+ regs_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
+ memset(regs_page, 0, sizeof(unsigned int)*n);
+ if (regs_page == NULL)
+ return -2;
+
+ iat_flash_read_regs();
+
+ /* start the data at the location specified in the registers */
+ if (0) /* for now it is 0, but put here a test to know whether
+ or not the NVRAM has been written before */
+ data_addr = regs_page[1];
+ else
+ data_addr = NVRAM_BLOCK_SIZE; /* let start at block 1 */
+
return 0;
}
void nvram_close(void)
{
+ /* write the last page before closing */
+ iat_flash_write_page(data_addr);
+
/* some actions to end accessing the flash */
free(data_page);
+
+ regs_page[4] = data_num_pages;
+ /* write the registers to the NVRAM before closing */
+ iat_flash_write_regs();
+ free(regs_page);
+}
+
+
+void nvram_set_pos(UNS32 pos)
+/* set the current position in the NVRAM to pos */
+{
+}
+
+
+void nvram_new_firmwave()
+{
+/*
+ this function is called whenever a new firmware is about
+ to be written in the NVRAM
+*/
+ data_addr = regs_page[1] + regs_page[4]*NVRAM_BLOCK_SIZE;
+ if (data_addr > NVRAM_MAX_SIZE)
+ data_addr = NVRAM_BLOCK_SIZE;
}
int _get_data_len(int type)
@@ -233,16 +274,22 @@
}
-char nvram_write(int type, int access_attr, void *data)
+char nvram_write_data(int type, int access_attr, void *data)
/* return 0 if successfull */
{
int len = _get_data_len(type);
- if (data_len+len > 256)
+ if (data_len+len > NVRAM_BLOCK_SIZE)
{
iat_flash_write_page(data_addr);
data_len = 0;
- data_addr += 256;
+ data_addr += NVRAM_BLOCK_SIZE;
+
+ /* wrap-around address pointer */
+ if (data_addr > NVRAM_MAX_SIZE)
+ data_addr = NVRAM_BLOCK_SIZE;
+
+ data_num_pages++;
}
memcpy(((char *)data_page)+data_len, data, len);
@@ -253,14 +300,19 @@
}
-char nvram_read(int type, int access_attr, void *data)
+char nvram_read_data(int type, int access_attr, void *data)
/* return 0 if successful */
{
int len = _get_data_len(type);
- if (data_len+len > 256)
+ if (data_len+len > NVRAM_BLOCK_SIZE)
{
- data_addr += 256;
+ data_addr += NVRAM_BLOCK_SIZE;
+
+ /* wrap-around address pointer */
+ if (data_addr > NVRAM_MAX_SIZE)
+ data_addr = NVRAM_BLOCK_SIZE;
+
iat_flash_read_page(data_addr);
data_len = 0;
}
@@ -272,12 +324,36 @@
return 0;
}
+/*
+ NVRAM registers at block 0
+ pos description
+ 0 version of the current dictionnary
+ 1 starting address for data block
+ 2 date of last writing
+ 3 address of the previous dictionnary
+ 4 size in pages of the current dict
+*/
+void nvram_write_reg(UNS32 reg, UNS16 pos)
+/* write reg at the position in the data block 0 */
+{
+ regs_page[pos] = reg;
+}
+
+UNS32 nvram_read_reg(UNS16 pos)
+/* read reg at the position in the data block 0 */
+{
+ return regs_page[pos];
+}
+
/*
LED
*/
-void led_set_redgreen(unsigned char bits)
+void led_set_redgreen(UNS8 bits)
+/* bits : each bit of this uns8 is assigned a led
+ 0=off, 1=on
+*/
{
lpc2138_redgreenled_set(bits);
}
--- a/drivers/ecos_lpc2138_sja1000/lpc2138.h Thu May 11 13:52:43 2006 +0200
+++ b/drivers/ecos_lpc2138_sja1000/lpc2138.h Fri May 12 22:14:03 2006 +0200
@@ -25,10 +25,16 @@
#define _LPC2138_H_
+/* block and maximum size of NVRRAM in bytes */
+#define NVRAM_BLOCK_SIZE 256
+#define NVRAM_MAX_SIZE 1024*512
+
extern short data_len;
+extern short data_num_pages;
extern unsigned int *data_page;
extern unsigned int data_addr;
+extern unsigned int *regs_page;
void lpc2138_pinsel_set(int pin, LPC2138_PORT port, int size, int func);
void lpc2138_pinsel_clear(void);
@@ -45,7 +51,9 @@
void iat_flash_erase(unsigned int command_ee,unsigned int result_ee[]);
void iat_flash_write_page(unsigned int addr);
void iat_flash_read_page(unsigned int addr);
-
+
+void iat_flash_write_regs(void);
+void iat_flash_read_regs(void);
#endif
--- a/drivers/ecos_lpc2138_sja1000/lpc2138_pinout.h Thu May 11 13:52:43 2006 +0200
+++ b/drivers/ecos_lpc2138_sja1000/lpc2138_pinout.h Fri May 12 22:14:03 2006 +0200
@@ -1,7 +1,19 @@
/*
This file is part of CanFestival, a library implementing CanOpen Stack.
+ ____ _ _ _
+ / ___| / \ | \ | | ___ _ __ ___ _ __
+| | / _ \ | \| |/ _ \| '_ \ / _ \ '_ \
+| |___ / ___ \| |\ | (_) | |_) | __/ | | |
+ \____/_/ \_\_| \_|\___/| .__/ \___|_| |_|
+ |_|
+ ____ _
+ / ___|__ _ _ __ __ _ __| | __ _
+ | | / _` | '_ \ / _` |/ _` |/ _` |
+ | |__| (_| | | | | (_| | (_| | (_| |
+ \____\__,_|_| |_|\__,_|\__,_|\__,_|
- Author: Christian Fortin (canfestival@canopencanada.ca)
+ canfestival@canopencanada.ca
+/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
See COPYING file for copyrights details.
@@ -82,9 +94,13 @@
#define LPC2138_ale_PORT P0
#define LPC2138_ale_SIZE 1
-#define LPC2138_redgreenled 27 /* Pin 27 */
-#define LPC2138_redgreenled_PORT P0
-#define LPC2138_redgreenled_SIZE 2
+#define LPC2138_redled 27 /* Pin 27 */
+#define LPC2138_redled_PORT P0
+#define LPC2138_redled_SIZE 1
+
+#define LPC2138_greenled 28 /* Pin 28 */
+#define LPC2138_greenled_PORT P0
+#define LPC2138_greenled_SIZE 1
#define LPC2138_rd 29 /* Pin 29 */
#define LPC2138_rd_PORT P0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/ecos_lpc2138_sja1000/notes.txt Fri May 12 22:14:03 2006 +0200
@@ -0,0 +1,18 @@
+canOpenDriver.c
+ f_can_send
+ f_can_receive
+ interrupts
+ nvram_save/load
+ baudrate
+
+sja1000.c
+ hardware init
+
+lpc2138.c
+ iat_flash
+
+time_slicer.c
+ settimer
+ alarm
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/ecos_lpc2138_sja1000/nvram.h Fri May 12 22:14:03 2006 +0200
@@ -0,0 +1,49 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+ ____ _ _ _
+ / ___| / \ | \ | | ___ _ __ ___ _ __
+| | / _ \ | \| |/ _ \| '_ \ / _ \ '_ \
+| |___ / ___ \| |\ | (_) | |_) | __/ | | |
+ \____/_/ \_\_| \_|\___/| .__/ \___|_| |_|
+ |_|
+ ____ _
+ / ___|__ _ _ __ __ _ __| | __ _
+ | | / _` | '_ \ / _` |/ _` |/ _` |
+ | |__| (_| | | | | (_| | (_| | (_| |
+ \____\__,_|_| |_|\__,_|\__,_|\__,_|
+
+ canfestival@canopencanada.ca
+/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#if !defined(_NVRAM_IO_H_)
+#define _NVRAM_IO_H_
+
+
+int nvram_open(void);
+void nvram_close(void);
+
+char nvram_write_data(int type, int access_attr, void *data);
+char nvram_read_data(int type, int access_attr, void *data);
+
+void nvram_write_regs(void);
+void nvram_read_regs(void);
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/ecos_lpc2138_sja1000/nvram_iap.c Fri May 12 22:14:03 2006 +0200
@@ -0,0 +1,318 @@
+/*
+ canfestival@canopencanada.ca
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+flash.c
+ save to / retrieve from the non-volatile memory
+ to be tested
+ - can we write/read into an address without working with the whole page (256bytes)
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "applicfg.h"
+#include "data.h"
+#include "objdictdef.h"
+
+#include "lpc2138_defs.h" /* LPC21xx definitions */
+
+#define IAP_LOCATION 0x7ffffff1
+
+
+// define a page of data of NVRAM_BLOCK_SIZE bytes
+//
+short data_len; /* 0 to NVRAM_BLOCK_SIZE bytes */
+short data_num_pages;
+unsigned int *data_page = NULL;
+unsigned int data_addr;
+
+unsigned int *regs_page = NULL;
+
+// local definitons
+void ee_erase(unsigned int ,unsigned int[]); //function erases EEPROM
+void ee_write_page(unsigned int); //function adds a record in EEPROM
+void ee_read_page(unsigned int); //function reads the latest valid record in EEPROM
+
+typedef void (*IAP)(unsigned int [],unsigned int[]);
+IAP iap_entry;
+
+
+
+/************************************************************************/
+/* */
+/* function: */
+/* void ee_erase(unsigned int command_ee,unsigned int result_ee[]) */
+/* */
+/* type: void */
+/* */
+/* parameters: */
+/* command_ee - Not used. */
+/* result_ee[0] - Returns a response to the last IAP command used. */
+/* 0 - EEPROM successfully erased. */
+/* For all other response values, see microcontroller */
+/* User Manual, IAP Commands and Status Codes Summary. */
+/* result_ee[1] - Not used. */
+/* */
+/* version: 1.1 (01/27/2006) */
+/* */
+/* constants defined in LPC2k_ee.h used in this function: */
+/* EE_SEC_L - microcontroller's Flash sector where EEPROM begins */
+/* EE_SEC_H - microcontroller's Flash sector where EEPROM ends */
+/* EE_CCLK - microcontroller's system clock (cclk) */
+/* */
+/* description: */
+/* This function erases LPC2000 on-chip Flash sectors selected to act */
+/* as an EEPROM. All Flash sectors between EE_SEC_L abd EE_SEC_H */
+/* (including these sectors) will be erased using the In Application */
+/* Programming (IAP) routines (see User Manual for more details). */
+/* Also, this function disables all interrupts while erasing the */
+/* EEPROM. If this is not needed, three lines of the ee_erase */
+/* subroutine can simply be commented-out without affecting the */
+/* routine performance at all. */
+/* */
+/* revision history: */
+/* - Rev. 1.1 adds interrupt disable feature. */
+/* */
+/************************************************************************/
+void ee_erase(unsigned int command_ee,unsigned int result_ee[])
+{
+ unsigned int command_iap[5];
+ unsigned int result_iap[3];
+ unsigned long int enabled_interrupts;
+
+ enabled_interrupts = VICIntEnable; //disable all interrupts
+ VICIntEnClr = enabled_interrupts;
+
+ command_iap[0]=50; // prepare sectors from EE_SEC_L to EE_SEC_H for erase
+ command_iap[1]=EE_SEC_L;
+ command_iap[2]=EE_SEC_H;
+ iap_entry=(IAP) IAP_LOCATION;
+ iap_entry(command_iap,result_iap);
+
+ command_iap[0]=52; // erase sectors from EE_SEC_L to EE_SEC_H
+ command_iap[1]=EE_SEC_L;
+ command_iap[2]=EE_SEC_H;
+ command_iap[3]=EE_CCLK;
+ iap_entry=(IAP) IAP_LOCATION;
+ iap_entry(command_iap,result_iap);
+
+ command_iap[0]=53; // blankcheck sectors from EE_SEC_L to EE_SEC_H
+ command_iap[1]=EE_SEC_L;
+ command_iap[2]=EE_SEC_H;
+ iap_entry=(IAP) IAP_LOCATION;
+ iap_entry(command_iap,result_iap);
+
+ VICIntEnable = enabled_interrupts; //restore interrupt enable register
+
+ result_ee[0]=result_iap[0];
+ return;
+}
+
+/************************************************************************/
+/* */
+/* function: */
+/* void ee_write(unsigned int command_ee,unsigned int result_ee[]) */
+/* */
+/* type: void */
+/* */
+/* parameters: */
+/* command_ee - An address of a content of ee_data type that has */
+/* to be programmed into EEPROM. */
+/* result_ee[0] - Returns a response to the last IAP command used. */
+/* 0 - data successfully programmed in EEPROM. */
+/* 501 - no space in EEPROM to program data. */
+/* For all other response values, see microcontroller */
+/* User Manual, IAP Commands and Status Codes Summary. */
+/* result_ee[1] - Not used. */
+/* */
+/* version: 1.1 (01/27/2006) */
+/* */
+/* constants defined in LPC2k_ee.h used in this function: */
+/* EE_BUFFER_SIZE - IAP buffer size; must be 256 or 512 */
+/* NO_SPACE_IN_EEPROM - EEPROM is full and no data can be programmed */
+/* EE_BUFFER_MASK - parameter used for interfacing with IAP */
+/* EE_REC_SIZE - ee_data structure size in bytes */
+/* EE_SEC_L - micro's Flash sector where EEPROM begins */
+/* EE_SEC_H - micro's Flash sector where EEPROM ends */
+/* EE_CCLK - micro's system clock (cclk) */
+/* */
+/* description: */
+/* This function writes a single structure of ee_data type into the */
+/* EEPROM using an In Application Programming (IAP) routines (see */
+/* User Manual for more details). command_ee contains an address of */
+/* this structure. EEPROM is scanned for the last (if any) record */
+/* identifier (EE_REC_ID), and a new record is added next to it. */
+/* Also, this function disables all interrupts while erasing the */
+/* EEPROM. If this is not needed, three lines of the ee_write */
+/* subroutine can simply be commented-out without affecting the */
+/* routine performance at all. */
+/* */
+/* revision history: */
+/* - Rev. 1.1 fixes a bug related to verifying a content written into */
+/* the EEPROM. 1.0 was reporting missmatch even when there were no */
+/* problems at all. */
+/* Rev. 1.1 adds interrupt disable feature. */
+/* */
+/************************************************************************/
+
+void ee_write_page(unsigned int addr)
+{
+ unsigned long int enabled_interrupts;
+ // unsigned char ee_buffer[16];
+ unsigned int command_iap[5], result_iap[3];
+
+ enabled_interrupts = VICIntEnable; //disable all interrupts
+ VICIntEnClr = enabled_interrupts;
+
+ iap_entry = (IAP) IAP_LOCATION;
+
+ // prepare sectors from EE_SEC_L to EE_SEC_H for erase
+ command_iap[0] = 50;
+ command_iap[1] = EE_SEC_L;
+ command_iap[2] = EE_SEC_H;
+ iap_entry(command_iap, result_iap);
+
+ // copy RAM to flash/eeprom
+ command_iap[0] = 51;
+ command_iap[1] = (unsigned int) (addr & EE_START_MASK); // 256 kb boundary
+ command_iap[2] = (unsigned int) (data_page); // should be on a word boundary
+ command_iap[3] = 256;
+ command_iap[4] = EE_CCLK;
+ iap_entry(command_iap, result_iap);
+
+#if 0
+ // compare RAM and flash/eeprom
+ command_iap[0] = 56;
+ command_iap[1] = (unsigned int) data;
+ command_iap[2] = addr;
+ command_iap[3] = dlen;
+ iap_entry(command_iap, result_iap);
+#endif
+
+ VICIntEnable = enabled_interrupts; //restore interrupt enable register
+}
+
+
+/************************************************************************/
+/* */
+/* function: */
+/* void ee_read(unsigned int command_ee,unsigned int result_ee[]) */
+/* */
+/* type: void */
+/* */
+/* parameters: */
+/* command_ee - Not used. */
+/* result_ee[0] - Returns a response. */
+/* 0 - data successfully found in EEPROM. */
+/* 500 - no data/records available in EEPROM. */
+/* result_ee[1] - an address of the last record of ee_data type */
+/* in EEPROM. */
+/* */
+/* version: 1.1 (01/27/2006) */
+/* */
+/* constants defined in LPC2k_ee.h used in this function: */
+/* NO_RECORDS_AVAILABLE - EEPROM is empty/no records identifiable */
+/* with a record identifier (EE_REC_ID) found */
+/* EE_ADR_L - micro's Flash address from where EEPROM begins */
+/* EE_REC_SIZE - size (in bytes) of a ee_data structure */
+/* */
+/* description: */
+/* This function scans an EEPROM content looking for the last record */
+/* that can be identified with a record identifier (EE_REC_ID). When */
+/* such data is found, its address is passed as result_ee[1]. */
+/* */
+/* revision history: */
+/* - Rev. 1.0 had problems with accessing the last record in a fully */
+/* occupied EEPROM. Rev. 1.1 fixes this. */
+/* */
+/************************************************************************/
+void ee_read_page(unsigned int addr)
+{
+ memcpy(data_page, (unsigned int *)addr, sizeof(unsigned int)*64);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+
+/*
+ CAN FESTIVAL interface functions
+*/
+
+
+int _get_data_len(int type)
+{
+ int len = 0; /* number of bytes */
+ switch(type)
+ {
+ case boolean:
+ len = 1;
+ break;
+
+ case int8:
+ case uint8:
+ len = 1;
+ break;
+ case int16:
+ case uint16:
+ len = 2;
+ break;
+ case int24:
+ case uint24:
+ len = 3;
+ break;
+ case int32:
+ case uint32:
+ case real32:
+ len = 4;
+ break;
+ case int40:
+ case uint40:
+ len = 5;
+ break;
+ case int48:
+ case uint48:
+ len = 6;
+ break;
+ case int56:
+ case uint56:
+ len = 7;
+ break;
+ case int64:
+ case uint64:
+ case real64:
+ len = 8;
+ break;
+#if 0
+/* TO DO */
+ case visible_string:
+ case octet_string:
+ case unicode_string:
+ case time_of_day:
+ case time_difference:
+#endif
+ }
+
+ return len;
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/ecos_lpc2138_sja1000/nvram_iap.h Fri May 12 22:14:03 2006 +0200
@@ -0,0 +1,176 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+ canfestival@canopencanada.ca
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/************************************************************************/
+/* */
+/* LPC2k_ee.H: Header file enabling EEPROM support */
+/* for Philips LPC2000 microcontroller's on-chip Flash memory */
+/* (revision 1.0, May 13th, 2005.) */
+/* */
+/* This file is to be used with LPC2k_ee.c file */
+/* */
+/* IMPORTANT: on-chip Flash memory sector(s) intended to be used as */
+/* an EEPROM will be unavailable for regular code storage! The smallest */
+/* amount of Flash memory that can be used as an EEPROM is a single */
+/* Flash sector (regardless of the Flash sector actual size). */
+/* */
+/* If size of desired EEPROM requires several Flash sectors, these */
+/* sectors must be a consecutive ones. */
+/* */
+/************************************************************************/
+
+#define EE_SEC_L 1 //Flash sector where EEPROM begins (see UM for details)
+#define EE_SEC_H 3 //Flash sector where EEPROM ends (see UM for details)
+#define EE_ADDR_L 0x00001000 //Must match the EE_SEC_L Flash sector start address
+#define EE_ADDR_H 0x00003FFF //Must match the EE_SEC_H Flash sector end address
+#define EE_CCLK 60000 //system clock cclk expressed in kHz (5*12 MHz)
+
+/************************************************************************/
+/* */
+/* ee_data structure can be defined differently from this example. */
+/* The only requirement is to have _id field as it is defined here */
+/* since EE_REC_ID character is used to identify a record's presence */
+/* in the EEPROM memory. */
+/* */
+/* ==================================================================== */
+/* */
+/* IMPORTANT ARM memory access considerations: */
+/* */
+/* char : byte alligned. Can be accessed at any location in memory. */
+/* */
+/* short int: occupies 2 consecutive bytes. It can be read/write */
+/* accessed only when half-word alligned. Therefore, it is */
+/* located at addresses ending with 0x0, 0x2, 0x4, 0x6, 0x8, */
+/* 0xA, 0xC or 0xE. */
+/* */
+/* int : occupies 4 consecutive bytes. It can be read/write */
+/* accessed only when half-word alligned. Therefore, it is */
+/* located at addresses ending with 0x0, 0x4, 0x8 or 0xC. */
+/* */
+/* ==================================================================== */
+/* */
+/* Due to the LPC2000 Flash memory characteristics, an ee_data */
+/* structure size (EE_REC_SIZE) is limited to the following set: */
+/* */
+/* LPC2101/2/3, LPC2131/2/4/6/8, LPC2141/2/4/6/8: 0x10, 0x20, 0x40, */
+/* 0x80 or 0x100 */
+/* */
+/* LPC2104/5/6, LPC2112/4/9, LPC2124/9, LPC2192/4: 0x10, 0x20, 0x40, */
+/* 0x80, 0x100 or 0x200 */
+/* */
+/* ==================================================================== */
+/* */
+/* example1: */
+/* */
+/* struct ee_data{ //structure starts as word alligned */
+/* unsigned char _id; //1 byte - no allignement restr. */
+/* // 3 BYTE GAP!!!! */
+/* unsigned int _rec_count; //4 bytes - must be word alligned! */
+/* unsigned char _cs; //1 byte - no allignement restr. */
+/*}; // next structure will start as */
+/* // word alligned... */
+/* Structure in example 1 occupies 12 bytes of memory */
+/* */
+/* -------------------------------------------------------------------- */
+/* */
+/* example2: */
+/* */
+/* struct ee_data{ //structure starts as word alligned */
+/* unsigned char _id; //1 byte - no allignement restr. */
+/* unsigned char _cs; //1 byte - no allignement restr. */
+/* // 2 BYTE GAP!!!! */
+/* unsigned int _rec_count; //4 bytes - must be word alligned! */
+/*}; // next structure will start as */
+/* // word alligned... */
+/* Structure in example 2 occupies 8 bytes of memory */
+/* */
+/************************************************************************/
+
+struct ee_data{
+ unsigned char _id; // 4 bytes: 1 byte (char) + 3 byte GAP!
+ unsigned int _rec_count; // 4 bytes (int)
+ unsigned int _counter; // 4 bytes (int)
+ unsigned char _cs; // 4 bytes: 1 byte (char) + 3 byte GAP!
+}; // 16 bytes total
+
+/************************************************************************/
+/* */
+/* Disclaimer: all observations presented in example1, example 2 and */
+/* ee_data structure defined here are based on Keil's ARM compiler. */
+/* If another compiler is used, memory usage would have to be */
+/* re-examined and verified. */
+/* */
+/************************************************************************/
+
+
+#define EE_REC_SIZE 0x10 //see restrictions from above
+
+/********************************************************************/
+/* */
+/* Valid combinations for */
+/* EE_REC_SIZE, EE_BUFFER_SIZE, EE_BUFFER_MASK and EE_START_MASK */
+/* */
+/* EE_BUFFER_SIZE ! EE_START_MASK ! EE_REC_SIZE ! EE_BUFFER_MASK */
+/* ---------------------------------------------------------------- */
+/* 256 0xFFFFFF00 0x010 0xF0 */
+/* 256 0xFFFFFF00 0x020 0xE0 */
+/* 256 0xFFFFFF00 0x040 0xC0 */
+/* 256 0xFFFFFF00 0x080 0x80 */
+/* 256 0xFFFFFF00 0x100 0x00 */
+/* ---------------------------------------------------------------- */
+/* 512 0xFFFFFE00 0x010 0x1F0 */
+/* 512 0xFFFFFE00 0x020 0x1E0 */
+/* 512 0xFFFFFE00 0x040 0x1C0 */
+/* 512 0xFFFFFE00 0x080 0x180 */
+/* 512 0xFFFFFE00 0x100 0x100 */
+/* 512 0xFFFFFE00 0x200 0x000 */
+/********************************************************************/
+/* For LPC2101/2/3, LPC213x and LPC214x EE_BUFFER_SIZE is 256. */
+/* For all other LPC2000 devices EE_BUFFER_SIZE is always 512. */
+/********************************************************************/
+#define EE_BUFFER_SIZE 256
+#define EE_START_MASK 0xFFFFFF00
+#define EE_BUFFER_MASK 0x000000F0
+
+/********************************************************************/
+/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+/*!! !!*/
+/*!! !!*/
+/*!! DO NOT MODIFY THE FOLLOWING CODE!!! !!*/
+/*!! =================================== !!*/
+/*!! !!*/
+/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+/********************************************************************/
+
+#define EE_REC_ID 0xAA
+#define EE_SIZE (EE_ADDR_H+1-EE_ADDR_L)
+#define NO_RECORDS_AVAILABLE 500
+#define NO_SPACE_IN_EEPROM 501
+#define INDEX_OUT_OF_RANGE 502
+
+#ifndef _EEPROM_
+ extern const unsigned char eeprom[];
+ extern void ee_erase(unsigned int , unsigned int []); //function erases EEPROM
+ extern void ee_write(unsigned int , unsigned int []); //function adds a record in EEPROM
+ extern void ee_read (unsigned int , unsigned int []); //function reads the latest valid record in EEPROM
+ extern void ee_readn(unsigned int , unsigned int []); //function reads n-th record in EEPROM
+ extern void ee_count(unsigned int , unsigned int []); //function counts records in EEPROM
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/ecos_lpc2138_sja1000/nvram_readme Fri May 12 22:14:03 2006 +0200
@@ -0,0 +1,61 @@
+procedure for NVRAM
+===================
+
+data block 0
+------------
+This data block is located at the beginning of the NVRAM and contains
+a series of registers.
+eg. 1. the version number of the current dictionnary (32 bits)
+ 2. pointer to the current dictionnary (32 bits)
+ 3. date of last dictionnary dump (32 bits)
+ 4. pointer to the last dict (32 bits)
+ 5. size in page of the current dict
+
+a minimum number of registers should always be in this block (including a number of 'for future use' 32 bits registers). the remaining space will be left to the developper
+
+a 256kb data block could handled 64 registers
+
+data block 1 to N
+-----------------
+The place where to put the content of the dictionnary
+
+
+procedure to write in the NVRAM
+-------------------------------
+for each sub-index
+add a flag indicating the state
+ = 0 : normal
+ = -1 : this is a old sub-index, no longer used
+ = +1 : this is a new sub-index
+
+the sub-indexed flaged to -1 could be remove when doing a new release of dictionnary
+eg. from BIOS V0 to V1, flag the old sub-index to -1. but when going to V2, those must be remove from the dictionnary
+
+this flag is important when reloading the old NVRAM content. Since the writing and reading are done sequentially, the dictionnary and the NVRAM must be synchronised.
+
+
+ON BOOT
+-------
+1. read the block data 0 and check the NVRAM version number against the current dictionnary
+if the dict version = NVRAM version, then read the NVRAM using the normal procedure (state=0 and state=+1)
+if the dict version is newer then the NVRAM, read the NVRAM using the state=0 and state=-1 . this will ensure a synchone reading of the data
+
+2. if this is a new NVRAM, write the whole dictionnary to a NEW position in the NVRAM.
+ write all sub-indexes with state=0 and =+1, do not write does with state=-1
+ write the new version number in the registery and the date
+
+
+ON WRITE
+--------
+write the content of the whole dict (only those sub-indexes that must be saved) to the NVRAM
+write the version number
+write the date
+
+
+NEW VERSION OF BIOS
+-------------------
+When a new version of BIOS is downloaded into the device, special procedure must be taken (cf. ON BOOT and ON WRITE). But to avoid problem during the update (i.e. lost of NVRAM data or worst NVRAM corruption) fewer NVRAM manipulation should be performed. Therefore, when writing the new dictionary to NVRAM, it should be put AFTER the previous one. This will provide a way to go back and fetch the previous dictionnary saved values if needed.
+
+Obviously, the NVRAM has a limited capacity and it is possible that the new BIOS will overshoot the upper limit of memory. In that case, the algorithm should do a loop-around the addressed. Meaning, if the last block of data is reached, go back to data block 1 (data block 0 = registers). If the NVRAM is large enough, it should not cause problem (i.e. overwritting the beginning of the actual dict).
+
+Data Block 0 has the offset in memory to access the current dict. It also containt the pointer to the last version of the dict. Since the algo writing to the NVRAM does not compact memory, the size of the dict is not necessarily the size of the NVRAM memory it occupies.
--- a/drivers/ecos_lpc2138_sja1000/sja1000.c Thu May 11 13:52:43 2006 +0200
+++ b/drivers/ecos_lpc2138_sja1000/sja1000.c Fri May 12 22:14:03 2006 +0200
@@ -20,4 +20,159 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+#include "lpc2138_pinout.h"
+#include "lpc2138_defs.h"
+#include "lpc2138.h"
+
+#include "sja1000.h"
+
+
+#define CYGNUM_HAL_INTERRUPT_1 CYGNUM_HAL_INTERRUPT_EINT1
+#define CYGNUM_HAL_PRI_HIGH 0
+
+
+cyg_uint32 interrupt_1_isr(cyg_vector_t vector, cyg_addrword_t data);
+void interrupt_1_dsr(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+
+/* Interrupt for CAN device. */
+static cyg_interrupt interrupt_1;
+static cyg_handle_t interrupt_1_handle;
+
+
+void init_sja1000(void)
+{
+ do
+ {
+ sja1000_write(MOD, 1<<RM); /* demande reset */
+ }
+ while ((sja1000_read(MOD) & (1<<RM)) == 0); /* loop until reset good */
+
+/*
+ sja1000_write(bustiming0, ((0<<SJW1)|(0<<SJW0)|(0<<BRP5)|(0<<BRP4)|(0<<BRP3)|(0<<BRP2)|(0<<BRP1)|(0<<BRP0)));
+ sja1000_write(bustiming1, ((1<<SAM)|(0<<TSEG22)|(1<<TSEG21)|(0<<TSEG20)|(0<<TSEG13)|(1<<TSEG12)|(0<<TSEG11)|(0<<TSEG10)));
+*/
+
+/* OUTPUT CONTROL REGISTER */
+ sja1000_write(outputcontrol, ((1<<OCTP1)|(1<<OCTN1)|(0<<OCPOL1)|(1<<OCTP0)|(1<<OCTN0)|(0<<OCPOL0)|(1<<OCMODE1)|(0<<OCMODE0)));
+
+
+ sja1000_write(clockdivider, ((1<<CANmode)|(1<<CBP)|(1<<RXINTEN)|(0<<clockoff)|(1<<CD2)|(1<<CD1)|(1<<CD0)));
+ sja1000_write(16, 0x01); /* 0 code all accept block high bit */
+ sja1000_write(17, 0x00); /* 0 all accept block high bit */
+ sja1000_write(18, 0x00); /* 0 all accept block high bit */
+ sja1000_write(19, 0x00); /* 0 all accept block high bit */
+ sja1000_write(20, 0xFE); /* 1 mask */
+ sja1000_write(21, 0xFF);
+ sja1000_write(22, 0xFF);
+ sja1000_write(23, 0xFF);
+ sja1000_write(IER, 0x01);
+ sja1000_write(clockdivider, ((1<<CANmode)|(1<<CBP)|(1<<RXINTEN)|(0<<clockoff)|(1<<CD2)|(1<<CD1)|(0<<CD0)));
+
+ do
+ {
+ sja1000_write(MOD, (1<<AFM)|(0<<STM)|(0<<RM));
+ }
+ while ((sja1000_read(MOD) & (1<<RM)) == 1); /* loop until reset gone */
+}
+
+
+/***************************************************************************/
+
+
+void init_interrupts(void)
+{
+ cyg_vector_t interrupt_1_vector = CYGNUM_HAL_INTERRUPT_1;
+ cyg_priority_t interrupt_1_priority = CYGNUM_HAL_PRI_HIGH;
+
+ cyg_interrupt_create(
+ interrupt_1_vector,
+ interrupt_1_priority,
+ (cyg_addrword_t) 0,
+ (cyg_ISR_t *) &interrupt_1_isr,
+ (cyg_DSR_t *) &interrupt_1_dsr,
+ &interrupt_1_handle,
+ &interrupt_1);
+
+ cyg_interrupt_attach(interrupt_1_handle);
+
+ cyg_interrupt_acknowledge(interrupt_1_vector);
+
+ cyg_interrupt_unmask(interrupt_1_vector);
+}
+
+/* External Interrupt 1 Service */
+void eint1_srv(void) /*__irq*/
+{
+ //++intrp_count; // increment interrupt count
+ EXTINT = 2; // Clear EINT1 interrupt flag
+ VICVectAddr = 0; // Acknowledge Interrupt
+}
+
+
+/* Initialize EINT1 Interrupt Pin */
+void init_eint1(void)
+{
+ EXTMODE = 0x2; // Edge sensitive mode on EINT1
+ EXTPOLAR = 0; // falling edge sensitive
+ P0_PINSEL0 |= 2 << 28; // Enable EINT1 on GPIO_0.14
+ VICVectAddr0 = (unsigned long) eint1_srv; // set interrupt vector in VIC 0
+ VICVectCntl0 = 0x20 | 15; // use VIC 0 for EINT1 Interrupt
+ EXTINT = 2;
+ VICIntEnable = 1 << 15; // Enable EINT1 Interrupt
+}
+
+
+/*
+{
+ unsigned char byte=sja1000_read(0x02);
+
+ if (byte & 0x01)
+ {
+ // RXFIFO full
+ }
+
+ if (byte & 0x02)
+ {
+ // overrun
+ }
+
+ if (byte & 0x04)
+ {
+ // the cpu may write a msg
+ }
+
+ if (byte & 0x08)
+ {
+ // tx complete
+ }
+
+ if (byte & 0x10)
+ {
+ // receiving
+ }
+
+ if (byte & 0x20)
+ {
+ // transmitting
+ }
+
+ if (byte & 0x40)
+ {
+ // at least one of the error counter has reached or exceeeded
+ // the CPU warning limit
+ }
+
+ if (byte & 0x80)
+ {
+ // bus off
+ }
+}
+*/
+
+
--- a/examples/TestMasterSlave/Makefile.in Thu May 11 13:52:43 2006 +0200
+++ b/examples/TestMasterSlave/Makefile.in Fri May 12 22:14:03 2006 +0200
@@ -32,6 +32,7 @@
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
+LED_ENABLE = SUB_LED_ENABLE
INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
@@ -43,6 +44,12 @@
PROGDEFINES = -DUSE_XENO
endif
+ifeq ($(LED_ENABLE),YES)
+OBJS += ../../drivers/can_virtual/led_virtual.o
+PROG_CFLAGS += -DLED_ENABLE
+endif
+
+
all: TestMasterSlave
../../drivers/$(TARGET)/libcanfestival_$(TARGET).a:
--- a/include/can_driver.h Thu May 11 13:52:43 2006 +0200
+++ b/include/can_driver.h Fri May 12 22:14:03 2006 +0200
@@ -37,15 +37,15 @@
int canClose(CAN_HANDLE fd0);
void canReceiveLoop(CAN_HANDLE fd0);
-void led_set_redgreen(unsigned char bits);
+#include "data.h"
+
+void led_set_redgreen(CO_Data *d, unsigned char bits);
int nvram_open(void);
void nvram_close(void);
char nvram_write(int type, int access_attr, void *data);
char nvram_read(int type, int access_attr, void *data);
-#include "data.h"
-
struct struct_s_BOARD {
char * busname;
int baudrate;
--- a/include/led.h Thu May 11 13:52:43 2006 +0200
+++ b/include/led.h Fri May 12 22:14:03 2006 +0200
@@ -39,5 +39,4 @@
void led_set_state(CO_Data *d, int state);
-
#endif
--- a/src/Makefile.in Thu May 11 13:52:43 2006 +0200
+++ b/src/Makefile.in Fri May 12 22:14:03 2006 +0200
@@ -30,9 +30,9 @@
PREFIX = SUB_PREFIX
BINUTILS_PREFIX = SUB_BINUTILS_PREFIX
TARGET = SUB_TARGET
-LSS_ENABLE=SUB_LSS_ENABLE
-LED_ENABLE=SUB_LED_ENABLE
-NVRAM_ENABLE=SUB_NVRAM_ENABLE
+LSS_ENABLE = SUB_LSS_ENABLE
+LED_ENABLE = SUB_LED_ENABLE
+NVRAM_ENABLE = SUB_NVRAM_ENABLE
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
TIMERS_ENABLE = SUB_TIMERS_ENABLE
@@ -73,6 +73,7 @@
ifeq ($(LED_ENABLE),YES)
OBJS += $(TARGET)_led.o
SRC_HFILES += ../include/led.h
+PROG_CFLAGS += -DLED_ENABLE
endif
ifeq ($(NVRAM_ENABLE),YES)
--- a/src/led.c Thu May 11 13:52:43 2006 +0200
+++ b/src/led.c Fri May 12 22:14:03 2006 +0200
@@ -65,6 +65,8 @@
void led_set_state(CO_Data *d, int state)
{
+printf("led_set_state(%x)\n", state);
+
switch(state)
{
case Initialisation:
@@ -100,8 +102,8 @@
{
led_stop_timer();
- led_set_green(led_state_green);
- led_set_red(led_state_red);
+ //led_set_green(led_state_green);
+ //led_set_red(led_state_red);
}
else
@@ -168,15 +170,15 @@
}
led_start_timer(d, 200);
- led_set_red(led_state_red);
+ //led_set_red(led_state_red);
}
if (led_state_green < 2 && led_state_red < 2)
{
led_stop_timer();
- led_set_green(led_state_green);
- led_set_red(led_state_red);
+ //led_set_green(led_state_green);
+ //led_set_red(led_state_red);
}
}
@@ -197,7 +199,7 @@
void led_callback(CO_Data *d, UNS32 id)
{
- unsigned char bits = 0;
+ UNS8 bits = 0;
// RED LED
if (led_sequence_table[led_sequence_red][led_seq_index_red] == '1')
@@ -233,7 +235,7 @@
if (led_seq_index_green > strlen(led_sequence_table[led_sequence_green]))
led_seq_index_green = 0;
- led_set_redgreen(bits);
+ led_set_redgreen(d, bits);
}