31
31
#include "supervisor/board.h"
32
32
#include "shared-bindings/microcontroller/Pin.h"
33
33
34
+ #include "max32_port.h"
35
+ #include "spi_reva1.h"
36
+
34
37
// Note that any bugs introduced in this file can cause crashes
35
38
// at startupfor chips using external SPI flash.
36
39
40
+ #define SPI_PRIORITY 1
41
+
42
+ typedef enum {
43
+ SPI_FREE = 0 ,
44
+ SPI_BUSY ,
45
+ SPI_NEVER_RESET ,
46
+ } spi_status_t ;
47
+
48
+ // Set each bit to indicate an active SPI
49
+ // will be checked by ISR Handler for which ones to call
50
+ static uint8_t spi_active = 0 ;
51
+ static spi_status_t spi_status [NUM_SPI ];
52
+ static volatile int spi_err ;
53
+
54
+ // SPI Interrupt Handler
55
+ void spi_isr (void ) {
56
+ for (int i = 0 ; i < NUM_SPI ; i ++ ) {
57
+ if (spi_active & (1 << i )) {
58
+ MXC_SPI_AsyncHandler (MXC_SPI_GET_SPI (i ));
59
+ }
60
+ }
61
+ }
62
+
37
63
// Reset SPI when reload
38
64
void spi_reset (void ) {
39
65
// FIXME: Implement
40
66
return ;
41
67
}
42
68
43
69
// Construct SPI protocol, this function init SPI peripheral
70
+ // todo: figure out Chip select behavior
44
71
void common_hal_busio_spi_construct (busio_spi_obj_t * self ,
45
72
const mcu_pin_obj_t * sck ,
46
73
const mcu_pin_obj_t * mosi ,
47
74
const mcu_pin_obj_t * miso ,
48
75
bool half_duplex ) {
76
+ int temp , err = 0 ;
49
77
78
+ // Check for NULL Pointers && valid I2C settings
79
+ assert (self );
50
80
51
- // FIXME: Implement
81
+ // Assign I2C ID based on pins
82
+ temp = pinsToSpi (mosi , miso , sck );
83
+ if (temp == -1 ) {
84
+ // Error will be indicated by pinsToUart(tx, rx) function
85
+ return ;
86
+ } else {
87
+ self -> spi_id = temp ;
88
+ self -> spi_regs = MXC_SPI_GET_SPI (temp );
89
+ }
90
+
91
+ assert ((self -> spi_id >= 0 ) && (self -> spi_id < NUM_SPI ));
92
+
93
+ // Init I2C as main / controller node (0x00 is ignored)
94
+ // FIXME: MUST map the SPI pins to a spi_pins_t struct
95
+ if ((mosi != NULL ) && (miso != NULL ) && (sck != NULL )) {
96
+ // spi, mastermode, quadModeUsed, numSubs, ssPolarity, frequency
97
+ err = MXC_SPI_RevA1_Init ((mxc_spi_reva_regs_t * )self -> spi_regs , 1 , 0 , 1 , 0x00 , 1000000 );
98
+ if (err ) {
99
+ mp_raise_RuntimeError (MP_ERROR_TEXT ("Failed to init SPI.\n" ));
100
+ }
101
+ } else {
102
+ mp_raise_NotImplementedError (MP_ERROR_TEXT ("SPI needs MOSI, MISO, and SCK" ));
103
+ }
104
+
105
+ // Attach SPI pins
106
+ self -> mosi = mosi ;
107
+ self -> miso = miso ;
108
+ self -> sck = sck ;
109
+ common_hal_mcu_pin_claim (self -> mosi );
110
+ common_hal_mcu_pin_claim (self -> miso );
111
+ common_hal_mcu_pin_claim (self -> sck );
112
+
113
+ // Indicate to this module that the SPI is active
114
+ spi_active |= (1 << self -> spi_id );
115
+
116
+ /* Setup I2C interrupt */
117
+ NVIC_ClearPendingIRQ (MXC_SPI_GET_IRQ (self -> spi_id ));
118
+ NVIC_DisableIRQ (MXC_SPI_GET_IRQ (self -> spi_id ));
119
+ NVIC_SetPriority (MXC_SPI_GET_IRQ (self -> spi_id ), SPI_PRIORITY );
120
+ NVIC_SetVector (MXC_SPI_GET_IRQ (self -> spi_id ), (uint32_t )spi_isr );
121
+
122
+ return ;
52
123
}
53
124
54
125
// Never reset SPI when reload
55
126
void common_hal_busio_spi_never_reset (busio_spi_obj_t * self ) {
56
- // FIXME: Implement
127
+ common_hal_never_reset_pin (self -> mosi );
128
+ common_hal_never_reset_pin (self -> miso );
129
+ common_hal_never_reset_pin (self -> sck );
130
+ common_hal_never_reset_pin (self -> nss );
131
+
132
+ spi_status [self -> spi_id ] = SPI_NEVER_RESET ;
57
133
}
58
134
59
135
// Check SPI status, deinited or not
@@ -64,7 +140,16 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
64
140
// Deinit SPI obj
65
141
void common_hal_busio_spi_deinit (busio_spi_obj_t * self ) {
66
142
67
- // FIXME: Implement
143
+ MXC_SPI_Shutdown (self -> spi_regs );
144
+ common_hal_reset_pin (self -> mosi );
145
+ common_hal_reset_pin (self -> miso );
146
+ common_hal_reset_pin (self -> sck );
147
+ common_hal_reset_pin (self -> nss );
148
+
149
+ self -> mosi = NULL ;
150
+ self -> miso = NULL ;
151
+ self -> sck = NULL ;
152
+ self -> nss = NULL ;
68
153
}
69
154
70
155
// Configures the SPI bus. The SPI object must be locked.
@@ -74,14 +159,58 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
74
159
uint8_t phase ,
75
160
uint8_t bits ) {
76
161
77
- // FIXME: Implement
162
+ mxc_spi_clkmode_t clk_mode ;
163
+ int ret ;
164
+
165
+ self -> baudrate = baudrate ;
166
+ self -> polarity = polarity ;
167
+ self -> phase = phase ;
168
+ self -> bits = bits ;
169
+
170
+ switch ((polarity << 1 ) | (phase )) {
171
+ case 0b00 :
172
+ clk_mode = MXC_SPI_CLKMODE_0 ;
173
+ break ;
174
+ case 0b01 :
175
+ clk_mode = MXC_SPI_CLKMODE_1 ;
176
+ break ;
177
+ case 0b10 :
178
+ clk_mode = MXC_SPI_CLKMODE_2 ;
179
+ break ;
180
+ case 0b11 :
181
+ clk_mode = MXC_SPI_CLKMODE_3 ;
182
+ break ;
183
+ default :
184
+ mp_raise_ValueError (MP_ERROR_TEXT ("CPOL / CPHA must both be either 0 or 1\n" ));
185
+ return false;
186
+ }
187
+
188
+ ret = MXC_SPI_SetFrequency (self -> spi_regs , baudrate );
189
+ if (ret ) {
190
+ mp_raise_ValueError (MP_ERROR_TEXT ("Failed to set SPI Frequency\n" ));
191
+ return false;
192
+ }
193
+ ret = MXC_SPI_SetDataSize (self -> spi_regs , bits );
194
+ if (ret ) {
195
+ mp_raise_ValueError (MP_ERROR_TEXT ("Failed to set SPI Frame Size\n" ));
196
+ return false;
197
+ }
198
+ ret = MXC_SPI_SetMode (self -> spi_regs , clk_mode );
199
+ if (ret ) {
200
+ mp_raise_ValueError (MP_ERROR_TEXT ("Failed to set SPI Clock Mode\n" ));
201
+ return false;
202
+ }
78
203
return true;
79
204
}
80
205
81
206
// Lock SPI bus
82
207
bool common_hal_busio_spi_try_lock (busio_spi_obj_t * self ) {
83
- // FIXME: Implement
84
- return false;
208
+ if (spi_status [self -> spi_id ] != SPI_BUSY ) {
209
+ self -> has_lock = true;
210
+ return true;
211
+ } else {
212
+ return false;
213
+ }
85
214
}
86
215
87
216
// Check SPI lock status
@@ -98,18 +227,60 @@ void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
98
227
bool common_hal_busio_spi_write (busio_spi_obj_t * self ,
99
228
const uint8_t * data ,
100
229
size_t len ) {
230
+ int ret = 0 ;
101
231
102
- // FIXME: Implement
103
- return false;
232
+ mxc_spi_req_t wr_req = {
233
+ .spi = self -> spi_regs ,
234
+ .ssIdx = 0 ,
235
+ .txCnt = 0 ,
236
+ .rxCnt = 0 ,
237
+ .txData = (uint8_t * )data ,
238
+ .txLen = len ,
239
+ .rxData = NULL ,
240
+ .rxLen = 0 ,
241
+ .ssDeassert = 1 ,
242
+ .completeCB = NULL ,
243
+ .txDummyValue = 0xFF ,
244
+ };
245
+ ret = MXC_SPI_MasterTransaction (& wr_req );
246
+ if (ret ) {
247
+ return false;
248
+ } else {
249
+ return true;
250
+ }
104
251
}
105
252
106
253
// Read data into buffer
107
254
bool common_hal_busio_spi_read (busio_spi_obj_t * self ,
108
255
uint8_t * data , size_t len ,
109
256
uint8_t write_value ) {
110
257
111
- // FIXME: Implement
112
- return false;
258
+ int ret = 0 ;
259
+ // uint8_t tx_buffer[len] = {0x0};
260
+
261
+ // for (int i = 0; i < len; i++) {
262
+ // tx_buffer[i] = write_value;
263
+ // }
264
+
265
+ mxc_spi_req_t rd_req = {
266
+ .spi = self -> spi_regs ,
267
+ .ssIdx = 0 ,
268
+ .txCnt = 0 ,
269
+ .rxCnt = 0 ,
270
+ .txData = NULL ,
271
+ .txLen = len ,
272
+ .rxData = data ,
273
+ .rxLen = len ,
274
+ .ssDeassert = 1 ,
275
+ .completeCB = NULL ,
276
+ .txDummyValue = write_value ,
277
+ };
278
+ ret = MXC_SPI_MasterTransaction (& rd_req );
279
+ if (ret ) {
280
+ return false;
281
+ } else {
282
+ return true;
283
+ }
113
284
}
114
285
115
286
// Write out the data in data_out
@@ -119,8 +290,27 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self,
119
290
uint8_t * data_in ,
120
291
size_t len ) {
121
292
122
- // FIXME: Implement
123
- return false;
293
+ int ret = 0 ;
294
+
295
+ mxc_spi_req_t rd_req = {
296
+ .spi = self -> spi_regs ,
297
+ .ssIdx = 0 ,
298
+ .txCnt = 0 ,
299
+ .rxCnt = 0 ,
300
+ .txData = (uint8_t * )data_out ,
301
+ .txLen = len ,
302
+ .rxData = data_in ,
303
+ .rxLen = len ,
304
+ .ssDeassert = 1 ,
305
+ .completeCB = NULL ,
306
+ .txDummyValue = 0xFF ,
307
+ };
308
+ ret = MXC_SPI_MasterTransaction (& rd_req );
309
+ if (ret ) {
310
+ return false;
311
+ } else {
312
+ return true;
313
+ }
124
314
}
125
315
126
316
// Get SPI baudrate
0 commit comments