My foray into ASF isn't going quite as planned
Following on from this post I'm looking to implement a basic bitbang sequence to a shift register. As I've never used ASF before, I thought I'd get my head around this process by simply toggling a pin from HIGH to LOW every 500ms. Whilst I do have an Xplained board available, I'm using the 'user board' approach in Atmel Studio instead, adding in the required modules using the Wizard. The MCU in question is the ATSAME70Q21. The structure and code I have thus far is as follows:
conf_board.h:
#ifndef CONF_BOARD_H #define CONF_BOARD_H //Bitbang data and clock pins #define BBDAT IOPORT_CREATE_PIN(PIOB, 4) #define BBCLK IOPORT_CREATE_PIN(PIOB, 5) #define TEST IOPORT_CREATE_PIN(PIOD, 29) //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
init.c:
#include <asf.h> #include <board.h> #include <conf_board.h> void board_init(void) { /* This function is meant to contain board-specific initialization code * for, e.g., the I/O pins. The initialization can rely on application- * specific board configuration, found in conf_board.h. */ WDT->WDT_MR = WDT_MR_WDDIS; ioport_init(); ioport_reset_pin_mode(BBCLK); ioport_set_pin_dir(BBCLK, IOPORT_DIR_OUTPUT); ioport_set_pin_dir(BBDAT, IOPORT_DIR_OUTPUT); ioport_set_pin_dir(TEST, IOPORT_DIR_OUTPUT); }
main.c:
#include <asf.h> int main (void) { /* Insert system clock initialization code here (sysclk_init()). */ sysclk_init(); board_init(); bool pin_level; while (1) { pin_level = ioport_get_pin_level(BBCLK); if (pin_level) { ioport_set_pin_level(BBCLK, IOPORT_PIN_LEVEL_LOW); } else { ioport_set_pin_level(BBCLK, IOPORT_PIN_LEVEL_HIGH); } delay_ms(500); } /* Insert application code here, after the board has been initialized. */ }
As you can see, I define 3 pins:
- BBDAT (PB4 - pin 105)
- BBCLK (PB5 - pin 109)
- TEST (PD29 - pin 108)
In the main loop, the current value of the chosen pin is read (pin_level), and its value is then swapped in the if statement. I understand ioport provides a toggle function, but I'm doing it this way to make it easier to step through. I have a breakpoint on the 500ms delay, and an Action to print the value of pin_level.
When I run main.c with TEST as the ioport pin, pin_level switches between true and false as planned, which I've verified on my board with a multimeter. However, when I use either BBDAT or BBCLK, pin_level is always false (also verified with a multimeter).
Given that PB4 and PB5 are TWIHS pins, I had thought that maybe some muxing had been setup in the background, but I've reset the pin mode (via the ioport macro), made sure that none of the linked ASF libraries or modules have anything remotely related to TWIHS, so I'm not sure if that's the case. One difference to note from the datasheet is that PB4 and PB5 are of type GPIO_MLB, whereas PD29 is of type GPIO_AD. Having done some investigation I don't believe this should cause an issue, as the primary signal and direction for PD4/PD5 is still GPIO and I/O respectively, so they should be addressable/configurable as such.
What am I missing here?