1 /*
2  * Copyright (c) 2016 Erik Gilling
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <sys/types.h>
11 
12 #include <stm32f0xx.h>
13 
14 typedef enum {
15     SPI_PRESCALER_2 =   0 << 3,
16     SPI_PRESCALER_4 =   1 << 3,
17     SPI_PRESCALER_8 =   2 << 3,
18     SPI_PRESCALER_16 =  3 << 3,
19     SPI_PRESCALER_32 =  4 << 3,
20     SPI_PRESCALER_64 =  5 << 3,
21     SPI_PRESCALER_128 = 6 << 3,
22     SPI_PRESCALER_256 = 7 << 3,
23 } spi_prescaler_t;
24 
25 #define SPI_DATA_SIZE(x) ((((x) - 1) & 0xf) << 8)
26 typedef enum {
27     SPI_DATA_SIZE_4 = SPI_DATA_SIZE(4),
28     SPI_DATA_SIZE_5 = SPI_DATA_SIZE(5),
29     SPI_DATA_SIZE_6 = SPI_DATA_SIZE(6),
30     SPI_DATA_SIZE_7 = SPI_DATA_SIZE(7),
31     SPI_DATA_SIZE_8 = SPI_DATA_SIZE(8),
32     SPI_DATA_SIZE_9 = SPI_DATA_SIZE(9),
33     SPI_DATA_SIZE_10 = SPI_DATA_SIZE(10),
34     SPI_DATA_SIZE_11 = SPI_DATA_SIZE(11),
35     SPI_DATA_SIZE_12 = SPI_DATA_SIZE(12),
36     SPI_DATA_SIZE_13 = SPI_DATA_SIZE(13),
37     SPI_DATA_SIZE_14 = SPI_DATA_SIZE(14),
38     SPI_DATA_SIZE_15 = SPI_DATA_SIZE(15),
39     SPI_DATA_SIZE_16 = SPI_DATA_SIZE(16),
40 } spi_data_size_t;
41 
42 typedef enum {
43     SPI_CPOL_LOW =  0x0,
44     SPI_CPOL_HIGH = SPI_CR1_CPOL,
45 } spi_cpol_t;
46 
47 typedef enum {
48     SPI_CPHA_0 = 0x0,  // Data capture on first clock transition.
49     SPI_CPHA_1 = SPI_CR1_CPHA,  // Data capture on second clock transition.
50 } spi_cpha_t;
51 
52 typedef enum {
53     SPI_BIT_ORDER_MSB = 0,
54     SPI_BIT_ORDER_LSB = SPI_CR1_LSBFIRST,
55 } spi_bit_order_t;
56 
57 /**
58  * spi_init
59  *
60  * Initialize the SPI peripheral.  NOTE: ONLY SPI1 IS SUPPORTED.
61  *
62  * @param[in] data_size Size of SPI frame.
63  * @param[in] cpol      Clock polarity.
64  * @param[in] cpha      Clock phase.
65  * @param[in] bit_order Which order to transmit the bits on the data lines.
66  * @param[in] prescaler Divides the main peripheral clock to generate SCK.
67  */
68 void spi_init(spi_data_size_t data_size,
69               spi_cpol_t cpol,
70               spi_cpha_t cpha,
71               spi_bit_order_t bit_order,
72               spi_prescaler_t prescaler);
73 
74 /**
75  * spi_xfer
76  *
77  * Preform a SPI transfer.  Blocks until finished.
78  * TODO(konkers): Support write-only and read-only transactions.
79  * TODO(konkers): Add timeout support.
80  * TODO(konkers): Report errors.
81  *
82  * @param[in] tx_buf Buffer to transmit.
83  * @param[in] rx_buf Buffer to store received data.
84  * @param[in] len    Number of SPI frames to transmit.
85  *
86  * @return Number of frames transmitted on success, negative error code on
87  * failure.
88  */
89 ssize_t spi_xfer(const void *tx_buf, void *rx_buf, size_t len);
90 
91