summaryrefslogtreecommitdiff
path: root/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h
blob: 552de1e91fdb990a10245a3865c7af2a120b2160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
 * Copyright (c) 2006-2026, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-5      SummerGift   first version
 * 2026-04-16     wdfk-prog    Add SPI interrupt transfer mode scaffolding
 */

/**
 * @file drv_spi.h
 * @brief STM32 SPI bus driver private definitions.
 */

#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__

#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include "drv_dma.h"
#include <ipc/completion.h>

/* Enable STM32 hardware SPI driver code when any SPI instance is selected. */
#if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6)
#define BSP_HARDWARE_SPI
#endif

/* Aggregate polling transfer configuration from per-instance Kconfig macros. */
#if defined(BSP_SPI1_TX_USING_POLL) || defined(BSP_SPI2_TX_USING_POLL) || defined(BSP_SPI3_TX_USING_POLL) || defined(BSP_SPI4_TX_USING_POLL) || defined(BSP_SPI5_TX_USING_POLL) || defined(BSP_SPI6_TX_USING_POLL)
#define BSP_SPI_TX_USING_POLL
#endif

#if defined(BSP_SPI1_RX_USING_POLL) || defined(BSP_SPI2_RX_USING_POLL) || defined(BSP_SPI3_RX_USING_POLL) || defined(BSP_SPI4_RX_USING_POLL) || defined(BSP_SPI5_RX_USING_POLL) || defined(BSP_SPI6_RX_USING_POLL)
#define BSP_SPI_RX_USING_POLL
#endif

#if defined(BSP_SPI1_TX_USING_POLL) || defined(BSP_SPI1_RX_USING_POLL)
#define BSP_SPI1_USING_POLL
#endif

#if defined(BSP_SPI2_TX_USING_POLL) || defined(BSP_SPI2_RX_USING_POLL)
#define BSP_SPI2_USING_POLL
#endif

#if defined(BSP_SPI3_TX_USING_POLL) || defined(BSP_SPI3_RX_USING_POLL)
#define BSP_SPI3_USING_POLL
#endif

#if defined(BSP_SPI4_TX_USING_POLL) || defined(BSP_SPI4_RX_USING_POLL)
#define BSP_SPI4_USING_POLL
#endif

#if defined(BSP_SPI5_TX_USING_POLL) || defined(BSP_SPI5_RX_USING_POLL)
#define BSP_SPI5_USING_POLL
#endif

#if defined(BSP_SPI6_TX_USING_POLL) || defined(BSP_SPI6_RX_USING_POLL)
#define BSP_SPI6_USING_POLL
#endif

#if defined(BSP_SPI_TX_USING_POLL) || defined(BSP_SPI_RX_USING_POLL)
#define BSP_SPI_USING_POLL
#endif

#if defined(BSP_SPI6_TX_USING_DMA) && defined(BSP_SPI6_TX_USING_BDMA)
#error "SPI6 TX DMA and BDMA are mutually exclusive"
#endif

#if defined(BSP_SPI6_RX_USING_DMA) && defined(BSP_SPI6_RX_USING_BDMA)
#error "SPI6 RX DMA and BDMA are mutually exclusive"
#endif

/* Aggregate DMA transfer configuration from per-instance Kconfig macros.
 * SPI6 BDMA is a DMA-engine backend, so it shares the DMA transport path. */
#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_TX_USING_BDMA)
#define BSP_SPI_TX_USING_DMA
#endif

#if defined(BSP_SPI1_RX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) || defined(BSP_SPI6_RX_USING_BDMA)
#define BSP_SPI_RX_USING_DMA
#endif

#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA)
#define BSP_SPI1_USING_DMA
#endif

#if defined(BSP_SPI2_TX_USING_DMA) || defined(BSP_SPI2_RX_USING_DMA)
#define BSP_SPI2_USING_DMA
#endif

#if defined(BSP_SPI3_TX_USING_DMA) || defined(BSP_SPI3_RX_USING_DMA)
#define BSP_SPI3_USING_DMA
#endif

#if defined(BSP_SPI4_TX_USING_DMA) || defined(BSP_SPI4_RX_USING_DMA)
#define BSP_SPI4_USING_DMA
#endif

#if defined(BSP_SPI5_TX_USING_DMA) || defined(BSP_SPI5_RX_USING_DMA)
#define BSP_SPI5_USING_DMA
#endif

#if defined(BSP_SPI6_TX_USING_DMA) || defined(BSP_SPI6_RX_USING_DMA) || defined(BSP_SPI6_TX_USING_BDMA) || defined(BSP_SPI6_RX_USING_BDMA)
#define BSP_SPI6_USING_DMA
#endif

#if defined(BSP_SPI_TX_USING_DMA) || defined(BSP_SPI_RX_USING_DMA)
#define BSP_SPI_USING_DMA
#endif

/* Aggregate interrupt transfer configuration from per-instance Kconfig macros. */
#if defined(BSP_SPI1_TX_USING_INT) || defined(BSP_SPI2_TX_USING_INT) || defined(BSP_SPI3_TX_USING_INT) || defined(BSP_SPI4_TX_USING_INT) || defined(BSP_SPI5_TX_USING_INT) || defined(BSP_SPI6_TX_USING_INT)
#define BSP_SPI_TX_USING_INT
#endif

#if defined(BSP_SPI1_RX_USING_INT) || defined(BSP_SPI2_RX_USING_INT) || defined(BSP_SPI3_RX_USING_INT) || defined(BSP_SPI4_RX_USING_INT) || defined(BSP_SPI5_RX_USING_INT) || defined(BSP_SPI6_RX_USING_INT)
#define BSP_SPI_RX_USING_INT
#endif

#if defined(BSP_SPI1_TX_USING_INT) || defined(BSP_SPI1_RX_USING_INT)
#define BSP_SPI1_USING_INT
#endif

#if defined(BSP_SPI2_TX_USING_INT) || defined(BSP_SPI2_RX_USING_INT)
#define BSP_SPI2_USING_INT
#endif

#if defined(BSP_SPI3_TX_USING_INT) || defined(BSP_SPI3_RX_USING_INT)
#define BSP_SPI3_USING_INT
#endif

#if defined(BSP_SPI4_TX_USING_INT) || defined(BSP_SPI4_RX_USING_INT)
#define BSP_SPI4_USING_INT
#endif

#if defined(BSP_SPI5_TX_USING_INT) || defined(BSP_SPI5_RX_USING_INT)
#define BSP_SPI5_USING_INT
#endif

#if defined(BSP_SPI6_TX_USING_INT) || defined(BSP_SPI6_RX_USING_INT)
#define BSP_SPI6_USING_INT
#endif

#if defined(BSP_SPI_TX_USING_INT) || defined(BSP_SPI_RX_USING_INT)
#define BSP_SPI_USING_INT
#endif

/* Aggregate IRQ requirements from DMA and interrupt transfer modes. */
#if defined(BSP_SPI1_USING_DMA) || defined(BSP_SPI1_USING_INT)
#define BSP_SPI1_USING_IRQ
#endif

#if defined(BSP_SPI2_USING_DMA) || defined(BSP_SPI2_USING_INT)
#define BSP_SPI2_USING_IRQ
#endif

#if defined(BSP_SPI3_USING_DMA) || defined(BSP_SPI3_USING_INT)
#define BSP_SPI3_USING_IRQ
#endif

#if defined(BSP_SPI4_USING_DMA) || defined(BSP_SPI4_USING_INT)
#define BSP_SPI4_USING_IRQ
#endif

#if defined(BSP_SPI5_USING_DMA) || defined(BSP_SPI5_USING_INT)
#define BSP_SPI5_USING_IRQ
#endif

#if defined(BSP_SPI6_USING_DMA) || defined(BSP_SPI6_USING_INT)
#define BSP_SPI6_USING_IRQ
#endif

#if defined(BSP_SPI_USING_DMA) || defined(BSP_SPI_USING_INT)
#define BSP_SPI_USING_IRQ
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Attach an SPI device to a registered STM32 SPI bus.
 *
 * @param bus_name SPI bus name, such as "spi1".
 * @param device_name SPI device name to register.
 * @param cs_pin Chip-select pin used by the SPI device.
 * @return RT_EOK on success, otherwise an RT-Thread error code.
 */
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin);

/**
 * @brief Detach a previously attached STM32 SPI device.
 *
 * @param device_name SPI device name to detach.
 * @return RT_EOK on success, otherwise an RT-Thread error code.
 */
rt_err_t rt_hw_spi_device_detach(const char *device_name);

#ifdef __cplusplus
}
#endif

/**
 * @brief Static configuration for one STM32 SPI bus instance.
 */
struct stm32_spi_config
{
    SPI_TypeDef *Instance;     /**< SPI peripheral register base. */
    char *bus_name;            /**< RT-Thread SPI bus name. */
    IRQn_Type irq_type;        /**< SPI peripheral IRQ number. */
#ifdef BSP_SPI_RX_USING_DMA
    const struct stm32_dma_config *dma_rx; /**< RX DMA/BDMA configuration. */
#endif /* BSP_SPI_RX_USING_DMA */
#ifdef BSP_SPI_TX_USING_DMA
    const struct stm32_dma_config *dma_tx; /**< TX DMA/BDMA configuration. */
#endif /* BSP_SPI_TX_USING_DMA */
};

/**
 * @brief Board-level SPI device attachment information.
 */
struct stm32_spi_device
{
    rt_uint32_t pin;    /**< Chip-select pin number. */
    char *bus_name;     /**< SPI bus name used for attachment. */
    char *device_name;  /**< SPI device name registered on the bus. */
};

/**
 * @brief Runtime context for one STM32 SPI bus.
 */
struct stm32_spi
{
    SPI_HandleTypeDef handle;          /**< STM32 HAL SPI handle. */
    struct stm32_spi_config *config;   /**< Static bus configuration. */
    struct rt_spi_configuration *cfg;  /**< Active RT-Thread SPI configuration. */
    struct rt_spi_bus spi_bus;         /**< RT-Thread SPI bus object. */
    rt_uint16_t spi_xfer_flags;        /**< RT_DEVICE_FLAG_DMA_* and RT_DEVICE_FLAG_INT_* transfer flags. */
#ifdef BSP_SPI_USING_IRQ
    struct rt_completion cpt;          /**< Completion used by asynchronous SPI transfers. */
#endif /* BSP_SPI_USING_IRQ */
#ifdef BSP_SPI_USING_DMA
    struct
    {
#ifdef BSP_SPI_RX_USING_DMA
        DMA_HandleTypeDef handle_rx;   /**< STM32 HAL RX DMA/BDMA handle. */
#endif /* BSP_SPI_RX_USING_DMA */
#ifdef BSP_SPI_TX_USING_DMA
        DMA_HandleTypeDef handle_tx;   /**< STM32 HAL TX DMA/BDMA handle. */
#endif /* BSP_SPI_TX_USING_DMA */
    } dma;                             /**< DMA handles associated with this SPI bus. */
#endif /* BSP_SPI_USING_DMA */
};

#endif /*__DRV_SPI_H__ */