1 /*
2  * ===========================================================================================
3  *
4  *       Filename:  sunxi_hal_spi.h
5  *
6  *    Description:  SPI HAL definition.
7  *
8  *        Version:  Melis3.0
9  *         Create:  2019-11-18 11:11:56
10  *       Revision:  none
11  *       Compiler:  GCC:version 9.2.1
12  *
13  *         Author:  bantao@allwinnertech.com
14  *   Organization:  SWC-BPD
15  *  Last Modified:  2019-12-03 16:02:11
16  *
17  * ===========================================================================================
18  */
19 
20 #ifndef SUNXI_HAL_SPI_H
21 #define SUNXI_HAL_SPI_H
22 
23 #ifdef __cplusplus
24 extern "C"
25 {
26 #endif
27 
28 #include "sunxi_hal_common.h"
29 #include <hal_gpio.h>
30 #include <hal_dma.h>
31 /* #include <sunxi_drv_spi.h> */
32 #include <hal_sem.h>
33 #include <hal_clk.h>
34 #include <spi/platform_spi.h>
35 #include <spi/common_spi.h>
36 
37 
38 
39 /*****************************************************************************
40  * spi master
41  *****************************************************************************/
42 /** @brief This enum defines the SPI master port.
43  *  This chip total has 2 SPI master port
44  */
45 typedef enum
46 {
47     HAL_SPI_MASTER_0 = 0, /**< spi master port 0 */
48     HAL_SPI_MASTER_1 = 1, /**< spi master port 1 */
49     HAL_SPI_MASTER_2 = 2, /**< spi master port 1 */
50     HAL_SPI_MASTER_MAX = SPI_MAX_NUM,   /**< spi master max port number\<invalid\> */
51 } hal_spi_master_port_t;
52 
53 typedef struct
54 {
55     const uint8_t *tx_buf; /**< Data buffer to send, */
56     uint32_t tx_len; /**< The total number of bytes to send. */
57     uint32_t
58     tx_single_len; /**< The number of bytes to send in single mode. */
59     uint8_t *rx_buf;   /**< Received data buffer, */
60     uint32_t rx_len;   /**< The valid number of bytes received. */
61     uint8_t tx_nbits : 3;  /**< Data buffer to send in nbits mode */
62     uint8_t rx_nbits : 3;  /**< Data buffer to received in nbits mode */
63     uint8_t dummy_byte;    /**< Flash send dummy byte, default 0*/
64 #define SPI_NBITS_SINGLE 0x01  /* 1bit transfer */
65 #define SPI_NBITS_DUAL 0x02    /* 2bit transfer */
66 #define SPI_NBITS_QUAD 0x04    /* 4bit transfer */
67     uint8_t bits_per_word; /**< transfer bit_per_word */
68 } hal_spi_master_transfer_t;
69 
70 typedef enum spi_mode_type
71 {
72     SGLE_HALF_DUPLEX_RX, /* single mode, half duplex read */
73     SGLE_HALF_DUPLEX_TX, /* single mode, half duplex write */
74     DUAL_HALF_DUPLEX_RX, /* dual mode, half duplex read */
75     DUAL_HALF_DUPLEX_TX, /* dual mode, half duplex write */
76     QUAD_HALF_DUPLEX_RX, /* quad mode, half duplex read */
77     QUAD_HALF_DUPLEX_TX, /* quad mode, half duplex write */
78     FULL_DUPLEX_TX_RX,   /* full duplex read and write */
79     MODE_TYPE_NULL,
80 } spi_mode_type_t;
81 
82 typedef struct spi_dma
83 {
84     struct dma_slave_config config;
85     struct sunxi_dma_chan *chan;
86 } spi_dma_t;
87 
88 typedef struct sunxi_spi
89 {
90     int8_t result : 2;
91 #define SPI_XFER_READY 0
92 #define SPI_XFER_OK 1
93 #define SPI_XFER_FAILED -1
94 
95     bool sem;
96     uint16_t irqnum;
97     unsigned long base;
98     spi_mode_type_t mode_type;
99 
100     hal_clk_t pclk; /* PLL clock */
101     hal_clk_t bus_clk; /* BUS clock */
102     hal_clk_t mclk; /* spi module clock */
103     struct reset_control *reset;
104 
105     spi_dma_t dma_rx;
106     spi_dma_t dma_tx;
107 
108     char *align_dma_buf;
109 #define ALIGN_DMA_BUF_SIZE (4096 + 64)
110 
111     hal_sem_t xSemaphore_tx;
112     hal_sem_t xSemaphore_rx;
113 
114     hal_spi_master_port_t port;
115     hal_spi_master_transfer_t *transfer;
116 } sunxi_spi_t;
117 
118 typedef enum
119 {
120     SPI_MASTER_ERROR = -6,       /**< SPI master function error occurred. */
121     SPI_MASTER_ERROR_NOMEM = -5, /**< SPI master request mem failed. */
122     SPI_MASTER_ERROR_TIMEOUT = -4, /**< SPI master xfer timeout. */
123     SPI_MASTER_ERROR_BUSY = -3,    /**< SPI master is busy. */
124     SPI_MASTER_ERROR_PORT = -2,    /**< SPI master invalid port. */
125     SPI_MASTER_INVALID_PARAMETER =
126         -1,       /**< SPI master invalid input parameter. */
127     SPI_MASTER_OK = 0 /**< SPI master operation completed successfully. */
128 } spi_master_status_t;
129 
130 /** @brief selection of spi slave device connected to which cs pin of spi master
131 */
132 typedef enum
133 {
134     HAL_SPI_MASTER_SLAVE_0 =
135         0, /**< spi slave device connect to spi master cs0 pin */
136     HAL_SPI_MASTER_SLAVE_1 =
137         1, /**< spi slave device connect to spi master cs1 pin */
138     HAL_SPI_MASTER_SLAVE_MAX /**< spi master max cs pin number\<invalid\> */
139 } hal_spi_master_slave_port_t;
140 
141 /** @brief SPI master clock polarity definition */
142 typedef enum
143 {
144     HAL_SPI_MASTER_CLOCK_POLARITY0 = 0, /**< Clock polarity is 0 */
145     HAL_SPI_MASTER_CLOCK_POLARITY1 = 2  /**< Clock polarity is 1 */
146 } hal_spi_master_clock_polarity_t;
147 
148 /** @brief SPI master clock format definition */
149 typedef enum
150 {
151     HAL_SPI_MASTER_CLOCK_PHASE0 = 0, /**< Clock format is 0 */
152     HAL_SPI_MASTER_CLOCK_PHASE1 = 1  /**< Clock format is 1 */
153 } hal_spi_master_clock_phase_t;
154 
155 /** @brief SPI master transaction bit order definition */
156 typedef enum
157 {
158     HAL_SPI_MASTER_MSB_FIRST =
159         0, /**< Both send and receive data transfer MSB first */
160     HAL_SPI_MASTER_LSB_FIRST =
161         1 /**< Both send and receive data transfer LSB first */
162 } hal_spi_master_bit_order_t;
163 
164 /** @brief SPI master status. */
165 typedef enum
166 {
167     HAL_SPI_MASTER_STATUS_ERROR =
168         -6, /**< SPI master function error occurred. */
169     HAL_SPI_MASTER_STATUS_ERROR_NOMEM =
170         -5, /**< SPI master request mem failed. */
171     HAL_SPI_MASTER_STATUS_ERROR_TIMEOUT =
172         -4,                    /**< SPI master xfer timeout. */
173     HAL_SPI_MASTER_STATUS_ERROR_BUSY = -3, /**< SPI master is busy. */
174     HAL_SPI_MASTER_STATUS_ERROR_PORT = -2, /**< SPI master invalid port. */
175     HAL_SPI_MASTER_STATUS_INVALID_PARAMETER =
176         -1, /**< SPI master invalid input parameter. */
177     HAL_SPI_MASTER_STATUS_OK =
178         0 /**< SPI master operation completed successfully. */
179 } hal_spi_master_status_t;
180 
181 /** @brief SPI master running status. */
182 typedef enum
183 {
184     HAL_SPI_MASTER_BUSY = 0, /**< SPI master is busy. */
185     HAL_SPI_MASTER_IDLE = 1  /**< SPI master is idle. */
186 } hal_spi_master_running_status_t;
187 
188 typedef enum
189 {
190     HAL_SPI_MASTER_CS_AUTO = 0,
191     HAL_SPI_MASTER_CS_SOFT = 1,
192 } hal_spi_master_cs_mode_t;
193 
194 typedef struct
195 {
196     uint32_t clock_frequency; /**< SPI master clock frequency setting. */
197     hal_spi_master_slave_port_t
198     slave_port; /**< SPI slave device selection. */
199     hal_spi_master_bit_order_t
200     bit_order; /**< SPI master bit order setting. 0:MSB first 1:LSB
201                  first*/
202     hal_spi_master_clock_polarity_t
203     cpol; /**< SPI master clock polarity setting. 0:Active high
204             polarity(0 = Idle) 1:Active low polarity(1 = Idle) */
205     hal_spi_master_clock_phase_t
206     cpha; /**< SPI master clock phase setting. 0: Phase 0(Leading edge
207             for sample data)  1: Phase 1(Leading edge for setup data)
208             */
209     hal_spi_master_cs_mode_t csmode;
210 } hal_spi_master_config_t;
211 
212 typedef enum
213 {
214     SPI_WRITE_READ = 0, /**< SPI master is busy. */
215     SPI_CONFIG = 1  /**< SPI master is idle. */
216 } hal_spi_transfer_cmd_t;
217 
218 spi_master_status_t hal_spi_init(hal_spi_master_port_t port, hal_spi_master_config_t *cfg);
219 spi_master_status_t hal_spi_write(hal_spi_master_port_t port, const void *buf, uint32_t size);
220 spi_master_status_t hal_spi_deinit(hal_spi_master_port_t port);
221 spi_master_status_t hal_spi_read(hal_spi_master_port_t port, void *buf, uint32_t size);
222 spi_master_status_t hal_spi_xfer(hal_spi_master_port_t port, hal_spi_master_transfer_t *transfer);
223 spi_master_status_t hal_spi_hw_config(hal_spi_master_port_t port, hal_spi_master_config_t *spi_config);
224 void hal_spi_cs(hal_spi_master_port_t port, uint8_t on_off);
225 
226 #endif
227