Skip to content

Commit fa94739

Browse files
committed
Improved support for benchmarks
1 parent 960db70 commit fa94739

File tree

5 files changed

+179
-91
lines changed

5 files changed

+179
-91
lines changed

examples/Benchmark/Benchmark.ino

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "GPIO.h"
22
#include "SPI.h"
3+
#include "benchmark.h"
34

45
// Configuration: SPI/BITORDER
56
// #define USE_SOFTWARE_SPI
@@ -9,9 +10,11 @@
910
#if defined(USE_SOFTWARE_SPI)
1011
#include "Software/SPI.h"
1112
#if defined(ARDUINO_attiny)
12-
GPIO<BOARD::D0> ss;
13-
Software::SPI<BOARD::D1, BOARD::D2, BOARD::D3> spi;
14-
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D0> dev(spi);
13+
#include "Software/Serial.h"
14+
Software::Serial<BOARD::D0> Serial;
15+
GPIO<BOARD::D1> ss;
16+
Software::SPI<BOARD::D2, BOARD::D3, BOARD::D4> spi;
17+
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D1> dev(spi);
1518
#else
1619
GPIO<BOARD::D10> ss;
1720
Software::SPI<BOARD::D11, BOARD::D12, BOARD::D13> spi;
@@ -27,45 +30,85 @@ SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D10> dev(spi);
2730

2831
void setup()
2932
{
33+
Serial.begin(57600);
34+
while (!Serial);
35+
BENCHMARK_BASELINE(1000);
3036
}
3137

3238
void loop()
3339
{
34-
// 32-bit/4 byte test data
40+
// Measure SPI bus manager performance with and without slave select
41+
// and device setting
42+
43+
const uint8_t PRESCALE = spi.prescale(SPI::MAX_FREQ);
3544
static uint32_t value = 0;
3645
uint32_t res;
3746

38-
// SPI bus manager serial data transfer
47+
BENCHMARK("1a. SPI bus manager serial data transfer (1 byte)", 1000) {
48+
ss.toggle();
49+
spi.acquire(0, BITORDER, PRESCALE);
50+
spi.transfer(value);
51+
spi.release();
52+
ss.toggle();
53+
}
54+
3955
ss.toggle();
40-
spi.acquire(0, BITORDER, SPI::MIN_CLOCK_SCALE);
41-
spi.transfer(value);
56+
spi.acquire(0, BITORDER, PRESCALE);
57+
BENCHMARK("1b. - transfer only (1 byte)", 1000) {
58+
spi.transfer(value);
59+
}
4260
spi.release();
4361
ss.toggle();
44-
delayMicroseconds(20);
4562

46-
// SPI device driver serial data transfer
63+
BENCHMARK("2a. SPI device driver serial data transfer (1 byte)", 1000) {
64+
dev.acquire();
65+
dev.transfer(value);
66+
dev.release();
67+
}
68+
4769
dev.acquire();
48-
dev.transfer(value);
70+
BENCHMARK("2b. - transfer only (1 byte)", 1000) {
71+
dev.transfer(value);
72+
}
4973
dev.release();
50-
delayMicroseconds(10);
5174

52-
// SPI device driver serial buffer read
75+
BENCHMARK("3a. SPI device driver serial buffer read (4 bytes)", 1000) {
76+
dev.acquire();
77+
dev.read(&res, sizeof(value));
78+
dev.release();
79+
}
80+
5381
dev.acquire();
54-
dev.read(&res, sizeof(value));
82+
BENCHMARK("3b. - read only (4 bytes)", 1000) {
83+
dev.read(&res, sizeof(value));
84+
}
5585
dev.release();
56-
delayMicroseconds(10);
5786

58-
// SPI device driver serial buffer write
87+
BENCHMARK("4a. SPI device driver serial buffer write (4 bytes)", 1000) {
88+
dev.acquire();
89+
dev.write(&value, sizeof(value));
90+
dev.release();
91+
}
92+
5993
dev.acquire();
60-
dev.write(&value, sizeof(value));
94+
BENCHMARK("4b. - write only (4 bytes)", 1000) {
95+
dev.write(&value, sizeof(value));
96+
}
6197
dev.release();
62-
delayMicroseconds(10);
6398

64-
// SPI device driver serial buffer transfer
99+
BENCHMARK("5a. SPI device driver serial buffer transfer (4 bytes)", 1000) {
100+
dev.acquire();
101+
dev.transfer(&res, &value, sizeof(value));
102+
dev.release();
103+
}
104+
65105
dev.acquire();
66-
dev.transfer(&res, &value, sizeof(value));
106+
BENCHMARK("5b. - transfer only (4 bytes)", 1000) {
107+
dev.transfer(&res, &value, sizeof(value));
108+
}
67109
dev.release();
68110

69-
delayMicroseconds(100);
111+
Serial.println();
112+
delay(2000);
70113
value++;
71114
}

examples/ShiftIn/ShiftIn.ino

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
#include "GPIO.h"
22
#include "SRPI.h"
33
#include "SPI.h"
4+
#include "benchmark.h"
45

56
// Configuration: SPI/BITORDER
6-
#define USE_SOFTWARE_SPI
7-
// #define USE_HARDWARE_SPI
7+
// #define USE_SOFTWARE_SPI
88
// #define BITORDER LSBFIRST
99
#define BITORDER MSBFIRST
1010

1111
#if defined(USE_SOFTWARE_SPI)
1212
#include "Software/SPI.h"
1313
#if defined(ARDUINO_attiny)
14-
GPIO<BOARD::D0> ss;
15-
Software::SPI<BOARD::D1, BOARD::D2, BOARD::D3> spi;
16-
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D0> dev(spi);
17-
SRPI<BITORDER, BOARD::D1, BOARD::D2> srpi;
14+
Software::Serial<BOARD::D0> Serial;
15+
GPIO<BOARD::D1> ss;
16+
Software::SPI<BOARD::D2, BOARD::D3, BOARD::D4> spi;
17+
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D1> dev(spi);
18+
SRPI<BITORDER, BOARD::D2, BOARD::D3> srpi;
1819
#else
1920
GPIO<BOARD::D10> ss;
2021
Software::SPI<BOARD::D11, BOARD::D12, BOARD::D13> spi;
2122
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D10> dev(spi);
2223
SRPI<BITORDER, BOARD::D12, BOARD::D13> srpi;
2324
#endif
24-
#elif defined(USE_HARDWARE_SPI)
25+
26+
#else
2527
#include "Hardware/SPI.h"
2628
GPIO<BOARD::D10> ss;
2729
Hardware::SPI spi;
@@ -41,29 +43,35 @@ SRPI<BITORDER, BOARD::D12, BOARD::D13> srpi;
4143

4244
void setup()
4345
{
46+
Serial.begin(57600);
47+
while (!Serial);
4448
ss.output();
45-
spi.acquire(0, BITORDER, SPI::MIN_CLOCK_SCALE);
49+
spi.acquire(0, BITORDER, spi.prescale(SPI::MAX_FREQ));
50+
BENCHMARK_BASELINE(1000);
4651
}
4752

4853
void loop()
4954
{
5055
uint8_t value;
5156

52-
// 84 us, 95 kHz
53-
ss.toggle();
54-
value = shiftIn(MISO_PIN, SCK_PIN, BITORDER);
55-
ss.toggle();
56-
delayMicroseconds(10);
57+
BENCHMARK("1. Arduino core shiftIn", 1000) {
58+
ss.toggle();
59+
value = shiftIn(MISO_PIN, SCK_PIN, BITORDER);
60+
ss.toggle();
61+
}
62+
63+
BENCHMARK("2. SPI input operator", 1000) {
64+
ss.toggle();
65+
spi >> value;
66+
ss.toggle();
67+
}
5768

58-
// 13 us, 762 kHz
59-
ss.toggle();
60-
spi >> value;
61-
ss.toggle();
62-
delayMicroseconds(10);
69+
BENCHMARK("3, SRPI input operator", 1000) {
70+
ss.toggle();
71+
srpi >> value;
72+
ss.toggle();
73+
}
6374

64-
// 4.7 us, 1.78 HHz
65-
ss.toggle();
66-
srpi >> value;
67-
ss.toggle();
68-
delayMicroseconds(100);
75+
Serial.println();
76+
delay(2000);
6977
}

examples/ShiftOut/ShiftOut.ino

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
#include "GPIO.h"
22
#include "SRPO.h"
33
#include "SPI.h"
4+
#include "benchmark.h"
45

56
// Configuration: SPI/BITORDER
6-
#define USE_SOFTWARE_SPI
7-
// #define USE_HARDWARE_SPI
7+
// #define USE_SOFTWARE_SPI
88
// #define BITORDER LSBFIRST
99
#define BITORDER MSBFIRST
1010

1111
#if defined(USE_SOFTWARE_SPI)
1212
#include "Software/SPI.h"
1313
#if defined(ARDUINO_attiny)
14-
GPIO<BOARD::D0> ss;
15-
Software::SPI<BOARD::D1, BOARD::D2, BOARD::D3> spi;
16-
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D0> dev(spi);
17-
SRPO<BITORDER, BOARD::D1, BOARD::D2> srpo;
14+
Software::Serial<BOARD::D0> Serial;
15+
GPIO<BOARD::D1> ss;
16+
Software::SPI<BOARD::D2, BOARD::D3, BOARD::D4> spi;
17+
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D1> dev(spi);
18+
SRPI<BITORDER, BOARD::D2, BOARD::D3> srpi;
1819
#else
1920
GPIO<BOARD::D10> ss;
2021
Software::SPI<BOARD::D11, BOARD::D12, BOARD::D13> spi;
2122
SPI::Device<0, BITORDER, SPI::MAX_FREQ, BOARD::D10> dev(spi);
2223
SRPO<BITORDER, BOARD::D11, BOARD::D13> srpo;
2324
#endif
24-
#elif defined(USE_HARDWARE_SPI)
25+
26+
#else
2527
#include "Hardware/SPI.h"
2628
GPIO<BOARD::D10> ss;
2729
Hardware::SPI spi;
@@ -41,29 +43,35 @@ SRPO<BITORDER, BOARD::D11, BOARD::D13> srpo;
4143

4244
void setup()
4345
{
46+
Serial.begin(57600);
47+
while (!Serial);
4448
ss.output();
45-
spi.acquire(0, BITORDER, SPI::MIN_CLOCK_SCALE);
49+
spi.acquire(0, BITORDER, spi.prescale(SPI::MAX_FREQ));
50+
BENCHMARK_BASELINE(1000);
4651
}
4752

4853
void loop()
4954
{
5055
uint8_t value = 0xa5;
5156

52-
// 108 us, 72 kHz
53-
ss.toggle();
54-
shiftOut(MOSI_PIN, SCK_PIN, BITORDER, value);
55-
ss.toggle();
56-
delayMicroseconds(10);
57+
BENCHMARK("1. Arduino core shiftOut", 1000) {
58+
ss.toggle();
59+
shiftOut(MOSI_PIN, SCK_PIN, BITORDER, value);
60+
ss.toggle();
61+
}
62+
63+
BENCHMARK("2. SPI output operator", 1000) {
64+
ss.toggle();
65+
spi << value;
66+
ss.toggle();
67+
}
5768

58-
// 13 us, 762 kHz
59-
ss.toggle();
60-
spi << value;
61-
ss.toggle();
62-
delayMicroseconds(10);
69+
BENCHMARK("3, SRPO output operator", 1000) {
70+
ss.toggle();
71+
srpo << value;
72+
ss.toggle();
73+
}
6374

64-
// 8 us, 1.07 MHz
65-
ss.toggle();
66-
srpo << value;
67-
ss.toggle();
68-
delayMicroseconds(100);
75+
Serial.println();
76+
delay(2000);
6977
}

src/Hardware/AVR/SPI.h

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,43 @@ class SPI : public ::SPI {
4242
m_miso.input();
4343
}
4444

45+
/**
46+
* @override{SPI}
47+
* Calculate bus prescale from device frequency.
48+
* @param[in] frequency device access.
49+
* @return prescale
50+
*/
51+
virtual uint8_t prescale(uint32_t frequency)
52+
{
53+
uint16_t scale = F_CPU / frequency;
54+
if (scale <= 2) return (0b100);
55+
if (scale <= 4) return (0b000);
56+
if (scale <= 8) return (0b101);
57+
if (scale <= 16) return (0b001);
58+
if (scale <= 32) return (0b110);
59+
if (scale <= 64) return (0b111);
60+
return (0b011);
61+
}
62+
4563
/**
4664
* @override{SPI}
4765
* Acquire bus access. Yield until bus is released.
4866
* @param[in] mode of access.
4967
* @param[in] bitorder of serial data.
50-
* @param[in] scale clock frequency.
68+
* @param[in] prescale clock prescale.
5169
*/
52-
virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t scale)
70+
virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t prescale)
5371
{
5472
// Wait for bus manager to be released
5573
lock();
5674

57-
// Calculate clock setting for given scale
58-
uint8_t spr = 0;
59-
scale >>= 2;
60-
while (scale != 0) {
61-
spr++;
62-
scale >>= 1;
63-
}
64-
if (scale > 7) scale = 7;
65-
6675
// Set control registers: mode, bitorder and clock
6776
SPCR = _BV(SPE)
6877
| _BV(MSTR)
6978
| (bitorder == LSBFIRST ? _BV(DORD) : 0)
7079
| ((mode & 0x03) << CPHA)
71-
| ((spr >> 1) & 3);
72-
SPSR = ((spr & 0x01) == 0);
80+
| (prescale & 0x03);
81+
SPSR = ((prescale >> 3) & 0x01);
7382
}
7483

7584
/**
@@ -188,16 +197,16 @@ class SPI : public ::SPI {
188197
* Acquire bus access. Yield until bus is released.
189198
* @param[in] mode of access.
190199
* @param[in] bitorder of serial data.
191-
* @param[in] scale clock frequency.
200+
* @param[in] prescale clock prescale.
192201
*/
193-
virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t scale)
202+
virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t prescale)
194203
{
195204
// Wait for bus manager to be released
196205
lock();
197206

198207
// Not used: only MSBFIRST bitorder and max frequency
199208
(void) bitorder;
200-
(void) scale;
209+
(void) prescale;
201210

202211
// Set clock polarity
203212
m_sck.write(mode & 0x02);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy