IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UartIsp.cpp Source File

UartIsp.cpp

00001 #include "mbed.h"
00002 #include "UartIsp.h"
00003 #include "FatfsIjfwConfigurable.h"
00004 
00005 // Target MCU definitions
00006 const unsigned int RAM_BASE_ADDRESS = 268435456+1024;   // address = 0x10000000 + 0x400
00007 const int SECTOR_NUM = 8;
00008 const int SECTOR_SIZE = 4096;
00009 const int CHUNK_SIZE = 1024;                            // must be multiples of 512
00010 const int BUF_SIZE = 512;                               // CHUNK_SIZE / 2^n
00011 const int MCU_FREQ = 48000;
00012 
00013 
00014 UartIsp::UartIsp(RawSerial* _serial, FatfsIjfwConfigurable* _fs)
00015     : serial(_serial), fs(_fs) {
00016 }
00017 
00018 
00019 UartIsp::~UartIsp() {
00020 
00021 }
00022 
00023 
00024 void UartIsp::writeSerial(const char val) {
00025     serial->putc(val);
00026 }
00027 
00028 
00029 char UartIsp::readSerial() {
00030     return (char)serial->getc();
00031 }
00032 
00033 
00034 int UartIsp::readable() {
00035     return serial->readable();
00036 }
00037 
00038 
00039 void UartIsp::sleep(int msec) {
00040     wait_ms((double)msec);
00041 }
00042 
00043 
00044 UartIsp::ISP_RESULT UartIsp::runUartIsp(const char* filename) {
00045     // Open bin file
00046     fs->mount();
00047     int res = fs->open(filename, MODE_RO);
00048     if (res != FR_OK) {
00049         return ERR_FILE_OPEN;
00050     }
00051     
00052     buffer = new char[BUF_SIZE];
00053 
00054     // Clear Rx Buffer
00055     while(readable()) {
00056         readSerial();
00057     }
00058 
00059     // Open ISP mode and Synchronization of serial port
00060     if (!openIsp(MCU_FREQ)) {
00061         return ERR_SYNC_MCU;
00062     }
00063     // Disable echo back
00064 //    disableEchoBack();
00065 
00066     // Unlock Flash
00067     unlockFlash();
00068     // Erase all area
00069     if (!eraseFlash(0, 7)) {
00070         return ERR_UNLOCK_FLASH;
00071     }
00072     wait_ms(10);
00073 
00074     // Get bin data length
00075     int binDataLength = fs->filesize();
00076     if (binDataLength < 0) {
00077         return ERR_FILE_READ;
00078     }
00079 
00080     // Flash writting process
00081     int finishWrite = 0;
00082     int sector = 1;
00083 
00084     while (!finishWrite) {
00085         // Adjust sector size
00086         int sectorStart = SECTOR_SIZE * sector;
00087 
00088         int dataLength;
00089         unsigned int readAddress;
00090 
00091         for (int sectorPos = 0; sectorPos < SECTOR_SIZE; sectorPos += CHUNK_SIZE) {
00092             for (int chunkPos = 0; chunkPos < CHUNK_SIZE; chunkPos += BUF_SIZE) {
00093 
00094                 // Calculate data length to write
00095                 dataLength = BUF_SIZE;
00096                 readAddress = sectorStart + sectorPos + chunkPos;
00097                 if (readAddress + BUF_SIZE > binDataLength) {
00098                     dataLength = binDataLength - readAddress;
00099                 }
00100                 if (dataLength <= 0) {
00101                     continue;
00102                 }
00103 
00104                 // Move to file offset to read 
00105                 if (fs->lseek(readAddress) != FR_OK) {
00106                     return ERR_FILE_READ;
00107                 }
00108                 // Read memory card and store buffer
00109                 if (fs->read(buffer, dataLength) != dataLength) {
00110                     return ERR_FILE_READ;
00111                 }
00112 
00113                 // Calculate checksum of interrupt vector area
00114                 if (sector == 0 && sectorPos == 0 && chunkPos < BUF_SIZE) {
00115                     buffer[0x1C] = 0;
00116                     buffer[0x1C + 1] = 0;
00117                     buffer[0x1C + 2] = 0;
00118                     buffer[0x1C + 3] = 0;
00119 
00120                     int checksum = 0;
00121                     for (int i = 0; i < 8; i++) {
00122                         checksum += buffer[i*4];
00123                         checksum += buffer[i*4 + 1] << 8;
00124                         checksum += buffer[i*4 + 2] << 16;
00125                         checksum += buffer[i*4 + 3] << 24;
00126                     }
00127                     checksum = 0 - checksum;
00128 
00129                     buffer[0x1C] = checksum & 0xFF;
00130                     buffer[0x1C + 1] = (checksum >> 8) & 0xFF;
00131                     buffer[0x1C + 2] = (checksum >> 16) & 0xFF;
00132                     buffer[0x1C + 3] = (checksum >> 24) & 0xFF;
00133                 }
00134 
00135                 // Write to RAM
00136                 unsigned int ramAddress = RAM_BASE_ADDRESS + (unsigned int)chunkPos;
00137                 if (!writeToRam(buffer, ramAddress, dataLength)) {
00138                     return ERR_WRITE_TO_RAM;
00139                 }
00140             }
00141 
00142             // Copy from RAM to Flash
00143             prepareFlash(sector, sector);
00144 
00145             unsigned int flashAddress = sectorStart + sectorPos;
00146             if (!copyToFlash(flashAddress, RAM_BASE_ADDRESS, CHUNK_SIZE)) {
00147                 return ERR_COPY_TO_FLASH;
00148             }
00149         }
00150 
00151         // sector access order => 1, 2, ... , 6, 7, 0
00152         if (sector >= SECTOR_NUM - 1) {
00153             sector = 0;
00154         } else if (dataLength < BUF_SIZE) {
00155             sector = 0;
00156         } else if (sector == 0) {
00157             finishWrite = 1;
00158             wait_ms(300);
00159         } else {
00160             sector++;
00161         }
00162     }
00163     
00164     // BIN file close and delete
00165     fs->close();
00166     fs->deleteFirmFile(filename);
00167     delete [] buffer;
00168 
00169     return NOERROR;
00170 }