Simple coding question ATTINY402

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

So... I'm used to PORTA = 0xAA;  for example.

Now I seem to need to use PORT SET AND PORT CLEAR  type operations with bit specifiers

 

So here's the simple question,  how do I simply write to PORTA from a  variable or byte because PORTA = 0xAA doesn't compile anymore.

I guess the same question applies to the DDR.

 

Thanks

 

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

You should read this first.

 

http://ww1.microchip.com/downloa...

 

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

Compared to traditional tiny/mega

DDRx = PORTx.DIR
PINx = PORTx.IN
PORTx = PORTx.OUT

If you want to keep it simple you could just stick to those three. All your CLR, SET, TGL, etc are just bells and whistles that ice the cake.

Last Edited: Tue. Feb 9, 2021 - 05:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had found the getting started doc, and it says..
.. "The instances of the PORT peripheral registers control the I/O pins of the device.."
What on earth is an instance of a port register when its at home??
And " Portx.Dir" doesn't look like an actual register address to me,more like accessing a structure.

What am I missing?

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

rowifi wrote:
What on earth is an instance of a port register when its at home??

PORTA is an instance of Port;

PORTB is an instance of Port;

PORTC is an instance of Port;

etc ...

 

And " Portx.Dir" doesn't look like an actual register address to me,more like accessing a structure.

What am I missing?

You are accessing a structure which is mapped onto the port registers:

 

all the registers in all the ports are contiguous, and have the same layout - so a 'C' struct models that precisely

 

EDIT

 

From iotn402.h, the struct is:

/* I/O Ports */
typedef struct PORT_struct
{
    //          Register Name     Offset  Description
    //          --------------    ------  ------------------------
    register8_t DIR;           /* 00      Data Direction */
    register8_t DIRSET;        /* 01      Data Direction Set */
    register8_t DIRCLR;        /* 02      Data Direction Clear */
    register8_t DIRTGL;        /* 03      Data Direction Toggle */
    register8_t OUT;           /* 04      Output Value */
    register8_t OUTSET;        /* 05      Output Value Set */
    register8_t OUTCLR;        /* 06      Output Value Clear */
    register8_t OUTTGL;        /* 07      Output Value Toggle */
    register8_t IN;            /* 08      Input Value */
    register8_t INTFLAGS;      /* 09      Interrupt Flags */
    register8_t reserved_1[6]; /* 0A..0F  */
    register8_t PIN0CTRL;      /* 10      Pin 0 Control */
    register8_t PIN1CTRL;      /* 11      Pin 1 Control */
    register8_t PIN2CTRL;      /* 12      Pin 2 Control */
    register8_t PIN3CTRL;      /* 13      Pin 3 Control */
    register8_t PIN4CTRL;      /* 14      Pin 4 Control */
    register8_t PIN5CTRL;      /* 15      Pin 5 Control */
    register8_t PIN6CTRL;      /* 16      Pin 6 Control */
    register8_t PIN7CTRL;      /* 17      Pin 7 Control */
    register8_t reserved_2[8];
} PORT_t;

 

note that you do still have the old-style definitions, if you prefer; eg,

/* PORT (PORTA) - I/O Ports */
#define PORTA_DIR  _SFR_MEM8(0x0400)
#define PORTA_DIRSET  _SFR_MEM8(0x0401)
#define PORTA_DIRCLR  _SFR_MEM8(0x0402)
#define PORTA_DIRTGL  _SFR_MEM8(0x0403)
#define PORTA_OUT  _SFR_MEM8(0x0404)
#define PORTA_OUTSET  _SFR_MEM8(0x0405)
#define PORTA_OUTCLR  _SFR_MEM8(0x0406)
#define PORTA_OUTTGL  _SFR_MEM8(0x0407)
#define PORTA_IN  _SFR_MEM8(0x0408)
#define PORTA_INTFLAGS  _SFR_MEM8(0x0409)
#define PORTA_PIN0CTRL  _SFR_MEM8(0x0410)
#define PORTA_PIN1CTRL  _SFR_MEM8(0x0411)
#define PORTA_PIN2CTRL  _SFR_MEM8(0x0412)
#define PORTA_PIN3CTRL  _SFR_MEM8(0x0413)
#define PORTA_PIN4CTRL  _SFR_MEM8(0x0414)
#define PORTA_PIN5CTRL  _SFR_MEM8(0x0415)
#define PORTA_PIN6CTRL  _SFR_MEM8(0x0416)
#define PORTA_PIN7CTRL  _SFR_MEM8(0x0417)

 

But note how its much easier to set up the struct-style - you only need to define the structure once, and then the "instances" are just one-liners

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...
Last Edited: Tue. Feb 9, 2021 - 08:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also in iotn402.h is

#define PORTA                (*(PORT_t *) 0x0400) /* I/O Ports */

So that the expression PORTA.IN does the right thing.  I like this convention.

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

and it makes this easy: https://www.avrfreaks.net/commen...

 

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

 

rowifi wrote:
What on earth is an instance of a port register when its at home??

Well on "bigger" chips in the 402 family like 404/406 you have:

 

 

where there are two "instances" of the PORT_t that Andy showed above. But the situation with Tiny402 is possibly a little confusing as it only has:

 

 

so it only has the one instance - in which case the utility of first defining a common port structure (or UART structure or SPI structure or whatever) and then being able to instantiate a load of the same thing is possibly lost a little when a tiny402 only as ONE of each thing.

 

But when you trade up to a mega4809 (say) then you have things like:

 

 

So 6 ports with a common structure, 4 UARTs with a common structure and four Timer-Bs with a common structure.

 

Now you can develop code like:

UART_init(USART_t * pUART, int baud, etc);

then that single code can be used for the multiple instances like:

UART_init(&USART0, 9600, ...);
UART_init(&USART3, 19200, ...);
etc

On "traditional" AVR you would have needed separate:

UART0_init(9600, ...);
UATR3_init(19200, ...);
etc

so you'd actually be maintaining four different copies of UART_init() etc.

 

Of course, with Tiny402 you basically just get "only one instance of each thing" so the utility of this is possibly a little lost there.

 

Last Edited: Wed. Feb 10, 2021 - 10:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW wrote:
I like this convention

indeed.

 

The same convention is used in SAM-D - and by many (most? all?) other Cortex-M implementations ...

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

 

awneil wrote:

MattRW wrote:

I like this convention

 

indeed.

 

Me too. +1

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: Wed. Feb 10, 2021 - 01:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure why they don't go to the next step, but I suspect they feel tied down by the asm #define counterparts.

 

https://godbolt.org/z/WjK1q6

 

 

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

Well, sometimes if you have some legacy code you want to "upgrade" this kind of thing works reasonably well:

 

#define PORTA VPORTA.OUT
#define DDRA VPORTA.DIR
#define PINA VPORTA.IN

 

VPORTx closely resembles legacy ports. One difference is that you can't control the pull-up resistors from VPORTx.OUT, so that part of the code needs further changes.

Last Edited: Wed. Feb 10, 2021 - 10:13 PM