33 *
44 * The MIT License (MIT)
55 *
6- * Copyright (c) 2016 Damien P. George
6+ * Copyright (c) 2017 "Eric Poulsen" <eric@zyxod.com>
77 *
88 * Permission is hereby granted, free of charge, to any person obtaining a copy
99 * of this software and associated documentation files (the "Software"), to deal
2828#include <stdint.h>
2929#include <string.h>
3030
31-
3231#include "py/runtime.h"
3332#include "py/stream.h"
3433#include "py/mphal.h"
3534#include "extmod/machine_spi.h"
3635#include "machine_hw_spi.h"
3736#include "modmachine.h"
3837
39-
4038// if a port didn't define MSB/LSB constants then provide them
4139#ifndef MICROPY_PY_MACHINE_SPI_MSB
4240#define MICROPY_PY_MACHINE_SPI_MSB (0)
4341#define MICROPY_PY_MACHINE_SPI_LSB (1)
4442#endif
4543
46- #define MACHINE_HW_SPI_DEBUG_PRINTF (args ...) printf(args)
47-
48- STATIC void machine_hw_spi_deinit_internal (spi_host_device_t host , spi_device_handle_t * spi ) {
49-
50- switch (spi_bus_remove_device (* spi )) {
44+ STATIC void machine_hw_spi_deinit_internal (machine_hw_spi_obj_t * self ) {
45+ switch (spi_bus_remove_device (self -> spi )) {
5146 case ESP_ERR_INVALID_ARG :
5247 mp_raise_msg (& mp_type_OSError , "Invalid configuration" );
5348 return ;
@@ -57,7 +52,7 @@ STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_ha
5752 return ;
5853 }
5954
60- switch (spi_bus_free (host )) {
55+ switch (spi_bus_free (self -> host )) {
6156 case ESP_ERR_INVALID_ARG :
6257 mp_raise_msg (& mp_type_OSError , "Invalid configuration" );
6358 return ;
@@ -66,65 +61,18 @@ STATIC void machine_hw_spi_deinit_internal(spi_host_device_t host, spi_device_ha
6661 mp_raise_msg (& mp_type_OSError , "SPI bus already freed" );
6762 return ;
6863 }
69- }
70-
71- STATIC void machine_hw_spi_deinit (mp_obj_base_t * self_in ) {
72- machine_hw_spi_obj_t * self = (machine_hw_spi_obj_t * )self_in ;
73- if (self -> state == MACHINE_HW_SPI_STATE_INIT ) {
74- self -> state = MACHINE_HW_SPI_STATE_DEINIT ;
75- machine_hw_spi_deinit_internal (self -> host , & self -> spi );
76- }
77- }
78-
79-
80- STATIC void machine_hw_spi_transfer (mp_obj_base_t * self_in , size_t len , const uint8_t * src , uint8_t * dest ) {
81- machine_hw_spi_obj_t * self = MP_OBJ_TO_PTR (self_in );
82- int bits_to_send = len * self -> bits ;
83- if (self -> state == MACHINE_HW_SPI_STATE_DEINIT ) {
84- mp_raise_msg (& mp_type_OSError , "Transfer on deinitialized SPI" );
85- return ;
86- }
87-
88- struct spi_transaction_t transaction = {
89- .flags = 0 ,
90- .length = bits_to_send ,
91- .tx_buffer = NULL ,
92- .rx_buffer = NULL ,
93- };
94- bool shortMsg = len <= 4 ;
9564
65+ int8_t pins [3 ] = {self -> miso , self -> mosi , self -> sck };
9666
97- if (shortMsg ) {
98- if (src != NULL ) {
99- memcpy (& transaction .tx_data , src , len );
100- transaction .flags |= SPI_TRANS_USE_TXDATA ;
67+ for (int i = 0 ; i < 3 ; i ++ ) {
68+ if (pins [i ] != -1 ) {
69+ gpio_pad_select_gpio (pins [i ]);
70+ gpio_matrix_out (pins [i ], SIG_GPIO_OUT_IDX , false, false);
71+ gpio_set_direction (pins [i ], GPIO_MODE_INPUT );
10172 }
102- if (dest != NULL ) {
103- transaction .flags |= SPI_TRANS_USE_RXDATA ;
104- }
105- } else {
106- transaction .tx_buffer = src ;
107- transaction .rx_buffer = dest ;
108- }
109-
110- spi_device_transmit (self -> spi , & transaction );
111-
112- if (shortMsg && dest != NULL ) {
113- memcpy (dest , & transaction .rx_data , len );
11473 }
11574}
11675
117- /******************************************************************************/
118- // MicroPython bindings for hw_spi
119-
120- STATIC void machine_hw_spi_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
121- machine_hw_spi_obj_t * self = MP_OBJ_TO_PTR (self_in );
122- mp_printf (print , "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)" ,
123- self -> host , self -> baudrate , self -> polarity ,
124- self -> phase , self -> bits , self -> firstbit ,
125- self -> sck , self -> mosi , self -> miso );
126- }
127-
12876STATIC void machine_hw_spi_init_internal (
12977 machine_hw_spi_obj_t * self ,
13078 int8_t host ,
@@ -136,13 +84,14 @@ STATIC void machine_hw_spi_init_internal(
13684 int8_t sck ,
13785 int8_t mosi ,
13886 int8_t miso ) {
139- bool changed = false;
140- MACHINE_HW_SPI_DEBUG_PRINTF ("machine_hw_spi_init_internal(self, host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n" , host , baudrate , polarity , phase , bits , firstbit , sck , mosi , miso );
14187
88+ // if we're not initialized, then we're
89+ // implicitly 'changed', since this is the init routine
90+ bool changed = self -> state != MACHINE_HW_SPI_STATE_INIT ;
14291
143- MACHINE_HW_SPI_DEBUG_PRINTF ("machine_hw_spi_init_internal old values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n" , self -> host , self -> baudrate , self -> polarity , self -> phase , self -> bits , self -> firstbit , self -> sck , self -> mosi , self -> miso );
14492 esp_err_t ret ;
145- spi_host_device_t old_host = self -> host ;
93+
94+ machine_hw_spi_obj_t old_self = * self ;
14695
14796 if (host != -1 && host != self -> host ) {
14897 self -> host = host ;
@@ -195,17 +144,13 @@ STATIC void machine_hw_spi_init_internal(
195144
196145 if (changed ) {
197146 if (self -> state == MACHINE_HW_SPI_STATE_INIT ) {
198- MACHINE_HW_SPI_DEBUG_PRINTF ("machine_hw_spi_init_internal calling deinit()\n" );
199147 self -> state = MACHINE_HW_SPI_STATE_DEINIT ;
200- machine_hw_spi_deinit_internal (old_host , & self -> spi );
148+ machine_hw_spi_deinit_internal (& old_self );
201149 }
202150 } else {
203151 return ; // no changes
204152 }
205153
206- MACHINE_HW_SPI_DEBUG_PRINTF ("machine_hw_spi_init_internal new values: host = %d, baudrate = %d, polarity = %d, phase = %d, bits = %d, firstbit = %d, sck = %d, mosi = %d, miso = %d)\n" , self -> host , self -> baudrate , self -> polarity , self -> phase , self -> bits , self -> firstbit , self -> sck , self -> mosi , self -> miso );
207-
208-
209154 spi_bus_config_t buscfg = {
210155 .miso_io_num = self -> miso ,
211156 .mosi_io_num = self -> mosi ,
@@ -255,15 +200,68 @@ STATIC void machine_hw_spi_init_internal(
255200 return ;
256201 }
257202 self -> state = MACHINE_HW_SPI_STATE_INIT ;
258- MACHINE_HW_SPI_DEBUG_PRINTF ("machine_hw_spi_init_internal() returning\n" );
203+ }
204+
205+ STATIC void machine_hw_spi_deinit (mp_obj_base_t * self_in ) {
206+ machine_hw_spi_obj_t * self = (machine_hw_spi_obj_t * )self_in ;
207+ if (self -> state == MACHINE_HW_SPI_STATE_INIT ) {
208+ self -> state = MACHINE_HW_SPI_STATE_DEINIT ;
209+ machine_hw_spi_deinit_internal (self );
210+ }
211+ }
212+
213+ STATIC void machine_hw_spi_transfer (mp_obj_base_t * self_in , size_t len , const uint8_t * src , uint8_t * dest ) {
214+ machine_hw_spi_obj_t * self = MP_OBJ_TO_PTR (self_in );
215+
216+ int bits_to_send = len * self -> bits ;
217+ bool shortMsg = len <= 4 ;
218+
219+ if (self -> state == MACHINE_HW_SPI_STATE_DEINIT ) {
220+ mp_raise_msg (& mp_type_OSError , "Transfer on deinitialized SPI" );
221+ return ;
222+ }
223+
224+ struct spi_transaction_t transaction = {
225+ .flags = 0 ,
226+ .length = bits_to_send ,
227+ .tx_buffer = NULL ,
228+ .rx_buffer = NULL ,
229+ };
230+
231+ if (shortMsg ) {
232+ if (src != NULL ) {
233+ memcpy (& transaction .tx_data , src , len );
234+ }
235+ transaction .flags |= (SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA );
236+ } else {
237+ transaction .tx_buffer = src ;
238+ transaction .rx_buffer = dest ;
239+ }
240+
241+ spi_device_transmit (self -> spi , & transaction );
242+
243+ if (shortMsg && dest != NULL ) {
244+ memcpy (dest , & transaction .rx_data , len );
245+ }
246+ }
247+
248+ /******************************************************************************/
249+ // MicroPython bindings for hw_spi
250+
251+ STATIC void machine_hw_spi_print (const mp_print_t * print , mp_obj_t self_in , mp_print_kind_t kind ) {
252+ machine_hw_spi_obj_t * self = MP_OBJ_TO_PTR (self_in );
253+ mp_printf (print , "SPI(id=%u, baudrate=%u, polarity=%u, phase=%u, bits=%u, firstbit=%u, sck=%d, mosi=%d, miso=%d)" ,
254+ self -> host , self -> baudrate , self -> polarity ,
255+ self -> phase , self -> bits , self -> firstbit ,
256+ self -> sck , self -> mosi , self -> miso );
259257}
260258
261259STATIC void machine_hw_spi_init (mp_obj_base_t * self_in , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
262260 machine_hw_spi_obj_t * self = (machine_hw_spi_obj_t * )self_in ;
263261
264262 enum { ARG_id , ARG_baudrate , ARG_polarity , ARG_phase , ARG_bits , ARG_firstbit , ARG_sck , ARG_mosi , ARG_miso };
265263 static const mp_arg_t allowed_args [] = {
266- { MP_QSTR_id , MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = -1 } },
264+ { MP_QSTR_id , MP_ARG_INT , {.u_int = -1 } },
267265 { MP_QSTR_baudrate , MP_ARG_INT , {.u_int = -1 } },
268266 { MP_QSTR_polarity , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
269267 { MP_QSTR_phase , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = -1 } },
@@ -274,8 +272,6 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_
274272 { MP_QSTR_miso , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
275273 };
276274
277-
278-
279275 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
280276 mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ),
281277 allowed_args , args );
@@ -305,10 +301,9 @@ STATIC void machine_hw_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_
305301 mosi = machine_pin_get_id (args [ARG_mosi ].u_obj );
306302 }
307303
308- MACHINE_HW_SPI_DEBUG_PRINTF ("before calling internal\n" );
309304 machine_hw_spi_init_internal ( self , args [ARG_id ].u_int , args [ARG_baudrate ].u_int ,
310305 args [ARG_polarity ].u_int , args [ARG_phase ].u_int , args [ARG_bits ].u_int ,
311- args [ARG_firstbit ].u_int , sck , miso , mosi );
306+ args [ARG_firstbit ].u_int , sck , mosi , miso );
312307}
313308
314309mp_obj_t machine_hw_spi_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * all_args ) {
@@ -339,8 +334,8 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
339334 args [ARG_bits ].u_int ,
340335 args [ARG_firstbit ].u_int ,
341336 args [ARG_sck ].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id (args [ARG_sck ].u_obj ),
342- args [ARG_miso ].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id (args [ARG_miso ].u_obj ),
343- args [ARG_mosi ].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id (args [ARG_mosi ].u_obj ));
337+ args [ARG_mosi ].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id (args [ARG_mosi ].u_obj ),
338+ args [ARG_miso ].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id (args [ARG_miso ].u_obj ));
344339
345340 return MP_OBJ_FROM_PTR (self );
346341}
0 commit comments