Your SlideShare is downloading. ×
eCOG1 Microcontroller Application Note AN001 Internal Flash
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

eCOG1 Microcontroller Application Note AN001 Internal Flash

206
views

Published on


0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
206
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
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. eCOG1 Microcontroller Application Note AN001 Internal Flash
  • 2. COMMERCIAL IN CONFIDENCE CONTENTS 1 GLOSSARY................................................................................................................................................ 3 2 INTRODUCTION ........................................................................................................................................ 4 3 THE INTERNAL FLASH ............................................................................................................................ 5 3.1 Description .........................................................................................................................................................5 3.2 Flash Control Signals ........................................................................................................................................5 3.2.1 FMC Program Control Register ......................................................................................................................5 3.2.2 program_address .............................................................................................................................................7 3.2.3 program_data...................................................................................................................................................7 3.2.4 FMC Config Register. .....................................................................................................................................7 3.2.4.1 Flash Program .........................................................................................................................................7 3.2.4.2 Information Block Read ..........................................................................................................................8 3.2.4.3 irom_control ............................................................................................................................................9 3.3 Information Block Read ...................................................................................................................................9 3.3.1 info_read_address ...........................................................................................................................................9 3.3.2 info_read_data...............................................................................................................................................10 3.3.3 Manually reading the information block. ......................................................................................................10 3.4 Erase operations ..............................................................................................................................................10 3.4.1 mass erase .....................................................................................................................................................10 3.4.2 page erase ......................................................................................................................................................12 3.5 Programming operations ................................................................................................................................13 3.5.1 Page program ................................................................................................................................................13 3.5.2 Word program ...............................................................................................................................................15 3.6 Write Protect ...................................................................................................................................................16 3.7 Read Protect ....................................................................................................................................................17 3.8 Mapping the Flash into Code and Data space ..............................................................................................18 3.8.1 Code space ....................................................................................................................................................18 3.8.1.1 irom_code_logical_address ...................................................................................................................19 3.8.1.2 irom_code_physical_address.................................................................................................................19 3.8.1.3 irom_code_size......................................................................................................................................19 3.8.2 Data space .....................................................................................................................................................20 3.8.2.1 irom_data_logical_address ....................................................................................................................20 3.8.2.2 irom_data_physical_address .................................................................................................................21 3.8.2.3 irom_data_size ......................................................................................................................................21 3.8.2.4 translate_enable.....................................................................................................................................22 4 EXAMPLE APPLICATION ....................................................................................................................... 23 4.1 Description .......................................................................................................................................................23 4.2 Loading the application ..................................................................................................................................23 4.3 Running the application..................................................................................................................................24 5 LISTINGS ................................................................................................................................................. 25 5.1 Makefile............................................................................................................................................................25 5.2 internal.map.....................................................................................................................................................26 5.3 cstart.asm .........................................................................................................................................................26 5.4 flash.c................................................................................................................................................................26 5.5 fmc.h .................................................................................................................................................................33 5.6 fmc.c .................................................................................................................................................................33 5.7 tim.h..................................................................................................................................................................42 5.8 tim.c ..................................................................................................................................................................42 Rev 1.0 Page 2 of 45
  • 3. COMMERCIAL IN CONFIDENCE 1 GLOSSARY CGT Clock generator timer CPT Capture timer CPU Central processing unit GPT General purpose timer IO Input output IRAM Internal RAM IROM Internal ROM MMU Memory management unit PLL Phase locked loop RAM Random access memory ROM Read only memory RTC Real time clock SSM System support module TIM Timing 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 output pulse for the whole register. All numbers take the following base formats NN decimal ‘NN’ binary 0xNN hex Rev 1.0 Page 3 of 45
  • 4. COMMERCIAL IN CONFIDENCE 2 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 Demo Board in conjunction with the emulator. Instructions are given for loading and running this application. Rev 1.0 Page 4 of 45
  • 5. COMMERCIAL IN CONFIDENCE 3 THE INTERNAL FLASH 3.1 Description The eCOG1 internal Flash is a CMOS page erase, word (16-bit) program 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 are used to store the read and write protect status of 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 erases and programs with a 3.3-volt only power supply. All memory bits erase to 1. There are no order requirements in programming. Features • Single 3.3-volt power supply • Endurance: 20,000 Cycles(min) • Memory Organisation 32K by 16 + 64 by 16 • Greater than 100 years Data Retention at Room Temperature • Page Erase Capability • Fast Page Erase/Word Program Operation 3.2 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 code produced by the user. The Flash Memory must first be erased before programming, either a page or the whole memory can be erased. 3.2.1 FMC Program Control Register The flash control signals are accessed via the program control register, (reg.fmc.program_control, 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: Rev 1.0 Page 5 of 45
  • 6. COMMERCIAL IN CONFIDENCE 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 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 program control register has a “magic_value” 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 program control register, (address 0xFFC9), bit pattern is described in the table below. Bit Field RW 0 nvstr This field specifies the state of the NVSTR signal to the Flash memory. W,R 1 prog This field specifies the state of the PROG signal to the Flash memory. W,R 2 erase This field specifies the state of the ERASE signal to the Flash memory. W,R 3 mas1 This field specifies the state of the MAS1 signal to the Flash memory. W,R 4 xe This field specifies the state of the XE signal to the Flash memory. W,R 5 infren This field specifies the state of the INFREN signal to the Flash memory. W,R 6 erase_op When set to logic one this field allows an erase operation to be performed. W,R 7 program_op. When set to logic one this field allows a program write operation to be W,R performed. 15:8 magic_value. This field must be set to hex 29 for any program write or erase operation to W,R be performed. Rev 1.0 Page 6 of 45
  • 7. COMMERCIAL IN CONFIDENCE 3.2.2 program_address This register, (address 0xFFCA), is used to set the row and word address for program write and erase operations. Reading it will also return the status of the current operation. A new word address and program data value may only be written when bit 15, the busy bit, is zero. Bit Field RW 4:0 word_address This field specifies the word (Y) address for information reads and W,R program writes. This field is double buffered for program writes. 14:5 row_address This field specifies the row (X) address for information reads and program W,R writes. 15 busy When one, this bit indicates that the interface is busy. R 3.2.3 program_data This register is located at address 0xFFCB. Writing data to this register starts the write operation and therefore this should be the last action, all the necessary address and control signals having been set up and timed first. Bit Field RW 15:0 program_data. This register is used to set the data value to be written to the current word W,R, being addressed. DW 3.2.4 FMC Config Register. This register is used to configure the flash write strobe width and information block read duration. The register also contains the last_write bit, which modifies the behaviour of the busy bit in the program address register. 3.2.4.1 Flash Program During a program operation the write strobe width is equal to 1 plus the value written to the period bit field of the config 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.433618MHz Clock source = High PLL Clock divider = 4 CPU clock frequency = 20xCrystal Frequency/ Clock Divider = 22.168090MHz (With the Low PLL as the clock source and a 32.768kHz crystal this becomes 150x 32768/Clock Divider). CPU clock period = 1/22168090 = 45.11ns Rev 1.0 Page 7 of 45
  • 8. COMMERCIAL IN CONFIDENCE Period value = (2.1E-5 / 4.511E-8) - 1 = 464.53 round this up to the next integer, 465. The minimum write cycle period is the write strobe width plus 1 CPU clock cycle. The config register last_write bit is set before the last write to the flash. This results in the busy bit in the program address register remaining in the busy state until the write has completed. Normally the busy bit goes inactive as soon as the data has been accepted for a write, allowing the next address to be queued. 3.2.4.2 Information Block Read During an Information Block read, the access time is determined by the contents of the period bit field in the config register. The value entered equals the access time unit CPU clock cycles. The required value is calculated as in the following example: Flash access time = 110ns Crystal Frequency = 4.433618MHz Clock source = High PLL Clock divider = 4 CPU clock frequency = 20xCrystal Frequency/ Clock Divider = 22.168090MHz CPU clock period = 1/22168090 = 45.11ns Period value = Flash access time / CPU clock period = 2.44 Round this up to 3. If the Low PLL is used as the clock source with a 32.768kHz crystal, the range of clock frequencies available always result in a period value of 1. The FMC Config register, (address 0xFFC8), bit pattern is shown in the table below: Bit Field RW 8:0 period This field specifies the flash write period in terms of a number of cpu clock periods W,R for program write cycle. This register must be set to a non zero value for flash program/erase to be enabled. This field also specifies the information section read duration in terms of a number of cpu clock periods for information read cycles. 15 last_write When this bit is set to logic one the program address busy bit will stay busy W,R until the write has completed, otherwise it goes non-busy when the write data has been captured for write. This bit must be set before the last write to enable the end of the last write to be detected. Rev 1.0 Page 8 of 45
  • 9. COMMERCIAL IN CONFIDENCE 3.2.4.3 irom_control The Internal ROM control registeris 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 applications initialisation code. The early_request_enable 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 5MHz. 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 10MHz this field may be set to zero. In the range 10MHz to 25MHz it should be set to one. Bit Field RW 0 early_request_enable When this bit is set to logic 1 internal ROM accesses complete W,R 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 to access the R,W internal ROM. A value of 0 indicates that data is available the next CPU clock rising edge after the request to the ROM - a value of 1, the second clock rising edge. Up to 7 extra clock period delays can be added to the ROM access time. 4 cache_disable when set to logic 1, this bit disables the data from the internal ROM from R,W being written back to the internal code cache. 15:5 reserved R 3.3 Information Block Read The flash information block cannot be read directly. Data stored in this block must be accessed via IO registers fmc.info_read_address, (address 0xFFCC) and fmc.info_read_data, (address 0xFFCD). The read access timing is controlled using the period bit field in register fmc.config as described in section 3.2.4.2. 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.3.1 info_read_address This register is used to set the row and word address for information sector 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 info_read_address register triggers a read cycle from the address entered. Reading this register will return the address value and the busy bit, bit 15. This bit indicates the status of the current operation. When the busy bit goes low the read operation has completed and the data is available to be read from the info_read_data register. Rev 1.0 Page 9 of 45
  • 10. COMMERCIAL IN CONFIDENCE The info_read_address bit pattern is shown in the table below. Bit Field RW 4:0 word_address This field specifies the word (Y) address for information reads. W,R, DW 5 row_address This field specifies the row (X) address for information reads. W,R 15 busy When logic zero this field indicates that the current information read has completed R and data is now available. 3.3.2 info_read_data Reading this 16 bit register returns the data for the last completed information read operation. The data is valid when the busy bit in the info_read_address register goes low. Bit Field RW 15:0 info_read_data. Information read data. R 3.3.3 Manually reading the information block. The contents of the information block may be read manually using the eCOG emulator. The CPU must be stopped and the information block must not be read protected. Under these conditions the following commands may be used. (Where Address is a value in the range 0x00 – 0x3F). write_io_reg fmc info_read_address Address read_io_reg fmc info_read_data 3.4 Erase operations 3.4.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 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 fmc.program_control register. The mass erase operation requires the following sequence of writes to the Program Control register: Rev 1.0 Page 10 of 45
  • 11. COMMERCIAL IN CONFIDENCE 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 0x295a(0x297a) 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 refer to erasing both memory blocks. The following code performs a mass erase of the main memory block. Note the commented out line that sets the INFREN bit. By removing the “//” and allowing the compiler to compile this line the routine would be modified to erase both the main memory and the information blocks. extern int fmc_erase_all( void ) { int result = FMC_OK ; // Result returned by this procedure. reg.fmc.program_address.word = 0 ; // Not necessary to set this but it does no harm. reg.fmc.program_control.word = 0x2900 ; // Enable Erase/Program. reg.fmc.program_control.bits.erase_op = 1 ; // Enable Erase. reg.fmc.program_control.bits.xe = 1 ; // Set to 1 for all Erase/Program operations. reg.fmc.program_control.bits.mas1 = 1 ; // Enable Mass Erase. reg.fmc.program_control.bits.erase = 1 ; // Enable Erase. // reg.fmc.program_control.bits.infren = 1 ; // Include this line if you want to erase the // information area as well as the main block. tim_usec_delay( 5 ) ; // 5us wait. reg.fmc.program_control.bits.nvstr = 1 ; // Enable non-volatile storage. tim_msec_delay( 200 ) ; // 200ms wait. reg.fmc.program_control.bits.erase = 0 ; // Disable erase. tim_usec_delay( 100 ) ; // 100 us wait. reg.fmc.program_control.bits.xe = 0 ; // Reset the flash control bits. reg.fmc.program_control.bits.mas1 = 0 ; reg.fmc.program_control.bits.nvstr = 0 ; reg.fmc.program_control.bits.erase_op = 0 ; reg.fmc.program_control.word = 0x2900 ; // Clear all control signals. reg.fmc.program_control.word = 0x0000 ; // We are back to normal operation now. tim_usec_delay( 1 ) ; // 1us wait for recovery time. Rev 1.0 Page 11 of 45
  • 12. COMMERCIAL IN CONFIDENCE return result ; } 3.4.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 fmc.program_control 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 fmc.config register. 3. Set program control register to 0x2900. Enable program mode 4. Set the row field in fmc.program_address 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 refer to erasing the information block. The following code performs a page erase in the main memory block. Note the commented out line that sets the INFREN bit. By removing the “//” and allowing the compiler to compile this line the routine would be modified to erase the information block. static int erase_page( int page ) { int result = FMC_OK ; // Result returned by this procedure. int row_address = page << 3 ; // Find row address from page number. reg.fmc.program_control.word = 0x2900 ; // Enable Erase/Program. reg.fmc.program_address.bits.row_address = row_address ; // Set row address. reg.fmc.program_control.bits.erase_op = 1 ; // Enable erase. reg.fmc.program_control.bits.xe = 1 ; // Set to 1 for all erase/program operations. // reg.fmc.program_control.bit.infren =1; // Include this line if you want this routine to // erase the information block in place of the // main memory block. Rev 1.0 Page 12 of 45
  • 13. COMMERCIAL IN CONFIDENCE reg.fmc.program_control.bits.erase = 1 ; // Enable erase. tim_usec_delay( 5 ) ; // Wait 5us. reg.fmc.program_control.bits.nvstr = 1 ; // Enable non-volatile storage. tim_msec_delay( 10 ) ; // wait 10ms. reg.fmc.program_control.bits.erase = 0 ; // Disable erase. tim_usec_delay( 5 ) ; // Wait 5us. reg.fmc.program_control.bits.xe = 0 ; // Reset the flash control bits. reg.fmc.program_control.bits.nvstr = 0 ; tim_usec_delay( 1 ) ; // Wait 1us recovery time. reg.fmc.program_control.word = 0x2900 ; // Clear all control signals. reg.fmc.program_control.word = 0x0000 ; // We are back to normal operation now. return result ; } 3.5 Programming operations 3.5.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 program controller is triggered by writing the data value to the program_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 config register as described in section 3.2.4.2. The following sequence of events is required to program a row in the Flash Memory: Set the X row address in the program address register. Set program control register to 0x2992 Set xe, prog. Wait 5 uS Set program control register to 0x2993 Set xe, prog, nvstr. Wait 10 uS Loop 31 times writing the Y word address and the program data, waiting for controller to go non-busy each time. Set the last write bit and write the last Y word address and the last program data. Wait for the not busy bit to go active indicating the last write has completed. Set program control register to 0x2991 Clear prog. 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. Rev 1.0 Page 13 of 45
  • 14. COMMERCIAL IN CONFIDENCE 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 row_count loop after the XE bit has been set. The page value would be zero. If these changes where 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 are specifically wanting to alter the read and write protection settings, the device may be rendered useless for further development work. See section 3.6 for details. static int program_page( int page, const int * data ) { int row_address = page << 3 ; // find the row address from the page number. int word_count ; int row_count ; int original_period = reg.fmc.config.bits.period ; // Store the current setting of the period bit field, // we’ll need to restore this later. /* Tprog + Tads + Tadh >= 21 us * The closer this is to 21us the quicker the load will be. */ reg.fmc.config.bits.period = 0x1d1 ; // 0x1d1 gives 21us with a 4.433MHz xtal // with the cpu running at (high_PLL)/4 MHz. reg.fmc.program_control.word = 0x2900 ; // Enable Erase/Program. for ( row_count = 0 ; row_count < 8 ; row_count++ ) { reg.fmc.program_address.bits.row_address = row_address + row_count ; // Set row address. reg.fmc.program_control.bits.program_op = 1 ; // Enable programming operations. reg.fmc.program_control.bits.prog = 1 ; // Enable flash program signal. reg.fmc.program_control.bits.xe = 1 ; // Enable address. tim_usec_delay( 5 ) ; // Wait 5us. reg.fmc.program_control.bits.nvstr = 1 ; // Enable non volatile store operation tim_usec_delay( 10 ) ; // Wait 10us reg.fmc.config.bits.last_write = 0 ; // This is not the last word in the row. for ( word_count = 0 ; word_count < 32 ; word_count++ ) { if ( 31 == word_count ) reg.fmc.config.bits.last_write = 1 ; // Set when we get to the last word in the row. reg.fmc.program_address.bits.word_address = word_count ; // Set the word, (Y), address. reg.fmc.program_data = *data++ ; // Fetch the data to be stored and increment the // pointer. while ( reg.fmc.program_address.bits.busy ) // Wait until the program controller is not busy. ; } reg.fmc.program_control.bits.prog = 0 ; // Disable the flash prog signal. tim_usec_delay( 5 ) ; // Wait 5us. Rev 1.0 Page 14 of 45
  • 15. COMMERCIAL IN CONFIDENCE reg.fmc.program_control.bits.nvstr = 0 ; // Disable the non-volatile store. tim_usec_delay( 1 ) ; // Wait 1us for recovery. reg.fmc.program_control.word = 0x2900 ; // Clear all control signals. } reg.fmc.program_control.word = 0x0000 ; // exit program mode. reg.fmc.config.bits.period = original_period ; // Restore the original period setting. return FMC_OK ; } 3.5.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 its order. 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 it’s 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 that will be written to and the most significant bit always set to zero. When performing single word writes the last_write bit in the fmc config register must always be set before the address and data values are written to their respective registers as, by definition, we are not writing more data during this programming operation. The sequence of event required to program a single word is similar to that require 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 line that sets the infren bit. By including this line the routine is modified to write to the information block rather than the main memory. Caution: Do not write to locations 0-3 in the information block unless you are specifically wanting to alter the read and write protection settings, the device may be rendered useless for further development work. See section 3.6 for details. static int word_write( int addr, int data ) { int original_period = reg.fmc.config.bits.period ; // Store the current setting of the period bit field, // we’ll need to restore this later. /* Tprog + Tads + Tadh >= 21 us * The closer this is to 21us the quicker the load will be. */ reg.fmc.config.bits.period = 0x1d1 ; // 0x1d1 gives 21us with a 4.433MHz xtal // with the cpu running at (high_PLL)/4 MHz. reg.fmc.program_control.word = 0x2900 ; // Enable program/erase operations. reg.fmc.program_control.bits.program_op = 1 ; // Enable program operation. reg.fmc.program_control.bits.prog = 1 ; // Set the flash prog signal. reg.fmc.program_control.bits.xe = 1 ; // Set the flash address enable signal. //reg.fmc.program_control.bits.infren = 1 ; // Include this line to select the information block in Rev 1.0 Page 15 of 45
  • 16. COMMERCIAL IN CONFIDENCE // place of main memory. tim_usec_delay( 5 ) ; // Wait 5us. reg.fmc.program_control.bits.nvstr = 1 ; // Enable the non volatile store operation. tim_usec_delay( 10 ) ; // Wait 10us. reg.fmc.config.bits.last_write = 1 ; // Set last_write as we are not writing more data // during this operation. reg.fmc.program_address.word = addr ; // Set the address. reg.fmc.program_data = data ; // Write the data. while ( reg.fmc.program_address.bits.busy ) // Wait for the end of the programming cycle. ; reg.fmc.program_control.bits.prog = 0 ; // Clear the flash prog signal. tim_usec_delay( 5 ) ; // Wait 5us. reg.fmc.program_control.bits.nvstr = 0 ; // Disable the non volatile store tim_usec_delay( 1 ) ; // Wait 1us for the recovery time. reg.fmc.program_control.word = 0x2900 ; // Clear all signals. reg.fmc.program_control.word = 0x0000 ; // Back to normal operation now. reg.fmc.config.bits.period = original_period ; // Restore the original period setting. return FMC_OK ; } 3.6 Write Protect The Write Protect register, (fmc.write_page_protect, address 0xFFCE), is loaded at Power On from locations 2 and 3 of the information area of the Flash Memory. This register determines the areas of the Flash memory that the user can access for writes from the user code. The loaded value may be read by the user code. This register is loaded 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 bit from the lower address is zero and from the upper address is one. This prevents a protect bit accidentally being set. The format for the write protect register is described in the table below. Bit Function 0 When active the whole information area is write protected. 8 When active memory area 0 to 4K is write protected. 9 When active memory area 4 to 8K is write protected. Rev 1.0 Page 16 of 45
  • 17. COMMERCIAL IN CONFIDENCE 10 When active memory area 8 to 12K is write protected. 11 When active memory area 12 to 16K is write protected. 12 When active memory area 16 to 20K is write protected. 13 When active memory area 20 to 24K is write protected. 14 When active memory area 24 to 28K is write protected. 15 When active memory area 28 to 32K is write protected. In order to write protect an area or areas of the flash the user must write a value into location 2 of the information block such that a zero appears in each bit position corresponding with the address ranges to be protected and a one appears at all other bits. Location 3 of the information block then has the compliment of the value written to location 2 written to it. Example: In order to protect addresses 0 to 8k write 0xfcff, (all ones except bits 8 and 9), to location 2 in the infomation block. Write 0x0300, (all zeros except 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 is written to erase the contents of the information block. 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 write protect register value can be read using the emulator command: read_io_reg fmc write_page_protect 3.7 Read Protect The Read Protect register, (fmc.read_page_protect, address 0xFFCF), is loaded from the lower two locations of the information area of the Flash Memory at Power On. This register determines the areas of the Flash memory that the user can access for read via the eICE interface. The loaded value may be read by the user code. The sequence of events that loads this register is as follows: At Power, On location 0 of the information area of the Flash Memory is read into the Read Protect register. Next, location 1 of the information area of the Flash Memory 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 the Flash Memory. The result is that a bit in the read protect register is only set active (one) if the bit from the lower address is zero and the bit from the upper address is one. This prevents a protect bit accidentally being set. The format for the read protect register is described in the table below. Bit Function 0 When active the whole information area is read protected. 8 When active memory area 0 to 4K is read protected. Rev 1.0 Page 17 of 45
  • 18. COMMERCIAL IN CONFIDENCE 9 When active memory area 4 to 8K is read protected. 10 When active memory area 8 to 12K is read protected. 11 When active memory area 12 to 16K is read protected. 12 When active memory area 16 to 20K is read protected. 13 When active memory area 20 to 24K is read protected. 14 When active memory area 24 to 28K is read protected. 15 When active memory area 28 to 32K is read protected. In order to read protect an area or areas of the flash the user must write a value into location 0 of the information block such that a zero appears in each bit position corresponding with the address ranges to be protected and a one appears at all other bits. Location 1 of the information block then has the compliment of the value written to location 0 written to it. Example: In order to protect addresses 0 to 8k write 0xfcff, (all ones except bits 8 and 9), to location 0 in the information block. Write 0x0300, (all zeros except 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 will not be 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 would erase the information block. The data in all areas of the main memory block of the flash would once more be readable. In order to prevent this the information block must be write protected. The information block is write protected when bit 0 of the write protect register is set, (See section 3.6 Write Protect). By write protecting this area the 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 emulator command: read_io_reg fmc read_page_protect 3.8 Mapping the Flash into Code and Data space 3.8.1 Code space Before code can be executed from the flash it must be allocated space in the memory map. This is normally performed in the cstart.asm file.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 Physical Size ------------------------------------------------------------------------ 1. CODE H'0000-H'00FF IROM H'0000-H'00FF 256 2. DATA H'0000-H'00FF IRAM H'0000-H'00FF 256 3. DATA H'FEA0-H'FFCF Registers 304 The cstart code that sets up the memory map is located in the first page of flash, (address 0-0xff), and can therefore be accessed by the CPU immediately after a reset/power on. Rev 1.0 Page 18 of 45
  • 19. COMMERCIAL IN CONFIDENCE Three registers need to be set in order to map the required amount of flash to the required logical address, these being mmu.irom_code_logical_address mmu.irom_code_physical_address and mmu.irom_code_size. 3.8.1.1 irom_code_logical_address This register, address 0xFF44, specifies the top 16 bits of the logical start address for the irom memory block mapped into the code memory space. To get the actual start address the value in this register must be shifted up by 8 bits. The LSB bits must be zeroed according to the block size, therefore 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 will result in erroneous behaviour. The bit pattern for the irom_code_logical_address register is shown in the table below. Bit Field RW 15:0 code_logical_address Logical start address for a segment of memory mapped into the W,R code memory address space. The value in the register must be shifted up by 8 bits to get the actual start address 3.8.1.2 irom_code_physical_address This register, address 0xFF45, specifies the top bits of the physical start address for the irom memory block mapped into the code memory space. To get the actual start address the value in this register must be shifted up by 8 bits. For an application running its code from the flash this register would usually be set to zero. The LSB bits must be zeroed according to the block size, therefore 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 will result in erroneous behaviour. The bit pattern for the irom_code_physical_address register is shown in the table below. Bit Field RW 7:0 irom_physical_address physical start address for a segment of internal rom memory W,R mapped into code memory space. The value in the register must be shifted up by 8 bits to get the actual start address 15:8 reserved R 3.8.1.3 irom_code_size This register, address 0xFF46, specifies the size of the irom memory segment to be mapped into the code address space. If all bits are zero the segment size is 256 words, setting a bit increases the segment size by n a power of two. Only segments of size 2 are valid, attempting to set this register to obtain any other size will produce erroneous behaviour. The table below shows the valid settings for this register and the associated memory segment sizes. Register value Segment size (words) 0x0000 256 Rev 1.0 Page 19 of 45
  • 20. COMMERCIAL IN CONFIDENCE 0x0001 512 0x0003 1024 0x0007 2048 0x000f 4096 0x001f 8192 0x003f 16384 0x007f 32768 The table below shows the bit pattern for the irom_code_size register. Bit Field RW 7:0 small_code_size size of segment of memory to be mapped into code memory address W,R 15 space, segment size range is 256 to 2 words. 15:8 reserved R 3.8.2 Data space As with the mapping of the code space, the data space is normally allocated by the cstart.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 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 -------------------------------------------------------------------------------------------------------------- H'0000 - H'07FF FLASH H'007800 - H'007FFF IROM H'0800 - H'E7FF NONE H'E800 - H'EFFF RAM H'000000 - H'0007FF IRAM H'F000 - H'FE9F NONE H'FEA0 - H'FFCF REGISTER H'FFD0 - H'FFFF NONE PH'000000 - PH'007FFF FLASH H'000000 - H'007FFF IROM PH'008000 - PH'FFFFFF NONE Here the entire 32K block has been mapped to the code space logical address range 0 – 7FFF. In addition, the top 2K of the flash block has been mapped to data space logical address range 0 – 07FF. 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 to the required logical address in data space, these being mmu.irom_data_logical_address; mmu.irom_data_physical_address; mmu.irom_data_size and mmu.translate_enable. 3.8.2.1 irom_data_logical_address This register, address 0xFF50, specifies the top 8 bits of the logical start address for the irom memory block mapped into the data memory space. To get the actual start address the value in this register must be shifted up by 8 bits. The LSB bits must be zeroed according to the block size, therefore 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 will result in erroneous behaviour. Bit Field RW 15:0 data_logical_address Logical start address for a segment of memory mapped into the W,R data memory address space The value in the register must be shifted up by 8 bits to get Rev 1.0 Page 20 of 45
  • 21. COMMERCIAL IN CONFIDENCE data memory address space. The value in the register must be shifted up by 8 bits to get the actual start address 3.8.2.2 irom_data_physical_address This register, address 0xFF51, specifies the top bits of the physical start address for the irom memory block mapped into the code memory space. To get the actual start address the value in this register must be shifted up by 8 bits. The LSB bits must be zeroed according to the block size, therefore 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 will result in erroneous behaviour. Bit Field RW 7:0 irom_physical_address physical start address for a segment of internal rom memory W,R mapped into data memory space. The value in the register must be shifted up by 8 bits to get the actual start address 15:8 reserved R 3.8.2.3 irom_data_size This register, address 0xFF52, specifies the size of the irom memory segment to be mapped into the data address space. If all bits are zero segment size is 256 words, setting a bit increases the segment size by a n power of two. Only segments of size 2 are valid, attempting to set this register to obtain any other size will produce erroneous behaviour. The table below shows the valid settings for this register and the associated memory segment sizes. Register value Segment size (words) 0x0000 256 0x0001 512 0x0003 1024 0x0007 2048 0x000f 4096 0x001f 8192 0x003f 16384 0x007f 32768 Bit Field RW 7:0 data_size size of segment of memory to be mapped into data memory address space, W,R 15 segment size range is 256 to 2 words. 15:8 reserved R Rev 1.0 Page 21 of 45
  • 22. COMMERCIAL IN CONFIDENCE 3.8.2.4 translate_enable The MMU address translator_enable register, address 0xFF43, is used to set which memory translations are active. In order for the internal flash to appear in the data space the irom_data bit, (bit 4), should be set to one. The logical address, physical address and size settings should be made before enabling the irom translation. A translator may not be enabled or disabled while data or code is being accessed through it. Bit Field RW 0 reserved for internal rom code translator enable, always set active thereby always R enabling the internal rom to be mapped into the code memory space. 1 iram_code R,W 2 eram_cs0_code R,W 3 eram_cs1_code R,W 4 irom_data when set to logic 1, this bit enables the internal rom to be mapped into the data R,W memory space. 5 reserved R 6 iram_data1 R,W 7 cache_ram0_data R,W 8 cache_ram1_data R,W 9 eram_cs0a_data R,W 10 eram_cs0b_data R,W 11 eram_cs1a_data R,W 12 eram_cs1b_data R,W 13 register_debug R,W 15:14 reserved R Rev 1.0 Page 22 of 45
  • 23. COMMERCIAL IN CONFIDENCE 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 eCOG demo pcb in conjunction with the emulator. It can however be used on any eCOG 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 from a different clock frequency to that used on the demo pcb. 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 Loading the application Having compiled the application the resulting code is downloaded to the demo pcb using the eCOG emulator. With the demo pcb powered and the CPU stopped enter the following command: load C:CyanFlashflash The above command assumes that the application code is in directory C:CyanFlash When the download is complete the memory map must be set manually. 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 application stored in RAM. Enter the following commands: write_io_reg mmu translate_enable 2 write_io_reg mmu irom_code_logical_addr 100 write_io_reg mmu iram_code_logical_addr 0 write_io_reg mmu iram_code_physical_addr 0 write_io_reg mmu iram_code_size 3 write_io_reg mmu iram_data_logical_addr 0 write_io_reg mmu iram_data_physical_addr 4 write_io_reg mmu iram_data_size 3 The application is now ready to run. Rev 1.0 Page 23 of 45
  • 24. COMMERCIAL IN CONFIDENCE 4.3 Running the application Having loaded the application and set up the memory map start the application using the emulators GO button. After a brief period stop the CPU again using the emulators STOP button. The user communicates with the application via two variables, these being $command_response an integer value and $command_data an array of 257 integers. The required command is selected by setting $command_response to the appropriate command code and $command_data is loaded with any data required by the requested command: Example: Program page 0 of the main memory, the command code is 8001. Enter the command: set $command_response 8001 For this command, $command_data contains the page number and $command_data +1 through +256 hold the data to be written. Enter the command: set $command_data 0 AAAA BBBB CCCC 1111 ......etc. Start the CPU using the emulators GO button and a few seconds later stop it again. The variable $command_response will now contain a response code. If all was well this should be 0001. Use the following command to display the response. display $command_response The table below summarises the command codes and the required data. Command Command Code Data Program Page 8001 command_data = page command_data +1 thro’ +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 Rev 1.0 Page 24 of 45
  • 25. COMMERCIAL IN CONFIDENCE 5 LISTINGS 5.1 Makefile #============================================================================= # Cyan Technology Ltd # Example application sofware for eCOG # # FILE # Makefile # # DESCRIPTION # Demonstration NMAKE makefile for the eCOG 'flash' example. # # This example code is also the code used by the Emulator to program the # IROM during the load command. # # The example is built from the command line using: # nmake # A complete re-build requires the following command: # nmake /a # The build files can be removed using the following command line: # nmake clean #============================================================================= CC=ecogncc CL=ecogcl CC_FLAGS= CL_FLAGS=-pack cstartup -o flash -alist -map flash flash.xpv : env irq.asm cstartup.asm flash.asm fmc.asm tim.asm @attrib -r cstartup.asm $(CL) $(CL_FLAGS) $(CC_FLAGS) irq.asm cstartup.asm flash.asm fmc.asm tim.asm @attrib +r cstartup.asm flash.asm : flash.c $(CC) $(CC_FLAGS) flash.c fmc.asm : fmc.c $(CC) $(CC_FLAGS) fmc.c tim.asm : tim.c $(CC) $(CC_FLAGS) tim.c clean : del /F flash.asm fmc.asm tim.asm del /F *.lif *.lib *.lkr *.lst del /F *.xpv *.xdv *.sym *.ram env : @SET ECOG1_INCLUDE=C:Program FilesCyan TechnologyeCog1 ToolkitCInclude @SET ECOG1_LIBRARY=C:Program FilesCyan TechnologyeCog1 ToolkitCLibrary @SET PATH=%PATH%;"C:Program FilesCyan TechnologyeCog1 ToolkitBin" Rev 1.0 Page 25 of 45
  • 26. COMMERCIAL IN CONFIDENCE 5.2 internal.map ;============================================================================= ; Cyan Technology Ltd ; Example application sofware for eCOG ; ; FILE ; flash.map ; ; DESCRIPTION ; Architecture description file for the flash demo application. This file tells the compiler/linker what ; memory map to use. ;============================================================================= code 0 3ff iram 0000 03ff data 0 3ff iram 0400 07ff 5.3 cstart.asm This application uses the standard cstart.asm file that is provided with the eCOG1 Toolkit. 5.4 flash.c /*============================================================================= Cyan Technology Limited FILE Flash.c DESCRIPTION Sample application to demonstrate Flash features. MODIFICATION DETAILS =============================================================================*/ #include <ecog.h> #include <ecog1.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_TIMING_PARAM 0x8004 #define CMD_READ_PROTECT 0x8005 #define CMD_WRITE_PROTECT 0x8006 #define CMD_INFO_WRITE 0x8007 Rev 1.0 Page 26 of 45
  • 27. COMMERCIAL IN CONFIDENCE /* 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 ) ; static void read_protect( void ) ; static void write_protect( void ) ; static void i_write( void ) ; /****************************************************************************** Global data declared in this module. 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 SYNOPOSIS 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 ) { /* Enable high reference and high PLL. */ reg.ssm.clock_enable.bits.high_osc = 1 ; reg.ssm.clock_enable.bits.high_pll = 1 ; /* Set CPU divider for maximum frequency. (High PLL/ 4) */ reg.ssm.cpu_clock_divider.bits.prescalar = 6 ; reg.ssm.cpu_clock_divider.bits.cpu_clock_divider = 7 ; /* Assert high PLL as source until it is accepted. */ while ( reg.ssm.cpu_clock_divider.bits.status != Rev 1.0 Page 27 of 45
  • 28. COMMERCIAL IN CONFIDENCE SSM_CPU_CLOCK_DIVIDER_STATUS_HIGH_PLL_CLOCK ) { reg.ssm.wakeup_mode.bits.clock_select = SSM_WAKEUP_MODE_CLOCK_SELECT_HIGH_PLL_CLOCK ; } /* GPT1 from high reference. */ reg.ssm.reset_clear.bits.high_ref_ripple_counter = 1 ; reg.ssm.reset_clear.bits.gpt1 = 1 ; reg.ssm.clock_source.bits.gpt1 = 0 ; reg.ssm.clock_source.bits.low_clock_timer = 0 ; reg.ssm.clock_enable.bits.gpt1 = 1 ; /* Port B as GPIO 8 ... */ reg.configuration.uio_config_select_abcdef.bits.port_b = 0 ; reg.configuration.uio_control_output_enable.bits.port_b = 1 ; reg.configuration.gpio_byte_1_control_l.word = 0x666 ; // Set default period in fmc config reg. reg.fmc.config.bits.period = 1 ; tim_init_msec( 1100, 0 ) ; tim_init_usec( 2, 0 ) ; while ( 1 ) { sif() ; if ( command_response & 0x8000 ) command_interpreter() ; } return 1 ; } /****************************************************************************** NAME command_interpreter SYNOPOSIS 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 : Rev 1.0 Page 28 of 45
  • 29. COMMERCIAL IN CONFIDENCE erase_page() ; break ; case CMD_ERASE_ALL : erase_all() ; break ; case CMD_TIMING_PARAM : timing_param() ; break ; case CMD_READ_PROTECT : read_protect() ; break ; case CMD_WRITE_PROTECT : write_protect() ; break ; case CMD_INFO_WRITE : i_write() ; break ; default : /* No command handler, so we provide the response. */ command_response = RESP_INVALID_COMMAND ; break ; } } /****************************************************************************** NAME program_page SYNOPOSIS 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 ; } Rev 1.0 Page 29 of 45
  • 30. COMMERCIAL IN CONFIDENCE result = fmc_program_page( page, command_data+1 ) ; if ( FMC_OK == result ) command_response = RESP_OK ; else command_response = RESP_ERR ; } /****************************************************************************** NAME erase_page SYNOPOSIS 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 ) { 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 SYNOPOSIS 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 ; Rev 1.0 Page 30 of 45
  • 31. COMMERCIAL IN CONFIDENCE else command_response = RESP_ERR ; } /****************************************************************************** NAME timing_param SYNOPOSIS 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 ; } /****************************************************************************** NAME read_protect SYNOPOSIS static void read_protect( void ) FUNCTION Sets the read protect locations in the information block of the flash. command_data[0] Required read protect register value. RETURNS RESP_OK, RESP_ERR in command_response. ******************************************************************************/ static void read_protect( void ) { int readp = command_data[0] ; int result ; result = fmc_protect(0 , readp ) ; if ( FMC_OK == result ) command_response = RESP_OK ; else command_response = RESP_ERR ; } /****************************************************************************** NAME write_protect Rev 1.0 Page 31 of 45
  • 32. COMMERCIAL IN CONFIDENCE SYNOPOSIS static void write_protect( void ) FUNCTION Sets the write protect locations in the information block of the flash. command_data[0] Required write protect register value. RETURNS RESP_OK, RESP_ERR or RESP_INVALID_DATA in command_response. ******************************************************************************/ static void write_protect( void ) { int writep = command_data[0] ; int result ; if (writep & 0x0001) // Don’t allow bit 0 to be set as this makes the protect { // settings permanent. command_response = RESP_INVALID_DATA ; return ; } result = fmc_protect( 2, writep ) ; if ( FMC_OK == result ) command_response = RESP_OK ; else command_response = RESP_ERR ; } /****************************************************************************** NAME i_write SYNOPOSIS static void i_write( void ) FUNCTION Writes a word to the information block of the flash. command_data[0] Address. command_data[1] Data. RETURNS RESP_OK, RESP_ERR or RESP_INVALID_DATA in command_response. ******************************************************************************/ static void i_write( void ) { int addr = command_data[0] ; int data = command_data[1] ; int result ; if (addr < 4) // Do not attempt to write to addresses 0-3 { // that is what the read/write protect commands are for. command_response = RESP_INVALID_DATA ; return ; } result = fmc_info_write( addr, data ) ; if ( FMC_OK == result ) Rev 1.0 Page 32 of 45
  • 33. COMMERCIAL IN CONFIDENCE command_response = RESP_OK ; else command_response = RESP_ERR ; } 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 #define FMC_BAD_ADDR 3 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 ) ; extern int fmc_protect( int addr, int data ) ; extern int fmc_info_write( int addr, int data ) ; 5.6 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 Rev 1.0 Page 33 of 45
  • 34. COMMERCIAL IN CONFIDENCE 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 ) ; extern int fmc_protect( int addr, 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 ) ; /* Implements a word write to Information block of flash */ static int info_write( int addr, int data) ; /****************************************************************************** Global data declared in this module. extern definitions for any external global data used by this module. File wide static data. ******************************************************************************/ /****************************************************************************** NAME fmc_page_write_allowed Rev 1.0 Page 34 of 45
  • 35. COMMERCIAL IN CONFIDENCE 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 & reg.fmc.write_page_protect ) 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. Rev 1.0 Page 35 of 45
  • 36. COMMERCIAL IN CONFIDENCE ******************************************************************************/ extern int fmc_erase_page( int page ) { 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 + 16 ; while ( page < last_page ) { result = erase_page( page ) ; if ( FMC_OK != result ) break ; page ++ ; } return result ; } Rev 1.0 Page 36 of 45
  • 37. COMMERCIAL IN CONFIDENCE /****************************************************************************** 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 ) { int result = FMC_OK ; reg.fmc.program_address.word = 0 ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_control.bits.erase_op = 1 ; reg.fmc.program_control.bits.xe = 1 ; reg.fmc.program_control.bits.mas1 = 1 ; reg.fmc.program_control.bits.erase = 1 ; reg.fmc.program_control.bits.infren = 1 ; // Erase main and info blocks tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 1 ; tim_msec_delay( 200 ) ; reg.fmc.program_control.bits.erase = 0 ; tim_usec_delay( 100 ) ; reg.fmc.program_control.bits.xe = 0 ; reg.fmc.program_control.bits.mas1 = 0 ; reg.fmc.program_control.bits.nvstr = 0 ; reg.fmc.program_control.bits.erase_op = 0 ; reg.fmc.program_control.bits.infren = 0 ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_control.word = 0x0000 ; tim_usec_delay( 1 ) ; return result ; } /****************************************************************************** NAME fmc_program_page SYNOPSIS extern int fmc_program_page( int page, const int * data ) Rev 1.0 Page 37 of 45
  • 38. COMMERCIAL IN CONFIDENCE 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( page ) ; if ( FMC_OK != result ) return result; result = erase_page( page ) ; if ( FMC_OK != result ) return result ; result = program_page( page, data ) ; return result ; } /****************************************************************************** NAME fmc_protect SYNOPSIS extern int fmc_protect( int addr, int data ) FUNCTION Writes to the Information block locations. RETURNS FMC_OK or FMC_PROTECTED if write protected. ******************************************************************************/ extern int fmc_protect( int addr, int data ) { if ( 0x0001 & reg.fmc.write_page_protect ) return FMC_PROTECTED ; info_write( addr, ~data) ; info_write( addr+1, data) ; return FMC_OK; } /****************************************************************************** NAME fmc_info_write SYNOPSIS extern int fmc_info_write( int addr, int data ) FUNCTION Rev 1.0 Page 38 of 45
  • 39. COMMERCIAL IN CONFIDENCE Writes to the Information block locations. RETURNS FMC_OK or FMC_PROTECTED if write protected or FMC_BAD_ADDR for addr <4. ******************************************************************************/ extern int fmc_info_write( int addr, int data ) { if (addr <4) return FMC_BAD_ADDR ; if ( 0x0001 & reg.fmc.write_page_protect ) return FMC_PROTECTED ; info_write( addr, data) ; return FMC_OK; } /****************************************************************************** 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 ; int row_address = page << 3 ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_address.bits.row_address = row_address ; reg.fmc.program_control.bits.erase_op = 1 ; reg.fmc.program_control.bits.xe = 1 ; // reg.fmc.program_control.bits.infren =1; // Including this line causes this routine to erase // the information block, (with page =0), in place // of a page from the main memory block. reg.fmc.program_control.bits.erase = 1 ; tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 1 ; tim_msec_delay( 10 ) ; reg.fmc.program_control.bits.erase = 0 ; tim_usec_delay( 5 ) ; Rev 1.0 Page 39 of 45
  • 40. COMMERCIAL IN CONFIDENCE reg.fmc.program_control.bits.xe = 0 ; reg.fmc.program_control.bits.nvstr = 0 ; tim_usec_delay( 1 ) ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_control.word = 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 row_address = page << 3 ; int word_count ; int row_count ; int original_period = reg.fmc.config.bits.period ; /* Tprog + Tads + Tadh >= 21 us * The closer this is to 21us the quicker the load will be. */ reg.fmc.config.bits.period = 0x1d1 ; reg.fmc.program_control.word = 0x2900 ; for ( row_count = 0 ; row_count < 8 ; row_count++ ) { reg.fmc.program_address.bits.row_address = row_address + row_count ; reg.fmc.program_control.bits.program_op = 1 ; reg.fmc.program_control.bits.prog = 1 ; reg.fmc.program_control.bits.xe = 1 ; tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 1 ; tim_usec_delay( 10 ) ; reg.fmc.config.bits.last_write = 0 ; for ( word_count = 0 ; word_count < 32 ; word_count++ ) { if ( 31 == word_count ) reg.fmc.config.bits.last_write = 1 ; reg.fmc.program_address.bits.word_address = word_count ; Rev 1.0 Page 40 of 45
  • 41. COMMERCIAL IN CONFIDENCE reg.fmc.program_data = *data++ ; while ( reg.fmc.program_address.bits.busy ) ; } reg.fmc.program_control.bits.prog = 0 ; tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 0 ; tim_usec_delay( 1 ) ; reg.fmc.program_control.word = 0x2900 ; } reg.fmc.program_control.word = 0x0000 ; reg.fmc.config.bits.period = original_period ; return FMC_OK ; } /****************************************************************************** NAME info_write SYNOPSIS static int info_write( int addr, int data ) FUNCTION Writes a word to the Information block of the flash. RETURNS FMC_OK ******************************************************************************/ static int info_write( int addr, int data ) { int row_address = 0 ; int original_period = reg.fmc.config.bits.period ; // Tprog + Tads + Tadh >= 21 us // The closer this is to 21us the quicker the load will be. reg.fmc.config.bits.period = 0x1d1 ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_address.bits.row_address = row_address ; reg.fmc.program_control.bits.program_op = 1 ; reg.fmc.program_control.bits.prog = 1 ; reg.fmc.program_control.bits.xe = 1 ; reg.fmc.program_control.bits.infren = 1 ;// Select info block. tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 1 ; Rev 1.0 Page 41 of 45
  • 42. COMMERCIAL IN CONFIDENCE tim_usec_delay( 10 ) ; reg.fmc.config.bits.last_write = 1 ; reg.fmc.program_address.bits.word_address = addr ; reg.fmc.program_data = data ; while ( reg.fmc.program_address.bits.busy ) ; reg.fmc.program_control.bits.prog = 0 ; tim_usec_delay( 5 ) ; reg.fmc.program_control.bits.nvstr = 0 ; tim_usec_delay( 1 ) ; reg.fmc.program_control.word = 0x2900 ; reg.fmc.program_control.word = 0x0000 ; reg.fmc.config.bits.period = original_period ; return FMC_OK ; } 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 tim.c /*============================================================================= Cyan Technology Limited FILE Rev 1.0 Page 42 of 45
  • 43. COMMERCIAL IN CONFIDENCE 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 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 ) Rev 1.0 Page 43 of 45
  • 44. COMMERCIAL IN CONFIDENCE { 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 ) Rev 1.0 Page 44 of 45
  • 45. COMMERCIAL IN CONFIDENCE FUNCTION 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 GPT1. RETURNS Nothing. ******************************************************************************/ static void set_ripple( int ripple ) { reg.ssm.clock_source_timer1.bits.gpt1 = ripple ; } /****************************************************************************** NAME delay SYNOPSIS static void delay( int count ) FUNCTION Loads GPT1 with count and waits until the counter goes down to zero. RETURNS ******************************************************************************/ static void delay( int count ) { reg.tim.control_enable.bits.gpt_1_count = 1 ; reg.tim.control_disable.bits.gpt_1_auto_reload = 1 ; reg.tim.gpt_1_load_value = count ; reg.tim.command.bits.gpt_1_load = 1 ; while ( reg.tim.gpt_1_count ) ; reg.tim.control_disable.bits.gpt_1_count = 1 ; } Rev 1.0 Page 45 of 45

×