Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions ports/atmel-samd/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,

// Always start at 250khz which is what SD cards need. They are sensitive to
// SPI bus noise before they are put into SPI mode.
uint8_t baud_value = samd_peripherals_baudrate_to_baud_reg_value(250000);
if (baud_value == 0) {
mp_raise_RuntimeError("SPI initial baudrate out of range.");
}
uint8_t baud_value = samd_peripherals_spi_baudrate_to_baud_reg_value(250000);
if (spi_m_sync_set_baudrate(&self->spi_desc, baud_value) != ERR_NONE) {
// spi_m_sync_set_baudrate does not check for validity, just whether the device is
// busy or not
Expand Down Expand Up @@ -179,10 +176,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {

bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
uint8_t baud_reg_value = samd_peripherals_baudrate_to_baud_reg_value(baudrate);
if (baud_reg_value == 0) {
mp_raise_ValueError("baudrate out of range");
}
uint8_t baud_reg_value = samd_peripherals_spi_baudrate_to_baud_reg_value(baudrate);

void * hw = self->spi_desc.dev.prvt;
// If the settings are already what we want then don't reset them.
Expand Down Expand Up @@ -279,3 +273,7 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uin
// }
return status >= 0; // Status is number of chars read or an error code < 0.
}

uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
return samd_peripherals_spi_baud_reg_value_to_baudrate(hri_sercomspi_read_BAUD_reg(self->spi_desc.dev.prvt));
}
16 changes: 9 additions & 7 deletions ports/atmel-samd/peripherals.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
// Routines that are the same across all samd variants.


// Convert frequency to clock-speed-dependent value. Return 0 if out of range.
uint8_t samd_peripherals_baudrate_to_baud_reg_value(const uint32_t baudrate) {
// Convert frequency to clock-speed-dependent value. Return 255 if > 255.
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate) {
uint32_t baud_reg_value = (uint32_t) (((float) PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY /
(2 * baudrate)) + 0.5f);
if (baud_reg_value > 0xff) {
return 0;
}
return (uint8_t) baud_reg_value;
(2 * baudrate)) - 0.5f);
return (uint8_t) (baud_reg_value > 255 ? 255 : baud_reg_value);
}

// Convert BAUD reg value back to a frequency.
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value) {
return PROTOTYPE_SERCOM_SPI_M_SYNC_CLOCK_FREQUENCY / (2 * (baud_reg_value + 1));
}

3 changes: 2 additions & 1 deletion ports/atmel-samd/peripherals.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
#include "mpconfigport.h"

// Routines common across chip families.
uint8_t samd_peripherals_baudrate_to_baud_reg_value(const uint32_t baudrate);
uint8_t samd_peripherals_spi_baudrate_to_baud_reg_value(const uint32_t baudrate);
uint32_t samd_peripherals_spi_baud_reg_value_to_baudrate(const uint8_t baud_reg_value);

#ifdef SAMD21
#include "samd21_peripherals.h"
Expand Down
2 changes: 1 addition & 1 deletion ports/atmel-samd/spi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void spi_flash_init(void) {
hri_sercomspi_write_CTRLA_DOPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DOPO);
hri_sercomspi_write_CTRLA_DIPO_bf(SPI_FLASH_SERCOM, SPI_FLASH_DIPO);

spi_m_sync_set_baudrate(&spi_flash_desc, samd_peripherals_baudrate_to_baud_reg_value(SPI_FLASH_BAUDRATE));
spi_m_sync_set_baudrate(&spi_flash_desc, samd_peripherals_spi_baudrate_to_baud_reg_value(SPI_FLASH_BAUDRATE));

gpio_set_pin_direction(SPI_FLASH_CS_PIN, GPIO_DIRECTION_OUT);
// There's already a pull-up on the board.
Expand Down
7 changes: 7 additions & 0 deletions ports/esp8266/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);

spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
self->frequency = SPI_CLK_FREQ;
spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);

Expand Down Expand Up @@ -107,6 +108,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
// Special case for full speed.
spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
spi_clock(HSPI, 0, 0);
self->frequency = 80000000L;
} else if (baudrate > 40000000L) {
return false;
} else {
Expand All @@ -118,6 +120,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
}
spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
spi_clock(HSPI, prediv, cntdiv);
self->frequency = 80000000L / (prediv * cntdiv);
}
spi_mode(HSPI, phase, polarity);
return true;
Expand Down Expand Up @@ -205,3 +208,7 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uin
return true;

}

uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
return self->frequency;
}
1 change: 1 addition & 0 deletions ports/esp8266/common-hal/busio/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

typedef struct {
mp_obj_base_t base;
uint32_t frequency;
bool locked;
bool deinited;
} busio_spi_obj_t;
Expand Down
2 changes: 1 addition & 1 deletion ports/esp8266/posix_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// Functions for external libs like axTLS, BerkeleyDB, etc.

void *malloc(size_t size) {
void *p = gc_alloc(size, false);
void *p = gc_alloc(size, false, false);
if (p == NULL) {
// POSIX requires ENOMEM to be set in case of error
errno = ENOMEM;
Expand Down
20 changes: 20 additions & 0 deletions ports/nrf/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,23 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uin
return true;
}

uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
switch (self->spi->FREQUENCY) {
case SPI_FREQUENCY_FREQUENCY_K125:
return 125000;
case SPI_FREQUENCY_FREQUENCY_K250:
return 250000;
case SPI_FREQUENCY_FREQUENCY_K500:
return 500000;
case SPI_FREQUENCY_FREQUENCY_M1:
return 1000000;
case SPI_FREQUENCY_FREQUENCY_M2:
return 2000000;
case SPI_FREQUENCY_FREQUENCY_M4:
return 4000000;
case SPI_FREQUENCY_FREQUENCY_M8:
return 8000000;
default:
return 0;
}
}
29 changes: 27 additions & 2 deletions shared-bindings/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "lib/utils/buffer_helper.h"
#include "lib/utils/context_manager_helpers.h"
#include "py/mperrno.h"
#include "py/nlr.h"
#include "py/objproperty.h"
#include "py/runtime.h"

//| .. currentmodule:: busio
Expand Down Expand Up @@ -137,7 +137,12 @@ static void check_lock(busio_spi_obj_t *self) {
//|
//| Configures the SPI bus. Only valid when locked.
//|
//| :param int baudrate: the clock rate in Hertz
//| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower
//| due to the granularity of available clock settings.
//| Check the `frequency` attribute for the actual clock rate.
//| **Note:** on the SAMD21, it is possible to set the baud rate to 24 MHz, but that
//| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is
//| within spec for the SAMD21.
//| :param int polarity: the base state of the clock line (0 or 1)
//| :param int phase: the edge of the clock that data is captured. First (0)
//| or second (1). Rising or falling depends on clock polarity.
Expand Down Expand Up @@ -350,6 +355,25 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 2, busio_spi_write_readinto);

//| .. attribute:: frequency
//|
//| The actual SPI bus frequency. This may not match the frequency requested
//| due to internal limitations.
//|
STATIC mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
raise_error_if_deinited(common_hal_busio_spi_deinited(self));
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_get_frequency(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequency);

const mp_obj_property_t busio_spi_frequency_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&busio_spi_get_frequency_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};

STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_spi_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
Expand All @@ -362,6 +386,7 @@ STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&busio_spi_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&busio_spi_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&busio_spi_write_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&busio_spi_frequency_obj) }
};
STATIC MP_DEFINE_CONST_DICT(busio_spi_locals_dict, busio_spi_locals_dict_table);

Expand Down
3 changes: 3 additions & 0 deletions shared-bindings/busio/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,7 @@ extern bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size
// Reads and write len bytes simultaneously.
extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len);

// Return actual SPI bus frequency.
uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H