LPC1778: Problem using EEPROM and IAP calls in the same application

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1778: Problem using EEPROM and IAP calls in the same application

827 Views
carstengroen
Senior Contributor II

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 ??

Labels (1)
0 Kudos
2 Replies

479 Views
carstengroen
Senior Contributor II

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 ?

0 Kudos

479 Views
jeremyzhou
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos