Skip to content

Commit 599492e

Browse files
authored
libraries/SPI: abs -> std::abs and cast fixes (#7362)
* libraries/SPI: remove pointless abs(...) call SPI library code erroneously assumed that: - abs() is a C function, so include stdlib.h is required. what happens instead is Arduino.h shadows `abs()` with it's own macro - uint32_t() - int32_t() promotes to int32_t, thus needing abs() Fix both issues, leaving existing calculations as-is. * additional changes for freq and constants - restore abs call, cast freq to correctly display the intent - update magic numbers comments - move some spiclk_t magic numbers to func consts
1 parent 89d0c78 commit 599492e

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

libraries/SPI/SPI.cpp

+18-9
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ void SPIClass::setFrequency(uint32_t freq) {
203203
static uint32_t lastSetRegister = 0;
204204

205205
if(freq >= ESP8266_CLOCK) {
206+
// magic number to set spi sysclock bit (see below.)
206207
setClockDivider(0x80000000);
207208
return;
208209
}
@@ -215,7 +216,7 @@ void SPIClass::setFrequency(uint32_t freq) {
215216
const spiClk_t minFreqReg = { 0x7FFFF020 };
216217
uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
217218
if(freq < minFreq) {
218-
// use minimum possible clock
219+
// use minimum possible clock regardless
219220
setClockDivider(minFreqReg.regValue);
220221
lastSetRegister = SPI1CLK;
221222
lastSetFrequency = freq;
@@ -227,8 +228,14 @@ void SPIClass::setFrequency(uint32_t freq) {
227228
spiClk_t bestReg = { 0 };
228229
int32_t bestFreq = 0;
229230

230-
// find the best match
231-
while(calN <= 0x3F) { // 0x3F max for N
231+
// aka 0x3F, aka 63, max for regN:6
232+
const uint8_t regNMax = (1 << 6) - 1;
233+
234+
// aka 0x1fff, aka 8191, max for regPre:13
235+
const int32_t regPreMax = (1 << 13) - 1;
236+
237+
// find the best match for the next 63 iterations
238+
while(calN <= regNMax) {
232239

233240
spiClk_t reg = { 0 };
234241
int32_t calFreq;
@@ -239,8 +246,8 @@ void SPIClass::setFrequency(uint32_t freq) {
239246

240247
while(calPreVari++ <= 1) { // test different variants for Pre (we calculate in int so we miss the decimals, testing is the easyest and fastest way)
241248
calPre = (((ESP8266_CLOCK / (reg.regN + 1)) / freq) - 1) + calPreVari;
242-
if(calPre > 0x1FFF) {
243-
reg.regPre = 0x1FFF; // 8191
249+
if(calPre > regPreMax) {
250+
reg.regPre = regPreMax;
244251
} else if(calPre <= 0) {
245252
reg.regPre = 0;
246253
} else {
@@ -254,19 +261,21 @@ void SPIClass::setFrequency(uint32_t freq) {
254261
calFreq = ClkRegToFreq(&reg);
255262
//os_printf("-----[0x%08X][%d]\t EQU: %d\t Pre: %d\t N: %d\t H: %d\t L: %d = %d\n", reg.regValue, freq, reg.regEQU, reg.regPre, reg.regN, reg.regH, reg.regL, calFreq);
256263

257-
if(calFreq == (int32_t) freq) {
264+
if(calFreq == static_cast<int32_t>(freq)) {
258265
// accurate match use it!
259266
memcpy(&bestReg, &reg, sizeof(bestReg));
260267
break;
261-
} else if(calFreq < (int32_t) freq) {
268+
} else if(calFreq < static_cast<int32_t>(freq)) {
262269
// never go over the requested frequency
263-
if(abs(freq - calFreq) < abs(freq - bestFreq)) {
270+
auto cal = std::abs(static_cast<int32_t>(freq) - calFreq);
271+
auto best = std::abs(static_cast<int32_t>(freq) - bestFreq);
272+
if(cal < best) {
264273
bestFreq = calFreq;
265274
memcpy(&bestReg, &reg, sizeof(bestReg));
266275
}
267276
}
268277
}
269-
if(calFreq == (int32_t) freq) {
278+
if(calFreq == static_cast<int32_t>(freq)) {
270279
// accurate match use it!
271280
break;
272281
}

libraries/SPI/SPI.h

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#define _SPI_H_INCLUDED
2323

2424
#include <Arduino.h>
25-
#include <stdlib.h>
2625

2726
#define SPI_HAS_TRANSACTION 1
2827

0 commit comments

Comments
 (0)