2626
2727#include " tft_spi.h"
2828
29- SPIClass TFT_SPI::SPIx (1 );
29+ SPIClass TFT_SPI::SPIx (TFT_SPI_DEVICE );
3030
3131void TFT_SPI::Init () {
3232 #if PIN_EXISTS(TFT_RESET)
@@ -38,40 +38,10 @@ void TFT_SPI::Init() {
3838 OUT_WRITE (TFT_BACKLIGHT_PIN, HIGH);
3939 #endif
4040
41- SET_OUTPUT (TFT_DC_PIN);
42- SET_OUTPUT (TFT_CS_PIN);
43- WRITE (TFT_DC_PIN, HIGH);
44- WRITE (TFT_CS_PIN, HIGH);
45-
46- /* *
47- * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
48- * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
49- * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
50- */
51- #if 0
52- #if SPI_DEVICE == 1
53- #define SPI_CLOCK_MAX SPI_CLOCK_DIV4
54- #else
55- #define SPI_CLOCK_MAX SPI_CLOCK_DIV2
56- #endif
57- uint8_t clock;
58- uint8_t spiRate = SPI_FULL_SPEED;
59- switch (spiRate) {
60- case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break;
61- case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break;
62- case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break;
63- case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
64- case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
65- case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
66- default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
67- }
68- #endif
41+ OUT_WRITE (TFT_DC_PIN, HIGH);
42+ OUT_WRITE (TFT_CS_PIN, HIGH);
6943
70- #if TFT_MISO_PIN == BOARD_SPI1_MISO_PIN
71- SPIx.setModule (1 );
72- #elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN
73- SPIx.setModule (2 );
74- #endif
44+ SPIx.setModule (TFT_SPI_DEVICE);
7545 SPIx.setClock (SPI_CLOCK_MAX_TFT);
7646 SPIx.setBitOrder (MSBFIRST);
7747 SPIx.setDataMode (SPI_MODE0);
@@ -114,17 +84,62 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
11484 return data >> 7 ;
11585}
11686
117- bool TFT_SPI::isBusy () { return false ; }
87+ bool TFT_SPI::isBusy () {
88+ #define __IS_DMA_CONFIGURED (__HANDLE__ ) ((__HANDLE__)->DMACCSrcAddr != 0 )
89+
90+ // DMA Channel 0 is hardcoded in dmaSendAsync() and dmaSend()
91+ if (!__IS_DMA_CONFIGURED (LPC_GPDMACH0)) return false ;
92+
93+ if (GPDMA_IntGetStatus (GPDMA_STAT_INTERR, 0 )) {
94+ // You should not be here - DMA transfer error flag is set
95+ // Abort DMA transfer and release SPI
96+ }
97+ else {
98+ // Check if DMA transfer completed flag is set
99+ if (!GPDMA_IntGetStatus (GPDMA_STAT_INTTC, 0 )) return true ;
100+ // Check if SPI TX butter is empty and SPI is idle
101+ if ((SSP_GetStatus (LPC_SSPx, SSP_STAT_TXFIFO_EMPTY) == RESET) || (SSP_GetStatus (LPC_SSPx, SSP_STAT_BUSY) == SET)) return true ;
102+ }
103+
104+ Abort ();
105+ return false ;
106+ }
107+
108+ void TFT_SPI::Abort () {
109+ // DMA Channel 0 is hardcoded in dmaSendAsync() and dmaSend()
110+
111+ // Disable DMA
112+ GPDMA_ChannelCmd (0 , DISABLE);
113+
114+ // Clear ERR and TC
115+ GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0 );
116+ GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0 );
117+
118+ // Disable DMA on SPI
119+ SSP_DMACmd (LPC_SSPx, SSP_DMA_TX, DISABLE);
120+
121+ // Deconfigure DMA Channel 0
122+ LPC_GPDMACH0->DMACCControl = 0U ;
123+ LPC_GPDMACH0->DMACCConfig = 0U ;
124+ LPC_GPDMACH0->DMACCSrcAddr = 0U ;
125+ LPC_GPDMACH0->DMACCDestAddr = 0U ;
118126
119- void TFT_SPI::Abort () { DataTransferEnd (); }
127+ DataTransferEnd ();
128+ }
120129
121130void TFT_SPI::Transmit (uint16_t Data) { SPIx.transfer (Data); }
122131
123- void TFT_SPI::TransmitDMA (uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
132+ void TFT_SPI::Transmit (uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
124133 DataTransferBegin (DATASIZE_16BIT);
125- WRITE (TFT_DC_PIN, HIGH);
126134 SPIx.dmaSend (Data, Count, MemoryIncrease);
127- DataTransferEnd ();
135+ Abort ();
136+ }
137+
138+ void TFT_SPI::TransmitDMA (uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
139+ DataTransferBegin (DATASIZE_16BIT);
140+ SPIx.dmaSendAsync (Data, Count, MemoryIncrease);
141+
142+ TERN_ (TFT_SHARED_SPI, while (isBusy ()));
128143}
129144
130145#endif // HAS_SPI_TFT
0 commit comments