Possible error in Microchip sample code

Hi I am new to baremetal coding with 4809, but thought I’d post this for the benefit of any other new types.

In the microchip example code for getting started with USART ( TB3216_Getting_Started_with_USART ) , I thnk there’s a coding error.

in the LED_on function the code is:
PORTB.OUT &= ~PIN5_bm; which clears the pin

and in the LED_off function the code is
PORTB.OUT |= PIN5_bm; which sets the pin

These just need the function names swapped over.

I am completely new to this stuff, so if I’m wrong that’s no surprise, but when I ran the code the LED was constantly on irrespective of the command sent via serial (ON or OFF)
I swapped the code and it works: ON => Led goes on. OFF=> Led goes off.


Hi, that looks not too bad. Typically, the PORTS are output registers which work like a bitmask, so each bit stands for an individual output. If you now write

// turn PIN5 of PORT5 on
PORTB.OUT |= (True << PIN5_bm);

this will set PIN_5 of PORTB to True (the << shift operation is really quick and won’t waste cycles, that’s why you’ll find those a lot when doing low-level embedded programming).
Similar for clearing a bit:

// turn PIN5 of PORTB off
PORTB.OUT &= ~(True << PIN5_bm);

will clear PIN5 by making sure that NONE of PORTB’s other bit’s values are touched.
The |= operator is used to set a bit within a byte register while &= operator makes sure that a bit is cleared, both without affecting the other bit’s states.

For clarification: this depends a lot on how the expressions are defined, in this case PIN5_bm. My description above is valid for a mask that defines the bit, so PIN5_bm = 5 in my case. For a different calculation, e.g. PIN5_bm = 0x10, then the above code you wrote would be perfect.

If the LED turns off by setting the pin HIGH you might just have a LED with inverted logic?


If the Cathode ("-") of the LED is connected to GND, a HIGH voltage on the other side (through a resistor) will turn it on. If the LED is tied to 3.3V through the ("+") side, the other side has to go to GND to allow current to flow from + to -.

The code you’ve posted definitely sets the pin to LOW / HIGH as it says, @schallbert is right. AND-ing with the bit-inverse of a bitmask (think, 1 << pin_number) will clear the correspnding bit, OR-ing it with the bitmask will set the bit. Whether the LED turns off or on on the board depends on how it’s wired, as per above.

If you’re using a premade development board or you’ve set up the LED yourself, we can have a look at schematics.

You are of course right to exchange the code in the LED_on() and LED_off() functions if your board has a LED with inverted logic.

Thanks for replies, it’s interesting to see the perspectives. I understand the logic concepts, my circuit is set as positive logic (pin goes high Led lights). I have been following examples in Elliot Eilliams’ MAKE: AVR book. I thought that pin bit masks such as PIN5_bm would be b00100000 (one in 5th bit postion zero indexed). When you OR that with whatever’s in the PORTB reg you get xx1xxxxx where x’s are unchanged.

So PORTB.OUT |= PIN5_bm; would set pin PB5 (if set as output in ddr)

Thanks for help.

Indeed. You can Ctrl+Click on any macro in the VSCode IDE and it will take you to the definition. In this case the iom4809.h file within the toolchain says

// Generic Port Pins

#define PIN0_bm 0x01
#define PIN0_bp 0
#define PIN1_bm 0x02
#define PIN1_bp 1
#define PIN2_bm 0x04
#define PIN2_bp 2
#define PIN3_bm 0x08
#define PIN3_bp 3
#define PIN4_bm 0x10
#define PIN4_bp 4
#define PIN5_bm 0x20
#define PIN5_bp 5
#define PIN6_bm 0x40
#define PIN6_bp 6
#define PIN7_bm 0x80
#define PIN7_bp 7

So the bp ones are like a pin number value an the bm is the bitmask, 1 << 0, 1 << 1, 1 << 2, etc. PIN5_bm is 0x20 which is “0010 0000” in binary, or 1 << 5, or, 5th bit from the right, zero-indexed, is set.

If you’ve setup the LED correctly then it’s even stranger that still a “LOW” on the pin turns of the LED – you should check voltages of the pin and the polarity of the LED (diode test) to double check what’s going on in the circuit here.

Eh, sorry I couldn’t read properly.

You’re absolutely right the functions need to be exchanged for your setup. The SDK code expects a inverted-logic LED

They code it so that if they want to turn the LED on, the pin has to be set to LOW. They’re expecting an inverted logic LED wireup here. So if you use a positive logic wireup, it will be inverted again. So all is nominal.

thanks - the Ctrl + click is a big tip, I was off to try to open the .h file once I’d found it :slight_smile: