Skip to content

Commit e7456e1

Browse files
committed
further optimizations
- extend read function to 16bit - add repeated write the same byte/word a specified number of time - revert increment option to dmaSend
1 parent b2e349c commit e7456e1

3 files changed

Lines changed: 61 additions & 40 deletions

File tree

STM32F1/cores/maple/libmaple/spi.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,21 @@ void spi_slave_enable(spi_dev *dev, spi_mode mode, uint32 flags) {
9393
* @return Number of elements transmitted.
9494
*/
9595
uint32 spi_tx(spi_dev *dev, const void *buf, uint32 len) {
96-
uint32 txed = 0;
97-
uint8 byte_frame = spi_dff(dev) == SPI_DFF_8_BIT;
98-
while ( txed < len ) {
99-
while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
100-
if (byte_frame) {
101-
dev->regs->DR = ((const uint8*)buf)[txed++];
102-
} else {
103-
dev->regs->DR = ((const uint16*)buf)[txed++];
104-
}
105-
}
96+
uint32 txed = len;
97+
spi_reg_map *regs = dev->regs;
98+
if ( spi_dff(dev) == SPI_DFF_8_BIT ) {
99+
const uint8 * dp8 = (const uint8*)buf;
100+
while ( len-- ) {
101+
while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
102+
regs->DR = *dp8++;
103+
}
104+
} else {
105+
const uint16 * dp16 = (const uint16*)buf;
106+
while ( len-- ) {
107+
while ( (regs->SR & SPI_SR_TXE)==0 ) ; //while ( spi_is_tx_empty(dev)==0 ); // wait Tx to be empty
108+
regs->DR = *dp16++;
109+
}
110+
}
106111
return txed;
107112
}
108113

@@ -163,6 +168,5 @@ static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
163168
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
164169
if ( (dev->regs->CR1&MASK)!=(cr1_config&MASK) ) spi_peripheral_disable(dev);
165170
dev->regs->CR1 = cr1_config;
166-
//spi_rx_dma_enable(dev);
167171
spi_peripheral_enable(dev);
168172
}

STM32F1/libraries/SPI/src/SPI.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void SPIClass::begin(void) {
160160
void SPIClass::beginSlave(void) {
161161
spi_init(_currentSetting->spi_d);
162162
configure_gpios(_currentSetting->spi_d, 0);
163-
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE);
163+
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_RX_ONLY);
164164
#ifdef SPI_DEBUG
165165
Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
166166
#endif
@@ -306,10 +306,10 @@ void SPIClass::endTransaction(void)
306306
* I/O
307307
*/
308308

309-
uint8 SPIClass::read(void)
309+
uint16 SPIClass::read(void)
310310
{
311311
while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ;
312-
return (uint8)spi_rx_reg(_currentSetting->spi_d);
312+
return (uint16)spi_rx_reg(_currentSetting->spi_d);
313313
}
314314

315315
void SPIClass::read(uint8 *buf, uint32 len)
@@ -321,7 +321,7 @@ void SPIClass::read(uint8 *buf, uint32 len)
321321
while ( rxed < len) {
322322
regs->DR = 0x00FF; // " write the data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
323323
while ( (regs->SR & SPI_SR_RXNE)==0 ) ; // wait till data is available in the Rx register
324-
buf[rxed++] = (uint8)(regs->DR); // read and store the received byte
324+
*buf++ = (regs->DR); // read and store the received byte
325325
}
326326
}
327327

@@ -332,11 +332,21 @@ void SPIClass::write(uint16 data)
332332
* by taking the Tx code from transfer(byte)
333333
* This almost doubles the speed of this function.
334334
*/
335-
spi_tx_reg(_currentSetting->spi_d, data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
336-
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
335+
spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
337336
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
338337
}
339338

339+
void SPIClass::write(uint16 data, uint32 n)
340+
{
341+
// Added by stevstrong: Repeatedly send same data by the specified number of times
342+
spi_reg_map * regs = _currentSetting->spi_d->regs;
343+
while ( (n--)>0 ) {
344+
regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
345+
while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty
346+
}
347+
while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning
348+
}
349+
340350
void SPIClass::write(const void *data, uint32 length)
341351
{
342352
spi_tx(_currentSetting->spi_d, data, length); // data can be array of bytes or words
@@ -346,18 +356,18 @@ void SPIClass::write(const void *data, uint32 length)
346356
uint16 b = spi_rx_reg(_currentSetting->spi_d); // dummy read, needed, don't remove!
347357
}
348358

349-
uint16_t SPIClass::transfer16(uint16_t wr_data) const {
350-
spi_tx_reg(_currentSetting->spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
359+
uint8 SPIClass::transfer(uint8 byte) const {
360+
spi_tx_reg(_currentSetting->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
351361
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
352362
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
353-
return (uint16)spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
363+
return (uint8)spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
354364
}
355365

356-
uint8 SPIClass::transfer(uint8 byte) const {
357-
spi_tx_reg(_currentSetting->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
366+
uint16_t SPIClass::transfer16(uint16_t wr_data) const {
367+
spi_tx_reg(_currentSetting->spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
358368
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
359369
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
360-
return (uint8)spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
370+
return (uint16)spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
361371
}
362372

363373
/* Roger Clark and Victor Perez, 2015
@@ -419,10 +429,10 @@ uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length
419429
* Still in progress.
420430
* 2016 - stevstrong - reworked to automatically detect bit size from SPI setting
421431
*/
422-
uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length)
432+
uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
423433
{
424434
if (length == 0) return 0;
425-
uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT);
435+
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
426436
uint8 b = 0;
427437
// dma1_ch3_Active=true;
428438
dma_init(_currentSetting->spiDmaDev);
@@ -438,7 +448,7 @@ uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length)
438448

439449
// while (dma1_ch3_Active);
440450
uint32_t m = millis();
441-
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & 0x2)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
451+
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
442452
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
443453
}
444454
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);

STM32F1/libraries/SPI/src/SPI.h

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ class SPISettings {
115115
init_MightInline(clock, bitOrder, dataMode, dataSize);
116116
}
117117
}
118+
SPISettings(uint32_t clock) {
119+
if (__builtin_constant_p(clock)) {
120+
init_AlwaysInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
121+
} else {
122+
init_MightInline(clock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
123+
}
124+
}
118125
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); }
119126
private:
120127
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
@@ -216,38 +223,38 @@ class SPIClass {
216223
*/
217224

218225
/**
219-
* @brief Return the next unread byte.
226+
* @brief Return the next unread byte/word.
220227
*
221-
* If there is no unread byte waiting, this function will block
228+
* If there is no unread byte/word waiting, this function will block
222229
* until one is received.
223230
*/
224-
uint8 read(void);
231+
uint16 read(void);
225232

226233
/**
227234
* @brief Read length bytes, storing them into buffer.
228235
* @param buffer Buffer to store received bytes into.
229-
* @param length Number of bytes to store in buffer. This
236+
* @param length Number of bytes to store in buffer. This
230237
* function will block until the desired number of
231238
* bytes have been read.
232239
*/
233240
void read(uint8 *buffer, uint32 length);
234241

235242
/**
236-
* @brief Transmit a byte.
237-
* @param data Byte to transmit.
243+
* @brief Transmit one byte/word.
244+
* @param data to transmit.
238245
*/
239-
// void write(uint8 data);
240-
246+
void write(uint16 data);
247+
241248
/**
242-
* @brief Transmit a half word.
249+
* @brief Transmit one byte/word a specified number of times.
243250
* @param data to transmit.
244251
*/
245-
void write(uint16 data);
252+
void write(uint16 data, uint32 n);
246253

247254
/**
248-
* @brief Transmit multiple bytes.
249-
* @param buffer Bytes to transmit.
250-
* @param length Number of bytes in buffer to transmit.
255+
* @brief Transmit multiple bytes/words.
256+
* @param buffer Bytes/words to transmit.
257+
* @param length Number of bytes/words in buffer to transmit.
251258
*/
252259
void write(const void * buffer, uint32 length);
253260

@@ -283,7 +290,7 @@ class SPIClass {
283290
* @param data buffer half words to transmit,
284291
* @param length Number of bytes in buffer to transmit.
285292
*/
286-
uint8 dmaSend(void * transmitBuf, uint16 length);
293+
uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1);
287294

288295
/*
289296
* Pin accessors

0 commit comments

Comments
 (0)