diff options
Diffstat (limited to 'tests/spi-master')
-rw-r--r-- | tests/spi-master/Makefile.stm32l1-generic | 18 | ||||
-rw-r--r-- | tests/spi-master/README.md | 25 | ||||
-rw-r--r-- | tests/spi-master/hw.h | 41 | ||||
-rw-r--r-- | tests/spi-master/main-stm32l1-generic.c | 103 |
4 files changed, 187 insertions, 0 deletions
diff --git a/tests/spi-master/Makefile.stm32l1-generic b/tests/spi-master/Makefile.stm32l1-generic new file mode 100644 index 0000000..52ad2ec --- /dev/null +++ b/tests/spi-master/Makefile.stm32l1-generic @@ -0,0 +1,18 @@ +BOARD = stm32l1-generic +PROJECT = spi-master-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../../shared + +CFILES = main-$(BOARD).c +#CFILES += spi-master.c +CFILES += trace.c trace_stdio.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../../libopencm3 +DEVICE=stm32l151xb +OOCD_FILE = openocd.stm32l1-generic.cfg +include ../../rules.mk diff --git a/tests/spi-master/README.md b/tests/spi-master/README.md new file mode 100644 index 0000000..fddca8d --- /dev/null +++ b/tests/spi-master/README.md @@ -0,0 +1,25 @@ +SPI master mode tests + +While some of the disco boards have some form of spi device onboard, +which would, on the face of it, make testing easy, it's a different +device on each board, and there are boards without it. + +Instead, use a known SPI peripheral on all boards, and require/expect +a known fixed SPI slave device. Use a soft controller SPI slave device +for the far side, for double the test coverage! + +the "trigger" pin is bounced when each iteration of the test code starts, +allowing synchronization with a sigrok script that helps assure that +results are as expected. + +Debug is via SWO wherever possible, PA2 (tx only) on less capable cores + +Pinouts: + (red) (orange) (yellow)(brown) (black) +board SCK MISO MOSI CS periph trigger +f4-disco PB13 PB14 PB15 PB12 spi2 PB11 +l1-disco PB13 PB14 PB15 PB12 spi2 PB11 + + +Notes for monitoring with sigrok: +$ sigrok-cli -d fx2lafw -C D0=TRIG,D1=CS,D2=CLK,D3=MISO,D4=MOSI -c samplerate=12Mhz:captureratio=4 --time=150ms -t TRIG=r -P spi:clk=CLK:miso=MISO:mosi=MOSI -l 4 2>/dev/null | grep -- -data diff --git a/tests/spi-master/hw.h b/tests/spi-master/hw.h new file mode 100644 index 0000000..2cbbea8 --- /dev/null +++ b/tests/spi-master/hw.h @@ -0,0 +1,41 @@ +/* + * March 2017 Karl Palsson <karlp@tweak.net.au> + */ + +#include <stdbool.h> +#include <stdint.h> + +#pragma once + +struct hw_detail +{ + uint32_t periph; /* eg: SPI2 */ + uint32_t periph_rcc; /* eg: RCC_SPI2 */ + uint32_t periph_rst; /* eg: RST_SPI2 */ + uint32_t pins; /* to set to the AF for the periph */ + uint32_t port; /* eg GPIOB */ + uint32_t port_rcc; /* for the gpio pins */ + uint32_t trigger_rcc; + uint32_t trigger_port; + uint32_t trigger_pin; +}; + +extern struct hw_detail hw_details; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Expected to setup clocks, turn on all peripherals, and configure + * any gpios necessary. + * @param hw pointer to hw details necessary + */ + void hw_setup(struct hw_detail* hw); + + /* let devices have a status led */ + void hw_set_led(bool val); + +#ifdef __cplusplus +} +#endif diff --git a/tests/spi-master/main-stm32l1-generic.c b/tests/spi-master/main-stm32l1-generic.c new file mode 100644 index 0000000..1763995 --- /dev/null +++ b/tests/spi-master/main-stm32l1-generic.c @@ -0,0 +1,103 @@ +/* + * March 2017 Karl Palsson <karlp@tweak.net.au> + */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/spi.h> +#include <libopencm3/stm32/rcc.h> + +#include "trace.h" + +#include "hw.h" +//#include "i2c-master.h" + +#define LED_DISCO_GREEN_PORT GPIOB +#define LED_DISCO_GREEN_PIN GPIO7 + + +struct hw_detail hw_details = { + .periph = SPI2, + .periph_rcc = RCC_SPI2, + .periph_rst = RST_SPI2, + .pins = GPIO13| GPIO14 | GPIO15, /* SPI pins for setting AF with */ + .port = GPIOB, + .port_rcc = RCC_GPIOB, + .trigger_rcc = RCC_GPIOB, + .trigger_port = GPIOB, + .trigger_pin = GPIO11, +}; + + +/* provided in board files please*/ +/** + * Setup any gpios or anything hardware specific. + * Should _only_ be things that can't be done in shared init() + */ +static void hw_init(void) +{ + /* trigger pin gpio */ + rcc_periph_clock_enable(hw_details.trigger_rcc); + gpio_mode_setup(hw_details.trigger_port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, hw_details.trigger_pin); + + /* spi control lines */ + rcc_periph_clock_enable(hw_details.port_rcc); + gpio_mode_setup(hw_details.port, GPIO_MODE_AF, GPIO_PUPD_NONE, hw_details.pins); + gpio_set_output_options(hw_details.port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, hw_details.pins); + gpio_set_af(hw_details.port, GPIO_AF5, hw_details.pins); +} + +static void test_init(void) +{ + /* Setup SPI parameters. */ + rcc_periph_clock_enable(hw_details.periph_rcc); + spi_init_master(hw_details.periph, SPI_CR1_BAUDRATE_FPCLK_DIV_16, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + /* Ignore the stupid NSS pin. */ + spi_enable_software_slave_management(hw_details.periph); + //spi_enable_ss_output(MRF_SPI); + spi_set_nss_high(hw_details.periph); + /* Finally enable the SPI. */ + spi_enable(hw_details.periph); +} + +static void test_task(void) { + static int i = 0; + printf("Test iteration %d\n", i++); + gpio_set(hw_details.trigger_port, hw_details.trigger_pin); + spi_xfer(hw_details.periph, 0xaa); + spi_xfer(hw_details.periph, 0x42); + spi_xfer(hw_details.periph, 0x69); + gpio_clear(hw_details.trigger_port, hw_details.trigger_pin); +} + +static void setup(void) +{ + printf("hi guys!\n"); + hw_init(); + test_init(); +} + + +int main(void) +{ + int i, j; + rcc_clock_setup_pll(&rcc_clock_config[RCC_CLOCK_VRANGE1_HSI_PLL_32MHZ]); + /* green led for ticking */ + rcc_periph_clock_enable(RCC_GPIOB); + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, + LED_DISCO_GREEN_PIN); + setup(); + + while (1) { + test_task(); + gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); + for (i = 0; i < 0x800000; i++) { /* Wait a bit. */ + __asm__("NOP"); + } + } + return 0; +} |