Skip to content

Commit 07ba8f2

Browse files
Updaded SPI with update from VictorPV
1 parent b8d1cd4 commit 07ba8f2

2 files changed

Lines changed: 84 additions & 51 deletions

File tree

STM32F1/libraries/SPI/src/SPI.cpp

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,20 @@ SPIClass::SPIClass(uint32 spi_num) {
119119
// clock divider setup is a bit of hack, and needs to be improved at a later date.
120120
_settings[0].spi_d = SPI1;
121121
_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
122+
_settings[0].spiDmaDev = DMA1;
123+
_settings[0].spiTxDmaChannel = DMA_CH3;
124+
_settings[0].spiRxDmaChannel = DMA_CH2;
122125
_settings[1].spi_d = SPI2;
123126
_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
127+
_settings[1].spiDmaDev = DMA1;
128+
_settings[1].spiTxDmaChannel = DMA_CH5;
129+
_settings[1].spiRxDmaChannel = DMA_CH4;
124130
#if BOARD_NR_SPI >= 3
125131
_settings[2].spi_d = SPI3;
126132
_settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock);
133+
_settings[2].spiDmaDev = DMA2;
134+
_settings[2].spiTxDmaChannel = DMA_CH2;
135+
_settings[2].spiRxDmaChannel = DMA_CH1;
127136
#endif
128137

129138
//pinMode(BOARD_SPI_DEFAULT_SS,OUTPUT);
@@ -358,51 +367,55 @@ uint8 SPIClass::dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length
358367
if (length == 0) return 0;
359368
uint8 b;
360369
if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) b = spi_rx_reg(_currentSetting->spi_d); //Clear the RX buffer in case a byte is waiting on it.
361-
dma1_ch3_Active=true;
362-
dma_init(DMA1);
363-
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
370+
// dma1_ch3_Active=true;
371+
dma_init(_currentSetting->spiDmaDev);
372+
// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
364373

365374
// RX
366-
spi_rx_dma_enable(SPI1);
367-
dma_setup_transfer(DMA1, DMA_CH2, &SPI1->regs->DR, DMA_SIZE_8BITS,
375+
spi_rx_dma_enable(_currentSetting->spi_d);
376+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, DMA_SIZE_8BITS,
368377
receiveBuf, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_TRNS_CMPLT));// receive buffer DMA
369-
dma_set_num_transfers(DMA1, DMA_CH2, length);
378+
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
370379

371380
// TX
372-
spi_tx_dma_enable(SPI1);
381+
spi_tx_dma_enable(_currentSetting->spi_d);
373382
if (!transmitBuf) {
374383
static uint8_t ff = 0XFF;
375384
transmitBuf = &ff;
376-
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
385+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, DMA_SIZE_8BITS,
377386
transmitBuf, DMA_SIZE_8BITS, (DMA_FROM_MEM | DMA_TRNS_CMPLT));// Transmit FF repeatedly
378387
}
379388
else {
380-
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
389+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, DMA_SIZE_8BITS,
381390
transmitBuf, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT));// Transmit buffer DMA
382391
}
383-
dma_set_num_transfers(DMA1, DMA_CH3, length);
392+
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
384393

385-
dma_enable(DMA1, DMA_CH2);// enable receive
386-
dma_enable(DMA1, DMA_CH3);// enable transmit
394+
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
395+
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
387396

388397
// while (dma1_ch3_Active);
389398
// if (receiveBuf) {
390399
uint32_t m = millis();
391-
while (dma1_ch3_Active) {
400+
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & 0x2)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
392401
if ((millis() - m) > 100) {
393-
dma1_ch3_Active = 0;
402+
// dma1_ch3_Active = 0;
394403
b = 2;
395404
break;
396405
}
397406
}
407+
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
398408

399409
// }
400410
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
401411
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
402-
dma_disable(DMA1, DMA_CH3);
403-
dma_disable(DMA1, DMA_CH2);
404-
spi_rx_dma_disable(SPI1);
405-
spi_tx_dma_disable(SPI1);
412+
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
413+
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
414+
spi_rx_dma_disable(_currentSetting->spi_d); // And disable generation of DMA request from the SPI port so other peripherals can use the channels
415+
spi_tx_dma_disable(_currentSetting->spi_d);
416+
if (spi_is_rx_nonempty(_currentSetting->spi_d) != 0){; // "4. Wait until RXNE=1 ..."
417+
uint8 x = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
418+
}
406419
return b;
407420
}
408421

@@ -415,24 +428,28 @@ uint8 SPIClass::dmaSend(uint8 *transmitBuf, uint16 length, bool minc) {
415428
if (length == 0) return 0;
416429
uint32 flags = ((DMA_MINC_MODE * minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
417430
uint8 b;
418-
dma1_ch3_Active=true;
419-
dma_init(DMA1);
420-
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
431+
// dma1_ch3_Active=true;
432+
dma_init(_currentSetting->spiDmaDev);
433+
// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
421434

422435
// TX
423-
spi_tx_dma_enable(SPI1);
424-
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
436+
spi_tx_dma_enable(_currentSetting->spi_d);
437+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, DMA_SIZE_8BITS,
425438
transmitBuf, DMA_SIZE_8BITS, flags);// Transmit buffer DMA
426-
dma_set_num_transfers(DMA1, DMA_CH3, length);
427-
dma_enable(DMA1, DMA_CH3);// enable transmit
439+
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
440+
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
428441

429-
while (dma1_ch3_Active);
430-
while (spi_is_rx_nonempty(_currentSetting->spi_d) == 0); // "4. Wait until RXNE=1 ..."
431-
b = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
442+
// while (dma1_ch3_Active);
443+
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & 0x2)==0); //Avoid interrupts and just loop waiting for the flag to be set.
444+
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
445+
432446
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
433447
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
434-
dma_disable(DMA1, DMA_CH3);
435-
spi_tx_dma_disable(SPI1);
448+
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
449+
spi_tx_dma_disable(_currentSetting->spi_d);
450+
if (spi_is_rx_nonempty(_currentSetting->spi_d) != 0){; // "4. Wait until RXNE=1 ..."
451+
uint8 x = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
452+
}
436453
return b;
437454
}
438455

@@ -441,23 +458,27 @@ uint8 SPIClass::dmaSend(uint16 *transmitBuf, uint16 length, bool minc) {
441458
uint32 flags = ((DMA_MINC_MODE * minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
442459
uint8 b;
443460
dma1_ch3_Active=true;
444-
dma_init(DMA1);
445-
dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
461+
dma_init(_currentSetting->spiDmaDev);
462+
// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
446463

447464
// TX
448-
spi_tx_dma_enable(SPI1);
449-
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_16BITS,
465+
spi_tx_dma_enable(_currentSetting->spi_d);
466+
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, DMA_SIZE_16BITS,
450467
transmitBuf, DMA_SIZE_16BITS, flags);// Transmit buffer DMA
451-
dma_set_num_transfers(DMA1, DMA_CH3, length);
452-
dma_enable(DMA1, DMA_CH3);// enable transmit
468+
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
469+
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
453470

454-
while (dma1_ch3_Active);
455-
while (spi_is_rx_nonempty(_currentSetting->spi_d) == 0); // "4. Wait until RXNE=1 ..."
456-
b = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
471+
// while (dma1_ch3_Active);
472+
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & 0x2)==0); //Avoid interrupts and just loop waiting for the flag to be set.
473+
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
474+
457475
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
458476
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
459-
dma_disable(DMA1, DMA_CH3);
460-
spi_tx_dma_disable(SPI1);
477+
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
478+
spi_tx_dma_disable(_currentSetting->spi_d);
479+
if (spi_is_rx_nonempty(_currentSetting->spi_d) != 0){; // "4. Wait until RXNE=1 ..."
480+
b = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
481+
}
461482
return b;
462483
}
463484

STM32F1/libraries/SPI/src/SPI.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ class SPISettings {
121121

122122
spi_dev *spi_d;
123123
uint8_t _SSPin;
124-
uint32_t clockDivider;
124+
uint32_t clockDivider;
125+
dma_channel spiRxDmaChannel, spiTxDmaChannel;
126+
dma_dev* spiDmaDev;
125127

126128
friend class SPIClass;
127129
};
@@ -310,6 +312,23 @@ class SPIClass {
310312
* this HardwareSPI instance.
311313
*/
312314
spi_dev* c_dev(void) { return _currentSetting->spi_d; }
315+
316+
317+
spi_dev *dev(){ return _currentSetting->spi_d;}
318+
319+
/**
320+
* @brief Sets the number of the SPI peripheral to be used by
321+
* this HardwareSPI instance.
322+
*
323+
* @param spi_num Number of the SPI port. 1-2 in low density devices
324+
* or 1-3 in high density devices.
325+
*/
326+
327+
void setModule(int spi_num)
328+
{
329+
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
330+
}
331+
313332

314333
/* -- The following methods are deprecated --------------------------- */
315334

@@ -343,23 +362,16 @@ class SPIClass {
343362
*/
344363
uint8 recv(void);
345364

346-
spi_dev *dev(){ return _currentSetting->spi_d;}
347-
348-
void setModule(int spi_num)
349-
{
350-
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
351-
}
352-
353365
private:
354-
366+
/*
355367
static inline void DMA1_CH3_Event() {
356368
dma1_ch3_Active = 0;
357369
// dma_disable(DMA1, DMA_CH3);
358370
// dma_disable(DMA1, DMA_CH2);
359371
360372
// To Do. Need to wait for
361373
}
362-
374+
*/
363375
SPISettings _settings[BOARD_NR_SPI];
364376
SPISettings *_currentSetting;
365377

0 commit comments

Comments
 (0)