• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef __DUET_SPI_H
17 #define __DUET_SPI_H
18 
19 #include "duet.h"
20 #include <errno.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define DUET_SPI0_INDEX    0
27 #define DUET_SPI1_INDEX    1
28 #define DUET_SPI2_INDEX    2
29 #define DUET_SPI_NUM       3
30 
31 #define SPI_ROLE_MASTER       (0x0)
32 #define SPI_ROLE_SLAVE        (0x4)
33 #define SPI_ROLE_MASTER_SLAVE  SPI_ROLE_MASTER
34 
35 #define SPI_CPOL_CPHA_MODE 0
36 #define SPI_DMA_RX_CONFIG  DISABLE
37 #define SPI_DMA_TX_CONFIG  DISABLE
38 
39 #define SPI_CLK               (52000000)
40 #define SPI_FIFO_DEPTH        (8)
41 
42 #define SPI_FRAME_FORMAT_SPI  (0x0)
43 
44 #define SPI_SLAVE_OUTPUT_DISABLE  (1 << 3)
45 
46 #define SPI_CLK_POLARITY_POS   (0x6)
47 #define SPI_CLK_POLARITY_LOW   (0x0)
48 #define SPI_CLK_POLARITY_HIGH  (0x1 << SPI_CLK_POLARITY_POS)
49 
50 #define SPI_CLK_PHASE_POS      (0x7)
51 #define SPI_CLK_PHASE_1EDGE    (0x0)
52 #define SPI_CLK_PHASE_2EDGE    (0x1 << SPI_CLK_PHASE_POS)
53 
54 #define SPI_DATA_SIZE_4BIT    (0x3)
55 #define SPI_DATA_SIZE_8BIT    (0x7)
56 #define SPI_DATA_SIZE_16BIT   (0xF)
57 
58 /* SPI flags */
59 #define SPI_FLAG_TX_FIFO_EMPTY         (0x1)
60 #define SPI_FLAG_TX_FIFO_NOT_FULL      (1 << 1)
61 #define SPI_FLAG_RX_FIFO_NOT_EMPTY     (1 << 2)
62 #define SPI_FLAG_RX_FIFO_FULL          (1 << 3)
63 #define SPI_FLAG_BUSY                  (1 << 4
64 
65 /* SPI interrupts */
66 #define SPI_INTERRUPT_RX_FIFO_OVERRUN  (1 << 0)
67 #define SPI_INTERRUPT_RX_TIMEOUT       (1 << 1)
68 #define SPI_INTERRUPT_RX_FIFO_TRIGGER  (1 << 2)  // there are four or more entries in rx fifo
69 #define SPI_INTERRUPT_TX_FIFO_TRIGGER  (1 << 3)  // there are four or fewer entries in tx fifo. what happens when fifo level is exactly 4??
70 #define SPI_INTERRUPT_ALL              (0xf)
71 #define SPI_DISABLE_INTERRUPT_ALL      (0x0)
72 
73 #define SPI_DMA_TX_EN                  (1<<1)
74 #define SPI_DMA_RX_EN                  (1)
75 
76 typedef struct {
77     uint32_t mode;        /* spi communication mode */
78     uint32_t freq;        /* communication frequency Hz */
79 } duet_spi_config_t;
80 
81 typedef struct {
82     uint8_t      port;    /* spi port */
83     duet_spi_config_t config;  /* spi config */
84     void        *priv;    /* priv data */
85 } duet_spi_dev_t;
86 
87 typedef void (*duet_spi_callback_func)(uint8_t);
88 extern duet_spi_callback_func g_duet_spi_callback_handler[DUET_SPI_NUM];
89 
duet_spi_interrupt_clear(SPI_TypeDef * SPIx,uint8_t spi_interrupt)90 __STATIC_INLINE void duet_spi_interrupt_clear(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
91 {
92     SPIx->ICR |= spi_interrupt;
93 }
94 
duet_spi_get_flag_status(SPI_TypeDef * SPIx,uint8_t spi_flag)95 __STATIC_INLINE ITstatus duet_spi_get_flag_status(SPI_TypeDef *SPIx, uint8_t spi_flag)
96 {
97     return SPIx->SR & spi_flag;
98 }
99 
duet_spi_get_interrupt_status(SPI_TypeDef * SPIx,uint8_t spi_interrupt)100 __STATIC_INLINE ITstatus duet_spi_get_interrupt_status(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
101 {
102     return SPIx->MIS & spi_interrupt;
103 }
104 
duet_spi_get_raw_interrupt_status(SPI_TypeDef * SPIx,uint8_t spi_interrupt)105 __STATIC_INLINE ITstatus duet_spi_get_raw_interrupt_status(SPI_TypeDef *SPIx, uint8_t spi_interrupt)
106 {
107     return SPIx->RIS & spi_interrupt;
108 }
109 
110 void duet_spi_interrupt_config(SPI_TypeDef *SPIx, uint8_t spi_interrupt, uint8_t new_state);
111 int32_t duet_spi_dma_config(duet_spi_dev_t *spi, uint8_t dma_tx_rx_sel, uint8_t new_state);
112 int32_t duet_spi_cpol_cpha_config(duet_spi_dev_t *spi, uint8_t mode);
113 void duet_spi_cmd(SPI_TypeDef *SPIx, uint8_t new_state);
114 void duet_spi_struct_init(duet_spi_dev_t *init_struct);
115 
116 /**
117  * Initialises the SPI interface for a given SPI device
118  *
119  * @param[in]  spi  the spi device
120  *
121  * @return  0 : on success, EIO : if the SPI device could not be initialised
122  */
123 int32_t duet_spi_init(duet_spi_dev_t *spi);
124 
125 /**
126  * Spi send
127  *
128  * @param[in]  spi      the spi device
129  * @param[in]  data     spi send data
130  * @param[in]  size     spi send data size
131  * @param[in]  timeout  timeout in ms
132  *
133  * @return  0 : on success, EIO : if the SPI device could not be initialised
134  */
135 int32_t duet_spi_send(duet_spi_dev_t *spi, const uint8_t *data, uint16_t size, uint32_t timeout);
136 
137 /**
138  * De-initialises a SPI interface
139  *
140  *
141  * @param[in]  spi the SPI device to be de-initialised
142  *
143  * @return  0 : on success, EIO : if an error occurred
144  */
145 int32_t duet_spi_finalize(duet_spi_dev_t *spi);
146 
147 #ifdef __cplusplus
148 }
149 #endif
150 
151 #endif /* __DUET_SPI_H */
152