Skip to content

Commit e229a49

Browse files
authored
Merge pull request #4207 from geky/spi-remove-byte-locking
spi: Add SPI block-write to C++ and HAL for performance
2 parents 9355531 + e65bb8d commit e229a49

File tree

49 files changed

+688
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+688
-1
lines changed

drivers/SPI.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ int SPI::write(int value) {
7878
return ret;
7979
}
8080

81+
int SPI::write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
82+
lock();
83+
aquire();
84+
int ret = spi_master_block_write(&_spi, tx_buffer, tx_length, rx_buffer, rx_length);
85+
unlock();
86+
return ret;
87+
}
88+
8189
void SPI::lock() {
8290
_mutex->lock();
8391
}

drivers/SPI.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,25 @@ class SPI {
115115
*
116116
* @returns
117117
* Response from the SPI slave
118-
*/
118+
*/
119119
virtual int write(int value);
120120

121+
/** Write to the SPI Slave and obtain the response
122+
*
123+
* The total number of bytes sent and recieved will be the maximum of
124+
* tx_length and rx_length. The bytes written will be padded with the
125+
* value 0xff.
126+
*
127+
* @param tx_buffer Pointer to the byte-array of data to write to the device
128+
* @param tx_length Number of bytes to write, may be zero
129+
* @param rx_buffer Pointer to the byte-array of data to read from the device
130+
* @param rx_length Number of bytes to read, may be zero
131+
* @returns
132+
* The number of bytes written and read from the device. This is
133+
* maximum of tx_length and rx_length.
134+
*/
135+
virtual int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length);
136+
121137
/** Acquire exclusive access to this SPI bus
122138
*/
123139
virtual void lock(void);

hal/spi_api.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,23 @@ void spi_frequency(spi_t *obj, int hz);
116116
*/
117117
int spi_master_write(spi_t *obj, int value);
118118

119+
/** Write a block out in master mode and receive a value
120+
*
121+
* The total number of bytes sent and recieved will be the maximum of
122+
* tx_length and rx_length. The bytes written will be padded with the
123+
* value 0xff.
124+
*
125+
* @param[in] obj The SPI peripheral to use for sending
126+
* @param[in] tx_buffer Pointer to the byte-array of data to write to the device
127+
* @param[in] tx_length Number of bytes to write, may be zero
128+
* @param[in] rx_buffer Pointer to the byte-array of data to read from the device
129+
* @param[in] rx_length Number of bytes to read, may be zero
130+
* @returns
131+
* The number of bytes written and read from the device. This is
132+
* maximum of tx_length and rx_length.
133+
*/
134+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length);
135+
119136
/** Check if a value is available to read
120137
*
121138
* @param[in] obj The SPI peripheral to check

targets/TARGET_ARM_SSG/TARGET_BEETLE/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,20 @@ int spi_master_write(spi_t *obj, int value) {
262262
return data;
263263
}
264264

265+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
266+
int total = (tx_length > rx_length) ? tx_length : rx_length;
267+
268+
for (int i = 0; i < total; i++) {
269+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
270+
char in = spi_master_write(obj, out);
271+
if (i < rx_length) {
272+
rx_buffer[i] = in;
273+
}
274+
}
275+
276+
return total;
277+
}
278+
265279
uint8_t spi_get_module(spi_t *obj) {
266280
return obj->spi->MID;
267281
}

targets/TARGET_ARM_SSG/TARGET_IOTSS/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,20 @@ int spi_master_write(spi_t *obj, int value) {
268268
return (ssp_read(obj));
269269
}
270270

271+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
272+
int total = (tx_length > rx_length) ? tx_length : rx_length;
273+
274+
for (int i = 0; i < total; i++) {
275+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
276+
char in = spi_master_write(obj, out);
277+
if (i < rx_length) {
278+
rx_buffer[i] = in;
279+
}
280+
}
281+
282+
return total;
283+
}
284+
271285
int spi_slave_receive(spi_t *obj) {
272286
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
273287
}

targets/TARGET_ARM_SSG/TARGET_MPS2/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,20 @@ int spi_master_write(spi_t *obj, int value) {
268268
return (ssp_read(obj));
269269
}
270270

271+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
272+
int total = (tx_length > rx_length) ? tx_length : rx_length;
273+
274+
for (int i = 0; i < total; i++) {
275+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
276+
char in = spi_master_write(obj, out);
277+
if (i < rx_length) {
278+
rx_buffer[i] = in;
279+
}
280+
}
281+
282+
return total;
283+
}
284+
271285
int spi_slave_receive(spi_t *obj) {
272286
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
273287
}

targets/TARGET_Atmel/TARGET_SAM_CortexM0P/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,20 @@ int spi_master_write(spi_t *obj, int value)
555555
return rx_data;
556556
}
557557

558+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
559+
int total = (tx_length > rx_length) ? tx_length : rx_length;
560+
561+
for (int i = 0; i < total; i++) {
562+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
563+
char in = spi_master_write(obj, out);
564+
if (i < rx_length) {
565+
rx_buffer[i] = in;
566+
}
567+
}
568+
569+
return total;
570+
}
571+
558572
/** Check if a value is available to read
559573
*
560574
* @param[in] obj The SPI peripheral to check

targets/TARGET_Atmel/TARGET_SAM_CortexM4/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,20 @@ int spi_master_write(spi_t *obj, int value)
296296
return 0;
297297
}
298298

299+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
300+
int total = (tx_length > rx_length) ? tx_length : rx_length;
301+
302+
for (int i = 0; i < total; i++) {
303+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
304+
char in = spi_master_write(obj, out);
305+
if (i < rx_length) {
306+
rx_buffer[i] = in;
307+
}
308+
}
309+
310+
return total;
311+
}
312+
299313
/** Check if a value is available to read
300314
*
301315
* @param[in] obj The SPI peripheral to check

targets/TARGET_Freescale/TARGET_K20XX/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,20 @@ int spi_master_write(spi_t *obj, int value) {
140140
return obj->spi->POPR;
141141
}
142142

143+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
144+
int total = (tx_length > rx_length) ? tx_length : rx_length;
145+
146+
for (int i = 0; i < total; i++) {
147+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
148+
char in = spi_master_write(obj, out);
149+
if (i < rx_length) {
150+
rx_buffer[i] = in;
151+
}
152+
}
153+
154+
return total;
155+
}
156+
143157
int spi_slave_receive(spi_t *obj) {
144158
return spi_readable(obj);
145159
}

targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,20 @@ int spi_master_write(spi_t *obj, int value) {
141141
return obj->spi->D & 0xff;
142142
}
143143

144+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
145+
int total = (tx_length > rx_length) ? tx_length : rx_length;
146+
147+
for (int i = 0; i < total; i++) {
148+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
149+
char in = spi_master_write(obj, out);
150+
if (i < rx_length) {
151+
rx_buffer[i] = in;
152+
}
153+
}
154+
155+
return total;
156+
}
157+
144158
int spi_slave_receive(spi_t *obj) {
145159
return spi_readable(obj);
146160
}

targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ int spi_master_write(spi_t *obj, int value) {
120120
return obj->spi->D & 0xff;
121121
}
122122

123+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
124+
int total = (tx_length > rx_length) ? tx_length : rx_length;
125+
126+
for (int i = 0; i < total; i++) {
127+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
128+
char in = spi_master_write(obj, out);
129+
if (i < rx_length) {
130+
rx_buffer[i] = in;
131+
}
132+
}
133+
134+
return total;
135+
}
136+
123137
int spi_slave_receive(spi_t *obj) {
124138
return spi_readable(obj);
125139
}

targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ int spi_master_write(spi_t *obj, int value) {
199199
return ret;
200200
}
201201

202+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
203+
int total = (tx_length > rx_length) ? tx_length : rx_length;
204+
205+
for (int i = 0; i < total; i++) {
206+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
207+
char in = spi_master_write(obj, out);
208+
if (i < rx_length) {
209+
rx_buffer[i] = in;
210+
}
211+
}
212+
213+
return total;
214+
}
215+
202216
int spi_slave_receive(spi_t *obj) {
203217
return spi_readable(obj);
204218
}

targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ int spi_master_write(spi_t *obj, int value) {
199199
return ret;
200200
}
201201

202+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
203+
int total = (tx_length > rx_length) ? tx_length : rx_length;
204+
205+
for (int i = 0; i < total; i++) {
206+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
207+
char in = spi_master_write(obj, out);
208+
if (i < rx_length) {
209+
rx_buffer[i] = in;
210+
}
211+
}
212+
213+
return total;
214+
}
215+
202216
int spi_slave_receive(spi_t *obj) {
203217
return spi_readable(obj);
204218
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ int spi_master_write(spi_t *obj, int value)
118118
return rx_data & 0xffff;
119119
}
120120

121+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
122+
int total = (tx_length > rx_length) ? tx_length : rx_length;
123+
124+
for (int i = 0; i < total; i++) {
125+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
126+
char in = spi_master_write(obj, out);
127+
if (i < rx_length) {
128+
rx_buffer[i] = in;
129+
}
130+
}
131+
132+
return total;
133+
}
134+
121135
int spi_slave_receive(spi_t *obj)
122136
{
123137
return spi_readable(obj);

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ int spi_master_write(spi_t *obj, int value)
118118
return rx_data & 0xffff;
119119
}
120120

121+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
122+
int total = (tx_length > rx_length) ? tx_length : rx_length;
123+
124+
for (int i = 0; i < total; i++) {
125+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
126+
char in = spi_master_write(obj, out);
127+
if (i < rx_length) {
128+
rx_buffer[i] = in;
129+
}
130+
}
131+
132+
return total;
133+
}
134+
121135
int spi_slave_receive(spi_t *obj)
122136
{
123137
return spi_readable(obj);

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,20 @@ int spi_master_write(spi_t *obj, int value)
115115
return rx_data & 0xffff;
116116
}
117117

118+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
119+
int total = (tx_length > rx_length) ? tx_length : rx_length;
120+
121+
for (int i = 0; i < total; i++) {
122+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
123+
char in = spi_master_write(obj, out);
124+
if (i < rx_length) {
125+
rx_buffer[i] = in;
126+
}
127+
}
128+
129+
return total;
130+
}
131+
118132
int spi_slave_receive(spi_t *obj)
119133
{
120134
return spi_readable(obj);

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,20 @@ int spi_master_write(spi_t *obj, int value)
115115
return rx_data & 0xffff;
116116
}
117117

118+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
119+
int total = (tx_length > rx_length) ? tx_length : rx_length;
120+
121+
for (int i = 0; i < total; i++) {
122+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
123+
char in = spi_master_write(obj, out);
124+
if (i < rx_length) {
125+
rx_buffer[i] = in;
126+
}
127+
}
128+
129+
return total;
130+
}
131+
118132
int spi_slave_receive(spi_t *obj)
119133
{
120134
return spi_readable(obj);

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/spi_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ int spi_master_write(spi_t *obj, int value)
117117
return rx_data & 0xffff;
118118
}
119119

120+
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
121+
int total = (tx_length > rx_length) ? tx_length : rx_length;
122+
123+
for (int i = 0; i < total; i++) {
124+
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
125+
char in = spi_master_write(obj, out);
126+
if (i < rx_length) {
127+
rx_buffer[i] = in;
128+
}
129+
}
130+
131+
return total;
132+
}
133+
120134
int spi_slave_receive(spi_t *obj)
121135
{
122136
return spi_readable(obj);

0 commit comments

Comments
 (0)