summaryrefslogtreecommitdiff
path: root/tests/spi-master
diff options
context:
space:
mode:
Diffstat (limited to 'tests/spi-master')
-rw-r--r--tests/spi-master/Makefile.stm32l1-generic18
-rw-r--r--tests/spi-master/README.md25
-rw-r--r--tests/spi-master/hw.h41
-rw-r--r--tests/spi-master/main-stm32l1-generic.c103
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;
+}