uint32_t program( uint32_t *address, uint32_t *buffer ) // size is 256 bytes { uint32_t i ; if ( (uint32_t) address >= 0x08008000 ) { return 1 ; } if ( (uint32_t) address == 0x08000000 ) { eraseSector( 0 ) ; } if ( (uint32_t) address == 0x08004000 ) { eraseSector( 1 ) ; } // Now program the 256 bytes for (i = 0 ; i < 64 ; i += 1 ) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ // Wait for last operation to be completed waitFlashIdle() ; FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; *address = *buffer ; __disable_irq() ; /* Wait for operation to be completed */ waitFlashIdle() ; FLASH->CR &= (~FLASH_CR_PG); __enable_irq() ; /* Check the written value */ if ( *address != *buffer ) { /* Flash content doesn't match SRAM content */ return 2 ; } /* Increment FLASH destination address */ address += 1 ; buffer += 1 ; } return 0 ; }
void writeFlash(uint32_t *address, uint32_t *buffer) // page size is 256 bytes { if ((uint32_t) address == 0x08000000) { eraseSector(0); } else if ((uint32_t) address == 0x08004000) { eraseSector(1); } else if ((uint32_t) address == 0x08008000) { eraseSector(2); } else if ((uint32_t) address == 0x0800C000) { eraseSector(3); } else if ((uint32_t) address == 0x08010000) { eraseSector(4); } else if ((uint32_t) address == 0x08020000) { eraseSector(5); } else if ((uint32_t) address == 0x08040000) { eraseSector(6); } else if ((uint32_t) address == 0x08060000) { eraseSector(7); } for (uint32_t i=0; i<FLASH_PAGESIZE/4; i++) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ // Wait for last operation to be completed waitFlashIdle(); FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; *address = *buffer; /* Wait for operation to be completed */ waitFlashIdle(); FLASH->CR &= (~FLASH_CR_PG); /* Check the written value */ if (*address != *buffer) { /* Flash content doesn't match SRAM content */ return; } /* Increment FLASH destination address */ address += 1; buffer += 1; } }
/** * Erase all sectors of all chips. * * return 1 for success, 0 for failure */ uint8_t eraseAll(void) { uint8_t nBank; uint8_t nChip; for (nChip = 0; nChip < 2; ++nChip) { // erase 64 kByte = 8 banks at once (29F040) for (nBank = 0; nBank < FLASH_NUM_BANKS; nBank += FLASH_BANKS_ERASE_AT_ONCE) { if (!eraseSector(nBank, nChip)) return 0; } } return 1; }
/** @brief Writes a sector from memory to a sector in flash * * Uses writeWord to write a 1k block from sourceAddress(RAM) to * flashDestinationAddress, one word at a time. Give it the starting memory * address and the destination flash address. Both addresses will be * incremented by 1 word after a successful writeWord, until the whole 1024 * byte sector has been written. Before any writing occurs eraseSector is * called to make sure the destination is blank. * * @author Sean Keys * * @param RPage the page of RAM the RAMSourceAddress is located * @param RAMSourceAddress the address of the source data * @param PPage the page of flash where your flashDestinationAddress is located * @param flashDestinationAddress where your data will be written to in flash * * @return an error code. Zero means success, anything else is a failure. */ unsigned short writeSector(unsigned char RPage, unsigned short* RAMSourceAddress, unsigned char PPage , unsigned short* flashDestinationAddress){ if(((unsigned short)flashDestinationAddress % FLASHSECTORSIZE) != 0){ return ADDRESS_NOT_SECTOR_ALIGNED; } if(((unsigned short)flashDestinationAddress) < 0x4000){ return ADDRESS_NOT_FLASH_REGION; } /// @todo TODO Decide if we need to disable interrupts since we are manually setting Flash/RAM pages. eraseSector((unsigned char)PPage, (unsigned short*)flashDestinationAddress); /* First Erase our destination block */ unsigned short wordCount = FLASHSECTORSIZEINWORDS; /* Save pages */ unsigned char currentRPage = RPAGE; unsigned char currentPPage = PPAGE; /* Switch pages */ RPAGE = RPage; PPAGE = PPage; while (wordCount > 0) { unsigned short sourceData = *RAMSourceAddress; /*Convert the RAMAddr to data(dereference) */ unsigned short errorID = writeWord(flashDestinationAddress, sourceData); if(errorID != 0){ return errorID; } RAMSourceAddress++; flashDestinationAddress++; wordCount--; /* Decrement our word counter */ } /* Restore pages */ RPAGE = currentRPage; PPAGE = currentPPage; // @todo TODO verify the write? necessary?? return 0; }
/** @brief Writes a sector from memory to a sector in flash * * Uses writeWord to write a 1k block from sourceAddress(RAM) to * flashDestinationAddress, one word at a time. Give it the starting memory * address and the destination flash address. Both addresses will be * incremented by 1 word after a successful writeWord, until the whole 1024 * byte sector has been written. Before any writing occurs eraseSector is * called to make sure the destination is blank. * * @author Sean Keys * * @param RPage the page of RAM the RAMSourceAddress is located * @param RAMSourceAddress the address of the source data * @param PPage the page of flash where your flashDestinationAddress is located * @param flashDestinationAddress where your data will be written to in flash * * @return an error code. Zero means success, anything else is a failure. */ unsigned short writeSector(unsigned char RPage, unsigned short* RAMSourceAddress, unsigned char PPage , unsigned short* flashDestinationAddress){ if(((unsigned short)flashDestinationAddress % flashSectorSize) != 0){ return addressNotSectorAligned; } if(((unsigned short)flashDestinationAddress) < 0x4000){ return addressNotFlashRegion; } /// @todo TODO Decide if we need to disable interrupts since we are manually setting Flash/RAM pages. eraseSector((unsigned char)PPage, (unsigned short*)flashDestinationAddress); /* First Erase our destination block */ unsigned short wordCount = flashSectorSizeInWords; /* Save pages */ unsigned char currentRPage = RPAGE; unsigned char currentPPage = PPAGE; /* Switch pages */ RPAGE = RPage; PPAGE = PPage; while (wordCount > 0) { unsigned short sourceData = *RAMSourceAddress; /*Convert the RAMAddr to data(dereference) */ unsigned short errorID = writeWord(flashDestinationAddress, sourceData); if(errorID != 0){ return errorID; } RAMSourceAddress++; flashDestinationAddress++; wordCount--; /* Decrement our word counter */ } /* Restore pages */ RPAGE = currentRPage; PPAGE = currentPPage; return 0; }
/** * Write a block of 256 bytes to the flash. * The whole block must be located in one bank and in one flash chip. * If the flash block has an unknown state, erase it. * * return 1 for success, 0 for failure */ uint8_t __fastcall__ flashWriteBlock(uint8_t nBank, uint8_t nChip, uint16_t nOffset, uint8_t* pBlock) { uint16_t rv; uint8_t* pDest; uint8_t* pNormalBase; utilStr[0] = 0; utilAppendFlashAddr(nBank, nChip, nOffset); setStatus(utilStr); if (progressGetStateAt(nBank, nChip) == PROGRESS_UNTOUCHED) { if (!eraseSector(nBank, nChip)) { screenPrintSimpleDialog(apStrEraseFailed); return 0; } } eapiSetBank(nBank); pNormalBase = apNormalRomBase[nChip]; // when we write, we have to use the Ultimax address space pDest = apUltimaxRomBase[nChip] + nOffset; progressSetBankState(nBank, nChip, PROGRESS_WRITING); rv = eapiGlueWriteBlock(pDest, pBlock); if (rv != 0x100) { progressSetBankState(nBank, nChip, PROGRESS_UNTOUCHED); screenPrintSimpleDialog(apStrFlashWriteFailed); return 0; } progressSetBankState(nBank, nChip, PROGRESS_PROGRAMMED); return 1; }
void main(void) { uint8_t *pBuff; uint32_t addr, burst, pageMask, byteCount; /* Relocate vector table */ SCB->VTOR = 0x20000000; /* Disable interrupts */ __disable_irq(); /* Signal setup */ state.flashLoaderStatus = FLASHLOADER_STATUS_NOT_READY; state.debuggerStatus = DEBUGGERCMD_NOT_CONNECTED; /* Get device info including memory size */ setupEFM32(); /* Calculate size of available buffers. Two buffers are * used. Each buffer will fill up half of the remaining RAM. * Round down to nearest word boundry */ state.bufferSize = (state.sramSize - ((uint32_t) &flashBuffer - 0x20000000)) / 2; /* Only use full 4 bytes (1 word) */ state.bufferSize = state.bufferSize & 0xFFFFFFFC; /* Set the address of both buffers */ state.bufferAddress1 = (uint32_t) &flashBuffer; state.bufferAddress2 = ((uint32_t) &flashBuffer) + state.bufferSize; /* Signal setup complete. Ready to accept commands from programmer. */ state.flashLoaderStatus = FLASHLOADER_STATUS_READY; /* Poll debuggerStatus field to listen for commands * from programmer */ while(1) { /* Erase page(s) command */ if (state.debuggerStatus == DEBUGGERCMD_ERASE_PAGE) { /* Clear the flag to indicate that we are busy */ state.flashLoaderStatus = FLASHLOADER_STATUS_NOT_READY; state.debuggerStatus = DEBUGGERCMD_NONE; /* Enable flash writes */ MSC->WRITECTRL |= MSC_WRITECTRL_WREN; /* Get address of first page to erase */ uint32_t writeAddress = state.writeAddress1; /* Erase all pages in the given range */ for (addr = writeAddress; addr < writeAddress + state.numBytes1; addr += state.pageSize) { eraseSector( addr, state.pageSize ); } /* Disable flash writes */ MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN; /* Operation complete. Set flag to ready again. */ state.flashLoaderStatus = FLASHLOADER_STATUS_READY; } /* Mass erase command */ if (state.debuggerStatus == DEBUGGERCMD_MASS_ERASE) { /* Clear the flag to indicate that we are busy */ state.flashLoaderStatus = FLASHLOADER_STATUS_NOT_READY; state.debuggerStatus = DEBUGGERCMD_NONE; /* Enable flash writes */ MSC->WRITECTRL |= MSC_WRITECTRL_WREN; /* Unlock Mass Erase */ MSC->MASSLOCK = 0x631A; /* Erase entire flash */ doFlashCmd(MSC_WRITECMD_ERASEMAIN0 | MSC_WRITECMD_ERASEMAIN1); /* Reset lock */ MSC->MASSLOCK = 0; /* Disable flash writes again */ MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN; /* Operation complete. Set flag to ready again. */ state.flashLoaderStatus = FLASHLOADER_STATUS_READY; } /* Write command */ if (state.debuggerStatus == DEBUGGERCMD_WRITE_DATA1 || state.debuggerStatus == DEBUGGERCMD_WRITE_DATA2 ) { /* Select buffer based on write command */ bool useBuffer1 = state.debuggerStatus == DEBUGGERCMD_WRITE_DATA1 ? true : false; /* Clear the flag to indicate that we are busy */ state.flashLoaderStatus = FLASHLOADER_STATUS_NOT_READY; state.debuggerStatus = DEBUGGERCMD_NONE; pageMask = ~(state.pageSize - 1); /* Set up buffer, size and destination */ pBuff = useBuffer1 ? (uint8_t *)state.bufferAddress1 : (uint8_t *)state.bufferAddress2; byteCount = useBuffer1 ? state.numBytes1 : state.numBytes2; addr = useBuffer1 ? state.writeAddress1 : state.writeAddress2; /* Enable flash writes */ MSC->WRITECTRL |= MSC_WRITECTRL_WREN; /* Use double word writes if available */ if ( ( byteCount > 7 ) && writeDouble ) { if ( addr & 7 ) /* Start address not on 8 byte boundary ? */ { pgmWord( addr, *(uint32_t*)pBuff ); pBuff += 4; addr += 4; byteCount -= 4; } /* Enable double word writes */ MSC->WRITECTRL |= MSC_WRITECTRL_WDOUBLE; /* Writes as many words as possible using double word writes */ while ( byteCount > 7 ) { /* Max burst len is up to next flash page boundary. */ burst = MIN( byteCount, ( ( addr + state.pageSize ) & pageMask ) - addr ); /* Write data to flash */ burst -= pgmBurstDouble( addr, (uint32_t*)pBuff, burst ); pBuff += burst; addr += burst; byteCount -= burst; } /* Wait until operations are complete */ mscStatusWait( MSC_STATUS_BUSY, 0 ); /* Disable double word writes */ MSC->WRITECTRL &= ~MSC_WRITECTRL_WDOUBLE; } /* Writes all remaining bytes */ while ( byteCount ) { /* Max burst len is up to next flash page boundary. */ burst = MIN( byteCount, ( ( addr + state.pageSize ) & pageMask ) - addr ); /* Write data to flash */ pgmBurst( addr, (uint32_t*)pBuff, burst ); pBuff += burst; addr += burst; byteCount -= burst; } /* Wait until operations are complete */ mscStatusWait( MSC_STATUS_BUSY, 0 ); /* Disable flash writes */ MSC->WRITECTRL &= ~MSC_WRITECTRL_WREN; /* Operation complete. Set flag to ready again. */ state.flashLoaderStatus = FLASHLOADER_STATUS_READY; } } }
int main(void) { sysInfo = 0; SCS |= 0x01; FIODIR0 |= ((1<<21) | (1<<4) | (1<<11) | (1<<6) | (1<<23) | (1<<19) | (1<<17)); FIODIR0 |= (1<<12); FIOSET0 |= (1<<12); xx = 0x00; setSpeed(SPEED_30); lcd_init(0); serial_init(); startTimerIRQ(); startADC(); initKeys(); initSound(); startSoundIRQ(); initIR(); startIrIRQ(); RF_init(); startcc1100IRQ(); enableWOR(); initRTC(); startRtcIRQ(); enableIRQ(); testmenu_init(); init_menu(); initBacklight(); oldkeys[0] = keys[0]; oldkeys[1] = keys[0]; key_state = KEY_IDLE; set_font(BOLDFONT); BFS_Mount(); load_RC_setting(); load_RF_setting(); load_setting(); { struct RAWset_ RAWset; unsigned char x; unsigned long RAWcmdbase; RAWcmdbase = FLASH1_BASE +(secaddr[0]<<1); x=memcmp((void*)RAWcmdbase,"RC01",4); if(!x) { memcpy(&RAWset,(void *)RAWcmdbase,sizeof(struct RAWset_)); RAWset.name[7] = 0; BFS_SaveFile(BFS_ID_RAWslot0, sizeof(struct RAWset_), (unsigned char*) &RAWset); eraseSector(1,0); } } if (EncIsValid(irDevTab.device[irDevTab.active].encoder, irDevTab.device[irDevTab.active].set)) { setEncoder(irDevTab.device[irDevTab.active].encoder, irDevTab.device[irDevTab.active].set); } drawMainscreen(); ask_for_time(0); /* playSound((unsigned char*)sound1_data, sound1_len); waitSound(); playSound((unsigned char*)sound2_data, sound2_len); */ while (1) { if(keys[0] != oldkeys[0] || keys[1] != oldkeys[1]) { oldkeys[0] = keys[0]; oldkeys[1] = keys[1]; sysInfo |= 0x40; } switch(key_state) { case KEY_IDLE: if(sysInfo & 0x40) { sysInfo &= 0xBF; if(KEY_Betty) { setBacklight(BL_AUTO); menu_exec(&mainMenu); if (EncIsValid(irDevTab.device[irDevTab.active].encoder, irDevTab.device[irDevTab.active].set)) { setEncoder(irDevTab.device[irDevTab.active].encoder, irDevTab.device[irDevTab.active].set); } drawMainscreen(); } else if(KEY_2) { //setSpeed(SPEED_30); } else if(KEY_3) { //setSpeed(SPEED_60); } else if(KEY_A || KEY_B || KEY_C || KEY_D) { unsigned char x; //playSound((unsigned char*)sound3_data, sound3_len); x=0; if (KEY_B) x=1; if (KEY_C) x=2; if (KEY_D) x=3; if (EncIsValid(irDevTab.device[x].encoder, irDevTab.device[x].set)) { setBacklight(BL_AUTO); irDevTab.active = x; setEncoder(irDevTab.device[x].encoder, irDevTab.device[x].set); drawMainscreen(); } } /* else if(KEY_B) { } else if(KEY_C) { // playSound((unsigned char*)sound1_data, sound1_len); } else if(KEY_D) { // playSound((unsigned char*)sound2_data, sound2_len); }*/ if((keys[0] != 0) || (keys[1] != 0)) key_state = KEY_PRESS; } break; case KEY_PRESS: irSend(getCode()); key_state = KEY_HOLD; // autorepeat = 0; break; case KEY_HOLD: // if(autorepeat >= AUTO_TIMEOUT) irRepeat(); if(keys[0] == 0 && keys[1] == 0) key_state = KEY_RELEASE; break; case KEY_RELEASE: irStop(); key_state = KEY_IDLE; break; } if(serial_tstc() > 0) { i = serial_getc(); if(i=='.') { serial_puts("HELO"); } else if(i=='0') { setBacklight(0x00); // pwm value } else if(i=='1') { setBacklight(0x1F); // pwm value } else if(i=='2') { setBacklight(0x3F); // pwm value } else serial_putc(i); } if ((bl_val == 0) && (key_state == KEY_IDLE) && !((FIOPIN0 & (1<<30)) == 0) && (((RFstatus & (WORrxon | RXenabled)) == 0))) { EXTINT = 0x08; PCON = 0x02; PLLFEED = 0xAA; PLLFEED = 0x55; } if (timeInfo & timechanged) { printTime(86,152,(struct time_ *)&time); printDate(0,152,(struct date_ *)&date,0); timeInfo &= ~timechanged; } } return 0; }