//###################### P U B L I C F U N C T I O N S #######################
void initEMC(void)
{
//Power up lcd peripheral
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCEMC, true);
configureEMCPins();
//Disable all dynamic memory features
LPC_EMC->DynamicControl = 0;
LPC_EMC->Control = 0; //Disable peripheral
//Set little endian format
LPC_EMC->Config = 0;
//Use half clock as CPU 60 MHz
LPC_SC->EMCCLKSEL = 1;
//Disable automatic address shifting
//LPC_SC->SCS |= (1 << 0);
configureEMCForStaticMemory(&extProgFlash);
LPC_EMC->Control |= 1; //Enable the EMC
for(volatile uint32_t i = 0; i < 99999; i++) {}
}
//##################### P R I V A T E F U N C T I O N S ######################
static void configureEMCForStaticMemory(const EmcStaticMemoryConfig* conf)
{
//Set Extende wait time out
//0x0 = 16 clock cycles.
//0x1 - 0x3FF = (n+1) x16 clock cycles.
if(conf->extWait == EMC_MEM_EXTENDED_WAIT_ENABLE)
LPC_EMC->StaticExtendedWait = 0;
*statMemChanReg[conf->chan].StaticConfig = conf->memWidth;
*statMemChanReg[conf->chan].StaticConfig |= conf->pageMode;
*statMemChanReg[conf->chan].StaticConfig |= conf->chipSel;
*statMemChanReg[conf->chan].StaticConfig |= conf->laneState;
*statMemChanReg[conf->chan].StaticConfig |= conf->extWait;
*statMemChanReg[conf->chan].StaticConfig |= conf->buffer;
*statMemChanReg[conf->chan].StaticConfig |= conf->wrProt;
//Write enable delay: chip select -> write enable.
//0x0 = One EMCCLK cycle delay between assertion of chip select and we
//0x1 - 0xF = (n + 1) * EMCCLK cycle delay.
*statMemChanReg[conf->chan].StaticWaitWen = conf->writeEnableDelay;
//Output enable delay: chip select or address change, whichever is later,
// to the output enable.
//0x0 = No delay (POR reset value).
//0x1 - 0xF = n cycle delay. The delay is WAITOEN x tEMCCLK.
*statMemChanReg[conf->chan].StaticWaitOen = conf->readEnableDelay;
//Read delay: chip select -> read access
//first read only: 0x0 - 0x1E = (n + 1) * EMCCLK cycles for read accesses.
//For non-sequential reads, the wait state time is (WAITRD + 1) x tEMCCLK.
//0x1F = 32 EMCCLK cycles for read accesses.
*statMemChanReg[conf->chan].StaticWaitRd = conf->readDataDelay;
//Page Mode ready delay:
//0x0 - 0x1E = (n + 1) * EMCCLK cycle read access time
//0x1F = 32 EMCCLK cycle read access time.
*statMemChanReg[conf->chan].StaticWaitPage = conf->pageModeDelay;
//Write delay: chip select -> write access
//0x0 - 0x1E = (n + 2) * EMCCLK cycle write access time.
//0x1F = 33 EMCCLK cycle write access time.
*statMemChanReg[conf->chan].StaticWaitWr = conf->writeDataDelay;
////Turn round delay: number of bus turnaround cycles
//0x0 - 0xE = (n + 1) * EMCCLK turn-around cycles.
//0xF = 16 EMCCLK turn-around cycles.
*statMemChanReg[conf->chan].StaticWaitTurn = conf->waitTurnDelay;
}
static void configureEMCPins(void)
{
//OE
PINSEL_ConfigPin(4, 24, 1);
//WE
PINSEL_ConfigPin(4, 25, 1);
//BLE
PINSEL_ConfigPin(4, 26, 1);
//BHE
PINSEL_ConfigPin(4, 27, 1);
//CS0
PINSEL_ConfigPin(4, 30, 1);
//CS1
PINSEL_ConfigPin(4, 31, 1);
//D0_15
for(uint8_t dataPin = 0; dataPin < 16; dataPin ++)
PINSEL_ConfigPin(3, dataPin, 1);
//A0_21
for(uint8_t addrPin = 0; addrPin < 23; addrPin ++)
PINSEL_ConfigPin(4, addrPin, 1);
} |