Search code examples
embeddedpollingdmaatmelatmelstudio

XMEGA-A3BU Xplained - Determine if pushbutton 1 is pressed by polling using DMA


The assignment requires us to toggle ON LEDs if SW1 is pressed by using polling. I believe I am setting the direction of each port and reading the register correctly. However nothing happens when I press SW1. There is no way to debug and breakpoint the code while the code is running to see whats in the registers.

[HWGuide] states: [HWGuide]:http://ww1.microchip.com/downloads/en/DeviceDoc/doc8394.pdf

//LED0 = PR0 (PORTR PIN 0)
//LED1 = PR1 (PORTR PIN 1)
//SW1  = PF1 (PORTF PIN 1)

[Datasheet] states: [Datasheet]:http://ww1.microchip.com/downloads/en/DeviceDoc/atmel-8362-8-and-16bit-avr-microcontroller-atxmega256a3bu_datasheet.pdf

//PORTR starts at address = 0x07E0
//PORTF starts at address = 0x06A0

[Manual] states: [Manual]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf

//Data Input Value register on I/O = (Addr) + 0x08 = 0x06A8 (PORTF)

Code:

#define PORTR    *((volatile unsigned char *)0x7E0) /* I/O Port Register */
#define PORTF    *((volatile unsigned char *)0x6A0) /* I/O Port Register */
#define PORTF_IN *((volatile unsigned char *)0x6A8) //PORTF Input Value Reg
#define PORTR_OUTTGL    *((volatile unsigned char *)0x7E7) //LED Toggle Reg

#define ReadReg(port)           (port)
#define WriteReg(port, value)   (port = value)

int main(void)
{
    //set PORTR direction
    WriteReg(PORTR, 0xFF);
    //set PORTF direction
    WriteReg(PORTF, 0x00);
    while(1)
    {
        if((ReadReg(PORTF_IN) == 0xFD)) //if PF1 = 0
        { 
            WriteReg(PORTR_OUTTGL, 0x3); //toggle LEDs
        {
    {
}

I expect the register to read either (0x02)0000 0010 or the inverse (0xFD)1111 1101 and LEDs to turn on or off if the button is pressed.


Solution

  • Used bit manipulation to isolate the bit I was trying to poll for. Had no idea what the other bits could have been set to.

    int main(void)
    {
        //set PORTR direction
        WriteReg(PORTR, 0xFF);
        //set PORTF direction
        WriteReg(PORTF, 0xF9);
        while(1)
        {
            char statusPF1 = (ReadReg(PORTF_IN) & 0x02) >> 1;
            char statusPF2 = (ReadReg(PORTF_IN) & 0x04) >> 2;
    
            if((statusPF1 == 0)) //if PF1 = 0
            {
                WriteReg(PORTR_OUTTGL, 0x01); //toggle LED0
                _delay_ms(1000);
            }
            if((statusPF2 == 0)) //if PF2 = 0
            {
                WriteReg(PORTR_OUTTGL, 0x02); //toggle LED1
                _delay_ms(1000);
            }
            if ((statusPF1 != 0) && (statusPF2 != 0))
            {
                _blinkLEDs();
            }
        }
    }