• Main Page
  • Modules
  • Index
  • File List
  • Globals

projects/nrfgo_sdk/bootloader_32k/host_applications/bootlu1p_linux/flashprog.c

Go to the documentation of this file.
00001 /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is confidential property of Nordic 
00004  * Semiconductor ASA. Terms and conditions of usage are described in detail 
00005  * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 #include <stdio.h>
00013 #include <string.h>
00014 #include <usb.h>
00015 #include "bootldr_usb_cmds.h"
00016 #include "flashprog.h"
00017 
00018 const int BULK_OUT_EP = 0x01;
00019 const int BULK_IN_EP = 0x81;
00020 
00021 static char usb_write_buf[64];
00022 static char usb_read_buf[64];
00023 
00024 static void flash_page_program(usb_dev_handle *hdev, unsigned char *page_buf, int npage)
00025 {
00026     int i;
00027     usb_write_buf[0] = CMD_FLASH_WRITE_INIT;
00028     usb_write_buf[1] = npage;
00029     usb_bulk_write(hdev, BULK_OUT_EP, usb_write_buf, 2, 5000);
00030     usb_bulk_read(hdev, BULK_IN_EP, usb_read_buf, 1, 5000);
00031     for (i = 0; i < NUM_FLASH_BLOCKS; i++)
00032     {
00033         memcpy(usb_write_buf, &page_buf[i*USB_EP_SIZE], USB_EP_SIZE);
00034         usb_bulk_write(hdev, BULK_OUT_EP, usb_write_buf, USB_EP_SIZE, 5000);
00035         usb_bulk_read(hdev, BULK_IN_EP, usb_read_buf, 1, 5000);
00036     }
00037 }
00038 
00039 static void flash_program(usb_dev_handle *hdev, unsigned char *hex_buf, int startpage, int npages)
00040 {
00041     int i;
00042     unsigned char page_buf[FLASH_PAGE_SIZE];
00043 
00044     for (i = startpage; i < (startpage + npages); i++)
00045     {
00046         memcpy(page_buf, &hex_buf[i * FLASH_PAGE_SIZE], FLASH_PAGE_SIZE);
00047         flash_page_program(hdev, page_buf, i);
00048     }
00049 }
00050 
00051 static int flash_page_verify(usb_dev_handle *hdev, unsigned char *page_buf, int npage)
00052 {
00053     int i, nblock, n, fail_addr;
00054     char fail_byte;
00055     for (i = 0; i < NUM_FLASH_BLOCKS; i++)
00056     {
00057         nblock = npage * NUM_FLASH_BLOCKS + i;
00058 
00059         // Select upper/lower flash half:
00060         usb_write_buf[0] = CMD_FLASH_SELECT_HALF;
00061         usb_write_buf[1] = (char)(nblock >> 8);
00062         usb_bulk_write(hdev, BULK_OUT_EP, usb_write_buf, 2, 5000);
00063         usb_bulk_read(hdev, BULK_IN_EP, usb_read_buf, 1, 5000);
00064         
00065         usb_write_buf[0] = CMD_FLASH_READ;
00066         usb_write_buf[1] = (char)nblock;
00067         usb_bulk_write(hdev, BULK_OUT_EP, usb_write_buf, 2, 5000);
00068         usb_bulk_read(hdev, BULK_IN_EP, usb_read_buf, USB_EP_SIZE, 5000);
00069         for (n = 0; n < USB_EP_SIZE; n++)
00070         {
00071             if ((unsigned char)usb_read_buf[n] != page_buf[i * USB_EP_SIZE + n])
00072             {
00073                 fail_addr = npage * FLASH_PAGE_SIZE + i * USB_EP_SIZE + n;
00074                 fail_byte = usb_read_buf[n];
00075                 fprintf(stderr, "ERROR: The Flash contents does not match the file contents\nAddress = 0x%04X, Expected 0x%02X, got 0x%02X\n", fail_addr, (unsigned)page_buf[i * USB_EP_SIZE + n], (unsigned)fail_byte);
00076                 return 0;
00077             }
00078         }
00079     }
00080     return 1;
00081 }
00082 
00083 
00084 static int flash_verify(usb_dev_handle *hdev, unsigned char *hex_buf, int startpage, int npages)
00085 {
00086     int i;
00087     unsigned char page_buf[FLASH_PAGE_SIZE];
00088 
00089     for (i = startpage; i < (startpage + npages); i++)
00090     {
00091         memcpy(page_buf, &hex_buf[i * FLASH_PAGE_SIZE], FLASH_PAGE_SIZE);
00092         if (!flash_page_verify(hdev, page_buf, i))
00093             return 0;
00094     }
00095     return 1;
00096 }
00097 
00098 int flash_prog(usb_dev_handle *hdev, unsigned low_addr, unsigned high_addr,unsigned flash_size,  unsigned char *hex_buf)
00099 {
00100     unsigned num_flash_pages = flash_size/FLASH_PAGE_SIZE;
00101     fprintf(stdout, "Programming flash pages 1-%d...\n", num_flash_pages - 5);
00102     //
00103     // First program and verify the flash pages above page 0 and below the bootloader
00104     // (last four pages of the flash):
00105     flash_program(hdev, hex_buf, 1, num_flash_pages - 5);
00106     fprintf(stdout, "Verifying flash pages 1-%d...\n", num_flash_pages - 5);
00107     if (flash_verify(hdev, hex_buf, 1, num_flash_pages - 5) == 0)
00108     {
00109         return 0;
00110     }
00111     //
00112     // Then program page 0 and the pages containing the bootloader:
00113     fprintf(stdout, "Programming flash page 0...\n", num_flash_pages - 5);
00114     flash_program(hdev, hex_buf, 0, 1);
00115     if (high_addr > (num_flash_pages - 4)*FLASH_PAGE_SIZE)
00116     {
00117         // Only program pages containing bootloader if user program uses these pages
00118         fprintf(stdout, "Programming flash pages %d-%d...\n", num_flash_pages - 4, num_flash_pages - 1);
00119         flash_program(hdev, hex_buf, num_flash_pages - 4, 4);
00120     }
00121     fprintf(stdout, "Verifying flash page 0...\n", num_flash_pages - 5);
00122     if (flash_verify(hdev, hex_buf, 0, 1) == 0)
00123         return 0;
00124     if (high_addr > (num_flash_pages - 4)*FLASH_PAGE_SIZE)
00125     {
00126         fprintf(stdout, "Verifying flash pages %d-%d...\n", num_flash_pages - 4, num_flash_pages - 1);
00127         if(flash_verify(hdev, hex_buf, num_flash_pages - 4, 4) == 0)
00128         {
00129             return 0;
00130         }
00131     }
00132     return 1;
00133 }

Generated on Fri Apr 20 2012 14:11:45 for nRFGo SDK by  doxygen 1.7.2