AXMEGA newbie

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

Hi, am new to ATXmega as I am playing around with the atxmega256au. I intend controlling (open and close by input) of some SSR relay connected each to Port F of the microcontroller. This is a rough code belwo. Would love to know if am on the right track.

int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}
int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}#include <avr/io.h> 

int main() {

DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);

int i;

scanf("%d",i);

switch (i) {

case 1:

PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);

break;

case 12:

PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);

break;

case 14:

PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);

break;

case 22:

PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);

break;

 

 

 

PS: just a rough code

Josh

Last Edited: Wed. Jun 12, 2019 - 05:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  scanf("%d",i);

Exactly what do you think this scanf() is connected to? (hint: with the code you have written so far the answer is nothing). Anyway of everything you posted this bit:

#include <avr/io.h> 

int main() {
    DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);

    int i;
    scanf("%d",i);

    switch (i) {

        case 1:
            PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 12:
            PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 14:
            PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 22:
            PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

looks like it could be real C though for my money all the pointless (0 << n) stuff obscures the bit you ARE setting each time. I think it would just be clearer as:

#include <avr/io.h> 

int main() {
    DDRF = 0x7F; // bottom 7 bits output

    int i;
    scanf("%d",i);

    switch (i) {

        case 1:
            PORTF = (1<<0);
            break;

        case 12:
            PORTF = (1<<1);
            break;

        case 14:
            PORTF = (1<<2);
            break;

        case 22:
            PORTF = (1<<3);
            break;

You have not completed this code and I have no idea what the significance of 1 / 12/ 14 / 22 is? Perhaps some comments? But as you are inviting user input (and annoying users have the habit of typing anything!) you have to consider how to handle the case when it isn't one of those specific values - in other words switch() statements almost invariably require a "default:" case to catch "everything else".

 

Before the "#include <avr/io.h>" you seem to have several copies of the same thing? It is completely nonsensical. If I take just one of the "int main()" from there:

int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}

"case 1.2" ? A switch() in C uses an integer value as the switch control so I doubt the C compiler would even accept "1.2" but even if it did it would convert to int and treat it as just "1" anyway. 

 

This is further compounded by the fact that you seem to have three almost identical cases. Two are exactly "case 1.2:" and for good measure there is a very curious "case 1.2uA" in there too. Well for a start C won't let you have two cases with the same value. But then there's that "uA" suffix on the 3rd. While it's true that there are certain characters you can add to the end of C literal constants such as "U" and "L" (to mean "unsigned" and "long") then C might be willing to tolerate a "u" suffix but I'm not aware of "A" being valid C??

 

As it happens you also have cases for "12" and "12u". That's a bit of a conundrum for a couple of reasons. Like I say you can't have duplicates. But like I say by a strange coincidence "u" is a valid suffix for a numeric constant. By default literal constant in C are "int" (by implication that is "signed int") so "12" means a signed integer value of 12. While "12u" means an "unsigned integer value of 12". I imagine the head of the C compiler will probably explode at this stage. I think it's going to reject this as duplicate even though there's that subtle difference in sign.

 

To be honest I wonder if you may not be better off learning about things like this (the fundamentals of C) in a PC environment where things like scanf() "just work". 

 

Oh and that code does:

  return o;
}

A couple of things wrong with that. One is that it appears to be a lower case letter O not the digit 0 (zero). But the other is that this is an embedded micro - there is no where to return to. Most C compilers do have a "catch" so that if you ever make the mistake or returning from main() then there's usually an infinite loop to "hold it". But there may be adverse side-effects. For example in avr-gcc that loop is preceded by a cli() so if the main() code was using interrupts in some way they are turned off. So the general structure of an embedded micro program should generally always be:

int main() {
    one_time_initialisaiton_stuff();
    while (1) {
        the_core_stuff_done_repeatedly();
    }
    // it never gets this far
}

 

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

I have no problem with pseudo-code.   But please simplify it. 

e.g. to make it easier to read on the PC screen reduce the number cases.   Just type one or two cases.   add ellipsis to imply extra cases

 

Xmega registers are named differently to AVR special function registers.   e.g. PORTA.IN instead of PINA

 

I would avoid scanf() in an embedded program.   Much safer to specify buffer limits and use sscanf().

 

David.

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

I completely missed the fact that it was Xmega so:

 

DDRF = PORTF_DIR

PORTF = PORTF_OUT

 

and for completeness

 

PINF = PORTF_IN

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

Yes,  you can use a macro like PORTF_DIR instead of PORTF.DIR

 

And if you require very fast GPIO twiddling,  you can assign 4 VPORTs to the regular PORTs

VPORTs give you impressive performance.

 

David.

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

the several copies is an error. like I said earlier, its a rough code with a lot of errors. I want to use it for a device using an interface (hence the reason for the scanf. I know how to take care of the wrong user input. Am new to avr C and ust wanted to ensure am on the right track in preparing a block of code that will allow a user on an interface select any SSR relay to open (while the others remain close).

Josh

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

This is was really helpful bro. Sorry for how roughness of the block. but thank you so much. So in avr C, there is nothing like return 0?

Josh

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

clawson wrote:
the several copies is an error. like I said earlier, its a rough code with a lot of errors. I want to use it for a device using an interface (hence the reason for the scanf. I know how to take care of the wrong user input. Am new to avr C and ust wanted to ensure am on the right track in preparing a block of code that will allow a user on an interface select any SSR relay to open (while the others remain close).

Josh

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

The device am preparing this for has a user interface written in python, won't scanf work. 

please what is used as DDR in xmega ?

will the shifting I did also work for an xmega register?

any advice on a good avr programming textbook?

Josh

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

raven231996 wrote:
So in avr C, there is nothing like return 0?

Actually, for any micro without an OS, there is nothing to return too....

So embedded systems follow the template of init the h/w, then forever loop!

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

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

clawson wrote:

I completely missed the fact that it was Xmega so:

 

DDRF = PORTF_DIR

PORTF = PORTF_OUT

 

and for completeness

 

PINF = PORTF_IN

 

 

This is amazing 

any recommended books to read up on xmega (specific) programming 

Josh

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

ki0bk wrote:

raven231996 wrote:
So in avr C, there is nothing like return 0?

Actually, for any micro without an OS, there is nothing to return too....

So embedded systems follow the template of init the h/w, then forever loop!

 

Jim

 

 

 

please can you help with a format of a block of code so I see where the init falls into

Josh

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

raven231996 wrote:
please can you help with a format of a block of code
I already did:

int main() {
    one_time_initialisaiton_stuff();
    while (1) {
        the_core_stuff_done_repeatedly();
    }
    // it never gets this far
}

So the "one time" stuff will be things like setting up ports as input/output, starting timers, configuring UARTs and all that kind of thing. Then the repeated stuff is where you do stuff like reading inputs, setting outputs, doing things at ceratin time, making ADC reading, writing output to UART and so on.

 

Actually Arduino (which is a great way to learn AVRs by the way) really formalises this. They have a core program that looks like:

int main() {
    setup();
    while (1) {
        loop();
    }
    // it never gets this far
}

then in the code you actually write yourself you just fill in setup() and loop(). Again, you put the one time initialisation stuff into setup() and the stuff you want to have done repeatedly into loop().

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

I have used Arduino in the past but the company am doing my internship are writing pure C and building their own boards. So I am in the learning phase of embedded C and would love to learn so much under it and be even at least a bit as good as you guys. So please permit my errors.

Josh

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

"Dare to be naïve." - Buckminster Fuller

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

Why on earth are your pins not named, just a bunch of numbers is almost useless....

BATTERY_ALARM_REDLED

 

HOIST_ENABLE

ROCKET_LUNCH_NOW  cheeky

 

names tell you something that numbers don't.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

clawson wrote:

  scanf("%d",i);

Exactly what do you think this scanf() is connected to? (hint: with the code you have written so far the answer is nothing). Anyway of everything you posted this bit:

#include <avr/io.h> 

int main() {
    DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);

    int i;
    scanf("%d",i);

    switch (i) {

        case 1:
            PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 12:
            PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 14:
            PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

        case 22:
            PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
            break;

looks like it could be real C though for my money all the pointless (0 << n) stuff obscures the bit you ARE setting each time. I think it would just be clearer as:

#include <avr/io.h> 

int main() {
    DDRF = 0x7F; // bottom 7 bits output

    int i;
    scanf("%d",i);

    switch (i) {

        case 1:
            PORTF = (1<<0);
            break;

        case 12:
            PORTF = (1<<1);
            break;

        case 14:
            PORTF = (1<<2);
            break;

        case 22:
            PORTF = (1<<3);
            break;

You have not completed this code and I have no idea what the significance of 1 / 12/ 14 / 22 is? Perhaps some comments? But as you are inviting user input (and annoying users have the habit of typing anything!) you have to consider how to handle the case when it isn't one of those specific values - in other words switch() statements almost invariably require a "default:" case to catch "everything else".

 

Before the "#include <avr/io.h>" you seem to have several copies of the same thing? It is completely nonsensical. If I take just one of the "int main()" from there:

int main() 
{

  DDRF = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6);
  int i;

  scanf("%d",i);

  switch (i) {
  case 1.2:
    PORTF = (1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(1<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 12:
    PORTF = (0<<0)|(0<<1)|(1<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 1.2:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(1<<3)|(0<<4)|(0<<5)|(0<<6);
    break;
  case 120:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(1<<4)|(0<<5)|(0<<6);
    break;
  case 12u:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(1<<5)|(0<<6);
    break;
  case 1.2uA:
    PORTF = (0<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(1<<6);
    break;
  default:
    printf("no such selection");
  }
  return o;
}

"case 1.2" ? A switch() in C uses an integer value as the switch control so I doubt the C compiler would even accept "1.2" but even if it did it would convert to int and treat it as just "1" anyway. 

 

This is further compounded by the fact that you seem to have three almost identical cases. Two are exactly "case 1.2:" and for good measure there is a very curious "case 1.2uA" in there too. Well for a start C won't let you have two cases with the same value. But then there's that "uA" suffix on the 3rd. While it's true that there are certain characters you can add to the end of C literal constants such as "U" and "L" (to mean "unsigned" and "long") then C might be willing to tolerate a "u" suffix but I'm not aware of "A" being valid C??

 

As it happens you also have cases for "12" and "12u". That's a bit of a conundrum for a couple of reasons. Like I say you can't have duplicates. But like I say by a strange coincidence "u" is a valid suffix for a numeric constant. By default literal constant in C are "int" (by implication that is "signed int") so "12" means a signed integer value of 12. While "12u" means an "unsigned integer value of 12". I imagine the head of the C compiler will probably explode at this stage. I think it's going to reject this as duplicate even though there's that subtle difference in sign.

 

To be honest I wonder if you may not be better off learning about things like this (the fundamentals of C) in a PC environment where things like scanf() "just work". 

 

Oh and that code does:

  return o;
}

A couple of things wrong with that. One is that it appears to be a lower case letter O not the digit 0 (zero). But the other is that this is an embedded micro - there is no where to return to. Most C compilers do have a "catch" so that if you ever make the mistake or returning from main() then there's usually an infinite loop to "hold it". But there may be adverse side-effects. For example in avr-gcc that loop is preceded by a cli() so if the main() code was using interrupts in some way they are turned off. So the general structure of an embedded micro program should generally always be:

int main() {
    one_time_initialisaiton_stuff();
    while (1) {
        the_core_stuff_done_repeatedly();
    }
    // it never gets this far
}

 

 

where will the while (1) slot in the corrected block you did

Josh

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

avrcandies wrote:

Why on earth are your pins not named, just a bunch of numbers is almost useless....

BATTERY_ALARM_REDLED

 

HOIST_ENABLE

ROCKET_LUNCH_NOW  cheeky

 

names tell you something that numbers don't.

 

 

its just a rough code, am new to avr C. The numbers were planned to represent the current limit of the relays for easy selection on a user interface (pc)

 

Josh

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

raven231996 wrote:
ROCKET_LUNCH_NOW

 

Do rockets have different fuels for breakfast, lunch, tea, ... ?

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

ATXmega as I am playing around with the atxmega256au

 

Why are you writing all of this now ?...have you tried & got working an led blinking yet?  Start with the basics.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

avrcandies wrote:

ATXmega as I am playing around with the atxmega256au

 

Why are you writing all of this now ?...have you tried & got working an led blinking yet?  Start with the basics.

 

Yes I have

Josh

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

Please I when why are int8_t, int16_t and every other data type declaration used in embedded C instead of the normal int, double, float etc.

 

Are they used based on the number of bits of the ports on a microcontroller or what (an application example will help)

 

 

 

Thank you

Josh

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

I often write software to run 8-bit Arduino Uno, 32-bit ESP32, 32-bit ARM Cortex-4, ...

 

Different compilers have different native "int".

So life is clearer when you specify the exact type of a variable.

 

Especially important when you are using unsigned or signed variables  e.g. when unsigned char is promoted

Or when intermediate expressions will overflow a 16-bit signed int.

 

The compiler will be happier with "int" because it can match the native hardware better.   e.g. a Cortex-M4 is often faster with an int32_t than using a uint8_t that suits an AVR.

With most PC compilers an "int" is int32_t.    You seldom get any problems with promotion, extension or intermediate expressions.

Always choose the appropriate type of variable in embedded programs.

I suggest that you are "aware" of the promotion, extension or intermediate expression problems.

 

David.

 

p.s.   I would develop on the Arduino target you are familiar with e.g. Uno.    Then test on a Zero or Due.

This will show you different "int" sizes.    When developed,   you can port the working project to Xmega.    We can help with the "porting".

Last Edited: Wed. Jun 12, 2019 - 03:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

raven231996 wrote:

Please I when why are int8_t, int16_t and every other data type declaration used in embedded C instead of the normal int, double, float etc.

 

Are they used based on the number of bits of the ports on a microcontroller or what (an application example will help)

 

Thank you

The book you are learning C from should tell you about < stdint.h > and why it exists. If it doesn't tell you then get a better book.

 

Bottom line is that if I write "char", "short", "int", "long", "long long" in C you cannot possibly tell me how many bits are used in each of those and hence what numeric range they might be able to hold. For example on PCs "int" typically is 32 bits and can hold -2147483648 .. +2147483647 and yet "int" on an AVR is just 16 bits and can only hold -32768 .. +32767 so if you write:

int n = 12434567;

On a PC then that will work but on an AVR 'n' will actually contain -10,617. If, on the other hand I used:

#include <stdint.h>

int32_t n = 12434567;

then that is bound to work on PC, AVR or any other kind of architecture I build it on. What's more the reader can see by my choice of "int32_t" that I only ever expect 'n' to hold values in the range -2147483648 .. +2147483647

 

It's a very unwise programmer in this day and age (of all kinds of architectures and bit widths) to ever use base types like unsigned/signed char, short, int, long, long long. The only one you can probably rely on is char (the third one that is neither signed char nor unsigned char) that can still be used when you deal with characters not numbers.

 

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

clawson wrote:

raven231996 wrote:

Please I when why are int8_t, int16_t and every other data type declaration used in embedded C instead of the normal int, double, float etc.

 

Are they used based on the number of bits of the ports on a microcontroller or what (an application example will help)

 

Thank you

The book you are learning C from should tell you about < stdint.h > and why it exists. If it doesn't tell you then get a better book.

 

Bottom line is that if I write "char", "short", "int", "long", "long long" in C you cannot possibly tell me how many bits are used in each of those and hence what numeric range they might be able to hold. For example on PCs "int" typically is 32 bits and can hold -2147483648 .. +2147483647 and yet "int" on an AVR is just 16 bits and can only hold -32768 .. +32767 so if you write:

int n = 12434567;

On a PC then that will work but on an AVR 'n' will actually contain -10,617. If, on the other hand I used:

#include <stdint.h>

int32_t n = 12434567;

then that is bound to work on PC, AVR or any other kind of architecture I build it on. What's more the reader can see by my choice of "int32_t" that I only ever expect 'n' to hold values in the range -2147483648 .. +2147483647

 

It's a very unwise programmer in this day and age (of all kinds of architectures and bit widths) to ever use base types like unsigned/signed char, short, int, long, long long. The only one you can probably rely on is char (the third one that is neither signed char nor unsigned char) that can still be used when you deal with characters not numbers.

 

 

thank you

Josh

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

 

above is a screenshot of the source file of the device whose ports I intend using the block of codes (you assisted me with) to control switches connected to them. my issue now is merging the port program (you guys helped me on) with this source file. what file will I add the code, any need to create a header file  etc. Thank you

Josh

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

How could anyone possibly guess without knowing the contents of the files?

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

The ads file is for the external ADC. The Max5443 is for the DAC. The main file contains the functions the device is playing and always calls the experiment.C file when it's executing

Josh

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

Hello,

  SSRs can be one of the topics that can appear to be easy, but can be challenging.

 

In this case there is a bank of seven of them.  A scanf of the input returns a value between 0 and 6 which indicates which one, and only one,  in the bank of  SSRs will be "closed", or creating a physical electrical connection.

 

Is there allowed to be a period when all of the SSRs are off?  If yes, then what is the maximum value of this period?  If absolutely not; at least one SSR must have a closed electrical connection at all times; then what is the maximum period when there can be two (or more) on at the same time?

 

Are there weird side effects generated from the SSR switching?  ESD, ESR, EMP, EDB, and all that stuff?  How ;much energy are you switching off and on? 1 milliWatt, 1 kiloWatt?

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

The ads file is for the external ADC. The Max5443 is for the DAC. The main file contains the functions the device is playing and always calls the experiment.C file when it's executing

Why are you suddenly creating so many files?  How is that helping you, unless you remember what is in each file?   Close the file and all of your mistakes are nicely hidden away.  Now you will get really confused when a different file uses it.

Concentrate on writing one short program that works.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

The short program I wrote (which you guys assisted me with) has to be embedded into that source file

Josh

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

The intent is to control the current coming in by using a resistor connected to the input of the SSR and the SSR is connected to the microcontroller port. I just need to know where to place the block of code controlling (open or close) the ssr

Josh

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

I just need to know where to place the block of code controlling (open or close) the ssr

What do you mean?  You put it where you need it to be executed, or supply a functional call to it.  Do you have a good flowchart of what you are doing (or trying to do)?  It will show the proper place for everything to occur.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

No flowchart. It's a project being work on in the company am undertaking my internship. It's kind of a generational project as it hasn't been finished in a while

Josh

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

I was given the whole firmware to study

Josh

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

I was given the whole firmware to study

That means you'll probably be diagramming how the pieces of the pie fit together...if you don't have a clear vision of how the different gears interact, it will be hard to make useful progress.  While eventually hiding the inner working of each section is great to avoid information overload, ease maintenance, portability, etc'---not knowing how the basic system works is a fast path to nowhere.  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

avrcandies wrote:

I was given the whole firmware to study

That means you'll probably be diagramming how the pieces of the pie fit together...if you don't have a clear vision of how the different gears interact, it will be hard to make useful progress.  While eventually hiding the inner working of each section is great to avoid information overload, ease maintenance, portability, etc'---not knowing how the basic system works is a fast path to nowhere.  

 

thank you. doing so at the moment

Josh

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

ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, PIN4_bm)

 

please what does that mean above as its different from the convention I know. Are pins 2,3,4,5 set to 1(high)?

then why another pin4_bm?

Josh

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

Post a ZIP of the complete project if you want advice about specific statements.
.
If you can follow an ASF structure you deserve a medal.
.
There is probably some documentation for each function. I can only guess from a function name. You have to learn how to jump to a function definition and/or documentation.
.
David.

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

Josh

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

I was expecting to see an AS7 project that could be unzipped into a reader's PC.

I was expecting to see some form of HTML documentation e.g. from DOXYGEN

 

I could not see any HTML documentation at all.    But it looks as if it was intended to use DOXYGEN.

 

You can use the GitLab Search facilities.  e.g. ioport_set_port_level

 

This finds http://microfluidics.utoronto.ca...

and lines 257-

/**
 * \brief Set a group of IOPORT pins in a single port to a specified logical
 * value.
 *
 * \param port IOPORT port to write to
 * \param mask Pin mask of pins to modify
 * \param level Level of the pins to be modified
 */
static inline void ioport_set_port_level(ioport_port_t port,
		ioport_port_mask_t mask, ioport_port_mask_t level)
{
	arch_ioport_set_port_level(port, mask, level);
}

This gobbledygook means that the code was intended for DOXYGEN documentation.   Ask your manager how to generate the DOXGEN and how to navigate it.

 

Otherwise you just have to trawl through the code by guesswork.   i.e. guessing for likely words to Search for.   And then hoping you can spot the useful file.

 

Even from the documentation comment lines I am unsure what it is intended to do.   I would have to inspect the actual arch_ioport_set_port_level() code.

It would seem intuitive for level to be HIGH or LOW rather than a bit-mask.   But it might mean you read the current "level" via the bit-mask to determine the dynamic HIGH or LOW

 

If you get through your Internship you deserve a whole row of medals.

 

David.

Last Edited: Mon. Jun 17, 2019 - 08:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


ioport_set_port_level(ioport_port_t port,
		ioport_port_mask_t mask, ioport_port_mask_t level)

and:

ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, PIN4_bm)

do not really gel. I would say the person who invoked the code on this occasion did not understand the usage and use PIN4_bm as the last parameter in error. So it looks like you found a bug. I'm guessing the invocation was supposed to be something like:

ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, STATE_HIGH)
or
ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, STATE_LOW)

By the way, this looks an awful lot like an ASF function. If you Google the ASF manual you will find:

 

https://www.microchip.com/mplab/avr-support/advanced-software-framework

 

If you follow the links you get to:

Now I posted that picture to show that if you search "ioport" it shows various results and I can't guess which model of Xmega you are using so this is just to show there are various options. You will see that for each model of Xmega (A..E) there are links both to "documentation" and "quick start guides". I find the documentation to be virtually impenetrable so would always advise following links to "quick start" where they exist as those, on the whole, are quite easy to read and unlike the boring documentation they actually show the typical invocation sequence for the APIs. So If I just pick "Xmega A" at random:

 

doc:  https://asf.microchip.com/docs/latest/xmegaa/html/group__ioport__group.html

quick start:  https://asf.microchip.com/docs/latest/xmegaa/html/ioport_quickstart.html

 

Eventually you will get to:

 

https://asf.microchip.com/docs/latest/xmegaa/html/group__ioport__group.html#gaa1c3c3ecf8daabb58f458d60d04929b2

 

So the function is:

Set a group of IOPORT pins in a single port to a specified logical value.

Parameters

port IOPORT port to write to
mask Pin mask of pins to modify
level Level of the pins to be modified

References arch_ioport_set_port_level().

Referenced by main().

The actual function definition says this about the 3rd parameter:

enum ioport_value  level 

And you can click through on ioport_level to find the enum:

enum ioport_value

IOPORT levels.

Enumerator
IOPORT_PIN_LEVEL_LOW 

IOPORT pin value low

IOPORT_PIN_LEVEL_HIGH 

IOPORT pin value high

 

 

So in fact what you saw as:

ioport_set_port_level(IOPORT_PORTB, PIN2_bm|PIN3_bm|PIN4_bm|PIN5_bm, PIN4_bm)

is clearly a bug. The "PIN4_bm" on the end was supposed to be either IOPORT_PIN_LEVEL_LOW or IOPORT_PIN_LEVEL_HIGH

 

I would have very little confidence in this software if no one caught this during code review !

 

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

@Cliff,

 

The actual code in the OP's project says:

ioport_port_mask_t level

Your documentation link shows:

static void ioport_set_port_level 	( 	ioport_port_t  	port,
		ioport_port_mask_t  	mask,
		enum ioport_value  	level 
	) 		
	inlinestatic

Set a group of IOPORT pins in a single port to a specified logical value.

Parameters
    port	IOPORT port to write to
    mask	Pin mask of pins to modify
    level	Level of the pins to be modified

References arch_ioport_set_port_level().

Referenced by main().

It seems intuitive for level to be HIGH or LOW rather than a bit-mask.   I suspect   the OP's project just has an "elderly" ASF.

When a project is created with files from a specific ASF version,  you are stuck with it.    You need to read that specific documentation and study that specific implementation.

 

From a maintenance point of view you need to use the code from the ASF Release that was originally tested.   Bugs and all.

 

Or you migrate to a newer ASF,  newer Toolset, ... and perform EVERY test on your product.

 

David.

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

You might have hoped ASF would have backwards compatibility so the current documentation would cover both all the existing stuff and then new bits besides. Ho hum.

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

I looked up the OP's arch_ioport_set_port_level() to see how it was actually implemented:arch_ioport_set_port_level(

__always_inline static void arch_ioport_set_port_level(ioport_port_t port,
		ioport_port_mask_t mask, ioport_port_mask_t level)
{
	PORT_t *base = arch_ioport_port_to_base(port);

	base->OUTSET = mask & level;
	base->OUTCLR = mask & ~level;
}

So it does use a bit-mask for level.    And performs an operation that I did not expect.  i.e. it clears everything in the mask and sets only the bits in the "level" bit-mask.

 

The documentation in Cliff's link seems to be functionally different.   i.e. I assume it sets everything in the mask to HIGH or LOW "level".

The docs don't access the actual ASF code.   So I would have to import the whole ASF caboodle.

 

I am horrified that functionality could change without changing the name.     Untested.

 

David.

Last Edited: Mon. Jun 17, 2019 - 12:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

I was expecting to see an AS7 project that could be unzipped into a reader's PC.

I was expecting to see some form of HTML documentation e.g. from DOXYGEN

 

I could not see any HTML documentation at all.    But it looks as if it was intended to use DOXYGEN.

 

You can use the GitLab Search facilities.  e.g. ioport_set_port_level

 

This finds http://microfluidics.utoronto.ca...

and lines 257-

/**
 * \brief Set a group of IOPORT pins in a single port to a specified logical
 * value.
 *
 * \param port IOPORT port to write to
 * \param mask Pin mask of pins to modify
 * \param level Level of the pins to be modified
 */
static inline void ioport_set_port_level(ioport_port_t port,
		ioport_port_mask_t mask, ioport_port_mask_t level)
{
	arch_ioport_set_port_level(port, mask, level);
}

This gobbledygook means that the code was intended for DOXYGEN documentation.   Ask your manager how to generate the DOXGEN and how to navigate it.

 

Otherwise you just have to trawl through the code by guesswork.   i.e. guessing for likely words to Search for.   And then hoping you can spot the useful file.

 

Even from the documentation comment lines I am unsure what it is intended to do.   I would have to inspect the actual arch_ioport_set_port_level() code.

It would seem intuitive for level to be HIGH or LOW rather than a bit-mask.   But it might mean you read the current "level" via the bit-mask to determine the dynamic HIGH or LOW

 

If you get through your Internship you deserve a whole row of medals.

 

David.

Lol

Josh