@@ -52,7 +52,6 @@ void TFT_SPI::init() {
52
52
SPIx.Init .NSS = SPI_NSS_SOFT;
53
53
SPIx.Init .Mode = SPI_MODE_MASTER;
54
54
SPIx.Init .Direction = (TFT_MISO_PIN == TFT_MOSI_PIN) ? SPI_DIRECTION_1LINE : SPI_DIRECTION_2LINES;
55
- SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
56
55
SPIx.Init .CLKPhase = SPI_PHASE_1EDGE;
57
56
SPIx.Init .CLKPolarity = SPI_POLARITY_LOW;
58
57
SPIx.Init .DataSize = SPI_DATASIZE_8BIT;
@@ -61,25 +60,43 @@ void TFT_SPI::init() {
61
60
SPIx.Init .CRCCalculation = SPI_CRCCALCULATION_DISABLE;
62
61
SPIx.Init .CRCPolynomial = 10 ;
63
62
63
+ #ifndef STM32H7xx
64
+ SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // 18 MBit/s for F103, 21 MBit/s for F407, 25 MBit/s for F411
65
+ #else
66
+ SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // 20 MBit/s for H743
67
+ SPIx.Init .NSSPMode = SPI_NSS_PULSE_ENABLE;
68
+ SPIx.Init .NSSPolarity = SPI_NSS_POLARITY_LOW;
69
+ SPIx.Init .FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
70
+ SPIx.Init .MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
71
+ SPIx.Init .MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
72
+ SPIx.Init .MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
73
+ SPIx.Init .MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
74
+ SPIx.Init .IOSwap = SPI_IO_SWAP_DISABLE;
75
+ #endif
76
+
64
77
pinmap_pinout (digitalPinToPinName (TFT_SCK_PIN), PinMap_SPI_SCLK);
65
78
pinmap_pinout (digitalPinToPinName (TFT_MOSI_PIN), PinMap_SPI_MOSI);
66
79
#if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN
67
80
pinmap_pinout (digitalPinToPinName (TFT_MISO_PIN), PinMap_SPI_MISO);
68
81
#endif
69
- pin_PullConfig (get_GPIO_Port (STM_PORT (digitalPinToPinName (TFT_SCK_PIN))), STM_LL_GPIO_PIN (digitalPinToPinName (TFT_SCK_PIN)), GPIO_PULLDOWN);
70
82
71
83
#ifdef SPI1_BASE
72
84
if (SPIx.Instance == SPI1) {
73
85
__HAL_RCC_SPI1_CLK_ENABLE ();
74
86
#ifdef STM32F1xx
75
87
__HAL_RCC_DMA1_CLK_ENABLE ();
76
88
DMAtx.Instance = DMA1_Channel3;
89
+ SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // SPI1 clock on F1 and F4 is two times faster than SPI2 and SPI3 clock
77
90
#elif defined(STM32F4xx)
78
91
__HAL_RCC_DMA2_CLK_ENABLE ();
79
92
DMAtx.Instance = DMA2_Stream3;
80
93
DMAtx.Init .Channel = DMA_CHANNEL_3;
94
+ SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // SPI1 clock on F1 and F4 is two times faster than SPI2 and SPI3 clock
95
+ #elif defined(STM32H7xx)
96
+ __HAL_RCC_DMA1_CLK_ENABLE ();
97
+ DMAtx.Instance = DMA1_Stream4;
98
+ DMAtx.Init .Request = DMA_REQUEST_SPI1_TX;
81
99
#endif
82
- SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
83
100
}
84
101
#endif
85
102
#ifdef SPI2_BASE
@@ -92,6 +109,10 @@ void TFT_SPI::init() {
92
109
__HAL_RCC_DMA1_CLK_ENABLE ();
93
110
DMAtx.Instance = DMA1_Stream4;
94
111
DMAtx.Init .Channel = DMA_CHANNEL_0;
112
+ #elif defined(STM32H7xx)
113
+ __HAL_RCC_DMA1_CLK_ENABLE ();
114
+ DMAtx.Instance = DMA1_Stream4;
115
+ DMAtx.Init .Request = DMA_REQUEST_SPI2_TX;
95
116
#endif
96
117
}
97
118
#endif
@@ -105,25 +126,27 @@ void TFT_SPI::init() {
105
126
__HAL_RCC_DMA1_CLK_ENABLE ();
106
127
DMAtx.Instance = DMA1_Stream5;
107
128
DMAtx.Init .Channel = DMA_CHANNEL_0;
129
+ #elif defined(STM32H7xx)
130
+ __HAL_RCC_DMA1_CLK_ENABLE ();
131
+ DMAtx.Instance = DMA1_Stream4;
132
+ DMAtx.Init .Request = DMA_REQUEST_SPI3_TX;
108
133
#endif
109
134
}
110
135
#endif
111
136
112
- HAL_SPI_Init (&SPIx);
113
-
114
137
DMAtx.Init .Direction = DMA_MEMORY_TO_PERIPH;
115
138
DMAtx.Init .PeriphInc = DMA_PINC_DISABLE;
116
139
DMAtx.Init .PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
117
140
DMAtx.Init .MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
118
141
DMAtx.Init .Mode = DMA_NORMAL;
119
142
DMAtx.Init .Priority = DMA_PRIORITY_LOW;
120
- #ifdef STM32F4xx
143
+ #if ANY( STM32F4xx, STM32H7xx)
121
144
DMAtx.Init .FIFOMode = DMA_FIFOMODE_DISABLE;
122
145
#endif
123
146
}
124
147
125
148
void TFT_SPI::dataTransferBegin (uint16_t dataSize) {
126
- SPIx.Init .DataSize = dataSize == DATASIZE_8BIT ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT ;
149
+ SPIx.Init .DataSize = dataSize;
127
150
HAL_SPI_Init (&SPIx);
128
151
WRITE (TFT_CS_PIN, LOW);
129
152
}
@@ -148,28 +171,43 @@ uint32_t TFT_SPI::getID() {
148
171
uint32_t TFT_SPI::readID (const uint16_t inReg) {
149
172
uint32_t data = 0 ;
150
173
#if PIN_EXISTS(TFT_MISO)
151
- uint32_t BaudRatePrescaler = SPIx.Init .BaudRatePrescaler ;
152
- uint32_t i;
174
+ const uint32_t oldPrescaler = SPIx.Init .BaudRatePrescaler ;
153
175
154
- SPIx.Init .BaudRatePrescaler = SPIx. Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4 ;
176
+ SPIx.Init .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64 ;
155
177
dataTransferBegin (DATASIZE_8BIT);
156
178
writeReg (inReg);
157
179
158
180
if (SPIx.Init .Direction == SPI_DIRECTION_1LINE) SPI_1LINE_RX (&SPIx);
159
- __HAL_SPI_ENABLE (&SPIx);
160
181
161
- for (i = 0 ; i < 4 ; i++) {
162
- #if TFT_MISO_PIN != TFT_MOSI_PIN
163
- while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_TXE)) {}
164
- SPIx.Instance ->DR = 0 ;
165
- #endif
166
- while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_RXNE)) {}
167
- data = (data << 8 ) | SPIx.Instance ->DR ;
168
- }
182
+ #ifdef STM32H7xx
183
+ for (uint32_t i = 0 ; i < 4 ; i++) {
184
+ MODIFY_REG (SPIx.Instance ->CR2 , SPI_CR2_TSIZE, 1 );
185
+ __HAL_SPI_ENABLE (&SPIx);
186
+ SET_BIT (SPIx.Instance ->CR1 , SPI_CR1_CSTART);
187
+
188
+ #if TFT_MISO_PIN != TFT_MOSI_PIN
189
+ SPIx.Instance ->TXDR = 0 ;
190
+ #endif
191
+ while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_EOT)) {}
192
+ data = (data << 8 ) | SPIx.Instance ->RXDR ;
193
+ __HAL_SPI_DISABLE (&SPIx);
194
+ __HAL_SPI_CLEAR_EOTFLAG (&SPIx);
195
+ __HAL_SPI_CLEAR_TXTFFLAG (&SPIx);
196
+ }
197
+ #else
198
+ __HAL_SPI_ENABLE (&SPIx);
199
+ for (uint32_t i = 0 ; i < 4 ; i++) {
200
+ #if TFT_MISO_PIN != TFT_MOSI_PIN
201
+ while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_TXE)) {}
202
+ SPIx.Instance ->DR = 0 ;
203
+ #endif
204
+ while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_RXNE)) {}
205
+ data = (data << 8 ) | SPIx.Instance ->DR ;
206
+ }
207
+ #endif
169
208
170
209
dataTransferEnd ();
171
-
172
- SPIx.Init .BaudRatePrescaler = BaudRatePrescaler;
210
+ SPIx.Init .BaudRatePrescaler = oldPrescaler;
173
211
#endif
174
212
175
213
return data >> 7 ;
@@ -182,6 +220,9 @@ bool TFT_SPI::isBusy() {
182
220
#elif defined(STM32F4xx)
183
221
#define __IS_DMA_ENABLED (__HANDLE__ ) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
184
222
#define __IS_DMA_CONFIGURED (__HANDLE__ ) ((__HANDLE__)->Instance->PAR != 0 )
223
+ #elif defined(STM32H7xx)
224
+ #define __IS_DMA_ENABLED (__HANDLE__ ) (((DMA_Stream_TypeDef *)((__HANDLE__)->Instance))->CR & DMA_SxCR_EN)
225
+ #define __IS_DMA_CONFIGURED (__HANDLE__ ) (((DMA_Stream_TypeDef *)((__HANDLE__)->Instance))->PAR != 0 )
185
226
#endif
186
227
187
228
if (!__IS_DMA_CONFIGURED (&DMAtx)) return false ;
@@ -193,8 +234,13 @@ bool TFT_SPI::isBusy() {
193
234
else {
194
235
// Check if DMA transfer completed flag is set
195
236
if (__HAL_DMA_GET_FLAG (&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX (&DMAtx)) == 0 ) return true ;
196
- // Check if SPI transmit butter is empty and SPI is idle
197
- if ((!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_TXE)) || (__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY))) return true ;
237
+ #ifdef STM32H7xx
238
+ // Check if SPI data transfer is completed
239
+ if (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_EOT)) return true ;
240
+ #else
241
+ // Check if SPI is idle
242
+ if (__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY)) return true ;
243
+ #endif
198
244
}
199
245
200
246
abort ();
@@ -205,22 +251,40 @@ void TFT_SPI::abort() {
205
251
HAL_DMA_Abort (&DMAtx); // Abort DMA transfer if any
206
252
HAL_DMA_DeInit (&DMAtx);
207
253
208
- CLEAR_BIT (SPIx.Instance ->CR2 , SPI_CR2_TXDMAEN);
254
+ #ifdef STM32H7xx
255
+ CLEAR_BIT (SPIx.Instance ->CFG1 , SPI_CFG1_TXDMAEN);
256
+ __HAL_SPI_CLEAR_EOTFLAG (&SPIx);
257
+ __HAL_SPI_CLEAR_TXTFFLAG (&SPIx);
258
+ #else
259
+ CLEAR_BIT (SPIx.Instance ->CR2 , SPI_CR2_TXDMAEN);
260
+ #endif
209
261
210
- dataTransferEnd (); // Stop SPI and deselect CS
262
+ dataTransferEnd (); // Stop SPI and deselect CS
211
263
}
212
264
213
265
void TFT_SPI::transmit (uint16_t data) {
214
266
#if TFT_MISO_PIN == TFT_MOSI_PIN
215
267
SPI_1LINE_TX (&SPIx);
216
268
#endif
217
269
218
- __HAL_SPI_ENABLE (&SPIx);
270
+ #ifdef STM32H7xx
271
+ MODIFY_REG (SPIx.Instance ->CR2 , SPI_CR2_TSIZE, 1 );
272
+ __HAL_SPI_ENABLE (&SPIx);
273
+ SET_BIT (SPIx.Instance ->CR1 , SPI_CR1_CSTART);
274
+
275
+ SPIx.Instance ->TXDR = data;
219
276
220
- SPIx. Instance -> DR = data;
277
+ while (! __HAL_SPI_GET_FLAG (& SPIx, SPI_SR_EOT)) {}
221
278
222
- while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_TXE)) {}
223
- while ( __HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY)) {}
279
+ __HAL_SPI_CLEAR_EOTFLAG (&SPIx);
280
+ __HAL_SPI_CLEAR_TXTFFLAG (&SPIx);
281
+ #else
282
+ __HAL_SPI_ENABLE (&SPIx);
283
+ SPIx.Instance ->DR = data;
284
+ while (__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY)) {}
285
+ #endif
286
+
287
+ __HAL_SPI_DISABLE (&SPIx);
224
288
225
289
#if TFT_MISO_PIN != TFT_MOSI_PIN
226
290
__HAL_SPI_CLEAR_OVRFLAG (&SPIx); // Clear overrun flag in 2 Lines communication mode because received data is not read
@@ -237,35 +301,38 @@ void TFT_SPI::transmitDMA(uint32_t memoryIncrease, uint16_t *data, uint16_t coun
237
301
238
302
dataTransferBegin ();
239
303
240
- HAL_DMA_Start (&DMAtx, ( uint32_t )data, ( uint32_t )&(SPIx. Instance -> DR ), count);
241
- __HAL_SPI_ENABLE (& SPIx);
304
+ # ifdef STM32H7xx
305
+ HAL_DMA_Start (&DMAtx, ( uint32_t )data, ( uint32_t )&( SPIx. Instance -> TXDR ), count );
242
306
243
- SET_BIT (SPIx.Instance ->CR2 , SPI_CR2_TXDMAEN); // Enable Tx DMA Request
307
+ CLEAR_BIT (SPIx.Instance ->CFG1 , SPI_CFG1_TXDMAEN);
308
+ MODIFY_REG (SPIx.Instance ->CR2 , SPI_CR2_TSIZE, count);
309
+ SET_BIT (SPIx.Instance ->CFG1 , SPI_CFG1_TXDMAEN); // Enable Tx DMA Request
310
+ __HAL_SPI_ENABLE (&SPIx);
311
+ SET_BIT (SPIx.Instance ->CR1 , SPI_CR1_CSTART);
312
+ #else
313
+ HAL_DMA_Start (&DMAtx, (uint32_t )data, (uint32_t )&(SPIx.Instance ->DR ), count);
314
+
315
+ __HAL_SPI_ENABLE (&SPIx);
316
+ SET_BIT (SPIx.Instance ->CR2 , SPI_CR2_TXDMAEN); // Enable Tx DMA Request
317
+ #endif
244
318
245
319
TERN_ (TFT_SHARED_IO, while (isBusy ()));
246
320
}
247
321
248
322
void TFT_SPI::transmit (uint32_t memoryIncrease, uint16_t *data, uint16_t count) {
249
- DMAtx.Init .MemInc = memoryIncrease;
250
- HAL_DMA_Init (&DMAtx);
251
-
252
- if (TFT_MISO_PIN == TFT_MOSI_PIN)
253
- SPI_1LINE_TX (&SPIx);
254
-
255
- dataTransferBegin ();
256
-
257
- HAL_DMA_Start (&DMAtx, (uint32_t )data, (uint32_t )&(SPIx.Instance ->DR ), count);
258
- __HAL_SPI_ENABLE (&SPIx);
259
-
260
- SET_BIT (SPIx.Instance ->CR2 , SPI_CR2_TXDMAEN); // Enable Tx DMA Request
323
+ transmitDMA (memoryIncrease, data, count);
261
324
262
325
HAL_DMA_PollForTransfer (&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
263
- while ( __HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY)) {}
326
+ #ifdef STM32H7xx
327
+ while (!__HAL_SPI_GET_FLAG (&SPIx, SPI_SR_EOT)) {}
328
+ #else
329
+ while (__HAL_SPI_GET_FLAG (&SPIx, SPI_FLAG_BSY)) {}
330
+ #endif
264
331
abort ();
265
332
}
266
333
267
334
#if ENABLED(USE_SPI_DMA_TC)
268
- void TFT_SPI::TransmitDMA_IT (uint32_t memoryIncrease, uint16_t *data, uint16_t count) {
335
+ void TFT_SPI::transmitDMA_IT (uint32_t memoryIncrease, uint16_t *data, uint16_t count) {
269
336
270
337
DMAtx.Init .MemInc = memoryIncrease;
271
338
HAL_DMA_Init (&DMAtx);
0 commit comments