Louvre boot-loader protocol Revision Date history rev. a 20/06/14 Starting revision General description Transfer protocol to make a firmware update using NTAG on Louvre board. The protocol enable sending a file to program the flash memory of the LPC11U37 device mounted on the board. The board has also a NTAG IIC device, which is used to send/receive data via the NFC interface. To have the fastest exchange of data, the firmware code is transferred using the shared SRAM between RF and IIC. LPC11U37 flash memory ( from UM10462.pdf ) The LPC11U37 has 128kB of internal flash memory; the memory is organized as 32 sectors of 4kB each, each sector will include 16 pages of 256 bytes. The flash is accessed using the IAP functions, which can only handle data block multiple of 256 bytes. The Flash in ECC protected every 128 bits ( see chapter 20.6 ), which means you can also write memory in smaller blocks of 16 bytes, aligned over 16 bytes, by setting the unused bytes to 0xFF ( erased state ). For example, to write the 2 nd set of 16 bytes, without changing the other bytes of the same page, the data to write must be: 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, (1 st set ) (16 bytes of effective data ) ( 2 nd set ) 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, (3 rd set ).. fill the page with 0xFF. ( all other set ) The 16 byte minimum programming window is called sub-block ; this function is NOT used into the boot-loader LPC11U37 boot-loader memory map The boot-loader will use the first 2 sectors of the flash memory map ( 8kB reserved ) The application will always start at address 0x00002000 ( 3 rd block ), where the executable header structure is stored. at address 0x00002000 there is the application check-sum sum of every byte from the address 0x00002004 ( included ), calculated for a number of byte equal to the image length. LouvreBootloaderProtocol.doc 1/6
at address 0x00002004 there is the image length, over which the check-sum has to be calculated the address 0x00002008 there is the starting address of the application, where the bootloader has to jump to start execution. Basic binary file structure Compilers can generate executable in many different file formats. The actual implementation will only manage Intel.hex files. This file is described http://www.interlog.com/~speff/usefulinfo/hexfrmt.pdf Following the description, data is sent in records. This file format will enable to send data in records of different length and with non-sequential addresses. The standard.hex file is ASCII readable. Preparing the record To make the best of the communication bandwidth over RF, the best option is to send always a full frame of 64 bytes ( the size of the SRAM of the NTAG device ). Because of the freedom in the Intel.hex file, to make the best use of the bandwidth, a preprocessing of the.hex file is needed initialize an array of 128kB at 0xFF, the array will mimic the target device program flash read the file into an array of 1MB calculate file length and check-sum, add to the array at the proper address file length is calculated by taking the address of the last byte different from 0xFF and subtracting 0x00002004 which is the start address. scan the array till a byte different from 0xFF is found read from the 1MB array a maximum of 56 bytes at a time, and prepare a new boot-loader record: command ( 1 byte ) : specify the type of sent data address ( 3 bytes ) : specify the staring address of the data to transfer length ( 1 byte ) : the effective data length ( can be 0 if there are no data, for example in the last record ) data ( max 56 bytes ); you do not need to send any trailing 0xFF sequence, the data can be truncated to the last byte different from 0xFF and only this data sent; CRC ( 1 byte ) : calculated as in the Intel.hex document if the 56 bytes read are all 0xFF, do not send the record, and continue to scan till the next byte different from 0xFF LouvreBootloaderProtocol.doc 2/6
In this way you send records with consecutive addresses, and do not transmit record which have not to be programmed ( 0xFF, erase state of the flash ), minimizing data transfer time and programming time. To enable checking the whole file, the the transferred file must include an application check-sum The last record of the image is identified by a record with command byte 0x04. Command list The first byte of each frame is a command byte, used to identify the record type ad the bootloader action. Some command need a reply, and this will require a change of the NFC direction ( see diagram below ) Command list 0x02 -> boot-loader record <- This command does not have any answer 0x04 -> last boot-loader record <- The answer to this command in a record command ( 1 byte ) : 0x04 length ( 1 byte ) : the effective data length data ( max 56 bytes ); the bad record received list is sent. If the list is empty ( data length = 0 ) the boot-loader process has been completed with no error. If there is at least one element, the boot-loader exchange has to be repeated. 0x01 -> get firmware revision <- The answer to this command in a record command ( 1 byte ) : 0x01 length ( 1 byte ) : the effective data length revision string ( 23 ASCII bytes, Louvre x,y,z gg-mm-aaaa x,y,z revision major, minor,step gg-mm-aaaa firmware compilation date any other value : free for future use Sending the record From the NFC master device, each new record is simply copied into the shared SRAM of the NTAG. LouvreBootloaderProtocol.doc 3/6
The micro-controller waits the PD signal change to read the record, store the record on a local buffer. There is a timeout waiting the PD signal. If the timeout is exceeded, the boot-loader process is restarted from the beginning. The micro-controller will check the record CRC: CRC is OK, the record is handled CRC is not OK, the record is filled with 0xFF ( flash erase state ) and the record address is locally stored in a local bad record received list ( see answer to command last bootloader record ). After the micro-controller has fully read the shared SRAM, the NFC Master can send the next record; the NFC master has a waiting timeout; when expired the protocol is restarted from the beginning. The data direction is always from phone to device, and will change only after receiving the last boot-loader record ; the answer to this command is an acknowledge for the whole boot-loader process. If the list is empty, the boot-loader process is complete. If the list is not empty, ( in this revision of the document ) the boot-loader is restarted. ( To be implemented later : the Phone will change the direction again to send data, and will send now only the records whose address is stored in the received list. This will enable faster retry, filling only the data not received ok. If the bad record received list is too long ( longer than 18 records, 54 bytes ), the boot-loader is restarted from the beginning ). Timeout management If the NFC master timeout expires, the NFC master will switch off the field, wait 5 and restart. If the micro-controller timeout will expire, the micrcontroller stops any communication with the NFC master to let the NFC master timeout to expire. Boot-loader firmware The boot-loader firmware. From the Louvre perspective, the frames have to come in with rising addresses. The boot-loader has a 512 byte circular buffer ( two times the flash write page size ), and a start_address pointer, which is set to NULL. When a new frame is received: The command 0x02 will identify a bootloder record when a record with address 0x00002000 is received, the boot-loader process will start. the highest (24-9 ) bits of the record address are compared with the start_pointer if the value is the same : record data it is copied into the buffer using as a starting address the lower 9 bits of the received record address. If, during the copy, the 256 byte boundary is LouvreBootloaderProtocol.doc 4/6
crosses ( 255>256, 511>0 ) the overflowed 256 bytes of the buffer are stored into flash; if the flash sector boundary is crossed, before copying the data the flash sector is erased. If the value are different : store the last used 256 bytes of the buffer in flash. Update the start_address with the highest (24-9 ) bits of the record address, and repeat. At the end of the download process ( last record received, command 0x04 ), the boot-loader will check the bad record received list. If the list is not empty, the boot-loader will wait for another possible boot start; if the list is empty will calculate the application check-sum of the executable memory, using data stored into the header, if application check-sum is OK, the boot-loader will jump to the application starting point ( 0x00002008 ) if application check-sum is NOT Ok the boot-loader will wait for another possible boot start. LouvreBootloaderProtocol.doc 5/6
Phone Activate field Activate field Activate Select Louvre Micro is powered Exit from reset Wait PTHRU_ON_OFF Become 1 PTHRU_DIR = 0 PTHRU_ON_OFF = 1 FD_ON = 11b FD_OFF = 11b Write 64 bytes Wait FD becomes 1 Wait RF_LOCKED becomes 1 Read 64 bytes N Last block? Last block? N Wait RF_LOCKED becomes 0 PTHRU_ON_OFF = 0 PTHRU_DIR = 1 PTHRU_ON_OFF = 1 I2C_LOCKED=1 Wait RF_LOCKED becomes 1 Write response Read response LouvreBootloaderProtocol.doc 6/6