eCOG1 Internal Flash Memory
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
437
On Slideshare
437
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. AN001 – eCOG1 Internal Flash Memory Version 1.4 This document describes the internal flash memory implemented in the eCOG1 microcontroller. 24 January 2008 Cyan Technology Ltd.
  • 2. AN001 eCOG1 Internal Flash Memory Version 1.4 Confidential and Proprietary Information ©Cyan Technology Ltd., 2004, 2005 This document contains confidential and proprietary information of Cyan Technology Ltd and is protected by copyright laws. Its receipt or possession does not convey any rights to reproduce, manufacture, use or sell anything based on information contained within this document. Cyan TechnologyTM, the Cyan Technology logo and Max-eICETM are trademarks of Cyan Holdings Ltd. CyanIDE® and eCOG® are registered trademarks of Cyan Holdings Ltd. Cyan Technology Ltd recognises other brand and product names as trademarks or registered trademarks of their respective holders. Any product described in this document is subject to continuous developments and improvements. All particulars of the product and its use contained in this document are given by Cyan Technology Ltd in good faith. However, all warranties implied or expressed, including but not limited to implied warranties of merchantability, or fitness for purpose, are excluded. This document is intended only to assist the reader in the use of the product. Cyan Technology Ltd shall not be liable for any loss or damage arising from the use of any information in this guide, any error or omission in such information, or any incorrect use of the product. This product is not designed or intended to be used for on-line control of aircraft, aircraft navigation or communications systems or in air traffic control applications or in the design, construction, operation or maintenance of any nuclear facility, or for any medical use related to either life support equipment or any other life-critical application. Cyan Technology Ltd specifically disclaims any express or implied warranty of fitness for any or all of such uses. Ask your sales representative for details. 24 January 2008 Cyan Technology Ltd. Page 2
  • 3. AN001 eCOG1 Internal Flash Memory Version 1.4 Revision History Version Date Notes V1.0 First release V1.1 09/06/2004 Document format updated Changed to newer register naming style V1.2 22/07/2004 Clarification of block size values V1.3 04/11/2004 Changed font sizes V1.4 10/02/2005 Updated for CyanIDE 24 January 2008 Cyan Technology Ltd. Page 3
  • 4. AN001 eCOG1 Internal Flash Memory Version 1.4 Contents 1 Introduction.......................................................................................... 3 2 Glossary .............................................................................................. 6 3 Internal Flash Memory ......................................................................... 7 3.1 Description................................................................................................. 7 3.2 Features .................................................................................................... 7 3.3 Flash Control Signals ................................................................................ 7 3.3.1 Program Control Register ................................................................... 7 3.3.2 Program Address Register ................................................................. 8 3.3.3 Program Data Register ....................................................................... 8 3.3.4 Program Configuration Register ......................................................... 9 3.3.5 Program Write Cycle Time ................................................................. 9 3.3.6 MMU Flash Control Register ............................................................ 10 3.4 Information Block Read ........................................................................... 10 3.4.1 Information Block Read Address Register........................................ 10 3.4.2 Information Block Read Data Register ............................................. 11 3.4.3 Manually Reading the Information Block .......................................... 11 3.4.4 Information Block Read Cycle Time ................................................. 11 3.5 Erase Operations..................................................................................... 12 3.5.1 Mass Erase....................................................................................... 12 3.5.2 Page Erase....................................................................................... 13 3.6 Programming Operations ........................................................................ 14 3.6.1 Page Program .................................................................................. 14 3.6.2 Word Program .................................................................................. 16 3.7 Write Protect............................................................................................ 17 3.8 Read Protect............................................................................................ 18 3.9 Mapping Flash Memory Into Code and Data Space................................ 19 3.9.1 Code Space ...................................................................................... 19 3.9.2 Flash Code Logical Address............................................................. 19 3.9.3 Flash Code Physical Address........................................................... 19 3.9.4 Flash Code Size ............................................................................... 20 3.9.5 Data Space....................................................................................... 21 3.9.6 Flash Data Logical Address.............................................................. 21 3.9.7 Flash Data Physical Address............................................................ 22 3.9.8 Flash Data Size ................................................................................ 22 24 January 2008 Cyan Technology Ltd. Page 4
  • 5. AN001 eCOG1 Internal Flash Memory Version 1.4 3.9.9 Address Translate Enable ................................................................ 23 4 Example Application .......................................................................... 24 4.1 Description............................................................................................... 24 4.2 Opening the Project................................................................................. 24 4.3 Compiling the Application ........................................................................ 24 4.4 Loading the Application ........................................................................... 25 4.5 Running the application ........................................................................... 25 5 Software Listings ............................................................................... 27 5.1 Project Files............................................................................................. 27 5.2 cstartup.asm ............................................................................................ 28 5.3 flash.c ...................................................................................................... 32 5.4 fmc.c ........................................................................................................ 36 5.5 fmc.h........................................................................................................ 41 5.6 tim.c ......................................................................................................... 42 5.7 tim.h......................................................................................................... 45 5.8 iram.map.................................................................................................. 45 5.9 initfunc.py ................................................................................................ 45 24 January 2008 Cyan Technology Ltd. Page 5
  • 6. AN001 eCOG1 Internal Flash Memory Version 1.4 1 Introduction This document describes the internal flash memory implemented in the eCOG1 microcontroller. The various program and erase methods are described, as are the methods for determining and setting the read and write protect status of the main flash block. NOTE: The read/write protect mechanism should only be used in devices that are intended for use in production and that do not need to be re-programmed in the field. Once set the protection cannot be removed by the user. An example application is provided that demonstrates the operation of the flash memory. The application runs on the eCOG1 evaluation board in conjunction with the emulator. Instructions are given for loading and running this application. 2 Glossary CPU Central Processing Unit IRAM Internal RAM IROM Internal ROM MMU Memory Management Unit RAM Random Access Memory ROM Read Only Memory SSM System Support Module The RW field entries in the register descriptions are defined as follows: R Readable W Writable DW Write to this (or any other field) produces a decoded read or write strobe signal for the whole register. All numbers take the following base formats NN decimal ‘NN’ binary 0xNN hexadecimal The on-chip I/O registers may be accessed as complete registers, or as named bit fields within the registers. The include file ecog1.h contains structure definitions for all on-chip registers and bit fields. To access any register, use the structure prefix rg. To access a bit field within a register, use the structure prefix fd. For example: // Write to flash program data register rg.flash_prg_data = 0xA55A; // Write to period bit field in configuration register fd.flash_prg_cfg.period = 0x01F1; 24 January 2008 Cyan Technology Ltd. Page 6
  • 7. AN001 eCOG1 Internal Flash Memory Version 1.4 3 Internal Flash Memory 3.1 Description The eCOG1 internal flash is a CMOS page erase, word (16-bit) programmable flash memory which is partitioned into two memory blocks. One is the main memory block, the other is the information block. The main memory block is organised as 32,768 words by 16 bits and may be used to store both program code and constant data. The information block is organised as 64 words by 16 bits. The first four locations in the information block contain the read and write protection bits for the main memory block; the remaining locations are available for storing application specific data. The page erase operation erases all words within a page. A page is composed of eight adjacent rows for the main memory block and two adjacent rows for the information block. A row contains 32 words. The flash memory erases and programs with a 3V only power supply. All memory bits erase to logic 1. Single data words can be programmed in any order, and a more efficient page programming algorithm is described. 3.2 Features • Single 3.0V power supply • Endurance: 20,000 cycles minimum, 200,000 cycles typical. • Memory organisation 32K × 16 + 64 × 16 • Greater than 100 years data retention at room temperature • Page erase capability • Fast page erase and word program operation 3.3 Flash Control Signals The eCOG1 internal flash does not have built in program and erase timing control hardware. All the necessary flash control signals must be generated and timed by the application code. The flash memory must first be erased before programming. Either a single page or the whole memory can be erased. 3.3.1 Program Control Register The flash memory control signals are accessed via the program control register flash.prg_ctrl, located at address 0xFFC9. These signals are as follows: nvstr : When set, specifies a non-volatile store cycle. prog : When set, specifies a Program cycle. erase : When set, specifies an Erase cycle. mas1 : When set, specifies that that the erase cycle is a Mass Erase of the entire block. xe : Address enable signal, (active high). infren : Information block enable, (active high). The following tables describe the state of the various signals for each operating mode: Mode Truth Table Mode XE PROG ERASE MAS1 NVSTR Standby L L L L L Program H H L L H Page Erase H L H L H Mass Erase H L H H H 24 January 2008 Cyan Technology Ltd. Page 7
  • 8. AN001 eCOG1 Internal Flash Memory Version 1.4 INFREN Truth Table Mode INFREN = 1 INFREN = 0 Program Program information block Program main memory block Page Erase Erase information block Erase main memory block Mass Erase Erase both blocks Erase main memory block In addition to the above signals, the flash memory program control register contains the safe field that must be set to 0x29 in order to enable the flash erase and program operations, the erase_op bit which must be set to enable erase operations and the program_op bit which must be set to enable program operations. The flash memory program control register (address 0xFFC9) command field bit patterns are described in the table below. Program Control Register Bit Fields Bit Name Function R/W 0 nvstr Sets the state of the NVSTR signal to the flash memory R/W 1 prog Sets the state of the PROG signal to the flash memory R/W 2 erase Sets the state of the ERASE signal to the flash memory R/W 3 mas1 Sets the state of the MAS1 signal to the flash memory R/W 4 xe Sets the state of the XE signal to the flash memory R/W 5 infren Sets the state of the INFREN signal to the flash memory R/W 6 erase_op Set to 1 to enable erase operations R/W 7 program_op Set to 1 to enable program operations R/W 15:8 safe Must be set to 0x29 to enable any program write or enable R/W operations 3.3.2 Program Address Register The program address register flash.prg_adr is located at address 0xFFCA. It sets the row and word addresses for program write and erase operations. Reading it also returns the status of the current operation. A new word address and program data value may only be written when bit 15, the bsy bit, is zero. Program Address Register Bit Fields Bit Name Function R/W 4:0 word_address Sets the word (Y) address for information reads and program R/W writes. This field is double buffered for program writes. 14:5 row_address Sets the row (X) address for information reads and program R/W writes 15 bsy A ‘1’ indicates that the flash memory interface is busy R A ‘0’ indicates that the flash address for the next write cycle may be written into this register. 3.3.3 Program Data Register The program data register flash.prg_data is located at address 0xFFCB. Writing data to this register begins the write operation and therefore this should be the last action, after having set up and timed all the necessary address and control signals. 24 January 2008 Cyan Technology Ltd. Page 8
  • 9. AN001 eCOG1 Internal Flash Memory Version 1.4 Program Data Register Bit Fields Bit Name Function R/W 15:0 program_data Sets the data value to be written to the currently addressed R/W/ word in flash memory. DW 3.3.4 Program Configuration Register The program configuration register flash.prg_cfg is located at address 0xFFC8. This register is used to set the flash write and information block read cycle times. The register also contains the last_wr bit, which modifies the behaviour of the bsy bit in the program address register. Program Configuration Register Bit Fields Bit Name Function R/W 8:0 period Sets the flash memory write cycle time as a number of cpu clock R/W periods for subsequent program write cycles. This register must be set to a non-zero value for flash program/erase to be enabled. This field also sets the information block read cycle time as a number of cpu clock periods for subsequent information read cycles. 15 last_wr When set to 1, on subsequent flash write cycles the bsy bit stays R/W set until the write cycle is complete. When set to 0, the bsy bit is cleared when write data has been accepted for the current write cycle. The flash address for the next write cycle may then be queued in the flash.prg_adr register. 3.3.5 Program Write Cycle Time During a program write operation, the write strobe width is equal to 1 plus the value written to the period bit field of the configuration register, in CPU clock periods. From the device data, the write strobe width must be in the range 20us to 40us. For the example code presented in this application note, a nominal value of 21us has been used. The period field value is calculated as in the following example: Crystal Frequency = 4.433618 MHz Clock source = High PLL Clock divider = 4 CPU clock frequency = 20 x Crystal Frequency / Clock Divider = 22.168090 MHz (With the Low PLL as the clock source and a 32.768 kHz crystal this becomes 150 x 32768 / Clock Divider) CPU clock period = 1 / 22168090 = 45.11 ns Period value = (2.1E-5 / 4.511E-8) - 1 = 464.53 Round up to the next integer value = 465 The minimum write cycle period is the write strobe width plus 1 CPU clock cycle. The configuration register last_wr bit is set before the last write to the flash. This results in the bsy bit in the program address register remaining in the busy state until the write has completed. Normally the bsy bit goes inactive as soon as the data has been accepted for a write, allowing the next address to be queued. 24 January 2008 Cyan Technology Ltd. Page 9
  • 10. AN001 eCOG1 Internal Flash Memory Version 1.4 3.3.6 MMU Flash Control Register The MMU flash control register mmu.flash_ctrl is located at address 0xFF67. Generally, these bits should be considered as configuration bits, but it is necessary to change their state while the processor is running. It is recommended that a slow CPU clock is selected before this register is updated. Normally this register is set by the application initialisation code. The early_req_en bit improves the performance when accessing the flash by reducing the number of CPU clock cycles that it takes to complete the access to one. This feature may only be used when the CPU is being clocked at less than 5 MHz. The wait_states bit field is used to set the number of wait states that are added to a flash memory access. When operating the CPU with a clock frequency of less than 10 MHz this field may be set to zero. In the range 10 MHz to 25 MHz, it should be set to one. MMU Flash Control Register Bit Fields Bit Name Function R/W 0 early_req_en When this bit is set to logic 1, internal flash accesses complete R/W within one cycle. This bit should only be set if the CPU clock speed is below 5 MHz. 3:1 wait_states This field specifies the number of clock cycles that are required R/W to access the internal flash. A value of 0 indicates that data is available on the next CPU clock rising edge after the request to the flash - a value of 1, the second clock rising edge. Up to 7 extra clock period delays can be added to the flash memory access time. 4 cache_dis when set to logic 1, this bit prevents the data from the internal R/W flash from being written back to the internal code cache. 15:5 Reserved R 3.4 Information Block Read The flash memory information block is not memory-mapped and cannot be read directly. Data stored in this block is accessed via I/O registers flash.inf_rd_adr, (address 0xFFCC) and flash.inf_rd_data, (address 0xFFCD). The read access timing is controlled using the period bit field in register flash.prg_cfg as described in section 3.3.4. Note that locations 0 to 3 of the information block are used to control the read and write protect mechanism. An attempt to read these locations always returns a data value of 0xffff irrespective of the actual data stored. 3.4.1 Information Block Read Address Register This register sets the row and word addresses for information block reads. As the information block is treated as a single page, the distinction between row and word addresses can be ignored for most purposes. Bits 0 to 5 can be treated as a 6 bit address field. Writing an address to the information block read address register triggers a read cycle from the address entered. Reading this register returns the address value and the bsy status in bit 15. This bit indicates the status of the current operation. When the bsy bit is zero, the read operation has completed and the data is available to be read from the information block read data register. 24 January 2008 Cyan Technology Ltd. Page 10
  • 11. AN001 eCOG1 Internal Flash Memory Version 1.4 Information Block Read Address Register Bit Fields Bit Name Function R/W 5:0 adr Sets the address for information block reads. R/W/ DW 15 bsy A ‘1’ indicates that the information read cycle is incomplete. R A ‘0’ indicates that the information read cycle has completed and data is now available. 3.4.2 Information Block Read Data Register Reading this 16 bit register returns the data for the last completed information read operation. The data is valid when the bsy bit in the information block read address register is zero. Information Block Data Register Bit Fields Bit Name Function R/W 15:0 inf_rd_data Data read from the Information Block at the specified address R 3.4.3 Manually Reading the Information Block The contents of the information block may be read manually in CyanIDE, provided the CPU is stopped and the information block is not read protected. In the watch window, click on the watch button and enter the address 0xFFCC (the address of the flash.inf_rd_adr register). Repeat for address 0xFFCD (the address of the flash.inf_rd_data register). Use the drop- down list for each watched item to display their values as int (16-bit integer). Click in the value field for address 0xFFCC and enter an address in the range 0x00 – 0x3F to select the desired location in the information block. CyanIDE updates the watch window with the contents of the watched items, and shows the contents of the selected information block address in location 0xFFCD. 3.4.4 Information Block Read Cycle Time During an Information Block read, the access time is determined by the contents of the period bit field in the flash memory configuration register. The value entered equals the access time, in CPU clock cycles. The required value is calculated as in the following example: Flash read access time = 110ns Crystal Frequency = 4.433618 MHz Clock source = High PLL Clock divider = 4 CPU clock frequency = 20 x Crystal Frequency/ Clock Divider = 22.168090 MHz (With the Low PLL as the clock source and a 32.768 kHz crystal this becomes 150 x 32768 / Clock Divider) CPU clock period = 1 / 22168090 = 45.11 ns Period value = Flash access time / CPU clock period = 2.44 Round this up to the next integer value = 3. If the Low PLL is used as the clock source with a 32.768 kHz crystal, the range of clock frequencies available always results in a period value of 1. 24 January 2008 Cyan Technology Ltd. Page 11
  • 12. AN001 eCOG1 Internal Flash Memory Version 1.4 3.5 Erase Operations 3.5.1 Mass Erase The mass erase operation erases the entire memory. The user has the option to erase just the main memory block or both the main memory and the information blocks. By setting the infren bit (bit 5) in the program control register, both memory blocks are erased. If infren is reset to zero during the entire erase procedure, then only the main memory block is erased. The mass erase cycle is distinguished from a page erase by the setting of the mas1 bit in the flash.prg_ctrl register. The mass erase operation requires the following sequence of writes to the program control register: 1. Set program control register to 0x2900 - enable program mode. 2. Set program control register to 0x295c (0x297c) - set erase_op, (infren), xe, mas1, erase. 3. Wait 5 us. 4. Set program control register to 0x295d (0x297d) - set erase_op, (infren), xe, mas1, erase, nvstr. 5. Wait 200 ms. 6. Set program control register to 0x2959 (0x2979) - set erase_op, (infren), xe, mas1, nvstr. 7. Wait 100 us. 8. Set program control register to 0x2900 - clear all signals. 9. Set program control register to 0x0000 - exit program mode. The values in brackets above show the values required to erase both memory blocks, as opposed to just the main flash memory block. The following code performs a mass erase of the main memory block. Note the commented out lines that set the infren bit. By including these lines and excluding the previous lines, the routine is modified to erase both the main memory and the information blocks. extern int fmc_erase_all(void) { int result = FMC_OK; // Need a non-zero value in here fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_adr = 0; rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x295c; // Erasing only main flash area //rg.flash.prg_ctrl = 0x297c; // Erasing information block as well tim_usec_delay(5); rg.flash.prg_ctrl = 0x295d; // Erasing only main flash area //rg.flash.prg_ctrl = 0x297d; // Erasing information block as well tim_msec_delay(20); rg.flash.prg_ctrl = 0x2959; // Erasing only main flash area //rg.flash.prg_ctrl = 0x2979; // Erasing information block as well tim_usec_delay(100); rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x0000; return (result); } 24 January 2008 Cyan Technology Ltd. Page 12
  • 13. AN001 eCOG1 Internal Flash Memory Version 1.4 3.5.2 Page Erase The sequence of events required to erase a page of flash memory is similar to that required for the mass erase operation. The operation is however considerably quicker. The user has the option to erase either a page from the main memory block or the information block. The information block is selected by setting the infren bit in the flash.prg_ctrl register. The page erase operation requires the following sequence to be performed: 1. Calculate row address (page number shifted left 3 bits). 2. Set the period field in the flash.prg_cfg register. 3. Set program control register to 0x2900 - enable program mode. 4. Set the row field in flash.prg_adr register. 5. Set program control register to 0x2954 (0x2974) - set erase_op, (infren), xe, erase. 6. Wait 5 us. 7. Set program control register to 0x2955 (0x2975) - set erase_op, (infren), xe, erase, nvstr. 8. Wait 10 ms. 9. Set program control register to 0x2951 (0x2971) - set erase_op, (infren), xe, nvstr. 10. Wait 100 us. 11. Set program control register to 0x2900 - clear all signals. 12. Set program control register to 0x0000 - exit program mode. The numbers in brackets above show the values required for erasing the information block as opposed to a page in the main flash memory area. The following code performs a page erase in the main memory block. Note the commented out lines that sets the infren bit. By including these lines and excluding the previous lines, the routine is modified to erase a page in the information block. static int erase_page(int page) { int result = FMC_OK; int row_address = page << 3; // Need a non-zero value in here fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_ctrl = 0x2900; rg.flash.prg_adr = row_address << 5; rg.flash.prg_ctrl = 0x2954; // Erasing page in main flash area //rg.flash.prg_ctrl = 0x2974; // Erasing page in information block tim_usec_delay(5); rg.flash.prg_ctrl = 0x2955; // Erasing page in main flash area //rg.flash.prg_ctrl = 0x2975; // Erasing page in information block tim_msec_delay(10); rg.flash.prg_ctrl = 0x2951; // Erasing page in main flash area //rg.flash.prg_ctrl = 0x2971; // Erasing page in information block tim_usec_delay(5); rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x0000; return (result); } 24 January 2008 Cyan Technology Ltd. Page 13
  • 14. AN001 eCOG1 Internal Flash Memory Version 1.4 3.6 Programming Operations 3.6.1 Page Program A page is programmed by programming eight consecutive rows of 32 words in the main memory, or two rows of 32 words in the information block. The row address for the start of the page can be calculated by multiplying the page number by 8 (shift the page number left by 3 bits). The row address is then incremented by one after each 32 word row has been programmed. The flash program controller is triggered by writing the data value to the flash.prg_data register. All the necessary control signals must therefore be set up and timed before writing the data to this register. The word programming time is set in the period bit field in the flash memory program configuration register as described in section 3.3.4. The following sequence of operations is required to program a row in the flash memory: 1. Set the X row address in the program address register. 2. Set program control register to 0x2992 - set xe, prog. 3. Wait 5 us. 4. Set program control register to 0x2993 - set xe, prog, nvstr. 5. Wait 10 us. 6. Loop 31 times, writing the Y word address and the program data, waiting for the bsy bit to clear each time. 7. Set the last write bit, write the last Y word address and the last program data. 8. Wait for the bsy bit to clear indicating the last write has completed. 9. Set program control register to 0x2991 - clear prog. 10. Set program control register to 0x2900 - clear all signals. Care should be taken not to exceed the cumulative program period Thv while programming each row. The following code writes a page of data to the flash main memory block. The calling function passes the flash page number and a data pointer to the routine. This code could be modified to write to the page that forms the information block by changing the row_count loop test to row_count <2 and setting the infren bit in the flash.prg_ctrl register. The page value would be zero. If these changes were made care would have to be taken in preparing the page data as the routine would write to locations 0-3 in the information block, these being used by the read and write protect mechanism. Caution: Do not write to locations 0-3 in the information block unless you specifically want to alter the read and write protection settings. If these are written inadvertently, the device may be rendered useless for further development work. See section 3.7 for more details. 24 January 2008 Cyan Technology Ltd. Page 14
  • 15. AN001 eCOG1 Internal Flash Memory Version 1.4 static int program_page(int page, const int * data) { int addr = page << 8; int word_count; int row_count; /* This register is used to control the write period for the Flash memory. * The write period is (register+1) multiplied by the CPU period. The * write period must be between 20 and 40 micro seconds. The closer we get * to 20 micro seconds the faster the programming will be. * * Register CPU Freq Write Period * ------------------------------------ * 0x1F3 25 MHz 20 us * 0x1F3 12.5 MHz 40 us */ fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_ctrl = 0x2900; for (row_count = 0; row_count < 8; row_count++) { rg.flash.prg_adr = adr; rg.flash.prg_ctrl = 0x2992; tim_usec_delay(5); rg.flash.prg_ctrl = 0x2993; tim_usec_delay(10); fd.flash.prg_cfg.last_wr = 0; for (word_count = 0; word_count < 32; word_count++) { if (31 == word_count) fd.flash.prg_cfg.last_wr = 1; rg.flash.prg_adr = adr; rg.flash.prg_data = *data++; while (fd.flash.prg_adr.bsy) ; adr++; } rg.flash.prg_ctrl = 0x2991; rg.flash.prg_ctrl = 0x2900; } rg.flash.prg_ctrl = 0x0000; return (FMC_OK); } 24 January 2008 Cyan Technology Ltd. Page 15
  • 16. AN001 eCOG1 Internal Flash Memory Version 1.4 3.6.2 Word Program Although the flash is arranged into pages, each page consisting of eight rows of 32 words, there is no restriction to the amount of data that can be programmed or the order in which the data words are programmed. It is therefore possible to program a single word at any location in the flash. It may be convenient for the user to ignore the concept of the page with its associated row and word addresses when performing writes to individual words. In this case, the program address register may be accessed as a word with the lower 15 bits representing the address in flash to which data will be written, and the most significant bit always set to zero. When performing single word writes, the last_wr bit in the flash.prg_cfg register must always be set before the address and data values are written to their respective registers as, by definition, this is the last data item for this programming operation. The sequence of events required to program a single word is similar to that required for a complete row, the obvious difference being the removal of the loop construct that would be used to write multiple values. The code below performs a word write to the main memory block. Note the commented out lines that set the infren bit. Including these lines and excluding the previous lines modifies the routine to write to the information block rather than to main memory. Caution: Do not write to locations 0-3 in the information block unless it is required specifically to alter the read and write protection settings. If these are written incorrectly, the device may be rendered useless for further development work. See section 3.7 for details. static int word_write(int addr, int data) { /* This register is used to control the write period for the Flash memory. * The write period is (register+1) multiplied by the CPU period. The * write period must be between 20 and 40 micro seconds. The closer we get * to 20 micro seconds the faster the programming will be. * * Register CPU Freq Write Period * ------------------------------------ * 0x1F3 25 MHz 20 us * 0x1F3 12.5 MHz 40 us */ fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_ctrl = 0x2900; rg.flash.prg_adr = addr; rg.flash.prg_ctrl = 0x2992; // Writing to main flash memory //rg.flash.prg_ctrl = 0x29b ; // Writing to information block tim_usec_delay(5); rg.flash.prg_ctrl = 0x2993; // Writing to main flash memory //rg.flash.prg_ctrl = 0x29b3; // Writing to information block tim_usec_delay(10); // Set last_wr as we are not writing any more data during this operation. fd.flash.prg_cfg.last_wr = 1; rg.flash.prg_data = data; while (fd.flash.prg_adr.bsy) ; rg.flash.prg_ctrl = 0x2991; // Writing to main flash memory //rg.flash.prg_ctrl = 0x29b1; // Writing to information block tim_usec_delay(5); // Wait 5us. rg.flash.prg_ctrl = 0x2990; // Writing to main flash memory //rg.flash.prg_ctrl = 0x29b0; // Writing to information block tim_usec_delay(1); // Wait 1us for the recovery time. rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x0000; return (FMC_OK); } 24 January 2008 Cyan Technology Ltd. Page 16
  • 17. AN001 eCOG1 Internal Flash Memory Version 1.4 3.7 Write Protect The flash memory write protect register (flash.sect_wr_prot, address 0xFFCE) determines the areas of the flash memory that can be written to from user code. It is loaded at power-on from locations 2 and 3 of the information block area in flash memory. The contents of the write protect register may be read by user code. This register is loaded at power-up or reset, after the read protect register, as follows: Location 2 of the information area of the flash memory is read into the write protect register. Next, location 3 of the information area of the flash memory is read and each bit in the write protect register is only set active if it was previously zero and a one is read from the flash memory. The result is that a bit in the write protect register is only set active (one) if the corresponding bit in location 2 is zero, and the bit in location 3 is one. This prevents a protection bit being set accidentally. The format for the write protect register is described in the table below. Write Protect Register Bit Fields Bit Function 0 When set to ‘1’, the whole of the information block area is write protected. 8 When set to ‘1’, the flash memory area from 0 to 4K is write protected. 9 When set to ‘1’, the flash memory area from 4K to 8K is write protected. 10 When set to ‘1’, the flash memory area from 8K to 12K is write protected. 11 When set to ‘1’, the flash memory area from 12K to 16K is write protected. 12 When set to ‘1’, the flash memory area from 16K to 20K is write protected. 13 When set to ‘1’, the flash memory area from 20K to 24K is write protected. 14 When set to ‘1’, the flash memory area from 24K to 28K is write protected. 15 When set to ‘1’, the flash memory area from 28K to 32K is write protected. In order to write protect an area or areas of the flash memory, the user must write a value into location 2 of the information block such that a zero appears in each bit position corresponding to the address ranges to be protected and a one appears at all other bits, and the complement of this value must be written into location 3. Example: to write protect addresses 0 to 8K: (a) Write 0xfcff (zeros in bits 8 and 9) to location 2 of the information block. (b) Write 0x0300 (ones in bits 8 and 9) to location 3 of the information block. Once the appropriate values have been written to locations 2 and 3 of the information block and the power cycled, the data in the protected memory areas cannot be erased or overwritten by user code. The information block is write protected when bit 0 of the write protect register is set. By write protecting this area, the read/write protection settings become permanent. If the information block is not write protected, then the read/write protection of the main memory may be removed by user code which erases the contents of the information block. NOTE: The read/write protect mechanism should be made permanent only in devices that are intended for use in production and that do not need to be re-programmed in the field. Once set, the permanent protection cannot be removed by the user. With the CPU stopped, the current write protect register value can be read using the CyanIDE watch window or memory window to read location 0xFFCE. 24 January 2008 Cyan Technology Ltd. Page 17
  • 18. AN001 eCOG1 Internal Flash Memory Version 1.4 3.8 Read Protect The flash memory read protect register (flash.sect_rd_prot, address 0xFFCF) determines the areas of the flash memory that can be read via the eICE interface. It is loaded from locations 0 and 1 of the information area at power-on or reset. The contents of the read protect register may be read by user code. The sequence of events that loads this register is as follows: At power-on, location 0 of the information area in flash memory is read into the read protect register. Next, location 1 of the information area is read and each bit in the read protect register is only set active if it was previously zero and a one is read from flash memory. The result is that a bit in the read protect register is only set active (one) if the bit from location 0 is zero and the bit from location 1 is one. This prevents a read protect bit being set accidentally. The format for the read protect register is described in the table below. Read Protect Register Bit Fields Bit Function 0 When set to ‘1’, the whole of the information block area is read protected. 8 When set to ‘1’, the flash memory area from 0 to 4K is read protected. 9 When set to ‘1’, the flash memory area from 4K to 8K is read protected. 10 When set to ‘1’, the flash memory area from 8K to 12K is read protected. 11 When set to ‘1’, the flash memory area from 12K to 16K is read protected. 12 When set to ‘1’, the flash memory area from 16K to 20K is read protected. 13 When set to ‘1’, the flash memory area from 20K to 24K is read protected. 14 When set to ‘1’, the flash memory area from 24K to 28K is read protected. 15 When set to ‘1’, the flash memory area from 28K to 32K is read protected. In order to read protect an area or areas of the flash memory, the user must write a value into location 0 of the information block such that a zero appears in each bit position corresponding to the address ranges to be protected and a one appears at all other bits, and the complement of this value must be written into location 1. Example: to read protect addresses 0 to 8K: (a) Write 0xfcff (zeros in bits 8 and 9) to location 0 of the information block. (b) Write 0x0300 (ones in bits 8 and 9) to location 1 of the information block. Once the appropriate values have been written to locations 0 and 1 of the information block and the power cycled, the data in the protected memory areas are not readable via the eICE interface. In this state, the protection may be removed by using the eICE interface to load code into the internal RAM that erases the information block. When this code is executed, the data in all areas of the main memory block of the flash once more becomes readable. To prevent this if desired, the information block can be write protected by setting bit 0 of the write protect register (see section 3.7). By write protecting this area all read/write protection becomes permanent. NOTE: The read/write protect mechanism should only be made permanent in devices that are intended for use in production and that do not need to be re-programmed in the field. Once set, the protection cannot be removed by the user. With the CPU stopped, the current read protect register value can be read using the CyanIDE watch window or memory window to read location 0xFFCF. 24 January 2008 Cyan Technology Ltd. Page 18
  • 19. AN001 eCOG1 Internal Flash Memory Version 1.4 3.9 Mapping Flash Memory Into Code and Data Space 3.9.1 Code Space Before code can be executed from the flash memory, it must be allocated to code space in the memory map. This is normally performed in the startup file cstartup.asm. The eCOG1 microcontroller has both code and data memory spaces. Mapping flash into the data space is described in the next section. At power up the memory map is as follows: Logical address Physical address Size 1 CODE 0x0000 – 0x00FF Flash 0x0000 – 0x00FF 256 2 DATA 0x0000 – 0x00FF IRAM 0x0000 – 0x00FF 256 3 DATA 0xFEA0 – 0xFFCF Registers 304 The cstartup code that sets up the memory map is located in the first page of flash, (address 0x0-0x00ff), and can therefore be accessed by the CPU immediately after hardware reset or power on. Three registers need to be set in order to map the required amount of flash memory to the required logical address in code space: mmu.flash_code_log mmu.irom_code_phy mmu.irom_code_size 3.9.2 Flash Code Logical Address This register (mmu.flash_code_log, located at address 0xFF44) specifies the top 16 bits of the logical start address for the flash memory block, mapped into code memory address space. To get the actual start address the value in this register is shifted up by 8 bits. The least significant bits must be zeroed according to the block size, such that the start address is a multiple of the block size (or zero). For a 256 word block (the smallest mappable block size), the whole of the register specifies the logical mapping, for a 512 word block, bit zero of this register is set to zero, and so on. Setting a bit within the block size results in erroneous behaviour. The bit pattern for the flash code logical address register is shown in the table below. Flash Code Logical Address Register Bit Name Function R/W 15:0 mmu.flash_ Logical start address (top 16 bits) for a segment of memory R/W code_log mapped into the code memory address space. The register value is shifted up by 8 bits to get the actual 24 bit start address. 3.9.3 Flash Code Physical Address This register (mmu.flash_code_phy, located at address 0xFF45) specifies the top 16 bits of the physical start address for the flash memory block, mapped into code memory address space. To get the actual start address the value in this register is shifted up by 8 bits. For an application running its code from the flash, this register is usually set to zero. The LSB bits must be zeroed according to the block size, such that the physical start address is a multiple of the block size (or zero). For a 256 word block (smallest mappable block size), the whole of the register specifies the logical mapping. For a 512 word block bit zero of this register must be set to zero, and so on. Setting a bit within the block size results in erroneous behaviour. 24 January 2008 Cyan Technology Ltd. Page 19
  • 20. AN001 eCOG1 Internal Flash Memory Version 1.4 The bit pattern for the flash code physical address register is shown in the table below. IROM Code Physical Address Register Bit Name Function R/W 7:0 mmu.flash_ Physical start address for a segment of internal rom memory R/W code_phy mapped into the code memory address space. The register value is shifted up by 8 bits to get the actual start address. 15:8 reserved R 3.9.4 Flash Code Size This register (mmu.flash_code_size, located at address 0xFF46) specifies the size of the flash memory segment to be mapped into the code memory address space. If all bits are zero, the segment size is 256 words. Setting a bit to one increases the segment size by a power of two. Only segments of size 2n are valid; attempting to set this register to obtain any other size will produce erroneous behaviour. The table below shows the valid settings and associated segment sizes for this register. Register value Segment size (words) 0x0000 256 0x0001 512 0x0003 1024 0x0007 2048 0x000F 4096 0x001F 8192 0x003F 16384 0x007F 32768 The table below shows the bit pattern for the flash code size register. Flash Code Size Register Bit Name Function R/W 7:0 mmu.flash_ Size of memory segment to be mapped into code R/W code_size memory address space. Segment size range is from 256 to 215 words. 15:8 reserved R 24 January 2008 Cyan Technology Ltd. Page 20
  • 21. AN001 eCOG1 Internal Flash Memory Version 1.4 3.9.5 Data Space As with the mapping of the code space, the data space is normally allocated by the cstartup.asm code immediately after a reset/power on. An area of the flash may be mapped into data space in order to allow variables stored in RAM to be initialised or to make stored constant data available to the application. An area of flash may appear in both code and data space, as in the following example. Logical address Type Physical address Type Data 0x0000 – 0x07FF Flash 0x007800 – 0x007FFF IROM 0x0800 – 0xE7FF None 0xE800 – 0xEFFF Ram 0x000000 – 0x0007FF IRAM 0xF000 – 0xFE9F None 0xFEA0 – 0xFFCF Register 0xFFD0 – 0xFFFF None Code 0x000000 – 0x007FFF Flash 0x000000 – 0x007FFF IROM 0x008000 – 0xFFFFFF None Here the entire 32K block has been mapped to the code space logical address range 0x0 – 0x7FFF. In addition, the top 2K of the flash memory block has been mapped to data space logical address range 0x0 – 0x07FF. In these circumstances, it is up to the user to ensure that the compiled application code does not exceed 30K in size. Four registers need to be set in order to map the required amount of flash memory to the required logical address in data space: mmu.flash_data_log mmu.flash_data_phy mmu.flash_data_size mmu.translate_en 3.9.6 Flash Data Logical Address This register (mmu.flash_data_log, located at address 0xFF50) specifies the top 8 bits of the logical start address for the flash memory block, mapped into data memory address space. To get the actual start address the value in this register is shifted up by 8 bits. The least significant bits must be zeroed according to the block size, such that the start address is a multiple of the block size (or zero). For a 256 word block (the smallest mappable block size), the whole of the register specifies the logical mapping, for a 512 word block bit zero of this register must be set to zero, and so on. Setting a bit within the block size results in erroneous behaviour. The bit pattern for the mmu.flash_data_log register is shown in the table below. Flash Data Logical Address Register Bit Name Function R/W 15:0 mmu.flash_ Logical start address for a segment of memory mapped into R/W data_log the data memory address space. The register value is shifted up by 8 bits to get the actual start address 24 January 2008 Cyan Technology Ltd. Page 21
  • 22. AN001 eCOG1 Internal Flash Memory Version 1.4 3.9.7 Flash Data Physical Address This register (mmu.flash_data_phy, located at address 0xFF51) specifies the top bits of the physical start address for the flash memory block, mapped into the data memory address space. To get the actual start address the value in this register is shifted up by 8 bits. The LSB bits must be zeroed according to the block size, such that the start address is a multiple of the block size (or zero). For a 256 word block (smallest mappable block size), the whole of the register specifies the logical mapping. For a 512 word block bit zero of this register must be set to zero, and so on. Setting a bit within the block size results in erroneous behaviour. Flash Data Physical Address Register Bit Name Function R/W 7:0 mmu.flash_ Physical start address for a segment of internal rom memory, R/W data_phy mapped into data memory space. The register value is shifted up by 8 bits to get the actual start address. 15:8 reserved R 3.9.8 Flash Data Size This register (mmu.flash_data_size, located at address 0xFF52) specifies the size of the flash memory segment to be mapped into the data address space. If all bits are zero, the segment size is 256 words. Setting a bit increases the segment size by a power of two. Only segments of size 2n are valid; attempting to set this register to obtain any other size produces erroneous behaviour. The table below shows the valid settings and associated segment sizes for this register. Register value Segment size (words) 0x0000 256 0x0001 512 0x0003 1024 0x0007 2048 0x000F 4096 0x001F 8192 0x003F 16384 0x007F 32768 The table below shows the bit pattern for the flash data size register. Flash Data Size Register Bit Name Function R/W 7:0 mmu.flash_ Size of memory segment to be mapped into data R/W data_size memory address space. Segment size range is from 256 to 215 words. 15:8 reserved R 24 January 2008 Cyan Technology Ltd. Page 22
  • 23. AN001 eCOG1 Internal Flash Memory Version 1.4 3.9.9 Address Translate Enable The MMU address translate enable register (mmu.translate_en, located at address 0xFF43) is used to set which memory translations are active. For the internal flash to appear in the data space, the flash_data bit (bit 4) should be set to one. The logical address, physical address and size settings should be made before enabling the flash translation. A translation may not be enabled or disabled while data or code is being accessed through it. The bit pattern for the translate enable register is shown in the table below. Address Translate Enable Register Bit Name Notes R/W 0 reserved, set to 1 Internal flash code space translator enable; always set R active to enable the internal flash to be mapped into code space. 1 ram_code R/W 2 ext_cs0_code R/W 3 ext_cs1_code R/W 4 flash_data When set to logic 1, this bit enables the flash memory to R/W be mapped into data space 5 reserved R 6 ram_data1 R/W 7 cache0_data R/W 8 cache1_data R/W 9 ext_cs0_data0 R/W 10 ext_cs0_data1 R/W 11 ext_cs1_data0 R/W 12 ext_cs1_data1 R/W 15:13 reserved R 24 January 2008 Cyan Technology Ltd. Page 23
  • 24. AN001 eCOG1 Internal Flash Memory Version 1.4 4 Example Application 4.1 Description This example application demonstrates the use of the internal flash memory in the eCOG1 microcontroller and provides the user with a useful utility program for managing the flash memory. The code runs from the internal RAM and is intended for use on the eCOG1 evaluation board, in conjunction with the emulator or the CyanIDE debugger. It can however be used on any eCOG1 target board that has provision for the eICE interface. The application provides the following functions: 1. Program a page in the main memory block. 2. Erase a page in the main memory block. 3. Erase all memory. This erases the entire contents of both the main memory and the information block. 4. Set timing. This function allows the default timing parameters to be altered where the code is used on a target that is running with a different clock frequency to that used on the evaluation board. 5. Set read protection. Writes the required read protect register value. 6. Set write protection. Writes the required write protect register value. 7. Information block write. Writes a specified word to a specified address in the information block. 4.2 Opening the Project From the CyanIDE main menu, select Project->Open, and navigate to the directory in which the flash example project is stored. Select the project file (*.cyp) and click the Open button. CyanIDE opens the project and displays the source files in the navigator pane to the left of the main window. Double-click on any file in the navigator (or right-click and select Open) to open it in a code editor window in the main CyanIDE workspace. 4.3 Compiling the Application From the CyanIDE main menu, select Build->Build, or Build->Rebuild All. CyanIDE compiles the C source files, then assembles and links all assembly files to generate the project output binary file. Any compilation or assembly errors are listed in the build tab of the output window. Double-click on any error to open the corresponding source file in the editor, with the cursor at the line which contains the error. 24 January 2008 Cyan Technology Ltd. Page 24
  • 25. AN001 eCOG1 Internal Flash Memory Version 1.4 4.4 Loading the Application Having compiled the application, the resulting code is downloaded to the eCOG1 evaluation board using CyanIDE. From the main menu, select Debug->Run. CyanIDE downloads the file to target memory and starts execution. This example runs from internal ram rather than from flash memory. This means that when the download is complete, the memory map must be set to map the internal ram into code space. Starting the CPU without setting up the memory map simply results in the CPU attempting to run the code that is still stored in its flash memory, rather than the new application stored in RAM. CyanIDE uses the Python script language to automate user functions. For this example, it uses a Python macro initFunc (defined in the file initfunc.py included in the project) to set up the MMU ready to execute code from ram after downloading is complete. The Python file has the run_on_project_load property set within the project to indicate to CyanIDE that the file should be run when the project is first loaded. This installs the Python macro into the interpreter ready for use in the download procedures. The application is now ready to run. 4.5 Running the application Having loaded the application, set up the memory map, and started execution, wait for a brief period and pause the CPU using Debug->Pause menu item or the toolbar Pause button. The user communicates with the application via two static variables: command_response, an integer value command_data, an array of 257 integers The required command is selected by setting command_response to the appropriate command code. The array command_data is loaded with any data required by the requested command. Use the watch window and the memory window to set and display these variables. Example: Program page 0 of the main memory: the command code is 8001. Use the watch window to set the value of command_response to 0x8001: Click on the watch button, and enter the variable name command_response. Click on the value field of the watched item, and enter the value 0x8001. For this command, command_data[0] contains the page number and the following array elements within command_data[] hold the data to be written. Start the CPU using Debug->Run or the toolbar Run button and a few seconds later stop it again. The variable command_response in the watch window now contains a response code, normally 0001. 24 January 2008 Cyan Technology Ltd. Page 25
  • 26. AN001 eCOG1 Internal Flash Memory Version 1.4 The table below summarises the command codes and the required data. Command Command Code Data Program Page 8001 command_data = page command_data + 1 to + 256 = program data Erase Page 8002 command_data = page Erase All 8003 No data required Set Timing 8004 command_data = usec count value command_data + 1 = usec ripple value command_data + 2 = msec count value command_data + 3 = msec ripple value (see tim.c for details) Read Protect 8005 command_data = read protect value Write Protect 8006 command_data = write protect value Info Write 8007 command_data = address command_data + 1 = data The response codes are summarised in the table below. Code Meaning 0000 No action taken 0001 OK 0002 Error 0003 Invalid data supplied 0004 Invalid command code 24 January 2008 Cyan Technology Ltd. Page 26
  • 27. AN001 eCOG1 Internal Flash Memory Version 1.4 5 Software Listings 5.1 Project Files The flash example project includes the following files: • flash.cyp CyanIDE project file • flash.c main program • fmc.c, fmc.h flash memory programming functions • tim.c, tim.h timer functions • irq.asm reset and interrupt vectors • cstartup.asm C startup and initialisation code • hooks.asm dummy configuration code stubs • initfunc.py Python macro for MMU initialisation after download • iram.map memory map 24 January 2008 Cyan Technology Ltd. Page 27
  • 28. AN001 eCOG1 Internal Flash Memory Version 1.4 5.2 cstartup.asm This application uses the standard cstartup.asm file that is provided with the CyanIDE example projects, modified to set the ram data area to addresses 0x0 to 0x03FF. ;============================================================================== ; Cyan Technology Ltd ; ; FILE ; cstartup.asm - Assembler startup for C programs. ; ; DESCRIPTION ; Defines C segments. Contains initial code called before C is started ;============================================================================== MODULE cstartup .ALL ; ; C reserves DATA address 0 for the NULL pointer. The value H'DEAD is put in ; here so that it is easier to spot the effect of a NULL pointer during ; debugging. User memory for constants grows upwards from H'0001. The first ; address is given the equate symbol $??LO_ADDR. ; .SEG C_RESERVED1 ORG 0 dc H'DEAD $??LO_ADDR EQU $ ; ; DATA addresses H'03E0-H'03FF are used for scratchpad RAM in interrupt mode. ; DATA addresses H'03C0-H'03DF are used for scratchpad RAM in user mode. ; DATA addresses H'03B8-H'03BF are used for register storage in interrupt mode. ; Then follows the interrupt stack, user stack and user heap. ; User memory for variables grows downwards from the end of the user stack. ; This version of cstartup only contains one area of scratchpad RAM ; which constrains users not to write re-entrant re-interruptable ; code. ; The interrupt stack must start at IY-38 to be compatible with the C compiler. ; .SEG C_RESERVED2 ORG H'03B8 $??HI_ADDR DEQU $ ds 8 ; Interrupt register storage ds 32 ; User Scratchpad IY_SCRATCH DEQU $ $?irq_scratchpad? DEQU $ ds 32 ; Interrupt Scratchpad ; ; The registers that control the functional blocks of the eCOG1 are located ; at addresses H'FEA0 to H'FFCF. The C header file <ecog1.h> declares an ; external structure that descibes the registers. This variable is defined ; below. ; .SEG REGISTERS ORG H'FEA0 $fd: $rg ds 304 ; ; C requires the following segments: ; CONST - Constants in ROM. For example: ; const char c = 'c' ; ; printf( "Hello World!" ) ; ; VAR - Variables in RAM. These are set to zero by the cstartup code. ; For example: ; int i ; (in file scope) ; static int i ; (in function scope) ; INIT - Initialisd variables in RAM. For example: ; int i = 9 ; (in file scope) 24 January 2008 Cyan Technology Ltd. Page 28
  • 29. AN001 eCOG1 Internal Flash Memory Version 1.4 ; static int i = 9 ; (in function scope) ; INITC - Initialisation data for the INIT segment ; HEAP - The heap. Required if malloc() etc. are used. ; STACK - The stack. Always required. ; ; The memory allocated to each segment is defined by the value of ; $??<segment_name>_SIZE as set below. These sizes can be set manually or, if ; the appropriate line is tagged with !PACK and the -pack option is specified ; to ECOGCL, ECOGCL will write in the size actually required for the segment. ; The sizes of the STACK and HEAP segments must be set by the user. ; $??ISTACK_SIZE = H'0040 $??STACK_SIZE = H'0100 $??HEAP_SIZE = H'0080 ; ROM segments $??INITC_SIZE = h'0000 ; !PACK $??CONST_SIZE = h'0002 ; !PACK ; RAM segments $??INIT_SIZE = h'0000 ; !PACK $??VAR_SIZE = h'0107 ; !PACK ; -- Locate DATA segments in memory -- ; ; Segments are allocated sequentially by the ??ALLOCATE macro. They may be ; set at fixed addresses by setting ADDR prior to calling ??ALLOCATE. ; ??ALLOCATE MACRO seg .SEG &seg ORG ADDR $??&seg!_LO = ADDR ADDR = ADDR + $??&seg!_SIZE $??&seg!_HI = ADDR-1 ENDMAC ; Allocate DATA ROM ADDR = $??LO_ADDR ??ALLOCATE INITC ??ALLOCATE CONST ; Allocate DATA RAM ADDR = $??HI_ADDR - $??VAR_SIZE - $??INIT_SIZE ADDR = ADDR - $??ISTACK_SIZE - $??STACK_SIZE - $??HEAP_SIZE ??ALLOCATE INIT ??ALLOCATE VAR ??ALLOCATE HEAP ??ALLOCATE STACK ??ALLOCATE ISTACK ; -- Memory initialisation macros -- ; ; Segments may be initialised by filling with a constant value using the ; ??SEGFILL macro. Two symbols are passed, the segment name and the value to ; fill with. A third symbol (the size) is assumed. ; ??SEGFILL MACRO seg, value LOCAL fill_loop IF $??&seg!_SIZE ld x, #$??&seg ld al, #$??&seg!_SIZE ld ah, &value &fill_loop: st ah, @(0,x) add x, #1 sub al, #1 bne &fill_loop ENDIF ENDMAC ; ; Segments may be initialised by copying an initialisation segment with ; the ??SEGCOPY macro. Two symbols are passed, the source and destination ; segment names. ; ??SEGCOPY MACRO src, dest 24 January 2008 Cyan Technology Ltd. Page 29
  • 30. AN001 eCOG1 Internal Flash Memory Version 1.4 IF $??&src!_SIZE NE $??&dest!_SIZE .ERR "Copy segments different sizes" ENDIF IF $??&src!_SIZE ld x, #$??&src ld y, #$??&dest ld al, #$??&src!_SIZE bc ENDIF ENDMAC ; ; Fills a block of memory with a value. Three values are passed, the start ; address for the block, the number of addresses to write to and the value ; to be written. ; ??MEMFILL MACRO start, length, value LOCAL fill_loop ld x, &start ld al, &length ld ah, &value &fill_loop: st ah, @(0,x) add x, #1 sub al, #1 bne &fill_loop ENDMAC ; ; Input argument for main(). ; .SEG CONST argv dc 0,0 ; NULL as two-word byte address ; ; Start of Code. ; .CODE ORG H'40 $?cstart_code: bra $ecog1ConfigMMU ; configure MMU and Cache Banks $ecog1ConfigContinue: ; ; Initialise segments. The HEAP and STACK are filled with H'9999 and H'aaaa ; respectively so that their maximum runtime extents can be checked. The ; INIT segment is set from the ROM initialisers in the INITC segment. The non ; initialised RAM segment VAR is set to zero (compiler puts 0 initialised ; variables in these segments as well as uninitialised ones,x). ; ??SEGFILL HEAP, #h'9999 ??SEGFILL STACK, #h'AAAA ??SEGFILL ISTACK, #h'BBBB ??SEGCOPY INITC, INIT ??SEGFILL VAR, #h'0 ; Set interrupt stack pointer. ld y, #IY_SCRATCH ; Set user mode flag to allow interupts. st flags, @(-1,y) ld al, @(-1,y) or al, #h'10 st al, @(-1,y) ld flags, @(-1,y) ; Set usermode stack pointer ld y, #$??STACK_HI ; Call ecog1Config to setup eCOG1 peripherals ; Defined in module produced by configuration compiler bsr $ecog1Config ; Call main, setting argc and argv[0] to 0. 24 January 2008 Cyan Technology Ltd. Page 30
  • 31. AN001 eCOG1 Internal Flash Memory Version 1.4 ld ah, #argv ld al, #0 bsr $main ; ; Main may exit by returning or by explicitly calling $exit. In either case ; exit code will be in AL. ; $exit: brk ; Alert the user if in debug mode bra 0 ; Restart ; ; This is the minimal interrupt routine. The contents of FLAGS is restored ; as the program counter is restored using rti. ; $minimal_handler: st flags,@(-33,y) ; Store Flags st al, @(-34,y) ; Store AL ld al, @(-33,y) ; Put Flags into AL or al, #h'0010 ; Set usermode st al, @(-33,y) ; Store the value to be restored to Flags brk ; Alert the user if in debug mode ld al, @(-34,y) ; Restore AL rti @(-33,y) ; Restore PC and Flags ; ; The address exception can happen often during development. A handler ; is put here to catch the exception. ; $address_error: st flags,@(-33,y) ; Store Flags st al, @(-34,y) ; Store AL ld al, @(-33,y) ; Put Flags into AL or al, #h'0010 ; Set usermode st al, @(-33,y) ; Store the value to be restored to Flags brk ; Alert the user if in debug mode ld al, #h'a st al, @h'ff69 ; Clear status in mmu.address_exception ld al, #h'200 st al, @h'ff7a ; Clear status in emi.ctrl_sts ld al, @(-34,y) ; Restore AL rti @(-33,y) ; Restore PC and Flags ; End of startup code $??CSTARTUP_END EQU $ ENDMOD 24 January 2008 Cyan Technology Ltd. Page 31
  • 32. AN001 eCOG1 Internal Flash Memory Version 1.4 5.3 flash.c /*============================================================================= Cyan Technology Limited FILE flash.c DESCRIPTION Runs the emulators command interpreter to program the eCOG1's internal flash memory. MODIFICATION DETAILS =============================================================================*/ #include <ecog.h> #include <ecog1.h> #include "driver_lib.h" /****************************************************************************** Public functions written in this module. Define as extern here. ******************************************************************************/ /****************************************************************************** External functions accessed by this module. Specify through module public interface include files or define explicitly. ******************************************************************************/ #include "fmc.h" #include "tim.h" /****************************************************************************** Private typedefs, macros and constants. ******************************************************************************/ /* Command codes, written in using eICE. */ #define CMD_PROGRAM_PAGE 0x8001 #define CMD_ERASE_PAGE 0x8002 #define CMD_ERASE_ALL 0x8003 #define CMD_PROGRAM 0x8004 #define CMD_TIMING_PARAM 0x8005 /* Response codes, read out using eICE. */ #define RESP_RESET 0x0000 #define RESP_OK 0x0001 #define RESP_ERR 0x0002 #define RESP_INVALID_DATA 0x0003 #define RESP_INVALID_COMMAND 0x0004 /****************************************************************************** Private functions in this module. Define as static. ******************************************************************************/ /* The command interpreter. */ static void command_interpreter(void); /* Command implementations. */ static void erase_page(void); static void erase_all(void); static void program_page(void); static void timing_param(void); /****************************************************************************** Global data declared in this module. 24 January 2008 Cyan Technology Ltd. Page 32
  • 33. AN001 eCOG1 Internal Flash Memory Version 1.4 extern definitions for any external global data used by this module. File wide static data. ******************************************************************************/ /* Input and output variables, accesses using eICE. */ int command_response; int command_data[257]; /****************************************************************************** NAME main SYNOPSIS int main(void) FUNCTION C entry point. Sits in a loop waiting for a command and providing a window for eICE. RETURNS Never. ******************************************************************************/ int main(void) { ssm_cpu_clk(SSM_HIGH_PLL, 6, 7); ssm_tmr_clk(SSM_HIGH_REF, 0); tim_init_msec(1100, 0); tim_init_usec(2, 0); while (1) { sif() ; if (command_response & 0x8000) command_interpreter(); } return 1; } /****************************************************************************** NAME command_interpreter SYNOPSIS static void command_interpreter(void) FUNCTION Calls the appropriate command handler based on the command code in command_response. The command handlers are responsible for putting the response in command_response when the command has completed. RETURNS Nothing. ******************************************************************************/ static void command_interpreter(void) { switch (command_response) { case CMD_PROGRAM_PAGE: program_page(); break; case CMD_ERASE_PAGE: erase_page(); break; case CMD_ERASE_ALL: erase_all(); break; 24 January 2008 Cyan Technology Ltd. Page 33
  • 34. AN001 eCOG1 Internal Flash Memory Version 1.4 case CMD_TIMING_PARAM: timing_param(); break; default : /* No command handler, so we provide the response. */ command_response = RESP_INVALID_COMMAND; break; } } /****************************************************************************** NAME program_page SYNOPSIS static void program_page(void) FUNCTION Programs a page of Flash memory. This command does not perform the erase. The flash contains 128 pages of 256 words. command_data[0] page 0..127 command_data[1] data[0] 0..H'FFFF command_data[2] data[1] 0..H'FFFF ... command_data[256] data[255] 0..H'FFFF RETURNS RESP_OK, RESP_ERR or RESP_INVALID_DATA in command_response. ******************************************************************************/ static void program_page(void) { int page = command_data[0]; int result; if ((page < 0) || (page > 127)) { command_response = RESP_INVALID_DATA; return; } result = fmc_program_page(page, command_data + 1); if (FMC_OK == result) command_response = RESP_OK; else command_response = RESP_ERR; } /****************************************************************************** NAME erase_page SYNOPSIS static void erase_page(void) FUNCTION Erases a page of Flash memory. This command will fail if the page is write protected. The flash contains 128 pages of 256 words. command_data[0] page 0..127 RETURNS RESP_OK, RESP_ERR or RESP_INVALID_DATA in command_response. ******************************************************************************/ static void erase_page(void) { int page = command_data[0]; int result; if ((page < 0) || (page > 127)) 24 January 2008 Cyan Technology Ltd. Page 34
  • 35. AN001 eCOG1 Internal Flash Memory Version 1.4 { command_response = RESP_INVALID_DATA; return ; } result = fmc_erase_page(page); if (FMC_OK == result) command_response = RESP_OK; else command_response = RESP_ERR; } /****************************************************************************** NAME erase_all SYNOPSIS static void erase_all(void) FUNCTION Performs a mass erase of the Flash memory. RETURNS RESP_OK or RESP_ERR in command_response. ******************************************************************************/ static void erase_all(void) { int result = fmc_erase_all(); if (FMC_OK == result) command_response = RESP_OK; else command_response = RESP_ERR; } /****************************************************************************** NAME timing_param SYNOPSIS static void timing_param(void) FUNCTION Sets the values that will be used to provide micro and milli second delays. command_data[0] usec_count command_data[1] usec_ripple command_data[2] msec_count command_data[3] msec_ripple RETURNS RESP_OK in command_response ******************************************************************************/ static void timing_param(void) { tim_init_usec(command_data[0], command_data[1]); tim_init_msec(command_data[2], command_data[3]); command_response = RESP_OK; } 24 January 2008 Cyan Technology Ltd. Page 35
  • 36. AN001 eCOG1 Internal Flash Memory Version 1.4 5.4 fmc.c /*============================================================================= Cyan Technology Limited FILE - fmc.c Flash programming functions. DESCRIPTION The eCOG1 contains a 32K word flash. It is split into 8 areas of 4K words. Each area contains 16 pages of 256 words that can be erased and programmed independently. In the API, area is 0..7 page is 0..127 (8 areas of 16 pages) data is a block of 256 words to be programmed into a page MODIFICATION DETAILS =============================================================================*/ #include <ecog.h> #include <ecog1.h> /****************************************************************************** Public functions written in this module. Define as extern here. ******************************************************************************/ #include "fmc.h" extern int fmc_page_write_allowed(int page); extern int fmc_area_write_allowed(int area); extern int fmc_erase_page(int page); extern int fmc_erase_area(int area); extern int fmc_erase_all(void); extern int fmc_program_page(int page, const int *data); /****************************************************************************** External functions accessed by this module. Specify through module public interface include files or define explicitly. ******************************************************************************/ #include "tim.h" /****************************************************************************** Private typedefs, macros and constants. ******************************************************************************/ /****************************************************************************** Private functions in this module. Define as static. ******************************************************************************/ /* Implements the page erase and program protocols. */ static int erase_page(int page); static int program_page(int page, const int *data); /****************************************************************************** Global data declared in this module. 24 January 2008 Cyan Technology Ltd. Page 36
  • 37. AN001 eCOG1 Internal Flash Memory Version 1.4 extern definitions for any external global data used by this module. File wide static data. ******************************************************************************/ /****************************************************************************** NAME fmc_page_write_allowed SYNOPSIS extern int fmc_page_write_allowed(int page) FUNCTION Checks that the page is in an area that is not write protected. The flash contains 8 areas of 16 pages. RETURNS FMC_OK if not write protected. FMC_PROTECTED if write protected. ******************************************************************************/ extern int fmc_page_write_allowed(int page) { int area = page >> 4 ; int result = fmc_area_write_allowed(area); return result; } /****************************************************************************** NAME fmc_area_write_allowed SYNOPSIS extern int fmc_area_write_allowed(int area) FUNCTION Checks whether the area is write protected. The Flash contains 8 areas. RETURNS FMC_OK if not write protected. FMC_PROTECTED if write protected. ******************************************************************************/ extern int fmc_area_write_allowed(int area) { int test_mask = 0x0100 << area; if (test_mask & rg.flash.sect_wr_prot) return FMC_PROTECTED; return FMC_OK; } /****************************************************************************** NAME fmc_erase_page SYNOPSIS extern int fmc_erase_page(int page) FUNCTION Checks that the page is not write protected and performs a page erase. RETURNS FMC_OK if erase successfully completed. FMC_PROTECTED if write proteted. FMC_ERR for other programming problems. ******************************************************************************/ extern int fmc_erase_page(int page) 24 January 2008 Cyan Technology Ltd. Page 37
  • 38. AN001 eCOG1 Internal Flash Memory Version 1.4 { int result = FMC_OK; result = fmc_page_write_allowed(page); if (FMC_OK != result) return result; result = erase_page(page); return result; } /****************************************************************************** NAME fmc_erase_area SYNOPSIS extern int fmc_erase_area(int area) FUNCTION Checks that the areas is not write protected and performs page erases on all of the 16 pages within the area. RETURNS FMC_OK if erase successfully completed. FMC_PROTECTED if write proteted. FMC_ERR for other programming problems. ******************************************************************************/ extern int fmc_erase_area(int area) { int result = FMC_OK; int page; int last_page; result = fmc_area_write_allowed(area); if (FMC_OK != result) return result; page = area << 4; last_page = page + 1 ; while (page < last_page) { result = erase_page(page); if (FMC_OK != result) break; page++; } return result; } /****************************************************************************** NAME fmc_erase_all SYNOPSIS extern int fmc_erase_all(void) FUNCTION Performs a mass erase of the Flash memory. This function does not check for any write protected areas. RETURNS FMC_OK. ******************************************************************************/ extern int fmc_erase_all(void) { 24 January 2008 Cyan Technology Ltd. Page 38
  • 39. AN001 eCOG1 Internal Flash Memory Version 1.4 int result = FMC_OK ; /* Need a non-zero value in here. */ fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_adr = 0; rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x295c; tim_usec_delay(5); rg.flash.prg_ctrl = 0x295d; tim_msec_delay(200); rg.flash.prg_ctrl = 0x2959; tim_usec_delay(100); rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x0000; return result; } /****************************************************************************** NAME fmc_program_page SYNOPSIS extern int fmc_program_page(int page, const int *data) FUNCTION Checks that the page is not write protected then performs page program. RETURNS FMC_OK if erase successfully completed. FMC_PROTECTED if write proteted. FMC_ERR for other programming problems. ******************************************************************************/ extern int fmc_program_page(int page, const int *data) { int result = FMC_OK; result = fmc_page_write_allowed(pag ); if (FMC_OK != result) return result; result = erase_page(page); if (FMC_OK != result) return result; result = program_page(page, data); return result; } /****************************************************************************** NAME erase_page SYNOPSIS static int erase_page(int page) FUNCTION Implements the page erase protocol. RETURNS FMC_OK ******************************************************************************/ static int erase_page(int page) { int result = FMC_OK ; 24 January 2008 Cyan Technology Ltd. Page 39
  • 40. AN001 eCOG1 Internal Flash Memory Version 1.4 int row_address = page << 3 ; /* Need a non-zero value in here. */ fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_ctrl = 0x2900; rg.flash.prg_adr = row_address << 5; rg.flash.prg_ctrl = 0x2954; tim_usec_delay(5); rg.flash.prg_ctrl = 0x2955; tim_msec_delay(10); rg.flash.prg_ctrl = 0x2951; tim_usec_delay(5); rg.flash.prg_ctrl = 0x2900; rg.flash.prg_ctrl = 0x0000; return result; } /****************************************************************************** NAME program_page SYNOPSIS static int program_page(int page, const int *data) FUNCTION Implements the page program protocol. RETURNS FMC_OK ******************************************************************************/ static int program_page(int page, const int *data) { int adr = page << 8; int word_count ; int row_count ; /* This register is used to control the write period for the Flash memory. * The write period is (register+1) multiplied by the CPU period. The * write period must be between 20 and 40 micro seconds. The closer we get * to 20 micro seconds the faster the programming will be. * * Register CPU Freq Write Period * ------------------------------------ * 0x1F3 25 MHz 20 us * 0x1F3 12.5 MHz 40 us */ fd.flash.prg_cfg.period = 0x1f3; rg.flash.prg_ctrl = 0x2900; for (row_count = 0; row_count < 8; row_count++) { rg.flash.prg_adr = adr; rg.flash.prg_ctrl = 0x2992; tim_usec_delay(5); rg.flash.prg_ctrl = 0x2993; tim_usec_delay(10); fd.flash.prg_cfg.last_wr = 0; for (word_count = 0; word_count < 32; word_count++) { if (31 == word_count) fd.flash.prg_cfg.last_wr = 1; rg.flash.prg_adr = adr; rg.flash.prg_data = *data++ ; 24 January 2008 Cyan Technology Ltd. Page 40
  • 41. AN001 eCOG1 Internal Flash Memory Version 1.4 while (fd.flash.prg_adr.bsy) ; adr++; } rg.flash.prg_ctrl = 0x2991; rg.flash.prg_ctrl = 0x2900; } rg.flash.prg_ctrl = 0x0000; return FMC_OK; } 5.5 fmc.h /*============================================================================= Cyan Technology Limited FILE - fmc.h Flash programming functions. DESCRIPTION The eCOG1 contains a 32K word flash. It is split into 8 areas of 4K words. Each area contains 16 pages of 256 words that can be erased and programmed independently. In the API, area is 0..7 page is 0..127 (8 areas of 16 pages) data is a block of 256 words to be programmed into a page MODIFICATION DETAILS =============================================================================*/ /****************************************************************************** #defines, typedefs, macros, externs and constants. ******************************************************************************/ #define FMC_OK 0 #define FMC_ERR 1 #define FMC_PROTECTED 2 extern int fmc_page_write_allowed(int page); extern int fmc_area_write_allowed(int area); extern int fmc_erase_page(int page); extern int fmc_erase_area(int area); extern int fmc_erase_all(void); extern int fmc_program_page(int page, const int *data); 24 January 2008 Cyan Technology Ltd. Page 41
  • 42. AN001 eCOG1 Internal Flash Memory Version 1.4 5.6 tim.c /*============================================================================= Cyan Technology Limited FILE DESCRIPTION MODIFICATION DETAILS =============================================================================*/ #include <ecog.h> #include <ecog1.h> /****************************************************************************** Public functions written in this module. Define as extern here. ******************************************************************************/ #include "tim.h" extern int tim_init_msec(int count, int ripple); extern int tim_init_usec(int count, int ripple); extern int tim_msec_delay(int msec); extern int tim_usec_delay(int usec); /****************************************************************************** External functions accessed by this module. Specify through module public interface include files or define explicitly. ******************************************************************************/ /****************************************************************************** Private typedefs, macros and constants. ******************************************************************************/ /****************************************************************************** Private functions in this module. Define as static. ******************************************************************************/ static void set_ripple(int ripple); static void delay(int count); /****************************************************************************** Global data declared in this module. extern definitions for any external global data used by this module. File wide static data. ******************************************************************************/ static int usec_count ; static int usec_ripple ; static int msec_count ; static int msec_ripple ; /****************************************************************************** NAME tim_init_msec SYNOPSIS extern int tim_init_msec(int count, int ripple) FUNCTION Configures how millisecond delays will be implemented. Ripple selects one 24 January 2008 Cyan Technology Ltd. Page 42
  • 43. AN001 eCOG1 Internal Flash Memory Version 1.4 of 16 taps off the high reference ripple counter. Count specifies how many counts of the selected ripple tap equate to one millisecond. RETURNS ******************************************************************************/ extern int tim_init_msec(int count, int ripple) { msec_count = count; msec_ripple = ripple; return TIM_OK; } /****************************************************************************** NAME tim_init_usec SYNOPSIS extern int tim_init_usec(int count, int ripple) FUNCTION Configures how microsecond delays will be implemented. Ripple selects one of 16 taps off the high reference ripple counter. Count specifies how many counts of the selected ripple tap equate to one microsecond. RETURNS ******************************************************************************/ extern int tim_init_usec(int count, int ripple) { usec_count = count ; usec_ripple = ripple ; return TIM_OK ; } /****************************************************************************** NAME tim_msec_delay SYNOPSIS extern int tim_msec_delay(int msec) FUNCTION Implements a delay of a number of milliseconds. The delay will be greater than the delay requested. RETURNS TIM_OK ******************************************************************************/ extern int tim_msec_delay(int msec) { int count; set_ripple(msec_ripple); for (count = 0; count < msec; count++) delay(msec_count); return TIM_OK ; } /****************************************************************************** NAME tim_usec_delay SYNOPSIS extern int tim_usec_delay(int usec) FUNCTION 24 January 2008 Cyan Technology Ltd. Page 43
  • 44. AN001 eCOG1 Internal Flash Memory Version 1.4 Implements a delay of a number of microseconds. The delay will be greater than the delay requested. RETURNS TIM_OK ******************************************************************************/ extern int tim_usec_delay(int usec) { int count; set_ripple(usec_ripple); for (count = 0; count < usec; count++) delay(usec_count); return TIM_OK ; } /****************************************************************************** NAME set_ripple SYNOPSIS static void set_ripple(int ripple) FUNCTION Selects a clock input to TMR. RETURNS Nothing. ******************************************************************************/ static void set_ripple(int ripple) { fd.ssm.tap_sel3.tmr = ripple; } /****************************************************************************** NAME delay SYNOPSIS static void delay(int count) FUNCTION Loads TMR with count and waits until the counter goes down to zero. RETURNS ******************************************************************************/ static void delay(int count) { rg.tim.tmr_ld = count; rg.tim.cmd = TIM_CMD_TMR_LD_MASK; rg.tim.ctrl_en = TIM_CTRL_EN_TMR_CNT_MASK; while (rg.tim.tmr_cnt) ; rg.tim.ctrl_dis = TIM_CTRL_DIS_TMR_CNT_MASK; } 24 January 2008 Cyan Technology Ltd. Page 44
  • 45. AN001 eCOG1 Internal Flash Memory Version 1.4 5.7 tim.h /*============================================================================= Cyan Technology Limited FILE DESCRIPTION MODIFICATION DETAILS =============================================================================*/ /****************************************************************************** #defines, typedefs, macros, externs and constants. ******************************************************************************/ #define TIM_OK 0 #define TIM_ERR 1 extern int tim_init_msec(int count, int ripple); extern int tim_init_usec(int count, int ripple); extern int tim_msec_delay(int msec); extern int tim_usec_delay(int usec); 5.8 iram.map ;============================================================================= ; Cyan Technology Ltd ; Example application software for eCOG ; ; FILE ; flash.map ; ; DESCRIPTION ; Architecture description file for the IROM programmer. ;============================================================================= code 0 3ff iram 0000 03ff data 0 3ff iram 0400 07ff 5.9 initfunc.py # Initialisation function to reset MMU to map IRAM # This is called twice during entry to debug mode: # Stage 0 - before program download # Stage 1 - after program download def initFunc(stage): if stage == 1: mem = app.debugger.memory mem[0xff43] = 2 # mmu.translate_en mem[0xff44] = 100 # mmu.rom_code_log mem[0xff47] = 0 # mmu.ram_code_log mem[0xff48] = 0 # mmu.ram_code_phy mem[0xff49] = 3 # mmu.ram_code_size mem[0xff53] = 0 # mmu.ram_data0_log mem[0xff54] = 4 # mmu.ram_data0_phy mem[0xff55] = 3 # mmu.ram_data0_size return 0 # Install initFunc app.debugger.extension.setInitFunction(initFunc) 24 January 2008 Cyan Technology Ltd. Page 45