EEPROM read

Go To Last Post
30 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi 

I am using below code to EEPROM read 

EEPROM_read:
; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_read
; Set up address (r18:r17) in address register
out EEARH, r18
out EEARL, r17
; Start eeprom read by writing EERE
sbi EECR,EERE
; Read data from data register
in r16,EEDR
ret

 

But after compiling I am getting error for this line of code -sbic EECR,EEWE as operand out of range

I am using Atmel studio 7.0 with GCC compiler for 

please help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which MCU?

 

Odds are, in the chip you are using, EECR is outside the range of "special" registers where sbic will work (same range as for in and out operations). .

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Mon. Jan 2, 2017 - 07:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is ATmega8515

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any other answers?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes !

It works for me.

But I tested using Atmel studio 7.0 with Atmel Assembler NOT GCC compiler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks

But my entire code is in C language only EEPROM read and write is in assembly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SO why not do the EEPROM read in 'C', too??

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

execution time is fast and lesser instruction cycles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seriously?

 

The EEPROM read is the only bottleneck in your entire system?!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have solution for this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Ah! Another case of Premature Optimisation

One of many articles of this subject: https://en.wikipedia.org/wiki/Program_optimization#When_to_optimize

 

yogendra1 wrote:
Do you have solution for this?

Copy the C example from the datasheet. Test the code and move on. Believe me - speed of execution almost certainly won't be a problem here.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for you suggestion.

I tested the C example it works

But we want know why it wont work for 2 asm instruction

are there any Atmel restrictions ?

Question of moving on then we can move with other good controller which dont have such short comings

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yogendra1 wrote:
we want know why it wont work for 2 asm instruction

Surely, the error message you initially posted tells you clearly & explicitly why it's not allowed:

 

operand out of range

Have you looked at the legal operand ranges for sbic ?

 

Have you checked the values of EECR and EEWE ?

 

are there any Atmel restrictions 

They will be detailed in the Chip and/or Instruction Set documentation

 

other good controller which dont have such short comings

All controllers have limitations of one sort or another; AVR is a relatively "simple" architecture - so is bound to have more restrictions than "bigger" processors...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi ALL

Got it we have to include

#define __SFR_OFFSET 0

without this, it selects full range of SFR register location

 

Thank you all for your support

such type of discussion will help in improving our knowledge and even improving bugs in controller if any

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yogendra1 wrote:
improving bugs in controller

 

???

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

yogendra1 wrote:
execution time is fast and lesser instruction cycles

Have you examined the EEPROM facilities provided for your toolchain of choice -- which apparently is the version of GCC integrated into Atmel Studio 7 ?  Is that code really slower than your version?

 

You need to show more context -- more details -- for us to answer your repeated request for answers.  Give us all the information we need at once:

 

-- AVR model

-- Toolchain and version

-- Clock speed

-- Complete test program

-- Description of what you expect, and what is happening

 

Then you will get "solutions".  [and still discussion of why you think the toolchain-provided facilities, created and vetted by experts, are not optimal]

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yogendra1 wrote:
But we want know why it wont work for 2 asm instruction are there any Atmel restrictions ?
yogendra1 wrote:
Hi ALL Got it we have to include #define __SFR_OFFSET 0 without this, it selects full range of SFR register location

>>You<< have chosen to use the GCC toolchain.

 

Thus, >>you<< have to understand the conventions of the toolchain and language that >>you<< have chosen to use.

 

In this particular case, besides not giving complete information, you chose to use some chode written for a different toolchain.  Your first results wern't encouraging, were they?

 

And you (and your team?) are railing against "buggy" microcontrollers/toolchains.  With approaches as you are taking, I'll be surprised if you don't run into similar situations no matter what architecture you are working with.

 

I just posted CodeVision's EEPROM byte read routine in https://www.avrfreaks.net/comment...

004636 99f9      	SBIC EECR,EEWE
004637 cffe      	RJMP __EEPROMRDB
004638 93ff      	PUSH R31
004639 b7ff      	IN   R31,SREG
00463a 94f8      	CLI
00463b bda1      	OUT  EEARL,R26
00463c bdb2      	OUT  EEARH,R27
00463d 9af8      	SBI  EECR,EERE
00463e b5e0      	IN   R30,EEDR
00463f bfff      	OUT  SREG,R31
004640 91ff      	POP  R31
004641 9508      	RET

Does it have more instructions and more cycles than your posted code?  YES IT DOES!  Does it also take care of disabling interrupts during the critical time, as the datasheet says, so that your application will work properly?  YES IT DOES!  Does your code do that?  NO IT DOES NOT.

 

So indeed, you only save those cycles and still have a properly functioning application only if your application never invokes your code with global interrupts enabled.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can understand waiting for a previous write to complete.    Before you can issue any other EEPROM commands.   (Or SPM writes)

 

I can understand the reason for disabling interrupts when you are using a critical 4-cycle sequence to initiate a write.    An intervening ISR() would upset the 4-cycle restriction.

 

I do not see why you should disable interrupts when you read the EEPROM.

 

Regarding the Original Post.   I am sure that GCC, CV, ... library code will use an efficient ASM sequence.

I doubt if an app will notice any difference between C or any other language.

 

Reading is quick.   Writing is slow.    It is always worth using Update instead of Write.   It avoids a write when the EEPROM already has the desired value.   This improves throughput and is kind to the EEPROM endurance.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I do not see why you should disable interrupts when you read the EEPROM.

 

I used to know the answer to that.  But I'm older now, and we tend to forget things. ;)

 

I generally avoid EEPROM operations in ISRs. (I don't want the chance of being "stuck" for a few milliseconds.)  But in the general case, doesn't that help to make the EEPROM operation atomic?

 

Is the answer to your question "because the datasheet says so"?

The next code examples show assembly and C functions for reading the EEPROM. The exam-ples assume that interrupts are controlled so that no interrupts will occur during execution of
these functions.

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Jan 2, 2017 - 10:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You normally initiate a write (with interrupts disabled).

Once the actual write operation has started,  you can re-enable the interrupts.

 

Otherwise there is little point in having an EEPROM IRQ.

 

Perhaps someone knows a reason for disabling before a read.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EEWE is the bit 1 of register EECR.  Its value is 0x02.  The SBIC instruction needs to have the bit position value instead of the bit value.  Try using: sbic EECR , (1<<EEWE).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EEWE is the bit 1 of register EECR.  Its value is 0x02.  The SBIC instruction needs to have the bit position value instead of the bit value.  Try using: sbic EECR , (1<<EEWE).

???  I don't quite know what you are getting at here.  The code I posted from CV, as well as the OP's fragment, are correct as far as I know.  In my builds, EEWE has a value of 1.  SBIC takes a bit number, 0-7.

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I agree with Lee about SBIC.
.
I would love to know about READ and interrupts. I suspect that it is a lovingly pasted artifact from one datasheet to the next.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I would love to know about READ and interrupts. I suspect that it is a lovingly pasted artifact from one datasheet to the next.

In the general case, it would be needed if there are EEPROM operations in ISR(s), right?  To keep the reads atomic.

 

Writes in ISR, or some combination, are left as an exercise for the student.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah-ha.   Yes,   I suppose this is possible.    A regular EE_RDY_vect ISR() might service a current write,  and start a fresh write.

 

However,   the READ sequence already checks for the EEWE bit.   Any EE_RDY scheme would have to complete first.

 

Perhaps a Timer interrupt could fire in the middle of the READ sequence and start an EEPROM operation.

 

Somehow I think that the author would have a pretty good idea whether she is changing EEPROM registers inside an unrelated ISR().    And yes,   she would disable interrupts.    But she would not mix interrupt-driven and polled access in the same application.

 

You always ensure machine Registers and Status are preserved in an ISR().

If you choose to modify Special Function Registers in an ISR(),   you are normally "aware".

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Perhaps a Timer interrupt could fire in the middle of the READ sequence and start an EEPROM operation.

I had an app a while back that did a bit of work in an ISR.  At first, I had it use EEPROM for a small lookup table.  But then I caught myself and changed it...

 

1)  Even if everything ends up "clean", there still might be a few millisecond delay waiting for EEWE to clear if a mainline EEPROM write had just started when the interrupt hit.  Many apps may not want, or cannot tolerate, that.

 

2)  Let's take my small lookup table example and say it is just one byte.  Examining the CV version:

 

004636 99f9      	SBIC EECR,EEWE
004637 cffe      	RJMP __EEPROMRDB
004638 93ff      	PUSH R31
004639 b7ff      	IN   R31,SREG
00463a 94f8      	CLI
00463b bda1      	OUT  EEARL,R26
00463c bdb2      	OUT  EEARH,R27
00463d 9af8      	SBI  EECR,EERE
00463e b5e0      	IN   R30,EEDR
00463f bfff      	OUT  SREG,R31
004640 91ff      	POP  R31
004641 9508      	RET

... and remove the I-bit handling 4638,39,40 and 3f,40 lines.  The mainline is doing an EEPROM read, and the interrupt hits after line 463b.  You can see now that when the mainline resumes at 463c that EEARL could well have a different value.  A non-atomic operation and you end up with fruit salad.

 

I think it could get even worse with an EEPROM write in the ISR.  I think there is a hole here, even with the code shown.  Mainline EEPROM read is being done, and an interrupt hits on line 4638 or 4639 after the EEWE test passes.  The ISR starts an EEPROM write of a byte, and completes and returns to mainline code.  BUT THAT BYTE ERASE/WRITE IS STILL IN PROCESS.  Who knows what the result of the read (and maybe the write with EEAR changed out from underneath it) will be.

 

Short answer, IMO/IME:  Don't do AVR8 EEPROM operations inside ISRs without thinking through the above thoroughly.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Go on.   There are often ISR()s that change SFRs.    You just constrain yourself to obey simple rules.

e.g.   if you have interrupt driven USART,  you don't go reading/writing to the USART registers in foreground code.

 

Regarding the EE_RDY_vect.    If the EEPROM write completes during the SBIC/RJMP loop,  the interrupt fires during the loop too.

 

Mind you,  if I was using EE_RDY to initiate a new write,   I would definitely use CLI.

It only costs 4-cycles with a scratch register.   8-cycles if you PUSH/POP.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
There are often ISR()s that change SFRs.

???  Well, yes, of course there are.  But what does that have to do with this thread?

 

I wasn't talking about the EE_RDY vector.  IIRC my "lookup table" example had to do with a byte-wide EEPROM table used in ADC_COMPLETE.  But whatever...my analysis above stands: 

 

--If you are going to do EEPROM reads in ISR and mainline, then you need the CLI protection in your mainline EEPROM read operations.  I thought I demonstrated that sufficiently above.  And that answers your query about "Why?", right?

 

--If you are going to do EEPROM writes in ISR, and EEPROM reads in mainline (maybe writes, too), then even the CV sequence isn't good enough as I demonstrated.  Plus, there is a chance of having to wait some milliseconds in the ISR which may be disturbing or harmful to some apps.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know that this is a tad old but the reason for disabling ISR for read, is that ISR don't restore the eeprom pointer if it use it. 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Late to the game, but...

EEWE is the bit 1 of register EECR.  Its value is 0x02.  The SBIC instruction needs to have the bit position value instead of the bit value.  Try using: sbic EECR , (1<<EEWE).

Incorrect.

 

You are conflating sbic/s with s/cbr:

 

 

 

 

 

 

Note that sbr is actually an alias for ori, just as cbr is an alias for andi (with the 1's complement of the operand).

 

As already pointed out by others, the error issued was in reference to the register address, not the bit number.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Mar 1, 2017 - 01:28 AM