Skip to content

Commit 30417b8

Browse files
committed
words
1 parent 1d83599 commit 30417b8

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

cores/esp8266/core_esp8266_spi_utils.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <cstdint>
2323
#include <cstring>
24+
#include <memory>
2425

2526
// register names
2627
#include "esp8266_peri.h"
@@ -43,10 +44,14 @@ namespace experimental {
4344
* Kept in a separate function to aid with precaching
4445
* PRECACHE_* saves having to make the function IRAM_ATTR.
4546
*
47+
* PRELOAD_* allows access to consts and external values
48+
* through a different name, while also forcing immediate load.
49+
* (but, note that compiler only knows about DST and SRC as dependencies)
50+
*
4651
* Note: if porting to ESP32 mosi/miso bits are set in 2 registers, not 1.
4752
*/
4853

49-
#define PRELOAD_DST(DST,SRC)\
54+
#define PRELOAD_DST_SRC(DST,SRC)\
5055
__asm__ __volatile__ (\
5156
"mov %0, %1\n\t"\
5257
: "=r"(DST)\
@@ -61,13 +66,13 @@ namespace experimental {
6166
: "i"(SRC)\
6267
: "memory")
6368

64-
#define PRELOAD_VAR(DST,SRC)\
69+
#define PRELOAD_VAL(DST,SRC)\
6570
decltype(SRC) DST;\
66-
PRELOAD_DST(DST,SRC)
71+
PRELOAD_DST_SRC(DST,SRC)
6772

68-
#define PRELOAD_FUNC(DST,SRC)\
69-
decltype(&SRC) DST;\
70-
PRELOAD_DST(DST,SRC)
73+
#define PRELOAD_PTR(DST,SRC)\
74+
decltype(std::addressof(SRC)) DST;\
75+
PRELOAD_DST_SRC(DST,SRC)
7176

7277
static SpiOpResult PRECACHE_ATTR
7378
_SPICommand(uint32_t spiIfNum,
@@ -81,38 +86,38 @@ _SPICommand(uint32_t spiIfNum,
8186
// note that the function below only ever calls this one w/ spiIfNum==0
8287
// in case it is *really* necessary, preload spiIfNum as well
8388
#define VOLATILE_PTR(X) reinterpret_cast<volatile uint32_t *>(X)
84-
#define SPIADDR(X) const_cast<uint32_t *>(&(X))
89+
#define SPIADDR(X) const_cast<uint32_t *>(std::addressof(X))
8590

8691
// preload all required constants and functions into variables.
8792
// when modifying code below, always double-check the asm output
8893

8994
PRELOAD_IMMEDIATE(spi0cmd_addr, SPIADDR(SPI0CMD));
9095
PRELOAD_IMMEDIATE(spi1cmd_addr, SPIADDR(SPI1CMD));
9196
uint32_t *spibase = spiIfNum
92-
? reinterpret_cast<uint32_t*>(spi1cmd_addr)
93-
: reinterpret_cast<uint32_t*>(spi0cmd_addr);
97+
? reinterpret_cast<uint32_t *>(spi1cmd_addr)
98+
: reinterpret_cast<uint32_t *>(spi0cmd_addr);
9499
#define SPIREG(reg) \
95100
(*VOLATILE_PTR(spibase + (SPIADDR(reg) - SPIADDR(SPI0CMD))))
96101

97-
PRELOAD_FUNC(SPI_write_enablep, SPI_write_enable);
98-
PRELOAD_FUNC(Wait_SPI_Idlep, Wait_SPI_Idle);
102+
PRELOAD_PTR(SPI_write_enablep, SPI_write_enable);
103+
PRELOAD_PTR(Wait_SPI_Idlep, Wait_SPI_Idle);
99104

100-
PRELOAD_VAR(fchip, flashchip);
105+
PRELOAD_VAL(fchip, flashchip);
101106

102107
PRELOAD_IMMEDIATE(spicmdusr, SPICMDUSR);
103108
PRELOAD_IMMEDIATE(saved_ps, 0);
104109

105110
// also force 'pre_cmd' & 'spiu' mask constant to be loaded right now
106111
// (TODO write all of the preamble in asm directly?)
107-
PRELOAD_VAR(pre_cmd, _pre_cmd);
112+
PRELOAD_VAL(pre_cmd, _pre_cmd);
108113

109114
PRELOAD_IMMEDIATE(pre_cmd_spiu_mask, ~(SPIUMOSI | SPIUMISO));
110115
uint32_t _pre_cmd_spiu = spiu & pre_cmd_spiu_mask;
111-
PRELOAD_VAR(pre_cmd_spiu, _pre_cmd_spiu);
116+
PRELOAD_VAL(pre_cmd_spiu, _pre_cmd_spiu);
112117

113118
PRELOAD_IMMEDIATE(pre_cmd_spiu2_mask, ~0xFFFFu);
114119
uint32_t _pre_cmd_spiu2 = (spiu2 & pre_cmd_spiu2_mask) | pre_cmd;
115-
PRELOAD_VAR(pre_cmd_spiu2, _pre_cmd_spiu2);
120+
PRELOAD_VAL(pre_cmd_spiu2, _pre_cmd_spiu2);
116121

117122
if (!spiIfNum) {
118123
// Only need to disable interrupts and precache when using SPI0

0 commit comments

Comments
 (0)