ASF Port Read Write

Created on: 5 June 2016

Part 10 of the ASF ARM Tutorial

How to read and write a port or group of port pins using Atmel Software Framework.

ASF is used to read two switches on a port and write the switch values to two LEDs on a port of an Atmel ARM Cortex microcontroller. The port pins for the read and write operations are accessed using ASF functions from the IOPORT module that access the port pins as a group of pins rather than individual input and output pins.

The following ASF IOPORT module functions are used in this part of the ASF ARM tutorial:

  • ioport_enable_port() – enables the selected port or group of port pins determined by a mask value.
  • ioport_set_port_dir() – sets the direction of the port or group of port pins as either inputs or outputs.
  • ioport_set_port_mode() – sets the mode of the port such as enabling pull-up or pull-down resistors on the port pins.
  • ioport_get_port_level() – gets or reads the state of a port or group of port pins determined by a mask value.
  • ioport_set_port_level() – is used to write a value to a port or group of port pins.

Hardware Configuration and Circuit Diagram

Two switches are connected to two port pins PC23 and PC24. Two LEDs and series resistors are connected to port pins PA11 and PA12. These pins are taken from the EXT1 header of a SAM4N Xplained Pro board and the circuit built on a breadboard as shown in the image below. Make the necessary changes to the hardware and port definitions in the software if you are using a different board.

ASF Port Read Write Breadboard Circuit

ASF Port Read Write Breadboard Circuit

Switch and LED connections to the board are shown in the circuit diagram below.

Circuit Diagram for the In Out Port Project

Circuit Diagram for the In Out Port Project

Amazon.com

Amazon.co.uk

Creating the ASF Port Read Write Project

Create a new ASF project called in_out_port in Atmel Studio as explained in the ASF quick start checklist.

Add the IOPORT - General purpose I/O service (service) module to the project using the ASF Wizard. Although the System Clock Control service is shown in the modules added to the project in the image below, it is a dependency of the IOPORT module so will be added automatically.

In Out Port Project ASF Modules

In Out Port Project ASF Modules

In Out Port Application Code using ASF

Modify the following files in the in_out_port Atmel Studio project.

Hardware Definitions

Mask and offset values are defined in conf_board.h as shown in the code listing below. The offset value is used to shift the mask to the correct bit position on the LED and switch ports.

\src\config\conf_board.h

#ifndef CONF_BOARD_H
#define CONF_BOARD_H

// 2 LEDs on pins PA11 and PA12
// LEDs starting at pin 11 of PORTA
#define EXT_LED_PORTA_OFFSET    11
// 2 bit wide mask for LEDs on PORTA
#define EXT_LED_PORTA_MASK      (0x03 << EXT_LED_PORTA_OFFSET)

// 2 switches on pins PC23 and PC24
#define EXT_SW_PORTC_OFFSET     23
#define EXT_SW_PORTC_MASK       (0x03 << EXT_SW_PORTC_OFFSET)

// clock resonators
#define BOARD_FREQ_SLCK_XTAL (32768U)
#define BOARD_FREQ_SLCK_BYPASS (32768U)
#define BOARD_FREQ_MAINCK_XTAL (12000000U)
#define BOARD_FREQ_MAINCK_BYPASS (12000000U)
#define BOARD_MCK CHIP_FREQ_CPU_MAX
#define BOARD_OSC_STARTUP_US 15625

#endif // CONF_BOARD_H

Hardware Initialization

Pins on port A are set up as outputs and pins on port C are set up as inputs with pull-down resistors in the board_init() function in init.c as shown in the listing below.

\src\ASF\common\boards\user_board\init.c

#include <asf.h>
#include <board.h>
#include <conf_board.h>

void board_init(void)
{
    WDT->WDT_MR = WDT_MR_WDDIS; // disable watchdog
    ioport_init();              // call before using IOPORT service
    
    // enable PORTA and set direction of port as output
    ioport_enable_port(IOPORT_PIOA, EXT_LED_PORTA_MASK);
    ioport_set_port_dir(IOPORT_PIOA, EXT_LED_PORTA_MASK, IOPORT_DIR_OUTPUT);
    
    // enable PORTC and set direction of port as input
    ioport_enable_port(IOPORT_PIOC, EXT_SW_PORTC_MASK);
    ioport_set_port_dir(IOPORT_PIOC, EXT_SW_PORTC_MASK, IOPORT_DIR_INPUT);
    // enable pull-down resistors on port
    ioport_set_port_mode(IOPORT_PIOC, EXT_SW_PORTC_MASK, IOPORT_MODE_PULLDOWN);
}

Main Application code

In the main application code in main.c the state of the switches on port C are read into the port_pins variable. These values are then shifted to get them to the bottom of this variable.

The switch states that are stored in port_pins are then written to the two LEDs on PORT A. It is necessary to shift these bits to the correct bit positions to line up with the LEDs connected to PORT A.

\src\main.c

#include <asf.h>

int main (void)
{
    uint32_t port_pins;
    
    sysclk_init();
    board_init();

    while (1) {
        port_pins = ioport_get_port_level(IOPORT_PIOC, EXT_SW_PORTC_MASK);
        port_pins >>= EXT_SW_PORTC_OFFSET;
        ioport_set_port_level(IOPORT_PIOA, EXT_LED_PORTA_MASK, (port_pins << EXT_LED_PORTA_OFFSET));
    }
}

The following video shows the port read write / in out application running on a SAM4N Xplained Pro board.

Can't see the video? View on YouTube →

← Go back to Part 9 of the ASF ARM TutorialGo to Part 11 of the ASF ARM Tutorial →