//------------------------------------------------------------------------------ /// Performs the low-level initialization of the chip. //------------------------------------------------------------------------------ void LowLevelInit(unsigned int clockConfigEnable) { unsigned char i; pllConfiguration pll; mckrConfiguration mckr; if (clockConfigEnable) { // Switch MCK to Slow clock PMC_SwitchMck2SlowClock(); // enable Main oscillator PMC_EnableMainOsc(); // Then, cofigure PLLA and switch clock // MCK = 18.432MHz * 73 / 14 / 1 / 2 = 48MHz -> 0x10483F0E pll.mul = 0x49; pll.div = 0x0E; pll.usbdiv = 0; pll.pllout = 0; mckr.prescaler = AT91C_PMC_PRES_CLK; mckr.mdiv = AT91C_PMC_MDIV_2; mckr.plldiv2 = 0; PMC_ConfigureMckWithPlla(&pll, &mckr); } /* Initialize AIC */ AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; for (i = 1; i < 31; i++) { AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler; // Unstack nested interrupts for (i = 0; i < 8 ; i++) { AT91C_BASE_AIC->AIC_EOICR = 0; } // Enable Debug mode //AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT; /* Watchdog initialization *************************/ AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; /* Remap *******/ BOARD_RemapRam(); // Disable RTT and PIT interrupts (potential problem when program A // configures RTT, then program B wants to use PIT only, interrupts // from the RTT will still occur since they both use AT91C_ID_SYS) AT91C_BASE_RTTC->RTTC_RTMR &= ~(AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN); AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN; #if defined(norflash) BOARD_ConfigureNorFlash(BOARD_NORFLASH_DFT_BUS_SIZE); #endif }
//------------------------------------------------------------------------------ // Exported functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Performs the low-level initialization of the chip. Initialisation depends /// on where the application is executed: /// - in sdram: it means that sdram has previously been initialized. No further /// initialization is required. /// - in sram: PLL shall be initialized in LowLevelInit. Other initializations /// can be done later by the application. /// - in norflash: LowLevelInit can't be executed in norflash because SMC /// settings can't be changed while executing in external flash. /// LowLevelInit shall be executed in internal sram. It initializes /// PLL and SMC. /// This function also reset the AIC and disable RTT and PIT interrupts //------------------------------------------------------------------------------ void LowLevelInit(unsigned int clockConfigEnable) { unsigned char i; pllConfiguration pll; mckrConfiguration mckr; if (clockConfigEnable) { // Switch MCK to Slow clock PMC_SwitchMck2SlowClock(); // enable Main oscillator PMC_EnableMainOsc(); // Then, cofigure PLLA and switch clock // MCK = 18.432MHz * 73 / 14 / 1 / 2 = 48MHz -> 0x10483F0E pll.mul = 0x49; pll.div = 0x0E; pll.usbdiv = 0; pll.pllout = 0; mckr.prescaler = AT91C_PMC_PRES_CLK; mckr.mdiv = AT91C_PMC_MDIV_2; mckr.plldiv2 = 0; PMC_ConfigureMckWithPlla(&pll, &mckr); } /* Initialize AIC ****************/ AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; for (i = 1; i < 31; i++) { AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler; // Unstack nested interrupts for (i = 0; i < 8 ; i++) { AT91C_BASE_AIC->AIC_EOICR = 0; } /* Watchdog initialization *************************/ AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; /* Remap *******/ BOARD_RemapRam(); #if defined(norflash) BOARD_ConfigureNorFlash(BOARD_NORFLASH_DFT_BUS_SIZE); #endif }
//------------------------------------------------------------------------------ // Global functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int bufferSize, bufferAddr, memoryOffset; unsigned int eraseStartSector, eraseEndSector, bytesToErase; unsigned int i; const unsigned char busWidth[3] = {FLASH_CHIP_WIDTH_8BITS, FLASH_CHIP_WIDTH_16BITS, FLASH_CHIP_WIDTH_32BITS}; unsigned int comType = 0; TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); PIO_Configure(pPinsNf, PIO_LISTSIZE(pPinsNf)); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- NorFlash Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); TRACE_INFO("INIT command\n\r"); norFlash.norFlashInfo.baseAddress = BOARD_NORFLASH_ADDR; // Check device CFI and get Vendor setting from it. TRACE_INFO("\t Common Flash Interface detecting...\n\r"); for (i = 0; i < 3; i++) { // Configure SMC for Norflash accesses TRACE_INFO("\t Try bus width %d bits\n\r", busWidth[i] * 8); BOARD_ConfigureNorFlash(busWidth[i] * 8); if (!NorFlash_CFI_Detect(&norFlash, busWidth[i])) break; } if (norFlash.norFlashInfo.cfiCompatible == 0) { pMailbox->status = APPLET_DEV_UNKNOWN; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; TRACE_INFO("Device Unknown\n\r"); goto exit; } else { TRACE_INFO("manufactureID : 0x%08x, deviceID : 0x%08x\n\r", NORFLASH_ReadManufactoryID(&norFlash), NORFLASH_ReadDeviceID(&norFlash)); NORFLASH_ReadManufactoryID(&norFlash); // Get device parameters memSize = NorFlash_GetDeviceSizeInBytes(&(norFlash.norFlashInfo)); pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); #if defined (at91sam7se) pMailbox->argument.outputInit.bufferAddress = 0x21000000; #endif bufferSize = NorFlash_GetDeviceMaxBlockSize(&(norFlash.norFlashInfo)); if (bufferSize > MAX_BUFFER_SIZE) bufferSize = MAX_BUFFER_SIZE; pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = memSize; TRACE_INFO("bufferSize : %d memorySize : %d bufferAddr: 0x%x \n\r", pMailbox->argument.outputInit.bufferSize, pMailbox->argument.outputInit.memorySize, (unsigned int) &end); } } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bufferSize = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bufferSize); if (memoryOffset < lastErasedOffset) { lastErasedSector = 0xFFFF; } lastErasedOffset = memoryOffset + bufferSize - 1; eraseStartSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), memoryOffset); eraseEndSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), lastErasedOffset); do { TRACE_INFO("lastErasedSector %d \n\r", lastErasedSector); if (eraseStartSector > lastErasedSector || lastErasedSector == 0xFFFF) { TRACE_INFO("Sector Erase in sector %d \n\r", eraseStartSector); if (NORFLASH_EraseSector( &norFlash, NorFlash_GetDeviceSectorAddress(&(norFlash.norFlashInfo),eraseStartSector))) { TRACE_INFO("Sector Erase failed in sector %d \n\r", eraseStartSector); pMailbox->status = APPLET_FAIL; goto exit; } lastErasedSector = eraseStartSector; } eraseStartSector++; } while (eraseStartSector <= eraseEndSector); // Write the buffer contents. if (NORFLASH_WriteData(&norFlash, memoryOffset, (unsigned char *)bufferAddr, bufferSize)) { TRACE_INFO("Program failed \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputWrite.bytesWritten = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bufferSize); NORFLASH_ReadData(&norFlash, memoryOffset, (unsigned char *) bufferAddr, bufferSize); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // BUFFER ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_BUFFER_ERASE) { TRACE_INFO("BUFFER ERASE command\n\r"); memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset; bytesToErase = NorFlash_GetDeviceMaxBlockSize(&(norFlash.norFlashInfo)) * 2; bytesToErase = ((memoryOffset + bytesToErase) > memSize) ? (memSize - memoryOffset): bytesToErase; lastErasedOffset = memoryOffset + bytesToErase; eraseStartSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), memoryOffset); eraseEndSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), lastErasedOffset); for (i = eraseStartSector; i <= eraseEndSector; i++) { if (NORFLASH_EraseSector( &norFlash, NorFlash_GetDeviceSectorAddress(&(norFlash.norFlashInfo),i))) { TRACE_INFO("Sector Erase failed in sector %d \n\r", i); pMailbox->status = APPLET_FAIL; goto exit; } lastErasedSector = i; } pMailbox->argument.outputBufferErase.bytesErased = bytesToErase; TRACE_INFO("Buffer Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command\n\r"); if (NORFLASH_EraseChip(&norFlash)) { TRACE_INFO("Full Erase failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Full Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit : // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ // Exported functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Performs the low-level initialization of the chip. Initialisation depends /// on where the application is executed: /// - in sdram: it means that sdram has previously been initialized. No further /// initialization is required. /// - in sram: PLL shall be initialized in LowLevelInit. Other initializations /// can be done later by the application. /// - in norflash: LowLevelInit can't be executed in norflash because SMC /// settings can't be changed while executing in external flash. /// LowLevelInit shall be executed in internal sram. It initializes /// PLL and SMC. /// This function also reset the AIC and disable RTT and PIT interrupts //------------------------------------------------------------------------------ void LowLevelInit( void ) { unsigned char i; // If already running in external ram, PLL settings have already been done #if !defined(sdram) && !defined(ddram) && !defined(bcram) /* Initialize main oscillator ****************************/ AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); // Initialize PLLA at 200MHz AT91C_BASE_PMC->PMC_PLLAR = BOARD_CKGR_PLLA | BOARD_PLLACOUNT | BOARD_MULA | BOARD_DIVA; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)); // Initialize PLLB for USB usage (if not already locked) if (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB)) { AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV | BOARD_CKGR_PLLB | BOARD_PLLBCOUNT | BOARD_MULB | BOARD_DIVB; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB)); } /* Switch to fast clock **********************/ /* Wait for the master clock if it was already initialized */ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); /* Switch to main oscillator + prescaler */ AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); // Select PLLA AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); #endif //#if !defined(sdram) && !defined(ddram) && !defined(bcram) /* Initialize AIC ****************/ AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; for (i = 1; i < 31; i++) { AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler; // Unstack nested interrupts for (i = 0; i < 8 ; i++) { AT91C_BASE_AIC->AIC_EOICR = 0; } /* Watchdog initialization *************************/ AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; /* Remap *******/ BOARD_RemapRam(); /* User reset is deleted (workaround Issue 5387) */ AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000; // Disable RTT and PIT interrupts (potential problem when program A // configures RTT, then program B wants to use PIT only, interrupts // from the RTT will still occur since they both use AT91C_ID_SYS) AT91C_BASE_RTTC->RTTC_RTMR &= ~(AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN); AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN; #if defined(norflash) BOARD_ConfigureNorFlash(BOARD_NORFLASH_DFT_BUS_SIZE); #endif }
//------------------------------------------------------------------------------ // Exported functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Performs the low-level initialization of the chip. Initialisation depends /// on where the application is executed: /// - in sdram: it means that sdram has previously been initialized. No further /// initialization is required. /// - in sram: PLL shall be initialized in LowLevelInit. Other initializations /// can be done later by the application. /// - in norflash: LowLevelInit can't be executed in norflash because SMC /// settings can't be changed while executing in external flash. /// LowLevelInit shall be executed in internal sram. It initializes /// PLL and SMC. /// This function also reset the AIC and disable RTT and PIT interrupts //------------------------------------------------------------------------------ void LowLevelInit(void) { unsigned char i; #if !defined(ddram) /* Initialize main oscillator ****************************/ AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); /* Initialize PLLA */ AT91C_BASE_PMC->PMC_PLLAR = BOARD_CKGR_PLLA | BOARD_PLLACOUNT | BOARD_MULA | BOARD_DIVA; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)); /* Wait for the master clock if it was already initialized */ while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); /* Switch to fast clock **********************/ /* Switch to main oscillator + prescaler */ AT91C_BASE_PMC->PMC_MCKR = BOARD_PRESCALER; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); /* Switch to PLL + prescaler */ AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); #endif /* Initialize AIC ****************/ AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler; for (i = 1; i < 31; i++) { AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler; // Unstack nested interrupts for (i = 0; i < 8 ; i++) { AT91C_BASE_AIC->AIC_EOICR = 0; } /* Watchdog initialization *************************/ AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; /* Remap *******/ BOARD_RemapRam(); // Disable RTT and PIT interrupts (potential problem when program A // configures RTT, then program B wants to use PIT only, interrupts // from the RTT will still occur since they both use AT91C_ID_SYS) AT91C_BASE_RTTC->RTTC_RTMR &= ~(AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN); AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN; #if defined(norflash) BOARD_ConfigureNorFlash(BOARD_NORFLASH_DFT_BUS_SIZE); #endif }