aboutsummaryrefslogtreecommitdiff
path: root/include/kern
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2020-12-04 23:16:31 -0700
committerJosh Rahm <joshuarahm@gmail.com>2020-12-04 23:16:31 -0700
commit7002cb8380406173407c9e8c8d16ebd670fff55c (patch)
treeb6ba377167ce193879347d692f087084f130c561 /include/kern
parent83deae717de8b940b0cb04d1d1989b0a4c250e35 (diff)
downloadstm32l4-7002cb8380406173407c9e8c8d16ebd670fff55c.tar.gz
stm32l4-7002cb8380406173407c9e8c8d16ebd670fff55c.tar.bz2
stm32l4-7002cb8380406173407c9e8c8d16ebd670fff55c.zip
Added kernel-level abstraction over the spi interface.
Diffstat (limited to 'include/kern')
-rw-r--r--include/kern/common.h25
-rw-r--r--include/kern/spi/spi_manager.h179
2 files changed, 190 insertions, 14 deletions
diff --git a/include/kern/common.h b/include/kern/common.h
index c5afe3f..021229b 100644
--- a/include/kern/common.h
+++ b/include/kern/common.h
@@ -1,9 +1,11 @@
#ifndef COMMON__H
#define COMMON__H
-#include <stdint.h>
-#include <stddef.h>
#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+typedef enum { ENDIANNESS_LITTLE, ENDIANNESS_BIG } endianness_t;
#define WEAK __attribute__((weak))
#define NORETURN __attribute__((noreturn))
@@ -28,23 +30,18 @@
#define PACKED __attribute__((packed))
#define BIT(n) (1 << (n))
-#define RESERVED_CONCAT_IMPL(x, y) x ## y
+#define RESERVED_CONCAT_IMPL(x, y) x##y
#define RESERVED_MACRO_CONCAT(x, y) RESERVED_CONCAT_IMPL(x, y)
-#define RESERVED(n) \
- bits_t RESERVED_MACRO_CONCAT(_r, __COUNTER__) :n
-
-#define RESERVE(type) \
- __IO type RESERVED_MACRO_CONCAT(_r, __COUNTER__)
+#define RESERVED(n) bits_t RESERVED_MACRO_CONCAT(_r, __COUNTER__) : n
+
+#define RESERVE(type) __IO type RESERVED_MACRO_CONCAT(_r, __COUNTER__)
-#define ptr2reg(ptr) \
- ((uint32_t) (ptrdiff_t) (ptr))
+#define ptr2reg(ptr) ((uint32_t)(ptrdiff_t)(ptr))
typedef __IO uint32_t bits_t;
-#define regset(reg, mask, val) \
- ((reg) = ((reg) & ~mask) | (val << CTZ(mask)))
+#define regset(reg, mask, val) ((reg) = ((reg) & ~mask) | (val << CTZ(mask)))
-#define regget(reg, mask) \
- (((reg) & mask) >> (CTZ(mask)))
+#define regget(reg, mask) (((reg)&mask) >> (CTZ(mask)))
#endif /* COMMON_H */
diff --git a/include/kern/spi/spi_manager.h b/include/kern/spi/spi_manager.h
new file mode 100644
index 0000000..53e4c2a
--- /dev/null
+++ b/include/kern/spi/spi_manager.h
@@ -0,0 +1,179 @@
+#ifndef KERN_SPI_SPI_MANAGER_H_
+#define KERN_SPI_SPI_MANAGER_H_
+
+#include "kern/common.h"
+
+#define SPI_ERROR_ALREADY_IN_USE 1
+#define SPI_ERROR_SELECTION_NOT_VALID 2
+
+typedef enum { SPI_CRCL_8_BITS, SPI_CRCL_16_BITS } spi_crcl_t;
+
+typedef enum {
+ SPI_DATA_SIZE_NOT_USED_0 = 0,
+ SPI_DATA_SIZE_NOT_USED_1 = 1,
+ SPI_DATA_SIZE_NOT_USED_2 = 2,
+ SPI_DATA_SIZE_4_BITS = 3,
+ SPI_DATA_SIZE_5_BITS = 4,
+ SPI_DATA_SIZE_6_BITS = 5,
+ SPI_DATA_SIZE_7_BITS = 6,
+ SPI_DATA_SIZE_8_BITS = 7,
+ SPI_DATA_SIZE_9_BITS = 8,
+ SPI_DATA_SIZE_10_BITS = 9,
+ SPI_DATA_SIZE_11_BITS = 10,
+ SPI_DATA_SIZE_12_BITS = 11,
+ SPI_DATA_SIZE_13_BITS = 12,
+ SPI_DATA_SIZE_14_BITS = 13,
+ SPI_DATA_SIZE_15_BITS = 14,
+ SPI_DATA_SIZE_16_BITS = 15,
+} spi_data_size_t;
+
+typedef enum {
+ SPI_BAUD_FPCLK_DIV_2 = 0,
+ SPI_BAUD_FPCLK_DIV_4 = 1,
+ SPI_BAUD_FPCLK_DIV_8 = 2,
+ SPI_BAUD_FPCLK_DIV_16 = 3,
+ SPI_BAUD_FPCLK_DIV_32 = 4,
+ SPI_BAUD_FPCLK_DIV_64 = 5,
+ SPI_BAUD_FPCLK_DIV_128 = 6,
+ SPI_BAUD_FPCLK_DIV_256 = 7,
+} spi_baud_t;
+
+typedef enum { SPI_MODE_MASTER, SPI_MODE_SLAVE } spi_mode_t;
+
+typedef enum { SPI_POLARITY_0, SPI_POLARITY_1 } spi_polarity_t;
+
+typedef enum {
+ /* The first clock transition is the first data capture edge. */
+ SPI_CLOCK_PHASE_FIRST,
+ /* The second clock transition is the first data capture edge. */
+ SPI_CLOCK_PHASE_SECOND,
+} spi_clock_phase_t;
+
+typedef enum {
+ SPI_DMA_PARITY_EVEN,
+ SPI_DMA_PARITY_ODD,
+} spi_dma_parity_t;
+
+typedef enum {
+ SPI_FIFO_THRESHOLD_HALF,
+ SPI_FIFO_THRESHOLD_QUARTER,
+} spi_fifo_threshold_t;
+
+typedef enum {
+ SPI_FRAME_FORMAT_MOTOROLA,
+ SPI_FRAME_FORMAT_TI,
+} spi_frame_format_t;
+
+typedef struct {
+ bool enable_bidirectional_data_mode;
+
+ /* Enable hardware crc checking. */
+ bool enable_crc;
+
+ /* CRC length. */
+ spi_crcl_t crc_length;
+
+ bool receieve_only;
+
+ bool enable_software_slave_management;
+
+ bool internal_slave_select;
+
+ endianness_t endianness;
+
+ spi_baud_t baud;
+
+ spi_mode_t spi_mode;
+
+ spi_polarity_t polarity;
+
+ spi_clock_phase_t clock_phase;
+
+ spi_dma_parity_t number_of_data_parity_tx;
+
+ spi_dma_parity_t number_of_data_parity_rx;
+
+ spi_fifo_threshold_t rx_interrupt_fifo_threshold;
+
+ spi_data_size_t data_size;
+
+ bool enable_tx_buffer_empty_interrupt;
+
+ bool enable_rx_buffer_not_empty_interrupt;
+
+ bool enable_error_interrupt;
+
+ spi_frame_format_t frame_format;
+
+ bool enable_nss_pulse;
+
+ bool enable_ss_output;
+
+ bool enable_tx_dma;
+
+ bool enable_rx_dma;
+
+ union {
+ struct {
+ bool output_enable;
+ } bidir_opts_t;
+ };
+} spi_opts_t;
+
+#define DEFAULT_SPI_OPTS { \
+ .enable_bidirectional_data_mode = 0,\
+ .enable_crc = 0,\
+ .crc_length = SPI_CRCL_8_BITS,\
+ .receieve_only = 0,\
+ .enable_software_slave_management = 1,\
+ .internal_slave_select = 1,\
+ .endianness = ENDIANNESS_LITTLE,\
+ .baud = SPI_BAUD_FPCLK_DIV_32,\
+ .spi_mode = SPI_MODE_MASTER,\
+ .polarity = SPI_POLARITY_0,\
+ .clock_phase = SPI_CLOCK_PHASE_FIRST,\
+ .number_of_data_parity_tx = SPI_DMA_PARITY_EVEN,\
+ .number_of_data_parity_rx = SPI_DMA_PARITY_EVEN,\
+ .rx_interrupt_fifo_threshold = SPI_FIFO_THRESHOLD_HALF,\
+ .data_size = SPI_DATA_SIZE_8_BITS,\
+ .enable_tx_buffer_empty_interrupt = 0,\
+ .enable_rx_buffer_not_empty_interrupt = 0,\
+ .enable_error_interrupt = 0,\
+ .frame_format = SPI_FRAME_FORMAT_MOTOROLA,\
+ .enable_nss_pulse = 0,\
+ .enable_ss_output = 0,\
+ .enable_tx_dma = 0 ,\
+ .enable_rx_dma = 0,\
+}
+
+typedef struct spi spi_t;
+
+typedef enum {
+#define SPI(sp, u) SPI_SELECT_##sp,
+#include "arch/stm32l4xxx/peripherals/tables/stm32l432xx/spi/buses.inc"
+#undef SPI
+
+ N_SPI_SELECT
+} spi_select_t;
+
+/* Reserve a spi bus. If an error occurs, NULL is returned
+ * and *ec is set to the appropriate value. */
+spi_t* reserve_spi(spi_select_t spi_select, spi_opts_t* opts, int* ec);
+
+/* Sets the SPI to enable. */
+void spi_start(spi_t* spi);
+
+/* Release the spi bus. */;
+void release_spi(spi_t* spi);
+
+void spi_set_crc_next(spi_t* spi);
+
+void spi_write_8_sync(spi_t* spi, uint8_t data);
+
+void spi_write_16_sync(spi_t* spi, uint16_t data);
+
+uint8_t spi_read_8_sync(spi_t* spi);
+
+uint16_t spi_read_16_sync(spi_t* spi);
+
+#endif /* KERN_SPI_SPI_MANAGER_H_ */