Occasional problem with IAP EEPROM in LPC11U68

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Occasional problem with IAP EEPROM in LPC11U68

ソリューションへジャンプ
2,462件の閲覧回数
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.

ラベル(2)
1 解決策
2,032件の閲覧回数
pavelhudecek
Contributor III

How can i mark this discussion as solved?

元の投稿で解決策を見る

0 件の賞賛
返信
7 返答(返信)
2,033件の閲覧回数
pavelhudecek
Contributor III

How can i mark this discussion as solved?

0 件の賞賛
返信
2,032件の閲覧回数
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.

2,032件の閲覧回数
pavelhudecek
Contributor III

Thank You, it is optimal solution.

0 件の賞賛
返信
2,032件の閲覧回数
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.

2,032件の閲覧回数
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 件の賞賛
返信
2,032件の閲覧回数
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 件の賞賛
返信
2,032件の閲覧回数
pavelhudecek
Contributor III

Solution found:

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