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

Dependencies:   mbed

参考URL http://www.cyberchabudai.org/index.php/entry?tag=IJFW

Committer:
oks486
Date:
Sun Aug 21 07:51:01 2016 +0000
Revision:
2:daf6c4719496
Parent:
1:11f73f269fdc
Modified I2c2mem for "FILES" command

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oks486 0:43cce7b453d0 1 #include "mbed.h"
oks486 0:43cce7b453d0 2 #include "UartIsp.h"
oks486 1:11f73f269fdc 3 #include "FatfsIjfwConfigurable.h"
oks486 0:43cce7b453d0 4
oks486 0:43cce7b453d0 5 // Target MCU definitions
oks486 0:43cce7b453d0 6 const unsigned int RAM_BASE_ADDRESS = 268435456+1024; // address = 0x10000000 + 0x400
oks486 0:43cce7b453d0 7 const int SECTOR_NUM = 8;
oks486 0:43cce7b453d0 8 const int SECTOR_SIZE = 4096;
oks486 0:43cce7b453d0 9 const int CHUNK_SIZE = 1024; // must be multiples of 512
oks486 0:43cce7b453d0 10 const int BUF_SIZE = 512; // CHUNK_SIZE / 2^n
oks486 0:43cce7b453d0 11 const int MCU_FREQ = 48000;
oks486 0:43cce7b453d0 12
oks486 0:43cce7b453d0 13
oks486 1:11f73f269fdc 14 UartIsp::UartIsp(RawSerial* _serial, FatfsIjfwConfigurable* _fs)
oks486 0:43cce7b453d0 15 : serial(_serial), fs(_fs) {
oks486 0:43cce7b453d0 16 }
oks486 0:43cce7b453d0 17
oks486 0:43cce7b453d0 18
oks486 0:43cce7b453d0 19 UartIsp::~UartIsp() {
oks486 0:43cce7b453d0 20
oks486 0:43cce7b453d0 21 }
oks486 0:43cce7b453d0 22
oks486 0:43cce7b453d0 23
oks486 0:43cce7b453d0 24 void UartIsp::writeSerial(const char val) {
oks486 0:43cce7b453d0 25 serial->putc(val);
oks486 0:43cce7b453d0 26 }
oks486 0:43cce7b453d0 27
oks486 0:43cce7b453d0 28
oks486 0:43cce7b453d0 29 char UartIsp::readSerial() {
oks486 0:43cce7b453d0 30 return (char)serial->getc();
oks486 0:43cce7b453d0 31 }
oks486 0:43cce7b453d0 32
oks486 0:43cce7b453d0 33
oks486 0:43cce7b453d0 34 int UartIsp::readable() {
oks486 0:43cce7b453d0 35 return serial->readable();
oks486 0:43cce7b453d0 36 }
oks486 0:43cce7b453d0 37
oks486 0:43cce7b453d0 38
oks486 0:43cce7b453d0 39 void UartIsp::sleep(int msec) {
oks486 0:43cce7b453d0 40 wait_ms((double)msec);
oks486 0:43cce7b453d0 41 }
oks486 0:43cce7b453d0 42
oks486 0:43cce7b453d0 43
oks486 0:43cce7b453d0 44 UartIsp::ISP_RESULT UartIsp::runUartIsp(const char* filename) {
oks486 0:43cce7b453d0 45 // Open bin file
oks486 0:43cce7b453d0 46 fs->mount();
oks486 0:43cce7b453d0 47 int res = fs->open(filename, MODE_RO);
oks486 0:43cce7b453d0 48 if (res != FR_OK) {
oks486 0:43cce7b453d0 49 return ERR_FILE_OPEN;
oks486 0:43cce7b453d0 50 }
oks486 0:43cce7b453d0 51
oks486 0:43cce7b453d0 52 buffer = new char[BUF_SIZE];
oks486 0:43cce7b453d0 53
oks486 0:43cce7b453d0 54 // Clear Rx Buffer
oks486 0:43cce7b453d0 55 while(readable()) {
oks486 0:43cce7b453d0 56 readSerial();
oks486 0:43cce7b453d0 57 }
oks486 0:43cce7b453d0 58
oks486 0:43cce7b453d0 59 // Open ISP mode and Synchronization of serial port
oks486 0:43cce7b453d0 60 if (!openIsp(MCU_FREQ)) {
oks486 0:43cce7b453d0 61 return ERR_SYNC_MCU;
oks486 0:43cce7b453d0 62 }
oks486 0:43cce7b453d0 63 // Disable echo back
oks486 0:43cce7b453d0 64 // disableEchoBack();
oks486 0:43cce7b453d0 65
oks486 0:43cce7b453d0 66 // Unlock Flash
oks486 0:43cce7b453d0 67 unlockFlash();
oks486 0:43cce7b453d0 68 // Erase all area
oks486 0:43cce7b453d0 69 if (!eraseFlash(0, 7)) {
oks486 0:43cce7b453d0 70 return ERR_UNLOCK_FLASH;
oks486 0:43cce7b453d0 71 }
oks486 0:43cce7b453d0 72 wait_ms(10);
oks486 0:43cce7b453d0 73
oks486 0:43cce7b453d0 74 // Get bin data length
oks486 0:43cce7b453d0 75 int binDataLength = fs->filesize();
oks486 0:43cce7b453d0 76 if (binDataLength < 0) {
oks486 0:43cce7b453d0 77 return ERR_FILE_READ;
oks486 0:43cce7b453d0 78 }
oks486 0:43cce7b453d0 79
oks486 0:43cce7b453d0 80 // Flash writting process
oks486 0:43cce7b453d0 81 int finishWrite = 0;
oks486 0:43cce7b453d0 82 int sector = 1;
oks486 0:43cce7b453d0 83
oks486 0:43cce7b453d0 84 while (!finishWrite) {
oks486 0:43cce7b453d0 85 // Adjust sector size
oks486 0:43cce7b453d0 86 int sectorStart = SECTOR_SIZE * sector;
oks486 0:43cce7b453d0 87
oks486 0:43cce7b453d0 88 int dataLength;
oks486 0:43cce7b453d0 89 unsigned int readAddress;
oks486 0:43cce7b453d0 90
oks486 0:43cce7b453d0 91 for (int sectorPos = 0; sectorPos < SECTOR_SIZE; sectorPos += CHUNK_SIZE) {
oks486 0:43cce7b453d0 92 for (int chunkPos = 0; chunkPos < CHUNK_SIZE; chunkPos += BUF_SIZE) {
oks486 0:43cce7b453d0 93
oks486 0:43cce7b453d0 94 // Calculate data length to write
oks486 0:43cce7b453d0 95 dataLength = BUF_SIZE;
oks486 0:43cce7b453d0 96 readAddress = sectorStart + sectorPos + chunkPos;
oks486 0:43cce7b453d0 97 if (readAddress + BUF_SIZE > binDataLength) {
oks486 0:43cce7b453d0 98 dataLength = binDataLength - readAddress;
oks486 0:43cce7b453d0 99 }
oks486 0:43cce7b453d0 100 if (dataLength <= 0) {
oks486 0:43cce7b453d0 101 continue;
oks486 0:43cce7b453d0 102 }
oks486 0:43cce7b453d0 103
oks486 0:43cce7b453d0 104 // Move to file offset to read
oks486 0:43cce7b453d0 105 if (fs->lseek(readAddress) != FR_OK) {
oks486 0:43cce7b453d0 106 return ERR_FILE_READ;
oks486 0:43cce7b453d0 107 }
oks486 0:43cce7b453d0 108 // Read memory card and store buffer
oks486 0:43cce7b453d0 109 if (fs->read(buffer, dataLength) != dataLength) {
oks486 0:43cce7b453d0 110 return ERR_FILE_READ;
oks486 0:43cce7b453d0 111 }
oks486 0:43cce7b453d0 112
oks486 0:43cce7b453d0 113 // Calculate checksum of interrupt vector area
oks486 0:43cce7b453d0 114 if (sector == 0 && sectorPos == 0 && chunkPos < BUF_SIZE) {
oks486 0:43cce7b453d0 115 buffer[0x1C] = 0;
oks486 0:43cce7b453d0 116 buffer[0x1C + 1] = 0;
oks486 0:43cce7b453d0 117 buffer[0x1C + 2] = 0;
oks486 0:43cce7b453d0 118 buffer[0x1C + 3] = 0;
oks486 0:43cce7b453d0 119
oks486 0:43cce7b453d0 120 int checksum = 0;
oks486 0:43cce7b453d0 121 for (int i = 0; i < 8; i++) {
oks486 0:43cce7b453d0 122 checksum += buffer[i*4];
oks486 0:43cce7b453d0 123 checksum += buffer[i*4 + 1] << 8;
oks486 0:43cce7b453d0 124 checksum += buffer[i*4 + 2] << 16;
oks486 0:43cce7b453d0 125 checksum += buffer[i*4 + 3] << 24;
oks486 0:43cce7b453d0 126 }
oks486 0:43cce7b453d0 127 checksum = 0 - checksum;
oks486 0:43cce7b453d0 128
oks486 0:43cce7b453d0 129 buffer[0x1C] = checksum & 0xFF;
oks486 0:43cce7b453d0 130 buffer[0x1C + 1] = (checksum >> 8) & 0xFF;
oks486 0:43cce7b453d0 131 buffer[0x1C + 2] = (checksum >> 16) & 0xFF;
oks486 0:43cce7b453d0 132 buffer[0x1C + 3] = (checksum >> 24) & 0xFF;
oks486 0:43cce7b453d0 133 }
oks486 0:43cce7b453d0 134
oks486 0:43cce7b453d0 135 // Write to RAM
oks486 0:43cce7b453d0 136 unsigned int ramAddress = RAM_BASE_ADDRESS + (unsigned int)chunkPos;
oks486 0:43cce7b453d0 137 if (!writeToRam(buffer, ramAddress, dataLength)) {
oks486 0:43cce7b453d0 138 return ERR_WRITE_TO_RAM;
oks486 0:43cce7b453d0 139 }
oks486 0:43cce7b453d0 140 }
oks486 0:43cce7b453d0 141
oks486 0:43cce7b453d0 142 // Copy from RAM to Flash
oks486 0:43cce7b453d0 143 prepareFlash(sector, sector);
oks486 0:43cce7b453d0 144
oks486 0:43cce7b453d0 145 unsigned int flashAddress = sectorStart + sectorPos;
oks486 0:43cce7b453d0 146 if (!copyToFlash(flashAddress, RAM_BASE_ADDRESS, CHUNK_SIZE)) {
oks486 0:43cce7b453d0 147 return ERR_COPY_TO_FLASH;
oks486 0:43cce7b453d0 148 }
oks486 0:43cce7b453d0 149 }
oks486 0:43cce7b453d0 150
oks486 0:43cce7b453d0 151 // sector access order => 1, 2, ... , 6, 7, 0
oks486 0:43cce7b453d0 152 if (sector >= SECTOR_NUM - 1) {
oks486 0:43cce7b453d0 153 sector = 0;
oks486 0:43cce7b453d0 154 } else if (dataLength < BUF_SIZE) {
oks486 0:43cce7b453d0 155 sector = 0;
oks486 0:43cce7b453d0 156 } else if (sector == 0) {
oks486 0:43cce7b453d0 157 finishWrite = 1;
oks486 0:43cce7b453d0 158 wait_ms(300);
oks486 0:43cce7b453d0 159 } else {
oks486 0:43cce7b453d0 160 sector++;
oks486 0:43cce7b453d0 161 }
oks486 0:43cce7b453d0 162 }
oks486 0:43cce7b453d0 163
oks486 0:43cce7b453d0 164 // BIN file close and delete
oks486 0:43cce7b453d0 165 fs->close();
oks486 1:11f73f269fdc 166 fs->deleteFirmFile(filename);
oks486 0:43cce7b453d0 167 delete [] buffer;
oks486 0:43cce7b453d0 168
oks486 0:43cce7b453d0 169 return NOERROR;
oks486 0:43cce7b453d0 170 }