xmega a3bu cannot change status of a PORT's pins

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

hi,

 

i'm using an xmega-a3bu Xplained board to receive data from a linux pc.  without flow control it's data overrun city (57600), as i'm storing values in flash sector-by-sector.  i believe the code is sufficiently fast to keep up at 57600 until i have to do a dataflash write...

 

i'm using J1 (PORTC) pins 2 and 3 for tx/rx, and the code to support this is from ASF.  of course, that stuff works fine.  8^O

 

after trying several port pin sets for cts/rts, i settled on using PORTB pins 2 and 3.  that code looks like this:

 

void uno_usart_cts_yes(void) {
	gpio_set_pin_high(J2_PIN3);
}

void uno_usart_cts_no(void) {
	gpio_set_pin_low(J2_PIN3);
}

in xmega_a3bu_xplained.h one can spy: 

#define J2_PIN3                        IOPORT_CREATE_PIN(PORTB, 3)

i see in "8/16-bit Atmel XMEGA A3BUMicrocontroller" on pp. 60 (at bottom) it says:

 

Base Address      Name       Description

0x0620                PORTB      Port B

 

Q1:  i thought all 8-bit i/o ports were mapped to a single byte?  here it seems that PORTB has 32 bytes (0x20) reserved to it, from 0x0620 through 0x062F.

 

so i setup debug to view "data IO" memory at "0x0620,data" and step through the code.

 

before the first gpio_set_pin... call:

data 0x0620  00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data 0x063A  00 00 00 00 00 00

 

after the first gpio_set_pin... call (was a "gpio_set_pin_low(J2_PIN3);"):

data 0x0620  00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data 0x063A  00 00 00 00 00 00

 

after the second gpio_set_pin... call (was a "gpio_set_pin_high(J2_PIN3);"):

data 0x0620  00 00 00 00 08 08 08 08 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data 0x063A  00 00 00 00 00 00

 

Q2:  i'm setting one pin high.  why should four bytes (0x0640-0x0647) change?

 

after the third gpio_set_pin... call (was a "gpio_set_pin_low(J2_PIN3);"):

data 0x0620  00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data 0x063A  00 00 00 00 00 00

 

all four bytes (?!?) now back to 0x00.

 

the big issue for me is that no matter what happens in the code and how it looks in memory, the voltage on the pin is ~1milliVolt, and will not budge.  set it high, set it low, it's showing ~1mV on my scope.  i swap the scope connection from J2 pin 3 to J2 pin 10 (vcc) and i see 3.3V, so i know the scope is connected properly to ground and thus should read a voltage off J2 pin 3.

 

if someone could please lmk where either i'm a total idiot, or i've made a serious wrong turn, or if i should RTFM (and if so, which one and which parts?), i'd appreciate it.

 

finally, Q3:  is it better for me to manually set the bits using some form of "PORTB |& << blah" code than using the function/service "gpio_set_pin..." calls?  the faster i can turn CTS off/on, the faster i can load the data into flash, yes?

 

thanks in advance!

This topic has a solution.
Last Edited: Mon. Sep 12, 2016 - 06:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In answer to question 3 the Xmegas have very useful SET, CLR & TGL extensions to some of the registers, including the PORTx.OUT register. So if you wanted to set a bit you can just do 

PORTx.OUTSET = PINn_bm;

where x is the port letter and n is the bit number. Similarly to clear you would do 

PORTx.OUTCLR = PINn_bm;

I don't know 100% if this is quicker than using the functions that come with ASF but I'd bet on it being the case. I personally never use ASF as it seems quite bloated from what I can tell.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi Howard,

 

hey, thanks for that!  i've swapped in that code, and it works fine.  while i can't judge speed without adding timing code, it certainly looks more appropriate to me.

 

sadly, nothing's happening at the pins vis-a-vis voltage.

do i have to invoke or have separate code that sets up the two pins i'm using for output?  the port i/o memory is changing, so if the pin voltage isn't changing...  maybe i'm missing this.

 

never mind - i found atmel pub doc8050 "Using the XMEGA IO Pins and External Interrupts", and am RTFMing now.

 

fwiw, i needed this:

 

    PORTB.DIRSET = PIN2_bm | PIN3_bm;   //  ind output voltage should change

 

wouldn't have found it if you didn't mention PORTx.functions.  thanks again Howard!

Last Edited: Mon. Sep 12, 2016 - 06:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, yeah I probably should've mentioned data direction setting too! Glad I could help!