1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

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
This commit is contained in:
Max Prokhorov 2020-06-13 21:17:06 +03:00 committed by GitHub
parent 89d0c78703
commit 599492ec43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 10 deletions

View File

@ -203,6 +203,7 @@ void SPIClass::setFrequency(uint32_t freq) {
static uint32_t lastSetRegister = 0; static uint32_t lastSetRegister = 0;
if(freq >= ESP8266_CLOCK) { if(freq >= ESP8266_CLOCK) {
// magic number to set spi sysclock bit (see below.)
setClockDivider(0x80000000); setClockDivider(0x80000000);
return; return;
} }
@ -215,7 +216,7 @@ void SPIClass::setFrequency(uint32_t freq) {
const spiClk_t minFreqReg = { 0x7FFFF020 }; const spiClk_t minFreqReg = { 0x7FFFF020 };
uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg); uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
if(freq < minFreq) { if(freq < minFreq) {
// use minimum possible clock // use minimum possible clock regardless
setClockDivider(minFreqReg.regValue); setClockDivider(minFreqReg.regValue);
lastSetRegister = SPI1CLK; lastSetRegister = SPI1CLK;
lastSetFrequency = freq; lastSetFrequency = freq;
@ -227,8 +228,14 @@ void SPIClass::setFrequency(uint32_t freq) {
spiClk_t bestReg = { 0 }; spiClk_t bestReg = { 0 };
int32_t bestFreq = 0; int32_t bestFreq = 0;
// find the best match // aka 0x3F, aka 63, max for regN:6
while(calN <= 0x3F) { // 0x3F max for N const uint8_t regNMax = (1 << 6) - 1;
// aka 0x1fff, aka 8191, max for regPre:13
const int32_t regPreMax = (1 << 13) - 1;
// find the best match for the next 63 iterations
while(calN <= regNMax) {
spiClk_t reg = { 0 }; spiClk_t reg = { 0 };
int32_t calFreq; int32_t calFreq;
@ -239,8 +246,8 @@ void SPIClass::setFrequency(uint32_t freq) {
while(calPreVari++ <= 1) { // test different variants for Pre (we calculate in int so we miss the decimals, testing is the easyest and fastest way) while(calPreVari++ <= 1) { // test different variants for Pre (we calculate in int so we miss the decimals, testing is the easyest and fastest way)
calPre = (((ESP8266_CLOCK / (reg.regN + 1)) / freq) - 1) + calPreVari; calPre = (((ESP8266_CLOCK / (reg.regN + 1)) / freq) - 1) + calPreVari;
if(calPre > 0x1FFF) { if(calPre > regPreMax) {
reg.regPre = 0x1FFF; // 8191 reg.regPre = regPreMax;
} else if(calPre <= 0) { } else if(calPre <= 0) {
reg.regPre = 0; reg.regPre = 0;
} else { } else {
@ -254,19 +261,21 @@ void SPIClass::setFrequency(uint32_t freq) {
calFreq = ClkRegToFreq(&reg); calFreq = ClkRegToFreq(&reg);
//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); //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);
if(calFreq == (int32_t) freq) { if(calFreq == static_cast<int32_t>(freq)) {
// accurate match use it! // accurate match use it!
memcpy(&bestReg, &reg, sizeof(bestReg)); memcpy(&bestReg, &reg, sizeof(bestReg));
break; break;
} else if(calFreq < (int32_t) freq) { } else if(calFreq < static_cast<int32_t>(freq)) {
// never go over the requested frequency // never go over the requested frequency
if(abs(freq - calFreq) < abs(freq - bestFreq)) { auto cal = std::abs(static_cast<int32_t>(freq) - calFreq);
auto best = std::abs(static_cast<int32_t>(freq) - bestFreq);
if(cal < best) {
bestFreq = calFreq; bestFreq = calFreq;
memcpy(&bestReg, &reg, sizeof(bestReg)); memcpy(&bestReg, &reg, sizeof(bestReg));
} }
} }
} }
if(calFreq == (int32_t) freq) { if(calFreq == static_cast<int32_t>(freq)) {
// accurate match use it! // accurate match use it!
break; break;
} }

View File

@ -22,7 +22,6 @@
#define _SPI_H_INCLUDED #define _SPI_H_INCLUDED
#include <Arduino.h> #include <Arduino.h>
#include <stdlib.h>
#define SPI_HAS_TRANSACTION 1 #define SPI_HAS_TRANSACTION 1