|
| 1 | +/** |
| 2 | + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: BSD-3-Clause |
| 5 | + */ |
| 6 | + |
| 7 | +#include <stdio.h> |
| 8 | +#include <stdlib.h> |
| 9 | + |
| 10 | +#include "pico/stdlib.h" |
| 11 | +#include "hardware/clocks.h" |
| 12 | +#include "hardware/pio.h" |
| 13 | +#include "hardware/spi.h" |
| 14 | +#include "clocked_input.pio.h" |
| 15 | + |
| 16 | +// Set up a PIO state machine to shift in serial data, sampling with an |
| 17 | +// external clock, and push the data to the RX FIFO, 8 bits at a time. |
| 18 | +// |
| 19 | +// Use one of the hard SPI peripherals to drive data into the SM through a |
| 20 | +// pair of external jumper wires, then read back and print out the data from |
| 21 | +// the SM to confirm everything worked ok. |
| 22 | +// |
| 23 | +// On your Pico you need to connect jumper wires to these pins: |
| 24 | +// - GPIO 2 -> GPIO 5 (clock output to clock input) |
| 25 | +// - GPIO 3 -> GPIO 4 (data output to data input) |
| 26 | + |
| 27 | +#define SPI_SCK_PIN 2 |
| 28 | +#define SPI_TX_PIN 3 |
| 29 | +// GPIO 4 for PIO data input, GPIO 5 for clock input: |
| 30 | +#define PIO_INPUT_PIN_BASE 4 |
| 31 | + |
| 32 | +#define BUF_SIZE 8 |
| 33 | + |
| 34 | +int main() { |
| 35 | + stdio_init_all(); |
| 36 | + |
| 37 | + // Configure the SPI before PIO to avoid driving any glitches into the |
| 38 | + // state machine. |
| 39 | + spi_init(spi0, 1000 * 1000); |
| 40 | + uint actual_freq_hz = spi_set_baudrate(spi0, clock_get_hz(clk_sys) / 6); |
| 41 | + printf("SPI running at %u Hz\n", actual_freq_hz); |
| 42 | + gpio_set_function(SPI_TX_PIN, GPIO_FUNC_SPI); |
| 43 | + gpio_set_function(SPI_SCK_PIN, GPIO_FUNC_SPI); |
| 44 | + |
| 45 | + // Load the clocked_input program, and configure a free state machine |
| 46 | + // to run the program. |
| 47 | + PIO pio = pio0; |
| 48 | + uint offset = pio_add_program(pio, &clocked_input_program); |
| 49 | + uint sm = pio_claim_unused_sm(pio, true); |
| 50 | + clocked_input_program_init(pio, sm, offset, PIO_INPUT_PIN_BASE); |
| 51 | + |
| 52 | + // Make up some random data to send. |
| 53 | + static uint8_t txbuf[BUF_SIZE]; |
| 54 | + puts("Data to transmit:"); |
| 55 | + for (int i = 0; i < BUF_SIZE; ++i) { |
| 56 | + txbuf[i] = rand() >> 16; |
| 57 | + printf("%02x\n", txbuf[i]); |
| 58 | + } |
| 59 | + |
| 60 | + // The "blocking" write function will send all the data in one go, and not |
| 61 | + // return until the full transmission is finished. |
| 62 | + spi_write_blocking(spi0, (const uint8_t*)txbuf, BUF_SIZE); |
| 63 | + |
| 64 | + // The data we just sent should now be present in the state machine's FIFO. |
| 65 | + puts("Reading back from RX FIFO:"); |
| 66 | + for (int i = 0; i < BUF_SIZE; ++i) { |
| 67 | + uint8_t rxdata = pio_sm_get_blocking(pio, sm); |
| 68 | + printf("%02x %s\n", rxdata, rxdata == txbuf[i] ? "OK" : "FAIL"); |
| 69 | + } |
| 70 | + puts("Done."); |
| 71 | +} |
0 commit comments