123

Dependencies:   mbed

Fork of LG by igor Apu

DeviceFlash.c

Committer:
Diletant
Date:
2016-05-09
Revision:
156:e68ee0bcdcda
Parent:
149:abbf7663d27d
Child:
167:bedc0a9d559a

File content as of revision 156:e68ee0bcdcda:

#include "Device.h"
#include <stdio.h>

extern Device device;
extern HashParam hashParamTable[HASH_PARAM_COUNT];

//Flash memory sectors
#define FLASH_SECTOR0_SIZE   0x1000
#define FLASH_SECTOR0_START  0x00000000
#define FLASH_SECTOR0_END    0x00000FFF

#define FLASH_SECTOR1_SIZE   0x1000
#define FLASH_SECTOR1_START  0X00001000
#define FLASH_SECTOR1_END    0X00001FFF

#define FLASH_SECTOR2_SIZE   0x1000
#define FLASH_SECTOR2_START  0X00002000
#define FLASH_SECTOR2_END    0X00002FFF

#define FLASH_SECTOR3_SIZE   0x1000
#define FLASH_SECTOR3_START  0X00003000
#define FLASH_SECTOR3_END    0X00003FFF

#define FLASH_SECTOR4_SIZE   0x1000
#define FLASH_SECTOR4_START  0X00004000
#define FLASH_SECTOR4_END    0X00004FFF

#define FLASH_SECTOR5_SIZE   0x1000
#define FLASH_SECTOR5_START  0X00005000
#define FLASH_SECTOR5_END    0X00005FFF

#define FLASH_SECTOR6_SIZE   0x1000
#define FLASH_SECTOR6_START  0X00006000
#define FLASH_SECTOR6_END    0X00006FFF

#define FLASH_SECTOR7_SIZE   0x1000
#define FLASH_SECTOR7_START  0X00007000
#define FLASH_SECTOR7_END    0X00007FFF

#define FLASH_SECTOR8_SIZE   0x1000
#define FLASH_SECTOR8_START  0x00008000
#define FLASH_SECTOR8_END    0X00008FFF

#define FLASH_SECTOR9_SIZE   0x1000
#define FLASH_SECTOR9_START  0x00009000
#define FLASH_SECTOR9_END    0X00009FFF

#define FLASH_SECTOR10_SIZE  0x1000
#define FLASH_SECTOR10_START 0x0000A000
#define FLASH_SECTOR10_END   0X0000AFFF

#define FLASH_SECTOR11_SIZE  0x1000
#define FLASH_SECTOR11_START 0x0000B000
#define FLASH_SECTOR11_END   0X0000BFFF

#define FLASH_SECTOR12_SIZE  0x1000
#define FLASH_SECTOR12_START 0x0000C000
#define FLASH_SECTOR12_END   0X0000CFFF

#define FLASH_SECTOR13_SIZE  0x1000
#define FLASH_SECTOR13_START 0x0000D000
#define FLASH_SECTOR13_END   0X0000DFFF

#define FLASH_SECTOR14_SIZE  0x1000
#define FLASH_SECTOR14_START 0x0000E000
#define FLASH_SECTOR14_END   0X0000EFFF

#define FLASH_SECTOR15_SIZE  0x1000
#define FLASH_SECTOR15_START 0x0000F000
#define FLASH_SECTOR15_END   0X0000FFFF

#define FLASH_SECTOR16_SIZE  0x8000
#define FLASH_SECTOR16_START 0x00010000
#define FLASH_SECTOR16_END   0x00017FFF

#define FLASH_SECTOR17_SIZE  0x8000
#define FLASH_SECTOR17_START 0x00018000
#define FLASH_SECTOR17_END   0x0001FFFF

#define FLASH_SECTOR18_SIZE  0x8000
#define FLASH_SECTOR18_START 0x00020000
#define FLASH_SECTOR18_END   0x00027FFF

#define FLASH_SECTOR19_SIZE  0x8000
#define FLASH_SECTOR19_START 0x00028000
#define FLASH_SECTOR19_END   0x0002FFFF

#define FLASH_SECTOR20_SIZE  0x8000
#define FLASH_SECTOR20_START 0x00030000
#define FLASH_SECTOR20_END   0x00037FFF

#define FLASH_SECTOR21_SIZE  0x8000
#define FLASH_SECTOR21_START 0x00038000
#define FLASH_SECTOR21_END   0x0003FFFF

#define FLASH_SECTOR22_SIZE  0x8000
#define FLASH_SECTOR22_START 0x00040000
#define FLASH_SECTOR22_END   0x00047FFF

#define FLASH_SECTOR23_SIZE  0x8000
#define FLASH_SECTOR23_START 0x00048000
#define FLASH_SECTOR23_END   0x0004FFFF

#define FLASH_SECTOR24_SIZE  0x8000
#define FLASH_SECTOR24_START 0x00050000
#define FLASH_SECTOR24_END   0x00057FFF

#define FLASH_SECTOR25_SIZE  0x8000
#define FLASH_SECTOR25_START 0x00058000
#define FLASH_SECTOR25_END   0x0005FFFF

#define FLASH_SECTOR26_SIZE  0x8000
#define FLASH_SECTOR26_START 0x00060000
#define FLASH_SECTOR26_END   0x00067FFF

#define FLASH_SECTOR27_SIZE  0x8000
#define FLASH_SECTOR27_START 0x00068000
#define FLASH_SECTOR27_END   0x0006FFFF

#define FLASH_SECTOR28_SIZE  0x8000
#define FLASH_SECTOR28_START 0x00070000
#define FLASH_SECTOR28_END   0x00077FFF

#define FLASH_SECTOR29_SIZE  0x8000
#define FLASH_SECTOR29_START 0x00078000
#define FLASH_SECTOR29_END   0x0007FFFF

void InitFlashWithDefaults(void){
  device.controller.flash.settings.hashSector = 22;
  //device.controller.flash.settings.hashPageLength = 256;
  
  device.controller.flash.settings.dataSector = 23;
  //device.controller.flash.settings.dataPageLength = 256;
}

void InitFlash(void){
}

uint32_t AddressFromSector(uint8_t sector){
  switch (sector){
    case 0: return FLASH_SECTOR0_START;
    case 1: return FLASH_SECTOR1_START;
    case 2: return FLASH_SECTOR2_START;
    case 3: return FLASH_SECTOR3_START;
    case 4: return FLASH_SECTOR4_START;
    case 5: return FLASH_SECTOR5_START;
    case 6: return FLASH_SECTOR6_START;
    case 7: return FLASH_SECTOR7_START;
    case 8: return FLASH_SECTOR8_START;
    case 9: return FLASH_SECTOR9_START;
    case 10: return FLASH_SECTOR10_START;
    case 11: return FLASH_SECTOR11_START;
    case 12: return FLASH_SECTOR12_START;
    case 13: return FLASH_SECTOR13_START;
    case 14: return FLASH_SECTOR14_START;
    case 15: return FLASH_SECTOR15_START;
    case 16: return FLASH_SECTOR16_START;
    case 17: return FLASH_SECTOR17_START;
    case 18: return FLASH_SECTOR18_START;
    case 19: return FLASH_SECTOR19_START;
    case 20: return FLASH_SECTOR20_START;
    case 21: return FLASH_SECTOR21_START;
    case 22: return FLASH_SECTOR22_START;
    case 23: return FLASH_SECTOR23_START;
    case 24: return FLASH_SECTOR24_START;
    case 25: return FLASH_SECTOR25_START;
    case 26: return FLASH_SECTOR26_START;
    case 27: return FLASH_SECTOR27_START;
    case 28: return FLASH_SECTOR28_START;
    case 29: return FLASH_SECTOR29_START;
    default: return 0;
  }
}

uint16_t LengthFromSector(uint8_t sector){
  switch (sector){
    case 0: return FLASH_SECTOR0_SIZE;
    case 1: return FLASH_SECTOR1_SIZE;
    case 2: return FLASH_SECTOR2_SIZE;
    case 3: return FLASH_SECTOR3_SIZE;
    case 4: return FLASH_SECTOR4_SIZE;
    case 5: return FLASH_SECTOR5_SIZE;
    case 6: return FLASH_SECTOR6_SIZE;
    case 7: return FLASH_SECTOR7_SIZE;
    case 8: return FLASH_SECTOR8_SIZE;
    case 9: return FLASH_SECTOR9_SIZE;
    case 10: return FLASH_SECTOR10_SIZE;
    case 11: return FLASH_SECTOR11_SIZE;
    case 12: return FLASH_SECTOR12_SIZE;
    case 13: return FLASH_SECTOR13_SIZE;
    case 14: return FLASH_SECTOR14_SIZE;
    case 15: return FLASH_SECTOR15_SIZE;
    case 16: return FLASH_SECTOR16_SIZE;
    case 17: return FLASH_SECTOR17_SIZE;
    case 18: return FLASH_SECTOR18_SIZE;
    case 19: return FLASH_SECTOR19_SIZE;
    case 20: return FLASH_SECTOR20_SIZE;
    case 21: return FLASH_SECTOR21_SIZE;
    case 22: return FLASH_SECTOR22_SIZE;
    case 23: return FLASH_SECTOR23_SIZE;
    case 24: return FLASH_SECTOR24_SIZE;
    case 25: return FLASH_SECTOR25_SIZE;
    case 26: return FLASH_SECTOR26_SIZE;
    case 27: return FLASH_SECTOR27_SIZE;
    case 28: return FLASH_SECTOR28_SIZE;
    case 29: return FLASH_SECTOR29_SIZE;
    default: return 0;
  }
}
/*
uint8_t sectorFromAddress(uint32_t address){
       if (address >= FLASH_SECTOR29_START) return 29;
  else if (address >= FLASH_SECTOR28_START) return 28;
  else if (address >= FLASH_SECTOR27_START) return 27;
  else if (address >= FLASH_SECTOR26_START) return 26;
  else if (address >= FLASH_SECTOR25_START) return 25;
  else if (address >= FLASH_SECTOR24_START) return 24;
  else if (address >= FLASH_SECTOR23_START) return 23;
  else if (address >= FLASH_SECTOR22_START) return 22;
  else if (address >= FLASH_SECTOR21_START) return 21;
  else if (address >= FLASH_SECTOR20_START) return 20;
  else if (address >= FLASH_SECTOR19_START) return 19;
  else if (address >= FLASH_SECTOR18_START) return 18;
  else if (address >= FLASH_SECTOR17_START) return 17;
  else if (address >= FLASH_SECTOR16_START) return 16;
  else if (address >= FLASH_SECTOR15_START) return 15;
  else if (address >= FLASH_SECTOR14_START) return 14;
  else if (address >= FLASH_SECTOR13_START) return 13;
  else if (address >= FLASH_SECTOR12_START) return 12;
  else if (address >= FLASH_SECTOR11_START) return 11;
  else if (address >= FLASH_SECTOR10_START) return 10;
  else if (address >= FLASH_SECTOR9_START) return 9;
  else if (address >= FLASH_SECTOR8_START) return 8;
  else if (address >= FLASH_SECTOR7_START) return 7;
  else if (address >= FLASH_SECTOR6_START) return 6;
  else if (address >= FLASH_SECTOR5_START) return 5;
  else if (address >= FLASH_SECTOR4_START) return 4;
  else if (address >= FLASH_SECTOR3_START) return 3;
  else if (address >= FLASH_SECTOR2_START) return 2;
  else if (address >= FLASH_SECTOR1_START) return 1;
  else return 0;
}
*/

DeviceFlashHash * FlashFindByHash(uint32_t hash){
  uint16_t sectorLength = LengthFromSector(device.controller.flash.settings.hashSector);
  uint16_t hashCapacity = sectorLength / sizeof(DeviceFlashHash);
  uint32_t sectorAddress = AddressFromSector(device.controller.flash.settings.hashSector);
  DeviceFlashHash * item = (DeviceFlashHash *)sectorAddress;
  for (uint16_t i = 0; i < hashCapacity; i++){
    if (item->hash == 0) break;
    if (item->hash == hash) return item;
    item++;
  }
  return 0;
}

void DeviceFlashReadAll(void){
  uint16_t count = 0;
  uint16_t sectorLength = LengthFromSector(device.controller.flash.settings.hashSector);
  uint16_t hashCapacity = sectorLength / sizeof(DeviceFlashHash);
  uint32_t sectorAddress = AddressFromSector(device.controller.flash.settings.hashSector);
  DeviceFlashHash * item = (DeviceFlashHash *)sectorAddress;
  for (uint16_t i = 0; i < hashCapacity; i++){
    if (item->hash == 0) break; //Cleared
    if (item->hash == 0xffffffff) break; //Erased
    for (uint32_t j = 0; j < HASH_PARAM_COUNT; j++){
      if (item->hash == hashParamTable[j].hash){
        //if (item->size == hashParamTable[j].size){
          uint8_t * src = (uint8_t *)item->address;
          uint8_t * dst = hashParamTable[j].ref;
          for (uint16_t k = 0; k < hashParamTable[j].size; k++){
            *dst = *src; src++; dst++;
          }
        //}
      }
    }
    item++;
    count++;
  }
  sprintf(device.service.buffer,"FlashReadAll(): %d\r\n",count); WriteConcole();
}

void FlashOperationWritePage(DeviceFlashWriteOperation * op){
  uint32_t res;
  if (op->sectorPosition == 0){
    //Prepare new sector for write operation
    res = u32IAP_PrepareSectors(op->sector, op->sector);
    sprintf(device.service.buffer,"PrepareSectors(): %02d %08x\r\n",op->sector, res); WriteConcole();
    //Erase new sector
    res = u32IAP_EraseSectors(op->sector, op->sector);
    sprintf(device.service.buffer,"EraseSectors(): %02d %08x\r\n",op->sector, res); WriteConcole();
  }
  if (op->bytes < op->maxBytes){
    //Prepare sector for write operation
    res = u32IAP_PrepareSectors(op->sector, op->sector);
    sprintf(device.service.buffer,"PrepareSectors(): %02d %08x\r\n",op->sector, res); WriteConcole();
    //Copy page buffer to flash
    res = u32IAP_CopyRAMToFlash(op->sectorAddress + op->sectorPosition, (uint32_t)&op->pageBuffer[0], FLASH_PAGE_SIZE);
    sprintf(device.service.buffer,"CopyRAMToFlash(): %8x %08x\r\n", op->sectorAddress + op->sectorPosition, res); WriteConcole();
    //Update bytes count
    op->bytes += FLASH_PAGE_SIZE;
    //Update sector position
    op->sectorPosition += FLASH_PAGE_SIZE;
    if (op->sectorPosition == op->sectorLength){
      //Update sector address
      op->sectorAddress += op->sectorLength;
      //Clear sector position
      op->sectorPosition = 0;
      //Update sector
      op->sector += 1;
    }
    //Update page position
    op->pagePosition = 0;
  }
}

void FlashOperationAppend(DeviceFlashWriteOperation * op, void * src, uint16_t count){
  uint8_t * ptr = (uint8_t*) src;
  for (uint16_t i = 0; i < count; i++){
    op->pageBuffer[op->pagePosition] = *ptr;
    op->pagePosition++;
    ptr++;
    //Write page buffer
    if (op->pagePosition == FLASH_PAGE_SIZE){
      FlashOperationWritePage(op);
    }
  }
}

void FlashOperationComplete(DeviceFlashWriteOperation * op){
  for (uint16_t i = op->pagePosition; i < FLASH_PAGE_SIZE; i++){
    op->pageBuffer[op->pagePosition] = 0xff;
    op->pagePosition++;
  }
  FlashOperationWritePage(op);
}

void DeviceFlashWriteAll(void){
  //#pragma pack(push)  /* push current alignment to stack */
  //#pragma pack(4)     /* set alignment to 4 byte boundary */
  DeviceFlashWriteOperation hash;
  //#pragma pack(pop)   /* restore original alignment from stack */
  hash.sector = device.controller.flash.settings.hashSector;
  hash.sectorAddress = AddressFromSector(hash.sector);
  hash.sectorLength = LengthFromSector(hash.sector);
  hash.sectorPosition = 0;
  hash.pagePosition = 0;
  //hash.pageLength = device.flash.settings.hashPageLength;
  hash.bytes = 0;
  hash.maxBytes = hash.sectorLength;
  
  DeviceFlashWriteOperation data;
  data.sector = device.controller.flash.settings.dataSector;
  data.sectorAddress = AddressFromSector(data.sector);
  data.sectorLength = LengthFromSector(data.sector);
  data.sectorPosition = 0;
  data.pagePosition = 0;
  //data.pageLength = device.flash.settings.dataPageLength;
  data.bytes = 0;
  data.maxBytes = FLASH_SECTOR29_END - data.sectorAddress;
  
  NVIC_DisableIRQ(TIMER1_IRQn);
  NVIC_DisableIRQ(TIMER2_IRQn);
  NVIC_DisableIRQ(EINT3_IRQn);
  //SystemInitDef();
  
  for (uint32_t i = 0; i < HASH_PARAM_COUNT; i++){
    FlashOperationAppend(&hash, &hashParamTable[i].hash, 4);
    uint32_t address = data.sectorAddress + data.sectorPosition + data.pagePosition;
    FlashOperationAppend(&hash, &address, 4);
    FlashOperationAppend(&data, hashParamTable[i].ref, hashParamTable[i].size);
  }
  FlashOperationComplete(&hash);
  FlashOperationComplete(&data);
  
  NVIC_EnableIRQ(TIMER1_IRQn);
  NVIC_EnableIRQ(TIMER2_IRQn);
  NVIC_EnableIRQ(EINT3_IRQn);
}