From d8cf31b09489a0f445828cdaa629f1d795d82005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20H=C3=BC=C3=9Fler?= Date: Thu, 16 Dec 2021 14:44:07 +0100 Subject: [PATCH] drivers/include/periph: Add PIO driver interface --- drivers/include/periph/pio.h | 185 +++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 drivers/include/periph/pio.h diff --git a/drivers/include/periph/pio.h b/drivers/include/periph/pio.h new file mode 100644 index 0000000000..872a89a2f6 --- /dev/null +++ b/drivers/include/periph/pio.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2021 Otto-von-Guericke Universität Magdeburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup drivers_periph_pio Programmable IO (PIO) + * @ingroup drivers_periph + * @brief Low-level PIO peripheral driver + * + * Programmable IO (PIO) is a cycle accurate IO control interface to emulate + * common IO standards like: I2C, SPI, UART or custom wire protocols as for the + * well known WS2812B LEDs. + * PIO programs are written in an MCU specific assembly language and they are + * saved in .pio files. The programs have to be loaded in the PIOs instruction + * memory. Once written to memory, a program can be executed by a state machines. + * A state machine can only execute one program at a time but multiple state + * machines can run the same program as access to instruction memory is shared. + * The user is responsible to allocate/deallocate instruction memory and + * lock/unlock state machines. + * + * PIO programs are very versatile and execution may depend on hardware quirks, + * thus specific setup must be performed by the CPU PIO driver implementation + * and the program code itself. + * The CPU driver implementation provides a set of known programs for common + * IO standards but user written programs are also possible and should be placed + * in cpu/$(CPU_FAM)/pio to make use of the processor specific PIO interface. + * + * This API simply takes a look at PIO programs as something that resides in + * memory and can be executed on demand, by a state machine. + * + * @experimental This API is experimental and in an early state - + * expect changes! + * @{ + * @file + * @brief High-level PIO peripheral driver interface + * + * @author Fabian Hüßler + */ + +#ifndef PERIPH_PIO_H +#define PERIPH_PIO_H + +#include "periph_conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default PIO device access macro + */ +#ifndef PIO_DEV +#define PIO_DEV(x) (x) +#endif + +/** + * @brief Program location that states that the program + * has not been loaded into instruction memory + */ +#define PIO_PROGRAM_NOT_LOADED (-1) + +/** + * @brief Struct holding functions to be called on PIO interrupt requests + * + * The interrupt events and number of interrupts may be hardware dependent. + */ +struct pio_isr_vec; + +/** + * @brief PIO index type + */ +typedef unsigned pio_t; + +/** + * @brief PIO state machine index type + */ +typedef int pio_sm_t; + +/** + * @brief Struct that models a PIO program + */ +typedef struct { + unsigned instr_numof; /**< Number of instructions */ + int location; /**< Program location in memory */ + bool written; /**< Program was already written */ +} pio_program_t; + +/** + * @brief Initialize a PIO device + * + * @param[in] pio PIO index + * + * @note No initialization is performed if + * "DISABLE_MODULE += periph_init_pio" is set. + */ +void pio_init(pio_t pio); + +/** + * @brief Start automatically configured PIO programs + * + * @note No execution is automatically started if + * "DISABLE_MODULE += periph_init_pio" is set. + */ +void pio_start_programs(void); + +/** + * @brief Get exclusive access to one of the state machines of PIO @p pio + * + * @param[in] pio PIO index + * + * @return Success: Index of now locked state machine + * Failure: negative integer + */ +pio_sm_t pio_sm_lock(pio_t pio); + +/** + * @brief Release a previously locked state machine + * + * @param[in] pio PIO index + * @param[in] sm PIO state machine index + */ +void pio_sm_unlock(pio_t pio, pio_sm_t sm); + +/** + * @brief Start a state machine and execute the previously loaded program + * + * @param[in] pio PIO index + * @param[in] sm PIO state machine index + */ +void pio_sm_start(pio_t pio, pio_sm_t sm); + +/** + * @brief Stop the execution of a program + * + * @param[in] pio PIO index + * @param[in] sm PIO state machine index + */ +void pio_sm_stop(pio_t pio, pio_sm_t sm); + +/** + * @brief Allocate the required instruction memory + * to load the given PIO program into + * + * @param[in] pio PIO index + * @param[in, out] prog Pointer PIO program + * + * @return Success: 0 + * Failure: != 0 + */ +int pio_alloc_program(pio_t pio, pio_program_t *prog); + +/** + * @brief Convenience function which performs the usual PIO program + * resource acquisition. + * + * @ref pio_alloc_program + * @ref pio_sm_lock + * + * @param[out] pio_ptr Destination to store the PIO index + * @param[out] sm_ptr Destination to store the PIO state machine index + * @param[in, out] program Program pointer of the program to be allocated + * + * @return Success: 0 + * Failure: != 0 + */ +int pio_alloc_program_sm_lock_any(pio_t *pio_ptr, pio_sm_t *sm_ptr, pio_program_t *program); + +/** + * @brief Release the allocated instruction memory occupied by @p prog + * + * @param[in] pio PIO index + * @param[in] prog PIO program + */ +void pio_free_program(pio_t pio, pio_program_t *prog); + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_PIO_H */ +/** @} */