/****************************************************************************** Name: GNDS_FL_EraseSector Description: Erases one sector. Parameters: 1) address within sector to erase Returns: GD_OK GD_ERR_FLASH_ERASE if device returns an error GD_ERR_TIMEOUT if custom timeout occurs ******************************************************************************/ GERR GNDS_FL_EraseSector(U32 sectorAddress) { U16 rd; U32 timeout; GERR ferr; ferr = GD_OK; GNDS_FL_Reset(); flashWriteCmd(CMD_ERASE_SETUP, 0); flashWriteCmd(CMD_SECTOR_ERASE, sectorAddress); /* wait until erasing is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = TIMEOUT; while ((ferr == GD_ERR_BAD_PARAMETER)&&((timeout--) > 0)) { rd = flashRead(sectorAddress); if ((rd & DQ7)!=0) ferr = GD_OK; else if ((rd & DQ5)!=0) { rd = flashRead(sectorAddress); if ((rd & DQ7)!=0) ferr = GD_OK; else ferr = GD_ERR_FLASH_ERASE; } } if (timeout == 0) ferr = GD_ERR_TIMEOUT; GNDS_FL_Reset(); return ferr; }
/****************************************************************************** Name: GNDS_FL_EraseChip Description: Erases whole flash memory device. Parameters: none Returns: GD_OK GD_ERR_FLASH_ERASE if device returns an error GD_ERR_TIMEOUT if custom timeout occurs ******************************************************************************/ GERR GNDS_FL_EraseChip() { U16 rd; U32 timeout; GERR ferr; ferr = GD_OK; GNDS_FL_Reset(); flashWriteCmd(CMD_ERASE_SETUP, 0); flashWriteCmd(CMD_CHIP_ERASE, 0); /* wait until erasing is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = 10*TIMEOUT; /* takes longer than write or sector erase! */ while ((ferr == GD_ERR_BAD_PARAMETER)&&((timeout--) > 0)) { rd = flashRead(0); if ((rd & DQ7)!=0) ferr = GD_OK; else if ((rd & DQ5)!=0) { rd = flashRead(0); if ((rd & DQ7)!=0) ferr = GD_OK; else ferr = GD_ERR_FLASH_ERASE; } } if (timeout == 0) ferr = GD_ERR_TIMEOUT; GNDS_FL_Reset(); return ferr; }
/****************************************************************************** Name: GNDS_FL_Write Description: Writes to flash memory. Parameters: 1) start address (in flash memory space) 2) pointer to buffer 3) size = number of words to write Returns: GD_OK GD_ERR_FLASH_WRITE if device returns an error GD_ERR_TIMEOUT if custom timeout ******************************************************************************/ GERR GNDS_FL_Write(U32 address, U16* data, U32 size) { U16 rd; U32 i, timeout; GERR ferr; ferr = GD_OK; for (i = 0; i < size; i++) { flashWriteCmd(CMD_PROGRAM, 0); flashWrite(address, data[i]); /* wait until programming is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = TIMEOUT; while ((ferr == GD_ERR_BAD_PARAMETER)&&((timeout--) > 0)) { rd = flashRead(address); if ((rd&DQ7)==(data[i]&DQ7)) ferr = GD_OK; else if ((rd&DQ5)==DQ5) { /* check DQ7 again according to flash device specification */ rd = flashRead(address); if ((rd&DQ7)==(data[i]&DQ7)) ferr = GD_OK; else ferr = GD_ERR_FLASH_WRITE; } } if (timeout == 0) ferr = GD_ERR_TIMEOUT; if (ferr != GD_OK) return ferr; address++; } return ferr; }
esError storageRead( struct storageSpace * space, void * buffer) { esError error; struct storageSpace nvmSpace; if ((error = flashRead(space->phy.base, &nvmSpace, sizeof(nvmSpace)))) { return (error); } if (checksumParity8(&nvmSpace, sizeof(nvmSpace)) != 0) { return (ES_ERROR_OBJECT_INVALID); } if ((nvmSpace.signature != space->signature) || (nvmSpace.data.size != space->data.size)) { return (ES_ERROR_OBJECT_INVALID); } if ((error = flashRead(STORAGE_DATA_ADDRESS(space->phy.base), buffer, nvmSpace.data.size))) { return (error); } if (checksumParity8(buffer, nvmSpace.data.size) != nvmSpace.data.checksum) { return (ES_ERROR_OBJECT_INVALID); } return (ES_ERROR_NONE); }
void readFromFlash(void) { efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "read f"); printMsg(logger, "readFromFlash()"); flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE); persisted_configuration_state_e result; if (!isValidCrc(&persistentState)) { result = CRC_FAILED; resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER); } else if (persistentState.version != FLASH_DATA_VERSION || persistentState.size != PERSISTENT_SIZE) { result = INCOMPATIBLE_VERSION; resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER); } else { /** * At this point we know that CRC and version number is what we expect. Safe to assume it's a valid configuration. */ result = OK; applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER); } // we can only change the state after the CRC check engineConfiguration->firmwareVersion = getRusEfiVersion(); if (result == CRC_FAILED) { printMsg(logger, "Need to reset flash to default due to CRC"); } else if (result == INCOMPATIBLE_VERSION) { printMsg(logger, "Resetting but saving engine type [%d]", engineConfiguration->engineType); } else { printMsg(logger, "Got valid configuration from flash!"); } }
u16 read16(const u32 address) { switch (address >> 24) { case 8: case 9: case 10: case 11: case 12: if (rtcIsEnabled() && (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)) return rtcRead(address); else return READ16LE(((u16 *)&rom[address & 0x1FFFFFE])); break; case 13: if (game.hasEEPROM()) return eepromRead(address); break; case 14: if (game.hasSRAM()) return sramRead(address); else if (game.hasFlash()) return flashRead(address); break; default: break; } return 0; }
u32 read32(const u32 address) { switch (address >> 24) { case 8: case 9: case 10: case 11: case 12: return READ32LE(((u32 *)&rom[address&0x1FFFFFC])); break; case 13: if (game.hasEEPROM()) return eepromRead(address); break; case 14: if (game.hasSRAM()) return sramRead(address); else if (game.hasFlash()) return flashRead(address); break; default: break; } return 0; }
// ------------------------------------- // Main function // ------------------------------------- void appMain(void) { uint16_t i; // timers (used to get an extra interrupt context) alarmInit(&timer, onTimer, NULL); alarmSchedule(&timer, 1000); // radio radioSetReceiveHandle(radioRecvCb); radioOn(); for (i = 0; i < BUFFER_SIZE; i++) { buffer[i] = i; } randomInit(); // SELECT_FLASH; // extFlashBulkErase(); // UNSELECT_FLASH; for (i = 0; ; i++) { uint32_t address = i * 64ul; SELECT_FLASH; if (IS_ALIGNED(address, EXT_FLASH_SECTOR_SIZE)) { PRINTF("erase address %lu\n", address); flashErase(address); } PRINTF("write address %lu\n", address); flashWrite(address); if (address > 0) { PRINTF("verify...\n"); flashRead(address - 64); } UNSELECT_FLASH; msleep(randomInRange(400, 1000)); PRINTF("send smth to radio...\n"); radioSend("hello world", sizeof("hello world")); greenLedToggle(); } }
GERR GD_FL_Goke_EraseSector(U32 sectorAddress) { U32 cnt; U16 rd; U32 timeout; GERR ferr; ferr = GD_OK; GD_FL_Goke_Reset(); flashWriteCmd(CMD_ERASE_SETUP, 0); flashWriteCmd(CMD_SECTOR_ERASE, sectorAddress); /* NOTE: It must be ensured that this loop is not "optimized away"! */ for ( cnt = 0; cnt < delayLoops; cnt++ ) _ASM("nop"); /* wait until erasing is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = TIMEOUT; while ((ferr == GD_ERR_BAD_PARAMETER)&&((timeout--) > 0)) { rd = flashRead(sectorAddress); if ((rd & DQ7)!=0) ferr = GD_OK; else if ((rd & DQ5)!=0) { rd = flashRead(sectorAddress); if ((rd & DQ7)!=0) ferr = GD_OK; else ferr = GD_ERR_FLASH_ERASE; } } if (timeout == 0) ferr = GD_ERR_TIMEOUT; GD_FL_Goke_Reset(); return ferr; }
static void readFromFlash(void) { flashRead(FLASH_ADDR, (char *) &flashState, FLASH_USAGE); setDefaultNonPersistentConfiguration(engineConfiguration2); if (!isValidCrc(&flashState)) { scheduleMsg(&logger, "Need to reset flash to default"); resetConfigurationExt(defaultEngineType, engineConfiguration, engineConfiguration2, boardConfiguration); } else { scheduleMsg(&logger, "Got valid configuration from flash!"); applyNonPersistentConfiguration(engineConfiguration, engineConfiguration2, engineConfiguration->engineType); } // we can only change the state after the CRC check engineConfiguration->firmwareVersion = getRusEfiVersion(); }
GBOOL GD_FL_Goke_IsSectorProtected(U32 sectorAddress) { U16 flag; U32 adr; adr = (sectorAddress & 0xFFFFFF00) | 0x00000002; GD_FL_Goke_Reset(); flashWriteCmd(CMD_AUTOSELECT, 0); flag = flashRead(adr) & 0x0001; GD_FL_Goke_Reset(); if (flag == 0) return GFALSE; return GTRUE; }
/**************************************************************************//** * \brief Read a sector and verify the checksum * * Read a sector and, if successful, verify its checksum as well. After * #READ_RETRIES failed read-verify attempts exit * * \param sectorNum The sector number to read in (0 to 4194303 for a * 2GB MMC card with 512B sector sizes). * \param[out] sector Pointer to a sector structure to fill. Most * likely you will be casting a more specific sector * type or a simple array to this interface * \retval 0 success * \retval -1 failure *****************************************************************************/ int secureFlashRead(unsigned long sectorNum, struct Sector *sector){ int calcChecksum = 0; int i = 0; for( i = 0; i < READ_RETRIES; i++) // Attempt to read the card multiple times { if(flashRead(sectorNum, sector) == 0) { calcChecksum = fletcherChecksum(sector->data, SECTOR_CRC_SIZE, 0); if(sector->checksum == calcChecksum){ return FLASH_SUCCESS; } } } if(i >= READ_RETRIES) return FLASH_TIMEOUT; // If checksums do not agree return fail return FLASH_SUCCESS; }
void readFromFlash(void) { printMsg(&logger, "readFromFlash()"); flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE); //setDefaultNonPersistentConfiguration(engineConfiguration2); if (!isValidCrc(&persistentState) || persistentState.size != PERSISTENT_SIZE) { printMsg(&logger, "Need to reset flash to default"); resetConfigurationExt(&logger, defaultEngineType, engineConfiguration, engineConfiguration2, boardConfiguration); } else { printMsg(&logger, "Got valid configuration from flash!"); applyNonPersistentConfiguration(&logger, engineConfiguration, engineConfiguration2); } // we can only change the state after the CRC check engineConfiguration->firmwareVersion = getRusEfiVersion(); }
u8 read8(const u32 address) { switch (address >> 24) { case 8: case 9: case 10: case 11: case 12: return rom[address & 0x1FFFFFF]; break; case 13: if (game.hasEEPROM()) return eepromRead(address); break; case 14: if (game.hasSRAM()) return sramRead(address); else if (game.hasFlash()) return flashRead(address); /*if (game.hasMotionSensor()) { switch (address & 0x00008f00) { case 0x8200: return systemGetSensorX() & 255; case 0x8300: return (systemGetSensorX() >> 8)|0x80; case 0x8400: return systemGetSensorY() & 255; case 0x8500: return systemGetSensorY() >> 8; } }*/ break; default: break; } return 0; }
/** * this method could and should be executed before we have any * connectivity so no console output here */ persisted_configuration_state_e readConfiguration(Logging * logger) { efiAssert(getRemainingStack(chThdSelf()) > 256, "read f", PC_ERROR); flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE); persisted_configuration_state_e result; if (!isValidCrc(&persistentState)) { result = CRC_FAILED; warning(CUSTOM_ERR_FLASH_CRC_FAILED, "flash CRC failed"); resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER); } else if (persistentState.version != FLASH_DATA_VERSION || persistentState.size != PERSISTENT_SIZE) { result = INCOMPATIBLE_VERSION; resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER); } else { /** * At this point we know that CRC and version number is what we expect. Safe to assume it's a valid configuration. */ result = OK; applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER); } // we can only change the state after the CRC check engineConfiguration->byFirmwareVersion = getRusEfiVersion(); return result; }
STATUS flashDiag (flash_dev_t * dev) { unsigned int *buf = 0; int i, len, sector; int rv = ERROR; if (flashCheck (dev) == ERROR) return ERROR; printf ("flashDiag: Testing device %d, " "base: 0x%x, %d sectors @ %d kB = %d kB\n", DEV_NO (dev), dev->base, dev->sectors, 1 << (dev->lgSectorSize - 10), dev->sectors << (dev->lgSectorSize - 10)); len = 1 << dev->lgSectorSize; printf ("flashDiag: Erasing\n"); if (flashErase (dev) == ERROR) { printf ("flashDiag: Erase failed\n"); goto done; } printf ("%d bytes requested ...\n", len); buf = malloc (len); printf ("allocated %d bytes ...\n", len); if (buf == 0) { printf ("flashDiag: Out of memory\n"); goto done; } /* * Write unique counting pattern to each sector */ for (sector = 0; sector < dev->sectors; sector++) { printf ("flashDiag: Write sector %d\n", sector); for (i = 0; i < len / 4; i++) buf[i] = sector << 24 | i; if (flashWrite (dev, sector << dev->lgSectorSize, (char *) buf, len) == ERROR) { printf ("flashDiag: Write failed (dev: %d, sector: %d)\n", DEV_NO (dev), sector); goto done; } } /* * Verify */ for (sector = 0; sector < dev->sectors; sector++) { printf ("flashDiag: Verify sector %d\n", sector); if (flashRead (dev, sector << dev->lgSectorSize, (char *) buf, len) == ERROR) { printf ("flashDiag: Read failed (dev: %d, sector: %d)\n", DEV_NO (dev), sector); goto done; } for (i = 0; i < len / 4; i++) { if (buf[i] != (sector << 24 | i)) { printf ("flashDiag: Verify error " "(dev: %d, sector: %d, offset: 0x%x)\n", DEV_NO (dev), sector, i); printf ("flashDiag: Expected 0x%08x, got 0x%08x\n", sector << 24 | i, buf[i]); goto done; } } } printf ("flashDiag: Erasing\n"); if (flashErase (dev) == ERROR) { printf ("flashDiag: Final erase failed\n"); goto done; } rv = OK; done: if (buf) free (buf); if (rv == OK) printf ("flashDiag: Device %d passed\n", DEV_NO (dev)); else printf ("flashDiag: Device %d failed\n", DEV_NO (dev)); return rv; }
GERR GD_FL_Goke_Check(U32 startAddress, GD_FL_CHIP_DATA_S* chipData) { U16 manufacturerCode; U16 deviceCode; U16 deviceCode2; U16 deviceCode3; manufacturerCode = 0; deviceCode = 0; thisStartAddress = startAddress; delayLoops = 0; /* read manufacture and device code */ GD_FL_Goke_Reset(); flashWriteCmd(CMD_AUTOSELECT, 0); manufacturerCode = flashRead(0); deviceCode = flashRead(1); GD_FL_Goke_Reset(); /* check manufacturer and device code */ if ( manufacturerCode == MANUFACTURER_CODE_GOKE ) { switch ( deviceCode ) { case DEVICE_CODE_MBM29DL323BE: chipData->size = SIZE_MBM29DL323BE; chipData->numberOfSectors = SECTORS_MBM29DL323BE; chipData->deviceName = (U8*)DEVICE_NAME_MBM29DL323BE; break; case DEVICE_CODE_MBM29PL160BD: chipData->size = SIZE_MBM29PL160BD; chipData->numberOfSectors = SECTORS_MBM29PL160BD; chipData->deviceName = (U8*)DEVICE_NAME_MBM29PL160BD; break; case DEVICE_CODE_MBM29LV160BE: chipData->size = SIZE_MBM29LV160BE; chipData->numberOfSectors = SECTORS_MBM29LV160BE; chipData->deviceName = (U8*)DEVICE_NAME_MBM29LV160BE; break; case DEVICE_CODE_MBM29LV800BE: chipData->size = SIZE_MBM29LV800BE; chipData->numberOfSectors = SECTORS_MBM29LV800BE; chipData->deviceName = (U8*)DEVICE_NAME_MBM29LV800BE; break; default: return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } chipData->manufactureName = (U8*)MANUFACTURER_NAME_GOKE; } else if ( manufacturerCode == MANUFACTURER_CODE_SPANSION ) { flashWriteCmd(CMD_AUTOSELECT, 0); deviceCode = flashRead(1); deviceCode2 = flashRead(0xE); // 0x1C / 2 deviceCode3 = flashRead(0xF); // 0x1E / 2 GD_FL_Goke_Reset(); switch ( deviceCode ) { #if defined(SMARTMPEG_E) || defined(SMARTMPEG_C) || defined(SMARTMPEG_M) || defined(SMARTMPEG) || defined(GK6105S) || defined(GK6106) case DEVICE_CODE_S29GL: if( ( deviceCode2 == __DEVICE_CODE2_S29GL064A_R4 ) && ( deviceCode3 == __DEVICE_CODE3_S29GL064A_R4_BOTTOM ) ) { chipData->size = SIZE_S29GL064A_R4_BOTTOM; chipData->numberOfSectors = SECTORS_S29GL064A_R4_BOTTOM; chipData->deviceName = (U8*)DEVICE_NAME_S29GL064A_R4_BOTTOM; delayLoops = DELAY_LOOPS_S29GL064A_R4_BOTTOM; deviceCode = DEVICE_CODE_S29GL064A_R4_BOTTOM; } else if( ( deviceCode2 == __DEVICE_CODE2_S29GL032A_R4 ) && ( deviceCode3 == __DEVICE_CODE3_S29GL032A_R4_BOTTOM ) ) { chipData->size = SIZE_S29GL032A_R4_BOTTOM; chipData->numberOfSectors = SECTORS_S29GL032A_R4_BOTTOM; chipData->deviceName = (U8*)DEVICE_NAME_S29GL032A_R4_BOTTOM; delayLoops = DELAY_LOOPS_S29GL032A_R4_BOTTOM; deviceCode = DEVICE_CODE_S29GL032A_R4_BOTTOM; } else if( ( deviceCode2 == __DEVICE_CODE2_S29GL032A_R3 ) && ( deviceCode3 == __DEVICE_CODE3_S29GL032A_R3_TOP ) ) { chipData->size = SIZE_S29GL032M_R3_TOP; chipData->numberOfSectors = SECTORS_S29GL032M_R3_TOP; chipData->deviceName = (U8*)DEVICE_NAME_S29GL032M_R3_TOP; delayLoops = DELAY_LOOPS_S29GL032M_R3_TOP; deviceCode = DEVICE_CODE_S29GL032M_R3_TOP; } // S29GL128N else if( ( deviceCode2 == __DEVICE_CODE2_S29GL128N ) && ( deviceCode3 == __DEVICE_CODE3_S29GL128N ) ) { chipData->size = SIZE_S29GL128N; chipData->numberOfSectors = SECTORS_S29GL128N; chipData->deviceName = (U8*)DEVICE_NAME_S29GL128N; delayLoops = DELAY_LOOPS_S29GL128N; deviceCode = DEVICE_CODE_S29GL128N; } //S29GL032N else if( ( deviceCode2 == __DEVICE_CODE2_S29GL032N_04 ) && ( deviceCode3 == __DEVICE_CODE2_S29GL032N_04_BOTTOM ) ) { chipData->size = SIZE_S29GL032N; chipData->numberOfSectors = SECTORS_S29GL032N; chipData->deviceName = (U8*)DEVICE_NAME_S29GL032N; delayLoops = DELAY_LOOPS_S29GL032N; deviceCode = DEVICE_CODE_S29GL032N; } else { return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } break; case DEVICE_CODE_S29AL0320TE: chipData->size = SIZE_S29AL0320TE; chipData->numberOfSectors = SECTORS_S29AL0320TE; chipData->deviceName = (U8*)DEVICE_NAME_S29AL0320TE; delayLoops = DELAY_LOOPS_S29AL0320TE; deviceCode = DEVICE_CODE_S29AL0320TE; break; case DEVICE_CODE_S29AL0320BE: chipData->size = SIZE_S29AL0320BE; chipData->numberOfSectors = SECTORS_S29AL0320BE; chipData->deviceName = (U8*)DEVICE_NAME_S29AL0320BE; delayLoops = DELAY_LOOPS_S29AL0320BE; deviceCode = DEVICE_CODE_S29AL0320BE; break; // case DEVICE_CODE_S29GL064A_R4: // chipData->size = SIZE_S29GL064A_R4; // chipData->numberOfSectors = SECTORS_S29GL064A_R4; // chipData->deviceName = (U8*)DEVICE_NAME_S29GL064A_R4; // delayLoops = DELAY_LOOPS_S29GL064A_R4; // break; #endif default: return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } chipData->manufactureName = (U8*)MANUFACTURER_NAME_SPANSION; } else if ( manufacturerCode == MANUFACTURER_CODE_MACRONIX ) { switch ( deviceCode ) { case DEVICE_CODE_MX29LV320CB: chipData->size = SIZE_MX29LV320CB; chipData->numberOfSectors = SECTORS_MX29LV320CB; chipData->deviceName = (U8*)DEVICE_NAME_MX29LV320CB; break; case DEVICE_CODE_MX29LV640CB: chipData->size = SIZE_MX29LV640CB; chipData->numberOfSectors = SECTORS_MX29LV640CB; chipData->deviceName = (U8*)DEVICE_NAME_MX29LV640CB; break; case DEVICE_CODE_MX29LV640EB: chipData->size = SIZE_MX29LV640E; chipData->numberOfSectors = SECTORS_MX29LV640E; chipData->deviceName = (U8*)DEVICE_NAME_MX29LV640E; break; default: return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } chipData->manufactureName = (U8*)MANUFACTURER_NAME_MACRONIX; } else if ( manufacturerCode == MANUFACTURER_CODE_EXELSEMI ) { switch ( deviceCode ) { case DEVICE_CODE_ES29LV160ET: chipData->size = SIZE_ES29LV160ET; chipData->numberOfSectors = SECTORS_ES29LV160ET; chipData->deviceName = (U8*)DEVICE_NAME_ES29LV160ET; break; default: return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } chipData->manufactureName = (U8*)MANUFACTURER_NAME_EXELSEMI; } else { return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } thisDeviceCode = deviceCode; thisManufacturerCode = manufacturerCode; chipData->manufactureCode = manufacturerCode; chipData->deviceCode = deviceCode; chipData->startAddress = startAddress; chipData->flashGetSectorAddressFct = (U32 (*)(U16))GD_FL_Goke_GetSectorAddress; chipData->flashGetSectorSizeFct = (U32 (*)(U16))GD_FL_Goke_GetSectorSize; chipData->flashResetFct = (void (*)())GD_FL_Goke_Reset; chipData->flashEraseChipFct = (GERR (*)(void))GD_FL_Goke_EraseChip; chipData->flashEraseSectorFct = (GERR (*)(U32))GD_FL_Goke_EraseSector; chipData->flashIsSectorProtectedFct = (GBOOL (*)(U32))GD_FL_Goke_IsSectorProtected; chipData->flashReadFct = (GERR (*)(U32, U16*, U32))GD_FL_Goke_Read; chipData->flashWriteFct = (GERR (*)(U32, U16*, U32))GD_FL_Goke_Write; #if defined(SMARTMPEG) /* add EXT IRQ0 to control A21 pin */ if(chipData->size == 0x400000) { if(GD_GPIO_Open(GD_GPIO_IRQ0, GD_GPIO_TYPE_OUTPUT_PUSH_PULL, NULL, &IRQ0Handle) != GD_OK) { return GD_ERR_FLASH_TYPE_NOT_SUPPORTED; } } #endif return GD_OK; }
GERR GD_FL_Goke_Read(U32 address, U16* data, U32 size) { U32 i; for (i=0; i<size; i++) data[i] = flashRead(address++); return GD_OK; }
GERR GD_FL_Goke_Write(U32 address, U16* data, U32 size) { U32 cnt; U16 rd; U32 i, timeout; GERR ferr; if (size == 0) return GD_OK; ferr = GD_OK; if ( (size == 1) || (thisManufacturerCode == MANUFACTURER_CODE_MACRONIX) || (thisManufacturerCode == MANUFACTURER_CODE_EXELSEMI) ) // slow programming just for security, maybe not necessary { for (i=0; (i<size) && (ferr==GD_OK); i++) { flashWriteCmd(CMD_PROGRAM, 0); flashWrite(address, data[i]); /* it must be ensured that this loop is not optimized away */ for (cnt = 0; cnt < delayLoops; cnt++) _ASM("nop"); /* wait until programming is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = TIMEOUT; while ( (ferr == GD_ERR_BAD_PARAMETER) && ((timeout--) > 0) ) { rd = flashRead(address); if ( (rd & DQ7) == (data[i] & DQ7) ) { ferr = GD_OK; } else if ( (rd & DQ5) == DQ5 ) { /* check DQ7 again according to flash device specification */ rd = flashRead(address); if ( (rd & DQ7) == (data[i] & DQ7) ) { ferr = GD_OK; } else { ferr = GD_ERR_FLASH_WRITE; } } } if (timeout == 0) { ferr = GD_ERR_TIMEOUT; } address++; } } else { /* enter fast mode */ flashWriteCmd(CMD_SET_FAST_MODE, 0); for (i=0; (i<size) && (ferr==GD_OK); i++) { flashWrite(address, CMD_PROGRAM); flashWrite(address, data[i]); /* it must be ensured that this loop is not optimized away */ for (cnt = 0; cnt < delayLoops; cnt++) _ASM("nop"); /* wait until programming is finished */ ferr = GD_ERR_BAD_PARAMETER; timeout = TIMEOUT; while ((ferr == GD_ERR_BAD_PARAMETER)&&((timeout--) > 0)) { rd = flashRead(address); if ( (rd & DQ7) == (data[i] & DQ7) ) { ferr = GD_OK; } else if ( (rd & DQ5) == DQ5 ) { rd = flashRead(address); if ( (rd & DQ7) == (data[i] & DQ7) ) { ferr = GD_OK; } else { ferr = GD_ERR_FLASH_WRITE; } } } if (timeout == 0) { ferr = GD_ERR_TIMEOUT; } address++; } /* reset fast programming mode */ address--; flashWrite(address, CMD_RESET_FAST_MODE_1); flashWrite(address, CMD_RESET_FAST_MODE_2); } return ferr; }
void cmd_flash(BaseSequentialStream *chp, int argc, char *argv[]) { int j, blockoffset; int status, address; char readBufferBefore[32]; flashsector_t i; chprintf(chp, "Flash test UTIL\r\n"); /* Handle warnings: */ if (argc >= 1) { if (strncmp(argv[0], "write", sizeof("write")) == 0) { if (argc >= 3) { blockoffset = atoi(argv[1]); if (blockoffset < 0 || blockoffset > FLASH_BLOCK_TESTCASE_COUNT) { chprintf(chp, "Offset must between %d and %d. Actual one was: %d \r\n", 0, FLASH_BLOCK_TESTCASE_COUNT, blockoffset); return; } /* use the fourth memory block for the tests */ address = FLASH_BASEADDR + (blockoffset * FLASH_BLOCKSIZE); /* extract the new value to store into it */ readBufferBefore[0] = atoi(argv[2]); status = flashWrite(address, readBufferBefore, FLASH_BLOCKSIZE); if (status != FLASH_RETURN_SUCCESS) { chprintf(chp, "Writing returned %d \r\n", status); return; } chprintf(chp, "test sector %u : stored at 0x%x %d\r\n", flashSectorAt(address), address, readBufferBefore[0]); } else { chprintf(chp, "flash needs additional parameter\r\n"); } } else if (strncmp(argv[0], "read", sizeof("read")) == 0) { for (i = 0; i < FLASH_BLOCK_TESTCASE_COUNT; ++i) { address = FLASH_BASEADDR + (i * FLASH_BLOCKSIZE); chprintf(chp, "test sector %u\t: 0x%x -> 0x%x (%u bytes)\r\n", flashSectorAt(address), address, address + FLASH_BLOCKSIZE, FLASH_BLOCKSIZE); status = flashRead(address, readBufferBefore, FLASH_BLOCKSIZE); if (status != FLASH_RETURN_SUCCESS) { chprintf(chp, "Reading returned %d\r\n", status); return; } for (j = 0; j < FLASH_BLOCKSIZE; j++) { chprintf(chp, "%02X ", readBufferBefore[j]); } chprintf(chp, "\r\n"); } } } else { flash_usage(chp); } }