Occasional problem with IAP EEPROM in LPC11U68

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

Occasional problem with IAP EEPROM in LPC11U68

Jump to solution
2,313 Views
pavelhudecek
Contributor III

Hi,

i use these functions:

static uint32_t iapCmd[5], iapRes[4];

uint32_t iapEEread(uint16_t eAdr, uint8_t *data, uint16_t bytes) {

   iapCmd[0] = IAP_EEPROM_READ;

   iapCmd[1] = (uint32_t) eAdr;

   iapCmd[2] = (uint32_t) data;

   iapCmd[3] = (uint32_t) bytes;

   iapCmd[4] = SystemCoreClock / 1000;

   LED_d3=1;

   iap_entry(iapCmd, iapRes);

   LED_d3=0;

   return iapRes[0];

}

uint32_t iapEEwrite(uint16_t eAdr, uint8_t *data, uint16_t bytes) {

   iapCmd[0] = IAP_EEPROM_WRITE;

   iapCmd[1] = (uint32_t) eAdr;

   iapCmd[2] = (uint32_t) data;

   iapCmd[3] = (uint32_t) bytes;

   iapCmd[4] = SystemCoreClock / 1000;

   LED_d3=1;

   iap_entry(iapCmd, iapRes);

   LED_d3=0;

   return iapRes[0];

}

Usually it is working properly, but sometimes (approximately 10 % if hundreds bytes writed, for example 353 bytes, but not if tens bytes writed, and 2 incidents in reading) a problem occurred:

Program stops at address 0xfffffffe, and LED stay ON.

iap_entry is from romapi_11u6x.h

builded in LPCXpresso v8.1.4 [Build 606] [2016-03-14]

SystemCoreClock is from startup set to 48000000.LPC11U68JBD100 is on custom board, blocked with 100n+10n 0805 capacitors on every supply pins, and two 22uF caps near. Supplied from 3,0V LDO.

Labels (2)
1 Solution
1,883 Views
pavelhudecek
Contributor III

How can i mark this discussion as solved?

View solution in original post

0 Kudos
Reply
7 Replies
1,884 Views
pavelhudecek
Contributor III

How can i mark this discussion as solved?

0 Kudos
Reply
1,883 Views
ursaminor
Contributor II

I can't help with marking this topic as solved, but you probably want to try this out first anyway:

LPC1100/LPC1300 EEPROM Library | www.LPCware.com 

(The link is to the obsolete LPCware site, can't find it in the new forum...)

After all, you don't have to disable interrupts for EEPROM access.

1,883 Views
pavelhudecek
Contributor III

Thank You, it is optimal solution.

0 Kudos
Reply
1,883 Views
pavelhudecek
Contributor III

I've found: The problem is caused by an interrupt.

Error not occurred afther these change:

LED_d3=1;

__disable_irq();

iap_entry(iapCmd, iapRes);

__enable_irq();

LED_d3=0;

But this solution I dislike. Functions are sometimes called upon already disabled interrupt and it is undesirable to be enabled in this case.

How can I detect whether the interrupt is enabled / disabled?

Thanks.

1,883 Views
avt
Contributor III

int __disable_irq(void); returns the value the IRQ interrupt mask has in the PSR before disabling IRQ interrupts. 

So so check the return value to see if it was enabled or not...

0 Kudos
Reply
1,883 Views
pavelhudecek
Contributor III

Thank you, but this is not working. If I try to find declaration of __disable_irq, I see this:

__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)

{

__ASM volatile ("cpsid i" : : : "memory");

}

0 Kudos
Reply
1,883 Views
pavelhudecek
Contributor III

Solution found:

__get_PRIMASK() returns 1/0 at depends on interrupt disabled/enabled.