Author Topic: [ATmega 0] register confusion  (Read 10318 times)

0 Members and 1 Guest are viewing this topic.

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21675
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #25 on: July 30, 2018, 02:01:12 am »
Mega series 0 is a recent release of the architecture. It is not an Xmega.

Ah, so it has features of both then.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #26 on: July 30, 2018, 06:20:16 am »
Yea, Atmega3208, 3209, 4808, 4809. They seem to be making a good start with just a couple of memory sizes instead of an army of variants and the peripherals seem to be setup for the future. Thought I might as well get straight into them as I have a week off work, one customer enquiry to myself and I've not got too much legacy AVR stuff written yet. The series number in the part number indicates that they may well take these further.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: [ATmega 0] register confusion
« Reply #27 on: July 30, 2018, 07:50:07 am »
Some of the new ATtiny chips have "XMega-style" peripherals as well.  (Attiny816, ATtiny817, etc)There are other sneaky differences - there is a "unified" address map that includes flash and eeprom, but no longer includes the CPU registers...

 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #28 on: July 30, 2018, 07:56:56 am »
Yea, hence the 48KB limit as they seem to want to stick to a 16bit bus so are limited to a total of 64KB.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #29 on: July 30, 2018, 09:28:16 am »
They do like to confuse matters. In the attached page i see no reference to what the hell the individual pin register name is. It takes some playing around in atmel studio to discover it: PORTx.PINnCTRL for example, where the pin number "n" is specified is not even mentioned neither is the actual register name given.
« Last Edit: July 30, 2018, 10:03:06 am by Simon »
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21675
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #30 on: July 30, 2018, 10:10:50 am »
Yeah, look up the docs on the product page.  So, https://www.microchip.com/wwwproducts/en/ATMEGA3208 and such.

There's the datasheet, the manual, the AVR000 appnote, the header files for the chip, and some other stuff.

I rather preferred the way they did it on the old MEGAs, with example code right there, and all the names consistent.  (I've found several inconsistent names and omitted and superfluous registers on the xmega64d3 I've been playing with. :palm: )  To wit, there are three ways things are named: the sections in the datasheet and manual; the register descriptions and summaries; the bits within them; and it's only coincidence if these match how the actual registers are named.

I find myself scanning through the header file often.  Get an IDE that shows references, and put the header file in the project or source however is necessary to get the references working.  (I use Code::Blocks, which apparently only shows references included from the source, so I just put in a #if 0 #include <avr/x64d3.h> #endif to keep that handy.)

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #31 on: July 30, 2018, 10:22:27 am »
Yes, but that page is from the register description page. It's "the" page that is supposed to tell you what the damn names are.....
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11248
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #32 on: July 30, 2018, 04:15:21 pm »
They do like to confuse matters. In the attached page i see no reference to what the hell the individual pin register name is. It takes some playing around in atmel studio to discover it: PORTx.PINnCTRL for example, where the pin number "n" is specified is not even mentioned neither is the actual register name given.
You have to just look at the header files. They are generated from files that are closest to the actual hardware.

Documentation if hard to get right, so sometimes there are problems like this and you have to adapt. That's part of the job, if you actually want to be an embedded developer. Complaining will not solve anything.

ARM have mistakes and omissions like this all the time. From all vendors, nobody is a saint here.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #33 on: July 30, 2018, 04:18:49 pm »
Yea, not even sure where to find the header files but I've not looked yet, I'll get round to it.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #34 on: July 30, 2018, 04:22:20 pm »
And no I don't buy this "we can't be arsed to get it right", I don't think my employer would of me either.....
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11248
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #35 on: July 30, 2018, 04:36:34 pm »
And no I don't buy this "we can't be arsed to get it right", I don't think my employer would of me either.....
Nobody is selling this. And this is not the attitude. If you want, you can report the issue and it will be put into the backlog. Given the amount  of documentation, it is unreasonable to expect  it to be perfect in all respects. Or the price of your MCUs will go way up.

This is the reality of the industry, you need to learn to deal with it. An if the employer has any sense or experience they will know this already.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #36 on: July 30, 2018, 09:43:34 pm »
I suppose next i will have to fit a reset button to my projects just in case ;)
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11248
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #37 on: July 30, 2018, 10:58:01 pm »
Not a reset button, but most products have the watchdog timer enabled, just in case. You can live it dangerously and assume you don't make any mistakes, but in reality everyone does.
Alex
 

Offline VinzC

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: [ATmega 0] register confusion
« Reply #38 on: July 31, 2018, 12:29:25 pm »
Quote
Basic Functions
Each I/O pin Pxn can be controlled by the registers in PORTx. Each pin group x has its own set of PORT
registers. The base address of the register set for pin n is at the byte address PORT + 0x10 + ÝŠ . The
index within that register set is n.
To use pin number n as an output only, write bit n of the PORTx.DIR register to '1'. This can be done by
writing bit n in the PORTx.DIRSET register to '1', which will avoid disturbing the configuration of other pins
in that group. The nth bit in the PORTx.OUT register must be written to the desired output value.
Similarly, writing a PORTx.OUTSET bit to '1' will set the corresponding bit in the PORTx.OUT register to
'1'. Writing a bit in PORTx.OUTCLR to '1' will clear that bit in PORTx.OUT to zero. Writing a bit in
PORTx.OUTTGL or PORTx.IN to '1' will toggle that bit in PORTx.OUT.
To use pin n as an input, bit n in the PORTx.DIR register must be written to '0' to disable the output driver.
This can be done by writing bit n in the PORTx.DIRCLR register to '1', which will avoid disturbing the
configuration of other pins in that group. The input value can be read from bit n in register PORTx.IN as
long as the ISC bit is not set to INPUT_DISABLE.
Writing a bit to '1' in PORTx.DIRTGL will toggle that bit in PORTx.DIR and toggle the direction of the
corresponding pin.

So is that confusing or what? to make a pin low I write to one register but to make it high I write to another. So can that mean the registers conflict or do they just have silicon to spare to make any register a state machine with 2 inputs?

Stuff I was intending to write #defines for seem hardly needed as they have made every action a different register so the define write themselves.....

Though hans' reply has provided good insights about what [I think] your problem might be, I'm sensing there's something left to be explained further down the line.

What you're quoting is your compiler's convention about manipulating ATmega registers. Your perception of registers is correct. What I find confusing and terribly implemented as well is that one has to write a logical 'one' to actually clear register bits. And there's also more than one way to do that through the various specific abstract terms. It *does* sound confusing because it is. Besides it gives no real clue what the generated assembly code will look like nor how the actual register works.

Let's take a small detour by the assembly land. Indeed to set a register bit to one, all you have to do is OR the register with an immediate value where all bits are cleared but the one bit you want to set (assembly code):
Code: [Select]
ori R15, 80 /* Set bit 7 in R15 */
andi R14, FE /* Clear bit 0 in R14 */

From your quote, PORTx.DIR actually represents the direction register for port x, aka DDRx, e.g. DDRA in the case of PORTA. OTOH PORTx.DIRSET actually is not a register but some form of compiler-defined "macro" or "symbol" (not very sure what it is exactly though), which translates write operations into compiled assembly code that properly sets the corresponding register. Same goes with PORTx.OUTSET, PORTx.OUTCLR and PORTx.OUTTGL, which are for setting, clearing and toggling port pins when written logical ones. It might spare you from mentally calculating what masks and hardware registers you need to use to set/clear bits but IMHO it's not very practical and is confusing at best.

In my opinion, this is but a convoluted way to implement a hardware programming interface. If you take a look at avr-gcc, there's no such complication/confusion: you manipulate those damn registers like... registers!  ;D Example, C-code:
Code: [Select]
DDRA |= 0x01 /* Set PORTA pin 0 as an output */
PORTA |= 0x01 /* Set PORTA pin 0 high */
PORTA &= ~0x01 /* Set PORTA pin 0 low */

In short, you write a logical 'one' to set a bit and a logical 'zero' to clear it. But to make matters more confusing, the above C code might be translated into assembly language like this:
Code: [Select]
sbi     DDRA,  0 /* Make PORTA pin 0 an output */
sbi     PORTA, 0 /* Set PORTA pin 0 high */
cbi     PORTA, 0 /* Set PORTA pin 0 low */

As you can see C instructions, which logically translate into a read-modify-write operation, are translated into a single bit-write instruction. This is made possible thanks to the optimizer.

But note that "sbi" and cbi" instructions are only valid for a limited set of AVR registers. There are other registers that require read-modify-write operations to manipulate their bits. But again: the optimizer will do that job.

I guess your compiler has made those operations invisible by providing some form of abstraction... which is not really required since it's the optimizer's job to translate C instructions into the appropriate assembly code. So one assignment instructions in C might translate into assembly "sbi/cbi" or a read-modify-write sequence, depending on the target register.

Anyway, I suggest you took a look at the generated assembly for more details. Also see AVR instruction set documentation.
« Last Edit: July 31, 2018, 12:35:13 pm by VinzC »
 
The following users thanked this post: hans

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #39 on: July 31, 2018, 03:10:43 pm »
Erm no. they can't be doing this in the compiler because then the datasheet is describing the compiler and not the chip.
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: [ATmega 0] register confusion
« Reply #40 on: July 31, 2018, 07:42:24 pm »
Maybe a different way to look at this would be:

1) Think about the port data register as an actual register, which drives the pin transistors. The same goes for the direction register: it drives the signal that disconnects the output stage. OK - these registers actually exist on the chip in some form or another.
2) Now, you could write to this data or direction register, like you traditionally do. But there's a problem! You have to write full 8/16/32/whatever bits at the time. In real-world MCU applications, you very often want to just toggle a single pin. So you traditionally need to:
- Read out the existing data
- Modify it
- Write it back
The compiler does this automatically for you, so it looks easy, but:
- It is slow,
- It creates possibilities for race conditions or glitches, because the operation is not atomic, and unrelated bits gets read and written back at a different time.


Now, think about this "new" way of doing thing as a "hardware accelerator", doing this tedious read-modify-write thing for you, so that the CPU only needs to run one simple write instruction to set or clear any bit - or actually, set any number of bits. You just control this "accelerator" by writing to these command registers, which are called set and clear. The point is, you never need to read anything to perform a write, like you had before. Which was dumb, since you are just writing. Needing to read first to write was the confusing thing!

This doesn't mean you should do more bit logic; it frees you from some! This is a simplification.

Having to write '1' to set the output to '0' makes sense as you think about it as a clearing command. 0 means "don't do anything to this bit; keep it like it was", and 1 means "do the specified operation for this bit". This logic stays the same, whether it's a "set" register, a "clear" register, or something more complex - such as an ADC "start conversion" command bit!

Even the plain old AVR had this kind of "accelerator"; the sbi and cbi instructions, which are specifically designed to do exactly this! But their use was limited to only part of the IO device mapping, so on some devices, you could use them for PORTA, but not for PORTF, for example. Which is stupid. Also, it's a bit confusing that a GPIO task has two specific instructions in the CPU instruction set. These instructions also only could set or clear only one single bit at a time. With these new register, you can, for example, set bits 0, 4 and 6 at the same time, using just one write operation, with no runtime math whatsoever.
« Last Edit: July 31, 2018, 07:51:45 pm by Siwastaja »
 
The following users thanked this post: hans, BillyD

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #41 on: July 31, 2018, 07:55:01 pm »
Indeed it makes life easier for the chip and faster because it is like a tri state output. There is a do nothing/pretend it's not there condition: the writing of "0". As I understand it the whole 8 bit register has to be written but as everythig is done by sending "1" you just do that and "0" has no effect, previously you had to do math on the 8 bit value to get the result needed, like you say hardware acceleration.
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: [ATmega 0] register confusion
« Reply #42 on: July 31, 2018, 08:13:11 pm »
Yes. Many (most?) ARM microcontrollers implement GPIO so that they go even further and combine these set/clear command registers into one set/clear register: so with a simple single write operation, you can change any arbitrary number of bits to 0, and any other arbitrary bits to 1, and leave the rest alone, all at the same time.

Such versatility is of course not needed too often, but it's there anyway. With 32-bit registers, you can easily do stuff like this!

Bit banding is a more generic and more elegant solution to this: you can access single bits without affecting others, and do this to anything the same way, not only the GPIO.

But traditionally, MCU designers want to solve problems in as many different ways as possible, and avoid solutions that are too simple or generic.

Actually, if we wanted everything to be truly simple, generic and easy to understand, we should try to get rid of the concept of minimum accessible memory size and alignment, which varies by instruction and even in the same system can vary between 1 bit, 4 bits, 8 bits, 16 bits, 32 bits, 64 bits, depending on what you are doing; and then a glue layer called "bit banding" is implemented on the top to emulate bit-level addressability.

But there's a lot of legacy tradition still going on.

A good thing in ARM cores is that they have relatively little "very strange oddities" going on, and are fairly easy to understand, even for a beginner. The definitely-large-enough address space avoids stupid complications like paging and separate addressing registers; the instruction set is IMO logical and makes sense; and the core implements a lot of things to make the programmer's (and compiler writer's) day easier: for example, the interrupt services are completely transparent, like any function, and the CPU performs the state push/pop completely.

(As a general comment, this whole ATmega0 thing feels dumb to me. Why would anyone learn such a new system, where all the tried-and-tested details are reimplemented, so that even the basic IO or even the ages-old and very well perceived programming scheme doesn't work the same way as before? Sure, if it offered something worth learning a new architecture, by all means... But if the user needs to learn something new, they are so much better off learning any of the mainstream ARM MCU series, such as STM32 or whatever.)
« Last Edit: July 31, 2018, 08:18:46 pm by Siwastaja »
 
The following users thanked this post: hans

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #43 on: July 31, 2018, 09:01:32 pm »


(As a general comment, this whole ATmega0 thing feels dumb to me. Why would anyone learn such a new system, where all the tried-and-tested details are reimplemented, so that even the basic IO or even the ages-old and very well perceived programming scheme doesn't work the same way as before? Sure, if it offered something worth learning a new architecture, by all means... But if the user needs to learn something new, they are so much better off learning any of the mainstream ARM MCU series, such as STM32 or whatever.)

Well as I do not have too much code base written yet and I like the features I am in a good position to move. ARM will come in time but I am placing bets on MCP releasing a new arm and hope it will base itself on the legacy of mega0.
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21675
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #44 on: July 31, 2018, 10:34:44 pm »
Oh interesting, peeked at the manual, they indeed do not provide registers on that.  I don't have the header for that one, I think, but that must be what they're doing, providing the new style interface but implementing it in software.  Sneaky, if you were expecting it to save time it won't!

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11248
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #45 on: July 31, 2018, 10:38:00 pm »
Oh interesting, peeked at the manual, they indeed do not provide registers on that.  I don't have the header for that one, I think, but that must be what they're doing, providing the new style interface but implementing it in software.  Sneaky, if you were expecting it to save time it won't!
What registers are you talking about? It is real hardware implementation, there is no software involved.
Alex
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21675
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #46 on: July 31, 2018, 10:48:11 pm »
Wait, did I doublemiss that?  Oh, fuck me, they put the register listing before the descriptions.  Thanks for breaking yet another tradition... :palm:

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline VinzC

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: [ATmega 0] register confusion
« Reply #47 on: July 31, 2018, 11:10:40 pm »
Erm no. they can't be doing this in the compiler because then the datasheet is describing the compiler and not the chip.
Okay, I double checked. Looks like I wasn't on the same page as you after all. My bad.

Anyway, if you take a look at the datasheet on page 142 you'll see the names to the right of the dot-notation actually are *offsets*, which are added to any PORTx address. That explains why port addresses "jump" by 0x0020. But in the end taking a look at the assembly code will tell you what's going on, i.e. if that is simply a language notation (a convention) or an actually a register name. I'm curious, could you please check that?
 

Offline VinzC

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: [ATmega 0] register confusion
« Reply #48 on: July 31, 2018, 11:18:46 pm »
Even the plain old AVR had this kind of "accelerator"; the sbi and cbi instructions, which are specifically designed to do exactly this! But their use was limited to only part of the IO device mapping, so on some devices, you could use them for PORTA, but not for PORTF, for example. Which is stupid. Also, it's a bit confusing that a GPIO task has two specific instructions in the CPU instruction set. These instructions also only could set or clear only one single bit at a time. With these new register, you can, for example, set bits 0, 4 and 6 at the same time, using just one write operation, with no runtime math whatsoever.

On those "plain old" AVR bit set, clear and even toggle can be done in one single instruction, be it for one or more bits; no need to read-modify-write (except for a few cases). Again, the optimizer translates into the proper instructions. The only trick is bit(s) toggle, which is done by writing one(s) to the corresponding PINx register. Still, one instruction.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: [ATmega 0] register confusion
« Reply #49 on: August 01, 2018, 12:19:13 am »
Quote
On those "plain old" AVR bit set, clear and even toggle can be done in one single instruction, be it for one or more bits;
No, you're wrong:  Multiple-bit set/clear in IO registers never existed, single bit set/clear had an extremely limited range, and bit-toggle was a kludge tacked on to only SOME of the newer CPUs (in a manner rather like the 0-series, actually.)  Manipulating a bit of PORT L on an ATmega1280 takes 10 bytes.

(Sigh.  I had a much longer version of this, but a wrong keystroke made it disappear. :-( )
Code: [Select]
int main() {
    PORTA |= 8;
   0:    13 9a           sbi    0x02, 3    ; 2
    GPIOR1 |= 8;
   2:    8a b5           in    r24, 0x2a    ; 42
   4:    88 60           ori    r24, 0x08    ; 8
   6:    8a bd           out    0x2a, r24    ; 42
    PORTL |= 8;
   8:    eb e0           ldi    r30, 0x0B    ; 11
   a:    f1 e0           ldi    r31, 0x01    ; 1
   c:    80 81           ld    r24, Z
   e:    88 60           ori    r24, 0x08    ; 8
  10:    80 83           st    Z, r24
The mega-0 architecture retains all the old functionality for GPIO bits (via the "virtual ports" in low memory) and adds the additional "modern style" (address-wasting!) registers as well.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf