22
22
#include " SPI.h"
23
23
#include " HardwareSerial.h"
24
24
25
+ #define SPI_FLASH_READ_MODE_MASK 0x196000
26
+
25
27
typedef union {
26
28
uint32_t regValue;
27
29
struct {
@@ -37,49 +39,200 @@ SPIClass SPI;
37
39
38
40
SPIClass::SPIClass () {
39
41
useHwCs = false ;
42
+ LastUsedDev = HSPI_IDLE;
43
+ }
44
+
45
+ void SPIClass::RegBackup (uint32 backup_mem[7 ])
46
+ {
47
+ uint8_t ptr = 0 ;
48
+
49
+ backup_mem[ptr++] = SPI1CMD;
50
+ backup_mem[ptr++] = SPI1C;
51
+ backup_mem[ptr++] = SPI1CLK;
52
+ backup_mem[ptr++] = SPI1U;
53
+ backup_mem[ptr++] = SPI1U1;
54
+ backup_mem[ptr++] = SPI1U2;
55
+ backup_mem[ptr] = SPI1P;
56
+ }
57
+
58
+ void SPIClass::RegRestore (uint32 backup_mem[7 ])
59
+ {
60
+ uint8_t ptr = 0 ;
61
+
62
+ SPI1CMD = backup_mem[ptr++];
63
+ SPI1C = backup_mem[ptr++];
64
+ SPI1CLK = backup_mem[ptr++];
65
+ SPI1U = backup_mem[ptr++];
66
+ SPI1U1 = backup_mem[ptr++];
67
+ SPI1U2 = backup_mem[ptr++];
68
+ SPI1P = backup_mem[ptr];
69
+ }
70
+
71
+ void SPIClass::OverlapInit (void )
72
+ {
73
+ // Enable HSPI overlap to SPI, Two SPI Masters on CSPI
74
+ IOSWAP |= IOSWAP2CS;
75
+
76
+ // Set higher priority for SPI than HSPI and enable HwCs
77
+ SPI0E3 |= 0x1 ;
78
+ SPI1E3 |= 0x3 ;
79
+ SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
40
80
}
41
81
42
- void SPIClass::begin () {
43
- pinMode (SCK, SPECIAL); // /< GPIO14
44
- pinMode (MISO, SPECIAL); // /< GPIO12
45
- pinMode (MOSI, SPECIAL); // /< GPIO13
82
+ void SPIClass::OverlapDeinit ( void )
83
+ {
84
+ // Disable HSPI overlap to SPI, Two SPI Masters on CSPI
85
+ IOSWAP &= ~IOSWAP2CS;
46
86
47
- SPI1C = 0 ;
48
- setFrequency (1000000 ); // /< 1MHz
49
- SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
50
- SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO);
51
- SPI1C1 = 0 ;
87
+ // Set higher priority for HSPI than SPI and disable HwCs
88
+ SPI0E3 &= ~0x1 ;
89
+ SPI1E3 &= ~0x3 ;
90
+ SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
52
91
}
53
92
54
- void SPIClass::end () {
55
- pinMode (SCK, INPUT);
56
- pinMode (MISO, INPUT);
57
- pinMode (MOSI, INPUT);
58
- if (useHwCs) {
59
- pinMode (SS, INPUT);
93
+ void SPIClass::begin (spi_devno dev_no) {
94
+ while (SPI1CMD & SPIBUSY) {}
95
+
96
+ SPISettings settings = {ESP8266_CLOCK, LSBFIRST, SPI_MODE0};
97
+ switch (dev_no){
98
+ case HSPI_CS_DEV :
99
+ pinMode (SCK, SPECIAL); // /< GPIO14
100
+ pinMode (MISO, SPECIAL); // /< GPIO12
101
+ pinMode (MOSI, SPECIAL); // /< GPIO13
102
+
103
+ SPI1C = 0 ;
104
+ SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
105
+ SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO);
106
+ SPI1C1 = 0 ;
107
+ settings._clock = 1000000 ; // Use default 1MHz Frequency
108
+ break ;
109
+ case SPI_CS0_FLASH :
110
+ OverlapInit ();
111
+ break ;
112
+ case SPI_CS1_DEV :
113
+ OverlapInit ();
114
+ pinMode (1 , FUNCTION_1); // GPIO1
115
+ break ;
116
+ case SPI_CS2_DEV :
117
+ OverlapInit ();
118
+ pinMode (0 , FUNCTION_1); // GPIO0
119
+ break ;
120
+ default : return ;
121
+ }
122
+
123
+ if ( LastUsedDev == HSPI_IDLE ) { // First begin()
124
+ SPI1C &= ~(SPI_FLASH_READ_MODE_MASK);
125
+ SPI1C |= (SPI0C & SPI_FLASH_READ_MODE_MASK);
126
+ RegBackup (hspi_flash_reg_backup);
127
+ bitClear (SPI1U, SPIUFLASHMODE);
128
+ HSPIdevSel ( {1000000 , LSBFIRST, SPI_MODE0}, HSPI_CS_DEV);
129
+ RegBackup (hspi_dev_reg_backup);
130
+ }
131
+
132
+ HSPIdevSel (settings, dev_no);
133
+ }
134
+
135
+ void SPIClass::end (spi_devno dev_no) {
136
+ while (SPI1CMD & SPIBUSY) {}
137
+
138
+ switch (dev_no){
139
+ case HSPI_CS_DEV :
140
+ pinMode (SCK, INPUT);
141
+ pinMode (MISO, INPUT);
142
+ pinMode (MOSI, INPUT);
143
+ if (useHwCs) {
144
+ pinMode (SS, INPUT);
145
+ }
146
+ break ;
147
+ case SPI_CS0_FLASH :
148
+ break ;
149
+ case SPI_CS1_DEV :
150
+ pinMode (1 , INPUT);
151
+ break ;
152
+ case SPI_CS2_DEV :
153
+ pinMode (0 , INPUT);
154
+ break ;
155
+ default : return ;
60
156
}
61
157
}
62
158
63
159
void SPIClass::setHwCs (bool use) {
64
- if (use) {
160
+ while (SPI1CMD & SPIBUSY) {}
161
+
162
+ if (LastUsedDev != HSPI_CS_DEV) return ; // Only HSPI allows the use of soft CS
163
+
164
+ if (use) {
65
165
pinMode (SS, SPECIAL); // /< GPIO15
66
166
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
67
167
} else {
68
- if (useHwCs) {
168
+ if (useHwCs) {
69
169
pinMode (SS, INPUT);
70
170
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
71
171
}
72
172
}
73
173
useHwCs = use;
74
174
}
75
175
76
- void SPIClass::beginTransaction (SPISettings settings) {
176
+ void SPIClass::HSPIdevSel (SPISettings settings, spi_devno dev_no)
177
+ {
77
178
while (SPI1CMD & SPIBUSY) {}
179
+
180
+ if ( LastUsedDev == SPI_CS0_FLASH && LastUsedDev != dev_no ) RegRestore (hspi_dev_reg_backup);
181
+ else if ( dev_no == SPI_CS0_FLASH && LastUsedDev != dev_no ) RegRestore (hspi_flash_reg_backup);
182
+
183
+ LastUsedDev = dev_no;
184
+
185
+ switch (dev_no){
186
+ case HSPI_CS_DEV :
187
+ bitClear (SPI1P, 0 );
188
+ bitSet (SPI1P, 1 );
189
+ bitSet (SPI1P, 2 );
190
+ setHwCs (useHwCs);
191
+ break ;
192
+ case SPI_CS0_FLASH :
193
+ bitClear (SPI1P, 0 );
194
+ bitSet (SPI1P, 1 );
195
+ bitSet (SPI1P, 2 );
196
+ SPI1U |= (SPIUCSSETUP | SPIUCSHOLD); // HwCs
197
+ break ;
198
+ case SPI_CS1_DEV :
199
+ bitClear (SPI1P, 1 );
200
+ bitSet (SPI1P, 0 );
201
+ bitSet (SPI1P, 2 );
202
+ SPI1U |= (SPIUCSSETUP | SPIUCSHOLD); // HwCs
203
+ break ;
204
+ case SPI_CS2_DEV :
205
+ bitClear (SPI1P, 2 );
206
+ bitSet (SPI1P, 0 );
207
+ bitSet (SPI1P, 1 );
208
+ SPI1U |= (SPIUCSSETUP | SPIUCSHOLD); // HwCs
209
+ break ;
210
+ default : break ;
211
+ }
212
+
78
213
setFrequency (settings._clock );
79
214
setBitOrder (settings._bitOrder );
80
215
setDataMode (settings._dataMode );
81
216
}
82
217
218
+ void SPIClass::beginTransaction (SPISettings settings, spi_devno dev_no, spi_modes spi_mode) {
219
+ HSPIdevSel (settings, dev_no);
220
+
221
+ SPI1C &= ~(SPICQIO | SPICDIO | SPICFASTRD); // Reset to defaults (SIO)
222
+ SPI1U &= ~(SPIUFWQIO | SPIUFWDIO);
223
+ switch (spi_mode) {
224
+ case SPI_QIO :
225
+ SPI1C |= (SPICQIO | SPICFASTRD);
226
+ SPI1U |= SPIUFWQIO;
227
+ break ;
228
+ case SPI_DIO :
229
+ SPI1C |= (SPICDIO | SPICFASTRD);
230
+ SPI1U |= SPIUFWDIO;
231
+ break ;
232
+ default : break ;
233
+ }
234
+ }
235
+
83
236
void SPIClass::endTransaction () {
84
237
}
85
238
@@ -102,7 +255,7 @@ void SPIClass::setDataMode(uint8_t dataMode) {
102
255
}
103
256
104
257
if (CPOL) {
105
- // todo How set CPOL???
258
+ // todo How set CPOL??? SPIC2CKO(H/L)M ???
106
259
}
107
260
108
261
}
@@ -209,9 +362,9 @@ void SPIClass::setFrequency(uint32_t freq) {
209
362
210
363
void SPIClass::setClockDivider (uint32_t clockDiv) {
211
364
if (clockDiv == 0x80000000 ) {
212
- GPMUX |= ( 1 << 9 ); // Set bit 9 if sysclock required
365
+ bitSet (GPMUX, 9 ); // Set bit 9 if sysclock required
213
366
} else {
214
- GPMUX &= ~( 1 << 9 );
367
+ bitClear (GPMUX, 9 );
215
368
}
216
369
SPI1CLK = clockDiv;
217
370
}
0 commit comments