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

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[ATmega 0] register confusion
« on: July 29, 2018, 07:53:41 pm »
I am somewhat confused about how the registers are supposed to work:

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.....
« Last Edit: July 29, 2018, 08:10:48 pm by Simon »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0]
« Reply #1 on: July 29, 2018, 08:09:09 pm »
Why do you need a state machine? Write to one register sets the output, write to the other clears it. There is no need to have a state machine for this.

This is a pretty standard feature. On ARMs we had this for years.

Quote
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.....
And this as well. Again, welcome to the world ARM processors lived in quite some time :)
« Last Edit: July 29, 2018, 08:13:15 pm by ataradov »
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #2 on: July 29, 2018, 08:15:03 pm »
Well i always said the ATmega 0 series was being done in ARM style but was laughed at.

But no this makes no sense. A register is a memory location. It tells the peripheral how to behave. If I write a 1 to the set the output in one register, and then write a 1 to another register to clear it there is a conflict.

Now the single 0 or 1 state of one pin is determined by 4 combinations from 2 bits of which 2 never occur. There has to be something, when you set both registers to "1" how does it know what to do?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #3 on: July 29, 2018, 08:17:27 pm »
But no this makes no sense. A register is a memory location. It tells the peripheral how to behave. If I write a 1 to the set the output in one register, and then write a 1 to another register to clear it there is a conflict.
But you don't write into a register. By writing into this memory-mapped location you are performing a bus transfer. How this bus transfer is handled internally it is up to the peripheral.

This is a very important concept to understand. I would recommend spending some time thinking about it and fully "getting" it.  This is used in a ton of places.
Alex
 
The following users thanked this post: hans, newbrain

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #4 on: July 29, 2018, 08:22:16 pm »
But you don't write into a register. By writing into this memory-mapped location you are performing a bus transfer. How this bus transfer is handled internally it is up to the peripheral.

This is a very important concept to understand. I would recommend spending some time thinking about it and fully "getting" it.  This is used in a ton of places.


I see. Well it does not make much difference to me, I am just curious. It does indeed appear to be "#define" in hardware.

They still call them registers and there was a load of jargon that made no sense but probably said what you just explained.
« Last Edit: July 29, 2018, 08:25:01 pm by Simon »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #5 on: July 29, 2018, 08:24:06 pm »
Saves your CPU cycle doing calculations such as P1OUT&=~BIT0 and P1OUT|=BIT0.

Actually I still need my "bit addressing" definitions as you still can't write to a bit. I take it things like:

#define bit_get(p,m) ((p) & (BIT(m)))
#define bit_s(p,m) ((p) |= (BIT(m)))
#define bit_c(p,m) ((p) &= ~(BIT(m)))
#define bit_flip(p,m) ((p) ^= (BIT(m))) // p is the register, m is the bit name
#define bit_write(c,p,m) (c ? bit_s(p, BIT(m)) : bit_c(p, BIT(m)))
#define BIT(x) (0x01 << (x))
#define LONGBIT(x) ((unsigned long)0x00000001 << (x))

#define bit1(p,m) ((p) |= (BIT(m)))
#define bit0(p,m) ((p) &= ~(BIT(m)))


still all work the same?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #6 on: July 29, 2018, 08:24:30 pm »
They still call them registers and there was a load of jargon that made sense but probably said what you just explained.
"Register" is a standard term  for memory-mapped I/O locations. But they don't have to be represented by the actual registers.
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #7 on: July 29, 2018, 08:27:12 pm »
Actually I still need my "bit addressing" definitions as you still can't write to a bit. I take it things like:

Not really. Here is an example for this style of peripheral: https://github.com/ataradov/mcu-starter-projects/blob/master/samd21/hal_gpio.h

You can still define the macros, if you want, but you don't really need to.

Also, for flips there is OUTTGL, so no need for a XOR.
« Last Edit: July 29, 2018, 08:32:39 pm by ataradov »
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #8 on: July 29, 2018, 08:33:57 pm »
I'm confused. Contrary to what the datasheet/manual implies PORTx.REGISTER is as far as it goes, PORTx.REGISTER1 is not accepted by the compiler. I still need to talk to the whole 8 bit register, I can't send 0 or 1 to a specific register bit.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #9 on: July 29, 2018, 08:36:04 pm »
I'm confused. Contrary to what the datasheet/manual implies PORTx.REGISTER is as far as it goes, PORTx.REGISTER1 is not accepted by the compiler. I still need to talk to the whole 8 bit register, I can't send 0 or 1 to a specific register bit.
If you want to set a bit "bit", do this: OUTSET = (1 << pin). That's exactly why they have separate SET and CLR. You don't don't need this bit manipulation magic and read-modify-write operation.
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #10 on: July 29, 2018, 08:38:16 pm »
So your macros will become:
Code: [Select]
#define bit_get(p,m) (IN & (BIT(m))
#define bit_s(p,m) (OUTSET = BIT(m))
#define bit_c(p,m) (OUTCLR = BIT(m))
#define bit_flip(p,m) (OUTTGL = BIT(m))
#define bit_write(c,p,m) (c ? bit_s(p, BIT(m)) : bit_c(p, BIT(m)))
#define bit1(p,m) (OUTSET = BIT(m))
#define bit0(p,m) (OUTCLR = BIT(m))

Whether you still want to have them as macros at this point is up to you. If you are used to using macros - continue to do so.
« Last Edit: July 29, 2018, 08:40:08 pm by ataradov »
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #11 on: July 29, 2018, 08:42:18 pm »
but (1 << pin) is still a mathematical operation required to address a single bit of the register. But is now faster as it will have the effect of directly addressing the bit in hardware even if i still nee the convoluted code. presumably (1 << pin) is calculated at compilation meaning no actual overhead when running in the application?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #12 on: July 29, 2018, 08:44:26 pm »
but (1 << pin) is still a mathematical operation required to address a single bit of the register. But is now faster as it will have the effect of directly addressing the bit in hardware even if i still nee the convoluted code. presumably (1 << pin) is calculated at compilation meaning no actual overhead when running in the application?
If you pass a constant bit index, then yes, it will be just calculated at compile time.

On many ARMs there is bit-banded I/O. There you can truly address individual bits. But I don't expect this to come to AVR, since address space is so limited.

The biggest problem this approach solves is having to read the value of the register, modify it and write it back. This requires 2 bus transfers + modification math + bit calculation shift. With the new approach you have one bus write and only bit calculation. Bit calculation will be optimized to a constant if bit is constant in both cases, of course.
« Last Edit: July 29, 2018, 08:46:49 pm by ataradov »
Alex
 
The following users thanked this post: hans

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #13 on: July 29, 2018, 08:47:26 pm »
Well clearly they are either keeping the AVR architecture alive by making it more ARM like, which is perhaps better for performance and more friendly to current ARM users and/or getting ready for a simple ARM device that inherits a lot from this architecture making it a more natural step with code compatibility.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #14 on: July 29, 2018, 08:49:33 pm »
Well clearly they are either keeping the AVR architecture alive by making it more ARM like, which is perhaps better for performance and more friendly to current ARM users and/or getting ready for a simple ARM device that inherits a lot from this architecture making it a more natural step with code compatibility.
May be. But you can get all this and much more at a cheaper price right now by simply switching to ARM.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #15 on: July 29, 2018, 08:51:24 pm »
seems PA1 etc is no longer accepted as standard pin definitions unless avr/io.h is not the place for the atmega-0 I/O definitions but the registers were accepted.

Ultimately I'll probably write my own definitions as there are now so many register names that it will be easier for code compatibility between projects to keep what i have and write appropriate code underneath.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #16 on: July 29, 2018, 08:53:01 pm »
Well clearly they are either keeping the AVR architecture alive by making it more ARM like, which is perhaps better for performance and more friendly to current ARM users and/or getting ready for a simple ARM device that inherits a lot from this architecture making it a more natural step with code compatibility.
May be. But you can get all this and much more at a cheaper price right now by simply switching to ARM.

This stuff in confusing me. I think if i learn the atmega-0 first it will be easier to get ARM and I'd not be surprised if by then a new microchip ARM series comes along.
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1857
  • Country: 00
Re: [ATmega 0] register confusion
« Reply #17 on: July 29, 2018, 08:53:55 pm »
Well i always said the ATmega 0 series was being done in ARM style but was laughed at.

But no this makes no sense. A register is a memory location. It tells the peripheral how to behave. If I write a 1 to the set the output in one register, and then write a 1 to another register to clear it there is a conflict.

Now the single 0 or 1 state of one pin is determined by 4 combinations from 2 bits of which 2 never occur. There has to be something, when you set both registers to "1" how does it know what to do?

Although ataradov answered this partially, this is a crucial difference to understand.

In traditional registers, as you understand, you have a set of bits in hardware that you can read/write, and then used by the peripheral to do stuff with. These registers are then traditionally implemented as D-flipflops, i.e. the peripheral address is matched from the bus, and then that value written is put into the D flipflop.

However in this case you have SET and CLR registers for port operations. You could view these registers as write-only. Picture that they are implemented as SR flipflops instead of D-flipflops. (or technically JK flipflop because we're dealing with synchronous, clocked, systems).

If you write to the SET register, those bits are wired to the set input of the flipflop. And the CLR it's wired to the reset flipflop.

It doesn't require this implementation, but I hope it helps in understanding.

This SET/CLR structure avoids the CPU having to perform a read-modify-write operation (i.e. an bitwise OR or AND operation with a particular bitmask), as it could be handled by peripheral internally. In particular, you avoid the "read" operation from the bus and only a write operation remains.
This is also useful because bitwise I/O operations are now atomic, i.e. you don't have to guard them when you need to deal with interrupts.

For ARM chips, cortex m3 and "up" features bitbanding. Here the whole peripheral and memory space is mapped into a separate piece memory region, where you can address each bit as an individual word, and read, set or clr them.

Also, this is not a particular feature of ARM. PIC32 also features these kind of registers, because on 32-bit CPUs as said, all I/O is done via RMW operations and thus painful.
« Last Edit: July 29, 2018, 08:56:03 pm by hans »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #18 on: July 29, 2018, 08:55:32 pm »
I think if i learn the atmega-0 first it will be easier to get ARM
I really don't think it is the case. You are still working with a thing that tries to work around the memory limitations. Moving ARM-like things into AVR just makes everything more awkward.
Alex
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18614
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [ATmega 0] register confusion
« Reply #19 on: July 29, 2018, 09:04:19 pm »
Well I think these new AVR's will be quicker to learn and as you have pointed out the peripherals are more ARM like. The price and performance is good and quite enough for me. I will need to look at ARM one day but at the moment these chips more than fill my needs. I need to get a better understanding of embedded peripherals in general and increase my skills in C before taking on anything any larger and with the Atmel buyout things will change so no point in jumping yet until the options are clear.
 

Offline SimonTopic starter

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


In traditional registers, as you understand, you have a set of bits in hardware that you can read/write, and then used by the peripheral to do stuff with. These registers are then traditionally implemented as D-flipflops, i.e. the peripheral address is matched from the bus, and then that value written is put into the D flipflop.

However in this case you have SET and CLR registers for port operations. You could view these registers as write-only. Picture that they are implemented as SR flipflops instead of D-flipflops. (or technically JK flipflop because we're dealing with synchronous, clocked, systems).


Ah right, got it, thank you

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4549
  • Country: us
Re: [ATmega 0] register confusion
« Reply #21 on: July 29, 2018, 11:43:16 pm »
Quote
seems PA1 etc is no longer accepted as standard pin definitions unless avr/io.h is not the place
See avr/portpins.h
Note the use of pointers :-)
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22435
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #22 on: July 30, 2018, 01:57:46 am »
Is this not XMEGA?  I've not seen it called "MEGA 0", and I'm not aware those registers are in any megas.  Just to avoid confusion.

Anyway, it makes perfect sense considering the logic operations: you're looking at the port-wide registers.  These only affect the pins written to.  You are writing a bit mask, not a bit state!

These registers are convenience, so you don't have to perform this operation (which is what you do on the vanilla MEGA, and can still do on XMEGA if you like):

PORTn = (PORTn & ~TurnOffBits) | TurnOnBits;

This compiles to at least four instructions.

Instead, you do:
PORTn.OUTCLR = TurnOffBits;
PORTn.OUTSET = TurnOnBits;

If assigning constants, this compiles to only one instruction each!

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

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12383
  • Country: us
    • Personal site
Re: [ATmega 0] register confusion
« Reply #23 on: July 30, 2018, 01:59:23 am »
Mega series 0 is a recent release of the architecture. It is not an Xmega.
Alex
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 22435
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: [ATmega 0] register confusion
« Reply #24 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!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf