drivers/ecos_lpc2138_sja1000/nvram_iap.c
changeset 93 16c8ceea8f18
parent 92 0d84d95790d9
child 94 bdf4c86be6b2
equal deleted inserted replaced
92:0d84d95790d9 93:16c8ceea8f18
     1 /*
       
     2                    canfestival@canopencanada.ca
       
     3 
       
     4 See COPYING file for copyrights details.
       
     5 
       
     6 This library is free software; you can redistribute it and/or
       
     7 modify it under the terms of the GNU Lesser General Public
       
     8 License as published by the Free Software Foundation; either
       
     9 version 2.1 of the License, or (at your option) any later version.
       
    10 
       
    11 This library is distributed in the hope that it will be useful,
       
    12 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14 Lesser General Public License for more details.
       
    15 
       
    16 You should have received a copy of the GNU Lesser General Public
       
    17 License along with this library; if not, write to the Free Software
       
    18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    19 
       
    20 flash.c
       
    21 	save to / retrieve from  the non-volatile memory
       
    22 	to be tested
       
    23 	- can we write/read into an address without working with the whole page (256bytes)
       
    24 */
       
    25 
       
    26 
       
    27 #include <stdio.h>
       
    28 #include <stdlib.h>
       
    29 
       
    30 #include "applicfg.h"
       
    31 #include "data.h"
       
    32 #include "objdictdef.h"
       
    33 
       
    34 #include "lpc2138_defs.h"                    /* LPC21xx definitions */
       
    35 
       
    36 #define IAP_LOCATION 			0x7ffffff1
       
    37 
       
    38 
       
    39 // define a page of data of NVRAM_BLOCK_SIZE bytes
       
    40 //
       
    41 short data_len; /* 0 to NVRAM_BLOCK_SIZE bytes */
       
    42 short data_num_pages;
       
    43 unsigned int *data_page = NULL;
       
    44 unsigned int data_addr;
       
    45 
       
    46 unsigned int *regs_page = NULL;
       
    47 
       
    48 // local definitons
       
    49 void ee_erase(unsigned int ,unsigned int[]);		//function erases EEPROM
       
    50 void ee_write_page(unsigned int);	//function adds a record in EEPROM
       
    51 void ee_read_page(unsigned int);	//function reads the latest valid record in EEPROM
       
    52 
       
    53 typedef void (*IAP)(unsigned int [],unsigned int[]);
       
    54 IAP iap_entry;
       
    55 
       
    56 
       
    57 int iat_init()
       
    58 {
       
    59 	int n = NVRAM_BLOCK_SIZE / sizeof(unsigned int);
       
    60 
       
    61 	/* some actions to initialise the flash */
       
    62 	data_len = 0;
       
    63 	data_num_pages = 0;
       
    64 
       
    65 	data_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
       
    66 	memset(data_page, 0, sizeof(unsigned int)*n);
       
    67 
       
    68 	if (data_page == NULL)
       
    69 		return -1;
       
    70 
       
    71 	regs_page = (unsigned int *)malloc(sizeof(unsigned int) * n);
       
    72 	memset(regs_page, 0, sizeof(unsigned int)*n);
       
    73 	if (regs_page == NULL)
       
    74 		return -2;
       
    75 
       
    76 	iat_flash_read_regs();
       
    77 
       
    78 	/* start the data at the location specified in the registers */ 
       
    79 	if (0) /* for now it is 0, but put here a test to know whether
       
    80                   or not the NVRAM has been written before */
       
    81 		data_addr = regs_page[1];
       
    82 	else
       
    83 		data_addr = NVRAM_BLOCK_SIZE; /* let start at block 1 */
       
    84 
       
    85 	return 0;
       
    86 }
       
    87 
       
    88 
       
    89 void iat_end()
       
    90 {
       
    91 	/* write the last page before closing */
       
    92 	iat_flash_write_page(data_addr);
       
    93 
       
    94 	/* some actions to end accessing the flash */
       
    95 	free(data_page);
       
    96 
       
    97 	regs_page[4] = data_num_pages;
       
    98 	/* write the registers to the NVRAM before closing */
       
    99 	iat_flash_write_regs();
       
   100 	free(regs_page);
       
   101 }
       
   102 
       
   103 
       
   104 
       
   105 /************************************************************************/
       
   106 /*                                                                    	*/
       
   107 /* function:								*/
       
   108 /*  void ee_erase(unsigned int command_ee,unsigned int result_ee[])	*/
       
   109 /*                                                                     	*/
       
   110 /* type: void                                                          	*/
       
   111 /*                                                                     	*/
       
   112 /* parameters: 								*/
       
   113 /* 	command_ee   - Not used.  	               			*/
       
   114 /*  result_ee[0] - Returns a response to the last IAP command used.	*/
       
   115 /*                 0 - EEPROM successfully erased.			*/
       
   116 /*                 For all other response values, see microcontroller 	*/
       
   117 /*		   User Manual, IAP Commands and Status Codes Summary.	*/
       
   118 /*  result_ee[1] - Not used.                         			*/
       
   119 /*                                                                     	*/
       
   120 /* version: 1.1 (01/27/2006)                                           	*/
       
   121 /*                                                                     	*/
       
   122 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   123 /*  EE_SEC_L 	 - microcontroller's Flash sector where EEPROM begins	*/
       
   124 /*  EE_SEC_H 	 - microcontroller's Flash sector where EEPROM ends	*/
       
   125 /*  EE_CCLK		 - microcontroller's system clock (cclk)        */
       
   126 /*                                                                     	*/
       
   127 /* description:								*/
       
   128 /*  This function erases LPC2000 on-chip Flash sectors selected to act 	*/
       
   129 /*  as an EEPROM. All Flash sectors between EE_SEC_L abd EE_SEC_H	*/
       
   130 /*  (including these sectors) will be erased using the In Application	*/
       
   131 /*  Programming (IAP) routines (see User Manual for more details). 	*/
       
   132 /*  Also, this function disables all interrupts while erasing the       */
       
   133 /*  EEPROM. If this is not needed, three lines of the ee_erase          */
       
   134 /*  subroutine can simply be commented-out without affecting the        */
       
   135 /*  routine performance at all.                                         */
       
   136 /*                                                                     	*/
       
   137 /* revision history:                                                   	*/
       
   138 /* - Rev. 1.1 adds interrupt disable feature.				*/
       
   139 /*                                                                     	*/
       
   140 /************************************************************************/
       
   141 void ee_erase(unsigned int command_ee,unsigned int result_ee[])
       
   142 {
       
   143 	unsigned int command_iap[5];
       
   144 	unsigned int result_iap[3];
       
   145 	unsigned long int enabled_interrupts;
       
   146 
       
   147 	enabled_interrupts = VICIntEnable;  //disable all interrupts
       
   148 	VICIntEnClr        = enabled_interrupts;
       
   149 
       
   150 	command_iap[0]=50;	// prepare sectors from EE_SEC_L to EE_SEC_H for erase
       
   151 	command_iap[1]=EE_SEC_L;
       
   152 	command_iap[2]=EE_SEC_H;
       
   153 	iap_entry=(IAP) IAP_LOCATION;
       
   154 	iap_entry(command_iap,result_iap);
       
   155 
       
   156 	command_iap[0]=52;	// erase sectors from EE_SEC_L to EE_SEC_H
       
   157 	command_iap[1]=EE_SEC_L;
       
   158 	command_iap[2]=EE_SEC_H;
       
   159 	command_iap[3]=EE_CCLK;
       
   160 	iap_entry=(IAP) IAP_LOCATION;
       
   161 	iap_entry(command_iap,result_iap);
       
   162 
       
   163 	command_iap[0]=53;	// blankcheck sectors from EE_SEC_L to EE_SEC_H
       
   164 	command_iap[1]=EE_SEC_L;
       
   165 	command_iap[2]=EE_SEC_H;
       
   166 	iap_entry=(IAP) IAP_LOCATION;
       
   167 	iap_entry(command_iap,result_iap);
       
   168 
       
   169 	VICIntEnable = enabled_interrupts;  //restore interrupt enable register
       
   170 
       
   171 	result_ee[0]=result_iap[0];
       
   172 	return;
       
   173 }
       
   174 
       
   175 /************************************************************************/
       
   176 /*                                                                    	*/
       
   177 /* function: 								*/
       
   178 /*  void ee_write(unsigned int command_ee,unsigned int result_ee[])	*/
       
   179 /*                                                                     	*/
       
   180 /* type: void                                                          	*/
       
   181 /*                                                                     	*/
       
   182 /* parameters: 								*/
       
   183 /* 	command_ee   - An address of a content of ee_data type that has	*/
       
   184 /*                 to be programmed into EEPROM.                       	*/
       
   185 /*  result_ee[0] - Returns a response to the last IAP command used.	*/
       
   186 /*                 0 - data successfully programmed in EEPROM.		*/
       
   187 /*               501 - no space in EEPROM to program data.             	*/
       
   188 /*                 For all other response values, see microcontroller 	*/
       
   189 /*		   User Manual, IAP Commands and Status Codes Summary.	*/
       
   190 /*  result_ee[1] - Not used.                           			*/
       
   191 /*                                                                     	*/
       
   192 /* version: 1.1 (01/27/2006)                                           	*/
       
   193 /*                                                                     	*/
       
   194 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   195 /*  EE_BUFFER_SIZE 	   - IAP buffer size; must be 256 or 512 	*/
       
   196 /*  NO_SPACE_IN_EEPROM - EEPROM is full and no data can be programmed	*/
       
   197 /*  EE_BUFFER_MASK	   - parameter used for interfacing with IAP	*/
       
   198 /*  EE_REC_SIZE   	   - ee_data structure size in bytes        	*/
       
   199 /*  EE_SEC_L 	 	   - micro's Flash sector where EEPROM begins	*/
       
   200 /*  EE_SEC_H 	 	   - micro's Flash sector where EEPROM ends	*/
       
   201 /*  EE_CCLK		 	   - micro's system clock (cclk)       	*/
       
   202 /*                                                                     	*/
       
   203 /* description:								*/
       
   204 /*  This function writes a single structure of ee_data type into the	*/
       
   205 /*  EEPROM using an In Application	Programming (IAP) routines (see */
       
   206 /*  User Manual for more details). command_ee contains an address of	*/
       
   207 /*  this structure. EEPROM is scanned for the last (if any) record 	*/
       
   208 /*  identifier (EE_REC_ID), and a new record is added next to it.      	*/
       
   209 /*  Also, this function disables all interrupts while erasing the       */
       
   210 /*  EEPROM. If this is not needed, three lines of the ee_write          */
       
   211 /*  subroutine can simply be commented-out without affecting the        */
       
   212 /*  routine performance at all.                                         */
       
   213 /*                                                                     	*/
       
   214 /* revision history:                                                   	*/
       
   215 /* - Rev. 1.1 fixes a bug related to verifying a content written into	*/
       
   216 /*   the EEPROM. 1.0 was reporting missmatch even when there were no	*/
       
   217 /*   problems at all.							*/
       
   218 /*   Rev. 1.1 adds interrupt disable feature.				*/
       
   219 /*                                                                     	*/
       
   220 /************************************************************************/
       
   221 
       
   222 void ee_write_page(unsigned int addr)
       
   223 {
       
   224 	unsigned long int enabled_interrupts;
       
   225 	// unsigned char ee_buffer[16];
       
   226 	unsigned int command_iap[5], result_iap[3];
       
   227 
       
   228 	enabled_interrupts = VICIntEnable;  //disable all interrupts
       
   229 	VICIntEnClr        = enabled_interrupts;
       
   230 
       
   231 	iap_entry = (IAP) IAP_LOCATION;
       
   232 
       
   233 	// prepare sectors from EE_SEC_L to EE_SEC_H for erase
       
   234 	command_iap[0] = 50;			
       
   235 	command_iap[1] = EE_SEC_L;
       
   236 	command_iap[2] = EE_SEC_H;
       
   237 	iap_entry(command_iap, result_iap);
       
   238 
       
   239 	// copy RAM to flash/eeprom
       
   240 	command_iap[0] = 51;
       
   241 	command_iap[1] = (unsigned int) (addr & EE_START_MASK); // 256 kb boundary
       
   242 	command_iap[2] = (unsigned int) (data_page);            // should be on a word boundary
       
   243 	command_iap[3] = 256;
       
   244 	command_iap[4] = EE_CCLK;
       
   245 	iap_entry(command_iap, result_iap);
       
   246 
       
   247 #if 0 
       
   248 	// compare RAM and flash/eeprom
       
   249 	command_iap[0] = 56;
       
   250 	command_iap[1] = (unsigned int) data;
       
   251 	command_iap[2] = addr;
       
   252 	command_iap[3] = dlen;
       
   253 	iap_entry(command_iap, result_iap);
       
   254 #endif
       
   255 
       
   256 	VICIntEnable = enabled_interrupts;  //restore interrupt enable register
       
   257 }
       
   258 
       
   259 
       
   260 /************************************************************************/
       
   261 /*                                                                    	*/
       
   262 /* function: 								*/
       
   263 /*  void ee_read(unsigned int command_ee,unsigned int result_ee[])	*/
       
   264 /*                                                                     	*/
       
   265 /* type: void                                                          	*/
       
   266 /*                                                                     	*/
       
   267 /* parameters: 								*/
       
   268 /* 	command_ee   - Not used.					*/
       
   269 /*  result_ee[0] - Returns a response.					*/
       
   270 /*                 0 - data successfully found in EEPROM.		*/
       
   271 /*               500 - no data/records available in EEPROM.		*/
       
   272 /*  result_ee[1] - an address of the last record of ee_data type	*/
       
   273 /*				   in EEPROM.  	              		*/
       
   274 /*                                                                     	*/
       
   275 /* version: 1.1 (01/27/2006)                                           	*/
       
   276 /*                                                                     	*/
       
   277 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   278 /*  NO_RECORDS_AVAILABLE - EEPROM is empty/no records identifiable	*/
       
   279 /*			   with a record identifier (EE_REC_ID) found	*/
       
   280 /*  EE_ADR_L 	    - micro's Flash address from where EEPROM begins	*/
       
   281 /*  EE_REC_SIZE    - size (in bytes) of a ee_data structure        	*/
       
   282 /*                                                                 	*/
       
   283 /* description:								*/
       
   284 /*  This function scans an EEPROM content looking for the last record 	*/
       
   285 /*  that can be identified with a record identifier (EE_REC_ID). When 	*/
       
   286 /*  such data is found, its address is passed as result_ee[1].		*/
       
   287 /*                                                                     	*/
       
   288 /* revision history:                                                   	*/
       
   289 /* - Rev. 1.0 had problems with accessing the last record in a fully	*/
       
   290 /*   occupied EEPROM. Rev. 1.1 fixes this.				*/
       
   291 /*                                                                     	*/
       
   292 /************************************************************************/
       
   293 void ee_read_page(unsigned int addr)
       
   294 {
       
   295 	memcpy(data_page, (unsigned int *)addr, sizeof(unsigned int)*64);
       
   296 }
       
   297 
       
   298 
       
   299 //////////////////////////////////////////////////////////////////////////////////////////
       
   300 //////////////////////////////////////////////////////////////////////////////////////////
       
   301 
       
   302 
       
   303 /*
       
   304 	CAN FESTIVAL interface functions
       
   305 */
       
   306 
       
   307 
       
   308 int _get_data_len(int type)
       
   309 {
       
   310 	int len = 0; /* number of bytes */
       
   311 	switch(type)
       
   312 	{
       
   313 		case  boolean:
       
   314 			len = 1;
       
   315 			break;
       
   316 
       
   317 		case  int8:
       
   318 		case  uint8:
       
   319 			len = 1;
       
   320 			break;
       
   321 		case  int16:
       
   322 		case  uint16:
       
   323 			len = 2;
       
   324 			break;
       
   325 		case  int24:
       
   326 		case  uint24:
       
   327 			len = 3;
       
   328 			break;
       
   329 		case  int32:
       
   330 		case  uint32:
       
   331 		case  real32:
       
   332 			len = 4;
       
   333 			break;
       
   334 		case  int40:
       
   335 		case  uint40:
       
   336 			len = 5;
       
   337 			break;
       
   338 		case  int48:
       
   339 		case  uint48:
       
   340 			len = 6;
       
   341 			break;
       
   342 		case  int56:
       
   343 		case  uint56:
       
   344 			len = 7;
       
   345 			break;
       
   346 		case  int64:
       
   347 		case  uint64:
       
   348 		case  real64:
       
   349 			len = 8;
       
   350 			break;
       
   351 #if 0
       
   352 /* TO DO */
       
   353 		case  visible_string:
       
   354 		case  octet_string:
       
   355 		case  unicode_string:
       
   356 		case  time_of_day:
       
   357 		case  time_difference:
       
   358 #endif
       
   359 	}
       
   360 
       
   361 	return len;
       
   362 }
       
   363 
       
   364 
       
   365