Add pio_clocked_input example
This commit is contained in:
parent
a62287a18e
commit
dbe9a66898
@ -1,6 +1,7 @@
|
||||
if (NOT PICO_NO_HARDWARE)
|
||||
add_subdirectory(addition)
|
||||
add_subdirectory(apa102)
|
||||
add_subdirectory(clocked_input)
|
||||
add_subdirectory(differential_manchester)
|
||||
add_subdirectory(hello_pio)
|
||||
add_subdirectory(hub75)
|
||||
|
||||
16
pio/clocked_input/CMakeLists.txt
Normal file
16
pio/clocked_input/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
add_executable(pio_clocked_input)
|
||||
|
||||
pico_generate_pio_header(pio_clocked_input ${CMAKE_CURRENT_LIST_DIR}/clocked_input.pio)
|
||||
|
||||
target_sources(pio_clocked_input PRIVATE clocked_input.c)
|
||||
|
||||
target_link_libraries(pio_clocked_input PRIVATE
|
||||
pico_stdlib
|
||||
hardware_pio
|
||||
hardware_spi
|
||||
)
|
||||
|
||||
pico_add_extra_outputs(pio_clocked_input)
|
||||
|
||||
# add url via pico_set_program_url
|
||||
example_auto_set_url(pio_clocked_input)
|
||||
71
pio/clocked_input/clocked_input.c
Normal file
71
pio/clocked_input/clocked_input.c
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/spi.h"
|
||||
#include "clocked_input.pio.h"
|
||||
|
||||
// Set up a PIO state machine to shift in serial data, sampling with an
|
||||
// external clock, and push the data to the RX FIFO, 8 bits at a time.
|
||||
//
|
||||
// Use one of the hard SPI peripherals to drive data into the SM through a
|
||||
// pair of external jumper wires, then read back and print out the data from
|
||||
// the SM to confirm everything worked ok.
|
||||
//
|
||||
// On your Pico you need to connect jumper wires to these pins:
|
||||
// - GPIO 2 -> GPIO 5 (clock output to clock input)
|
||||
// - GPIO 3 -> GPIO 4 (data output to data input)
|
||||
|
||||
#define SPI_SCK_PIN 2
|
||||
#define SPI_TX_PIN 3
|
||||
// GPIO 4 for PIO data input, GPIO 5 for clock input:
|
||||
#define PIO_INPUT_PIN_BASE 4
|
||||
|
||||
#define BUF_SIZE 8
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
|
||||
// Configure the SPI before PIO to avoid driving any glitches into the
|
||||
// state machine.
|
||||
spi_init(spi0, 1000 * 1000);
|
||||
uint actual_freq_hz = spi_set_baudrate(spi0, clock_get_hz(clk_sys) / 6);
|
||||
printf("SPI running at %u Hz\n", actual_freq_hz);
|
||||
gpio_set_function(SPI_TX_PIN, GPIO_FUNC_SPI);
|
||||
gpio_set_function(SPI_SCK_PIN, GPIO_FUNC_SPI);
|
||||
|
||||
// Load the clocked_input program, and configure a free state machine
|
||||
// to run the program.
|
||||
PIO pio = pio0;
|
||||
uint offset = pio_add_program(pio, &clocked_input_program);
|
||||
uint sm = pio_claim_unused_sm(pio, true);
|
||||
clocked_input_program_init(pio, sm, offset, PIO_INPUT_PIN_BASE);
|
||||
|
||||
// Make up some random data to send.
|
||||
static uint8_t txbuf[BUF_SIZE];
|
||||
puts("Data to transmit:");
|
||||
for (int i = 0; i < BUF_SIZE; ++i) {
|
||||
txbuf[i] = rand() >> 16;
|
||||
printf("%02x\n", txbuf[i]);
|
||||
}
|
||||
|
||||
// The "blocking" write function will send all the data in one go, and not
|
||||
// return until the full transmission is finished.
|
||||
spi_write_blocking(spi0, (const uint8_t*)txbuf, BUF_SIZE);
|
||||
|
||||
// The data we just sent should now be present in the state machine's FIFO.
|
||||
puts("Reading back from RX FIFO:");
|
||||
for (int i = 0; i < BUF_SIZE; ++i) {
|
||||
uint8_t rxdata = pio_sm_get_blocking(pio, sm);
|
||||
printf("%02x %s\n", rxdata, rxdata == txbuf[i] ? "OK" : "FAIL");
|
||||
}
|
||||
puts("Done.");
|
||||
}
|
||||
51
pio/clocked_input/clocked_input.pio
Normal file
51
pio/clocked_input/clocked_input.pio
Normal file
@ -0,0 +1,51 @@
|
||||
;
|
||||
; Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
.program clocked_input
|
||||
|
||||
; Sample bits using an external clock, and push groups of bits into the RX FIFO.
|
||||
; - IN pin 0 is the data pin
|
||||
; - IN pin 1 is the clock pin
|
||||
; - Autopush is enabled, threshold 8
|
||||
;
|
||||
; This program samples data with each rising clock edge (like mode 0 or mode 3
|
||||
; SPI). The data is actually sampled one system clock cycle after the rising
|
||||
; edge is observed, so a clock ratio of at least input_clk < clk_sys / 6 is
|
||||
; recommended for good sampling alignment.
|
||||
|
||||
wait 0 pin 1
|
||||
wait 1 pin 1
|
||||
in pins, 1
|
||||
|
||||
% c-sdk {
|
||||
static inline void clocked_input_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
||||
pio_sm_config c = clocked_input_program_get_default_config(offset);
|
||||
|
||||
// Set the IN base pin to the provided `pin` parameter. This is the data
|
||||
// pin, and the next-numbered GPIO is used as the clock pin.
|
||||
sm_config_set_in_pins(&c, pin);
|
||||
// Set the pin directions to input at the PIO
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 2, false);
|
||||
// Connect these GPIOs to this PIO block
|
||||
pio_gpio_init(pio, pin);
|
||||
pio_gpio_init(pio, pin + 1);
|
||||
|
||||
// Shifting to left matches the customary MSB-first ordering of SPI.
|
||||
sm_config_set_in_shift(
|
||||
&c,
|
||||
false, // Shift-to-right = false (i.e. shift to left)
|
||||
true, // Autopush enabled
|
||||
8 // Autopush threshold = 8
|
||||
);
|
||||
|
||||
// We only receive, so disable the TX FIFO to make the RX FIFO deeper.
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
|
||||
// Load our configuration, and start the program from the beginning
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
%}
|
||||
Reference in New Issue
Block a user