I have a problem with the combined use of IAP and EEPROM of the LPC1778.
Both works fine when used separately, but once I mix them, I get problems with the IAP interface.
I have narrowed it down quite a bit and think I know where the problem is, I just don't know how to avoid it...
First I do EEPROM_init and EEPROM_read.
After this I do IAP erase of a Flash sector. When the IAP command 0x52 (erase) is issued, I get a return value of 11 back (Flash interface busy).
I have narrowed it down to the EEPROM_Read function, I have included the EEPROM_read code here:
void EEPROM_Read(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count)
{
uint32_t i;
LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG));
LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset);
return; // IAP calls will work when returning here
if(mode == MODE_8_BIT)
LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH;
return; // IAP calls will NOT work when returning here
.
.
.
.
If I return from the EEPROM_Read function in the first return in line 7, the following IAP commands works fine.
If I return from the read function at the second return (line 10) the IAP commands works fine afterwards.
So it seems that the LPC_EEPROM->CMD assignment in line 9 is the problem.
So, there must be some dependency between the EEPROM and IAP interfaces ?
And if so, is there a "magic" value I can send to the EEPROM CMD register to "release" it so the IAP functions will work afterwards ??
Maybe NXP is off on vacation :smileywink:
So I will answer my question myself. Searching thru the archives, it seems that the EEPROM_Read() function has an error, I tried fixing that but this did not do it...
So, after each EEPROM_Read() I do a
LPC_EEPROM->INT_CLR_STATUS = ((1<<26)|(1<<28));
This clears the two status bits in the EEPROM engine, and voila, the IAP (Flash) functions starts to work. This is NOT exactly something that is mentioned in the users manuals etc (the influence the EEPROM peripheral has on the FLASH peripheral), maybe that would be something to include ?
Hi Carsten Groen,
Please using the following code instead of the previous EEPROM_Read function.
/*********************************************************************//**
* @brief Read data to EEPROM at specific address
* @param[in]
* data buffer that contain data that will be written to buffer
* mode Read mode, should be:
* - MODE_8_BIT : read 8 bit mode
* - MODE_16_BIT : read 16 bit mode
* - MODE_32_BIT : read 32 bit mode
* count number read data (bytes)
* @return data buffer that contain data that will be read to buffer
**********************************************************************/
void EEPROM_Read(uint16_t page_offset, uint16_t page_address, void* data, EEPROM_Mode_Type mode, uint32_t count)
{
uint32_t i;
uint8_t *tmp8 = (uint8_t *)data;
uint16_t *tmp16 = (uint16_t *)data;
uint32_t *tmp32 = (uint32_t *)data;
LPC_EEPROM->INT_CLR_STATUS = ((1 << EEPROM_ENDOF_RW)|(1 << EEPROM_ENDOF_PROG));
LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset);
if(mode == MODE_8_BIT)
LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH;
else if(mode == MODE_16_BIT){
LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH;
//check page_offset
if((page_offset &0x01)!=0)
return;
}
else{
LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH;
//page_offset must be a multiple of 0x04
if((page_offset & 0x03)!=0)
return;
}
//read and store data in buffer
for(i=0;i<count;i++){
if(mode == MODE_8_BIT){
*tmp8 = (uint8_t)(LPC_EEPROM -> RDATA);
tmp8++;
page_offset +=1;
}
else if (mode == MODE_16_BIT)
{
*tmp16 = (uint16_t)(LPC_EEPROM -> RDATA);
tmp16++;
page_offset +=2;
}
else{
*tmp32 = (uint32_t)(LPC_EEPROM ->RDATA);
tmp32++;
page_offset +=4;
}
while(!((LPC_EEPROM->INT_STATUS >> EEPROM_ENDOF_RW)&0x01));
LPC_EEPROM->INT_CLR_STATUS = (1 << EEPROM_ENDOF_RW);
if((page_offset >= EEPROM_PAGE_SIZE) && (i < count - 1)) {
page_offset = 0;
page_address++;
LPC_EEPROM->ADDR = EEPROM_PAGE_ADRESS(page_address)|EEPROM_PAGE_OFFSET(page_offset);
if(mode == MODE_8_BIT)
LPC_EEPROM->CMD = EEPROM_CMD_8_BIT_READ|EEPROM_CMD_RDPREFETCH;
else if(mode == MODE_16_BIT)
LPC_EEPROM->CMD = EEPROM_CMD_16_BIT_READ|EEPROM_CMD_RDPREFETCH;
else
LPC_EEPROM->CMD = EEPROM_CMD_32_BIT_READ|EEPROM_CMD_RDPREFETCH;
}
}
}
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------