drivers/ecos_lpc2138_sja1000/lpc2138.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 <stdio.h>
       
    24 #include <stdlib.h>
       
    25 
       
    26 #include "applicfg.h"
       
    27 // #include "objdictdef.h"
       
    28 
       
    29 #include "lpc2138_pinout.h"
       
    30 #include "lpc2138_defs.h"
       
    31 #include "lpc2138.h"
       
    32 
       
    33 #define IAP_LOCATION    0x7ffffff1
       
    34 
       
    35 // define a page of data of 256 bytes
       
    36 //
       
    37 short          data_len; /* 0 to 256 bytes */
       
    38 unsigned int   *data_page = NULL;
       
    39 unsigned int   data_addr;
       
    40 
       
    41 // local definitons
       
    42 void ee_erase(unsigned int ,unsigned int[]);		//function erases EEPROM
       
    43 void ee_write_page(unsigned int);	//function adds a record in EEPROM
       
    44 void ee_read_page(unsigned int);	//function reads the latest valid record in EEPROM
       
    45 
       
    46 typedef void (*IAP)(unsigned int [],unsigned int[]);
       
    47 IAP iap_entry;
       
    48 
       
    49 
       
    50 /***************************************************************************************/
       
    51 
       
    52 void lpc2138_pinsel_set(int pin, LPC2138_PORT port, int size, int func) 
       
    53 {
       
    54     int i;
       
    55 
       
    56     for (i = 0; i < size; pin++, i++) 
       
    57     {
       
    58         /* 2 bits par broche. */
       
    59         int shift = (pin - ((pin < 16) ? 0 : 16)) << 1;
       
    60 
       
    61         REG32_ADDR pinsel = (port == 1) ?
       
    62             (REG32_ADDR) P1_PINSEL2_ADDR : ((pin < 16) ?
       
    63                 (REG32_ADDR) P0_PINSEL0_ADDR : (REG32_ADDR) P0_PINSEL1_ADDR);
       
    64 
       
    65         *pinsel = (*pinsel & ~(BITMASK_2 << shift)) | (func << shift);
       
    66     }
       
    67 }
       
    68 
       
    69 void lpc2138_pinsel_clear() 
       
    70 {
       
    71     P0_PINSEL0 = 0x00000000;
       
    72     P0_PINSEL1 = 0x00000000;
       
    73     P1_PINSEL2 = 0x00000000;
       
    74 }
       
    75 
       
    76 
       
    77 int lpc2138_printf(void) 
       
    78 {
       
    79     return lpc2138_fprintf(stdout);
       
    80 }
       
    81 
       
    82 
       
    83 int lpc2138_printf_pins(void) 
       
    84 {
       
    85     return lpc2138_fprintf_pins(stdout);
       
    86 }
       
    87 
       
    88 
       
    89 int lpc2138_fprintf(FILE *stream) 
       
    90 {
       
    91     return fprintf(stream,
       
    92         "[p0=0x%08X,p0_iodir=0x%08X,p0_pinsel0=0x%08X,p0_pinsel1=0x%08X," \
       
    93         "p1=0x%08X,p1_iodir=0x%08X,p1_pinsel2=0x%08X]",
       
    94         P0_IOPIN, P0_IODIR, P0_PINSEL0, P0_PINSEL1,
       
    95         P1_IOPIN, P1_IODIR, P1_PINSEL2);
       
    96 }
       
    97 
       
    98 int lpc2138_fprintf_pins(FILE *stream) 
       
    99 {
       
   100     return fprintf(stream,
       
   101         "[cs_s1d13706=0x%X," \
       
   102         "cs_sja1000=0x%X," \
       
   103         "wait=0x%X," \
       
   104         "bhe=0x%X," \
       
   105         "interrupt_sja1000=0x%X," \
       
   106         "redgreenled=0x%X," \
       
   107         "ale=0x%X," \
       
   108         "rd=0x%X," \
       
   109         "wr=0x%X," \
       
   110         "data=0x%X," \
       
   111         "addresses=0x%X]",
       
   112         lpc2138_cs_s1d13706_get(),
       
   113         lpc2138_cs_sja1000_get(),
       
   114         lpc2138_wait_get(),
       
   115         lpc2138_bhe_get(),
       
   116         lpc2138_redgreenled_get(),
       
   117         lpc2138_interrupt_sja1000_get(),
       
   118         lpc2138_ale_get(),
       
   119         lpc2138_rd_get(),
       
   120         lpc2138_wr_get(),
       
   121         lpc2138_data_get(),
       
   122         lpc2138_addresses_get());
       
   123 }
       
   124 
       
   125 
       
   126 /*
       
   127 	SJA1000 interface
       
   128 */
       
   129 
       
   130 unsigned char sja1000_read(unsigned char addr8)
       
   131 {
       
   132     unsigned char data;
       
   133 
       
   134     lpc2138_data_set_mode(LPC2138_MODE_OUTPUT);
       
   135     lpc2138_ale_set(1);
       
   136     lpc2138_data_set(addr8);
       
   137 
       
   138     lpc2138_ale_set(0);
       
   139     lpc2138_data_set_mode(LPC2138_MODE_INPUT);
       
   140 
       
   141     lpc2138_cs_sja1000_set(0);
       
   142     lpc2138_rd_set(0);
       
   143     data = lpc2138_data_get();
       
   144     data = lpc2138_data_get();
       
   145 
       
   146     lpc2138_rd_set(1);
       
   147 
       
   148     lpc2138_cs_sja1000_set(1);
       
   149     lpc2138_data_set_mode(LPC2138_MODE_OUTPUT);
       
   150 
       
   151     return data;
       
   152 }
       
   153 
       
   154 
       
   155 void sja1000_write(unsigned char addr8, unsigned char data)
       
   156 {
       
   157     lpc2138_data_set_mode(LPC2138_MODE_OUTPUT);
       
   158 
       
   159     lpc2138_data_set(addr8);
       
   160 
       
   161     lpc2138_ale_set(1);
       
   162 
       
   163     lpc2138_ale_set(0);
       
   164     lpc2138_cs_sja1000_set(0);
       
   165     lpc2138_wr_set(0);
       
   166 
       
   167     lpc2138_data_set(data);
       
   168 
       
   169     lpc2138_wr_set(1);
       
   170     lpc2138_cs_sja1000_set(1);
       
   171 
       
   172 }
       
   173 
       
   174 /*
       
   175 	FLASH interface
       
   176 */
       
   177 
       
   178 /************************************************************************/
       
   179 /*                                                                    	*/
       
   180 /* function:								*/
       
   181 /*  void ee_erase(unsigned int command_ee,unsigned int result_ee[])	*/
       
   182 /*                                                                     	*/
       
   183 /* type: void                                                          	*/
       
   184 /*                                                                     	*/
       
   185 /* parameters: 								*/
       
   186 /* 	command_ee   - Not used.  	               			*/
       
   187 /*  result_ee[0] - Returns a response to the last IAP command used.	*/
       
   188 /*                 0 - EEPROM successfully erased.			*/
       
   189 /*                 For all other response values, see microcontroller 	*/
       
   190 /*		   User Manual, IAP Commands and Status Codes Summary.	*/
       
   191 /*  result_ee[1] - Not used.                         			*/
       
   192 /*                                                                     	*/
       
   193 /* version: 1.1 (01/27/2006)                                           	*/
       
   194 /*                                                                     	*/
       
   195 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   196 /*  EE_SEC_L 	 - microcontroller's Flash sector where EEPROM begins	*/
       
   197 /*  EE_SEC_H 	 - microcontroller's Flash sector where EEPROM ends	*/
       
   198 /*  EE_CCLK		 - microcontroller's system clock (cclk)        */
       
   199 /*                                                                     	*/
       
   200 /* description:								*/
       
   201 /*  This function erases LPC2000 on-chip Flash sectors selected to act 	*/
       
   202 /*  as an EEPROM. All Flash sectors between EE_SEC_L abd EE_SEC_H	*/
       
   203 /*  (including these sectors) will be erased using the In Application	*/
       
   204 /*  Programming (IAP) routines (see User Manual for more details). 	*/
       
   205 /*  Also, this function disables all interrupts while erasing the       */
       
   206 /*  EEPROM. If this is not needed, three lines of the ee_erase          */
       
   207 /*  subroutine can simply be commented-out without affecting the        */
       
   208 /*  routine performance at all.                                         */
       
   209 /*                                                                     	*/
       
   210 /* revision history:                                                   	*/
       
   211 /* - Rev. 1.1 adds interrupt disable feature.				*/
       
   212 /*                                                                     	*/
       
   213 /************************************************************************/
       
   214 void iat_flash_erase(unsigned int command_ee,unsigned int result_ee[])
       
   215 {
       
   216 	unsigned int command_iap[5];
       
   217 	unsigned int result_iap[3];
       
   218 	unsigned long int enabled_interrupts;
       
   219 
       
   220 	enabled_interrupts = VICIntEnable;  //disable all interrupts
       
   221 	VICIntEnClr        = enabled_interrupts;
       
   222 
       
   223 	command_iap[0]=50;	// prepare sectors from EE_SEC_L to EE_SEC_H for erase
       
   224 	command_iap[1]=EE_SEC_L;
       
   225 	command_iap[2]=EE_SEC_H;
       
   226 	iap_entry=(IAP) IAP_LOCATION;
       
   227 	iap_entry(command_iap,result_iap);
       
   228 
       
   229 	command_iap[0]=52;	// erase sectors from EE_SEC_L to EE_SEC_H
       
   230 	command_iap[1]=EE_SEC_L;
       
   231 	command_iap[2]=EE_SEC_H;
       
   232 	command_iap[3]=EE_CCLK;
       
   233 	iap_entry=(IAP) IAP_LOCATION;
       
   234 	iap_entry(command_iap,result_iap);
       
   235 
       
   236 	command_iap[0]=53;	// blankcheck sectors from EE_SEC_L to EE_SEC_H
       
   237 	command_iap[1]=EE_SEC_L;
       
   238 	command_iap[2]=EE_SEC_H;
       
   239 	iap_entry=(IAP) IAP_LOCATION;
       
   240 	iap_entry(command_iap,result_iap);
       
   241 
       
   242 	VICIntEnable = enabled_interrupts;  //restore interrupt enable register
       
   243 
       
   244 	result_ee[0]=result_iap[0];
       
   245 	return;
       
   246 }
       
   247 
       
   248 /************************************************************************/
       
   249 /*                                                                    	*/
       
   250 /* function: 								*/
       
   251 /*  void ee_write(unsigned int command_ee,unsigned int result_ee[])	*/
       
   252 /*                                                                     	*/
       
   253 /* type: void                                                          	*/
       
   254 /*                                                                     	*/
       
   255 /* parameters: 								*/
       
   256 /* 	command_ee   - An address of a content of ee_data type that has	*/
       
   257 /*                 to be programmed into EEPROM.                       	*/
       
   258 /*  result_ee[0] - Returns a response to the last IAP command used.	*/
       
   259 /*                 0 - data successfully programmed in EEPROM.		*/
       
   260 /*               501 - no space in EEPROM to program data.             	*/
       
   261 /*                 For all other response values, see microcontroller 	*/
       
   262 /*		   User Manual, IAP Commands and Status Codes Summary.	*/
       
   263 /*  result_ee[1] - Not used.                           			*/
       
   264 /*                                                                     	*/
       
   265 /* version: 1.1 (01/27/2006)                                           	*/
       
   266 /*                                                                     	*/
       
   267 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   268 /*  EE_BUFFER_SIZE 	   - IAP buffer size; must be 256 or 512 	*/
       
   269 /*  NO_SPACE_IN_EEPROM - EEPROM is full and no data can be programmed	*/
       
   270 /*  EE_BUFFER_MASK	   - parameter used for interfacing with IAP	*/
       
   271 /*  EE_REC_SIZE   	   - ee_data structure size in bytes        	*/
       
   272 /*  EE_SEC_L 	 	   - micro's Flash sector where EEPROM begins	*/
       
   273 /*  EE_SEC_H 	 	   - micro's Flash sector where EEPROM ends	*/
       
   274 /*  EE_CCLK		 	   - micro's system clock (cclk)       	*/
       
   275 /*                                                                     	*/
       
   276 /* description:								*/
       
   277 /*  This function writes a single structure of ee_data type into the	*/
       
   278 /*  EEPROM using an In Application	Programming (IAP) routines (see */
       
   279 /*  User Manual for more details). command_ee contains an address of	*/
       
   280 /*  this structure. EEPROM is scanned for the last (if any) record 	*/
       
   281 /*  identifier (EE_REC_ID), and a new record is added next to it.      	*/
       
   282 /*  Also, this function disables all interrupts while erasing the       */
       
   283 /*  EEPROM. If this is not needed, three lines of the ee_write          */
       
   284 /*  subroutine can simply be commented-out without affecting the        */
       
   285 /*  routine performance at all.                                         */
       
   286 /*                                                                     	*/
       
   287 /* revision history:                                                   	*/
       
   288 /* - Rev. 1.1 fixes a bug related to verifying a content written into	*/
       
   289 /*   the EEPROM. 1.0 was reporting missmatch even when there were no	*/
       
   290 /*   problems at all.							*/
       
   291 /*   Rev. 1.1 adds interrupt disable feature.				*/
       
   292 /*                                                                     	*/
       
   293 /************************************************************************/
       
   294 
       
   295 void iat_flash_write_page(unsigned int addr)
       
   296 {
       
   297 	unsigned long int enabled_interrupts;
       
   298 	// unsigned char ee_buffer[16];
       
   299 	unsigned int command_iap[5], result_iap[3];
       
   300 
       
   301 	enabled_interrupts = VICIntEnable;  //disable all interrupts
       
   302 	VICIntEnClr        = enabled_interrupts;
       
   303 
       
   304 	iap_entry = (IAP) IAP_LOCATION;
       
   305 
       
   306 	// prepare sectors from EE_SEC_L to EE_SEC_H for erase
       
   307 	command_iap[0] = 50;			
       
   308 	command_iap[1] = EE_SEC_L;
       
   309 	command_iap[2] = EE_SEC_H;
       
   310 	iap_entry(command_iap, result_iap);
       
   311 
       
   312 	// copy RAM to flash/eeprom
       
   313 	command_iap[0] = 51;
       
   314 	command_iap[1] = (unsigned int) (addr & EE_START_MASK); // 256 kb boundary
       
   315 	command_iap[2] = (unsigned int) (data_page);            // should be on a word boundary
       
   316 	command_iap[3] = 256;
       
   317 	command_iap[4] = EE_CCLK;
       
   318 	iap_entry(command_iap, result_iap);
       
   319 
       
   320 #if 0 
       
   321 	// compare RAM and flash/eeprom
       
   322 	command_iap[0] = 56;
       
   323 	command_iap[1] = (unsigned int) data;
       
   324 	command_iap[2] = addr;
       
   325 	command_iap[3] = dlen;
       
   326 	iap_entry(command_iap, result_iap);
       
   327 #endif
       
   328 
       
   329 	VICIntEnable = enabled_interrupts;  //restore interrupt enable register
       
   330 }
       
   331 
       
   332 
       
   333 /************************************************************************/
       
   334 /*                                                                    	*/
       
   335 /* function: 								*/
       
   336 /*  void ee_read(unsigned int command_ee,unsigned int result_ee[])	*/
       
   337 /*                                                                     	*/
       
   338 /* type: void                                                          	*/
       
   339 /*                                                                     	*/
       
   340 /* parameters: 								*/
       
   341 /* 	command_ee   - Not used.					*/
       
   342 /*  result_ee[0] - Returns a response.					*/
       
   343 /*                 0 - data successfully found in EEPROM.		*/
       
   344 /*               500 - no data/records available in EEPROM.		*/
       
   345 /*  result_ee[1] - an address of the last record of ee_data type	*/
       
   346 /*				   in EEPROM.  	              		*/
       
   347 /*                                                                     	*/
       
   348 /* version: 1.1 (01/27/2006)                                           	*/
       
   349 /*                                                                     	*/
       
   350 /* constants defined in LPC2k_ee.h used in this function:              	*/
       
   351 /*  NO_RECORDS_AVAILABLE - EEPROM is empty/no records identifiable	*/
       
   352 /*			   with a record identifier (EE_REC_ID) found	*/
       
   353 /*  EE_ADR_L 	    - micro's Flash address from where EEPROM begins	*/
       
   354 /*  EE_REC_SIZE    - size (in bytes) of a ee_data structure        	*/
       
   355 /*                                                                 	*/
       
   356 /* description:								*/
       
   357 /*  This function scans an EEPROM content looking for the last record 	*/
       
   358 /*  that can be identified with a record identifier (EE_REC_ID). When 	*/
       
   359 /*  such data is found, its address is passed as result_ee[1].		*/
       
   360 /*                                                                     	*/
       
   361 /* revision history:                                                   	*/
       
   362 /* - Rev. 1.0 had problems with accessing the last record in a fully	*/
       
   363 /*   occupied EEPROM. Rev. 1.1 fixes this.				*/
       
   364 /*                                                                     	*/
       
   365 /************************************************************************/
       
   366 void iat_flash_read_page(unsigned int addr)
       
   367 {
       
   368 	memcpy(data_page, (unsigned int *)addr, sizeof(unsigned int)*64);
       
   369 }
       
   370 
       
   371 
       
   372 
       
   373