From c37ade9aeba3c0608c8e8591e999871d96dadda8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 13 Mar 2018 12:44:00 -0700 Subject: [PATCH 1/2] Correct NO_TIMER index value for SAMD21. We check validity by ensuring it's lower than the total number of timers. 0 is a terrible number for the NO_TIMER value because its valid even though it shouldn't be. Fixes https://github.com/adafruit/Adafruit_CircuitPython_SimpleIO/issues/29 --- ports/atmel-samd/samd21_pins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/samd21_pins.c index f1d006de8bf0f..a6b19730f7c9f 100644 --- a/ports/atmel-samd/samd21_pins.c +++ b/ports/atmel-samd/samd21_pins.c @@ -57,7 +57,7 @@ .wave_output = p_wave_output \ } -#define NO_TIMER TCC(0, 0) +#define NO_TIMER TCC(0xff, 0) #define TOUCH(y_line) \ .has_touch = true, \ From 88aa0e2660e439fccac9c56b683a0e56b2399905 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Mar 2018 11:08:01 -0700 Subject: [PATCH 2/2] Remove SERCOM pointers from pin data structure because index is enough. This saves 380 bytes on the Arduino Zero build. (More pins == more savings.) --- ports/atmel-samd/common-hal/busio/I2C.c | 18 +++++++----- ports/atmel-samd/common-hal/busio/SPI.c | 11 ++++--- ports/atmel-samd/common-hal/busio/UART.c | 29 ++++++++++--------- .../common-hal/microcontroller/Pin.h | 5 ++-- ports/atmel-samd/peripherals.h | 2 ++ ports/atmel-samd/samd21_peripherals.c | 3 +- ports/atmel-samd/samd21_pins.c | 6 +--- ports/atmel-samd/samd51_peripherals.c | 3 +- ports/atmel-samd/samd51_pins.c | 8 ++--- 9 files changed, 44 insertions(+), 41 deletions(-) diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index 4182c86513868..4ac1f340c6f6b 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -46,19 +46,21 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, uint32_t sda_pinmux = 0; uint32_t scl_pinmux = 0; for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { - Sercom* potential_sercom = sda->sercom[i].sercom; - if (potential_sercom == NULL || - potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || + sercom_index = sda->sercom[i].index; + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom* potential_sercom = sercom_insts[sercom_index]; + if (potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || sda->sercom[i].pad != 0) { continue; } sda_pinmux = PINMUX(sda->pin, (i == 0) ? MUX_C : MUX_D); for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (potential_sercom == scl->sercom[j].sercom && + if (sercom_index == scl->sercom[j].index && scl->sercom[j].pad == 1) { scl_pinmux = PINMUX(scl->pin, (j == 0) ? MUX_C : MUX_D); sercom = potential_sercom; - sercom_index = scl->sercom[j].index; // 2 for SERCOM2, etc. break; } } @@ -77,7 +79,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, if (i2c_m_sync_init(&self->i2c_desc, sercom) != ERR_NONE) { mp_raise_OSError(MP_EIO); } - + gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF); gpio_set_pin_function(sda->pin, sda_pinmux); @@ -85,7 +87,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, gpio_set_pin_function(scl->pin, scl_pinmux); // clkrate is always 0. baud_rate is in kHz. - + // Frequency must be set before the I2C device is enabled. if (i2c_m_sync_set_baudrate(&self->i2c_desc, 0, frequency / 1000) != ERR_NONE) { mp_raise_ValueError("Unsupported baudrate"); @@ -113,7 +115,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { i2c_m_sync_disable(&self->i2c_desc); i2c_m_sync_deinit(&self->i2c_desc); - + reset_pin(self->sda_pin); reset_pin(self->scl_pin); self->sda_pin = NO_PIN; diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index eca73be78a460..a2bf30f054f5a 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -55,9 +55,12 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, uint8_t miso_pad = 0; uint8_t dopo = 255; for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { - Sercom* potential_sercom = clock->sercom[i].sercom; sercom_index = clock->sercom[i].index; // 2 for SERCOM2, etc. - if (potential_sercom == NULL || + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom* potential_sercom = sercom_insts[sercom_index]; + if ( #if defined(MICROPY_HW_APA102_SCK) && defined(MICROPY_HW_APA102_MOSI) && !defined(CIRCUITPY_BITBANG_APA102) (potential_sercom->SPI.CTRLA.bit.ENABLE != 0 && potential_sercom != status_apa102.spi_desc.dev.prvt && @@ -74,7 +77,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { if (!mosi_none) { - if(potential_sercom == mosi->sercom[j].sercom) { + if (sercom_index == mosi->sercom[j].index) { mosi_pinmux = PINMUX(mosi->pin, (j == 0) ? MUX_C : MUX_D); mosi_pad = mosi->sercom[j].pad; dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); @@ -91,7 +94,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } if (!miso_none) { for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { - if (potential_sercom == miso->sercom[k].sercom) { + if (sercom_index == miso->sercom[k].index) { miso_pinmux = PINMUX(miso->pin, (k == 0) ? MUX_C : MUX_D); miso_pad = miso->sercom[k].pad; sercom = potential_sercom; diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index 292e01e60ebc3..4cb7db2033987 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -71,7 +71,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (!have_tx && !have_rx) { mp_raise_ValueError("tx and rx cannot both be None"); } - + self->baudrate = baudrate; self->character_bits = bits; self->timeout_ms = timeout; @@ -82,10 +82,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { Sercom* potential_sercom = NULL; if (have_tx) { - potential_sercom = tx->sercom[i].sercom; sercom_index = tx->sercom[i].index; - if (potential_sercom == NULL || - potential_sercom->USART.CTRLA.bit.ENABLE != 0 || + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + potential_sercom = sercom_insts[sercom_index]; + if (potential_sercom->USART.CTRLA.bit.ENABLE != 0 || !(tx->sercom[i].pad == 0 || tx->sercom[i].pad == 2)) { continue; @@ -98,12 +100,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } } for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (((!have_tx && rx->sercom[j].sercom->USART.CTRLA.bit.ENABLE == 0) || - potential_sercom == rx->sercom[j].sercom) && + if (((!have_tx && rx->sercom[j].index < SERCOM_INST_NUM && + sercom_insts[rx->sercom[j].index]->USART.CTRLA.bit.ENABLE == 0) || + sercom_index == rx->sercom[j].index) && rx->sercom[j].pad != tx_pad) { rx_pinmux = PINMUX(rx->pin, (j == 0) ? MUX_C : MUX_D); rx_pad = rx->sercom[j].pad; - sercom = rx->sercom[j].sercom; + sercom = sercom_insts[rx->sercom[j].index]; sercom_index = rx->sercom[j].index; break; } @@ -147,7 +150,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // usart_async_init() sets a number of defaults based on a prototypical SERCOM // which don't necessarily match what we need. After calling it, set the values // specific to this instantiation of UART. - + // Set pads computed for this SERCOM. // TXPO: // 0x0: TX pad 0; no RTS/CTS @@ -182,7 +185,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836 // Look at the ASFv4 code example for async USART. usart_async_register_callback(usart_desc_p, USART_ASYNC_RXC_CB, usart_async_rxc_callback); - + if (have_tx) { gpio_set_pin_direction(tx->pin, GPIO_DIRECTION_OUT); @@ -193,7 +196,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } else { self->tx_pin = NO_PIN; } - + if (have_rx) { gpio_set_pin_direction(rx->pin, GPIO_DIRECTION_IN); gpio_set_pin_pull_mode(rx->pin, GPIO_PULL_OFF); @@ -238,7 +241,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t // Nothing to read. return 0; } - + struct io_descriptor *io; usart_async_get_io_descriptor(usart_desc_p, &io); @@ -266,7 +269,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t MICROPY_VM_HOOK_LOOP #endif } - + return total_read; } @@ -305,7 +308,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, *errcode = MP_EAGAIN; return MP_STREAM_ERROR; } - + struct usart_async_status async_status; // Could return ERR_BUSY, but if that's true there's already a problem. usart_async_get_status(usart_desc_p, &async_status); diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.h b/ports/atmel-samd/common-hal/microcontroller/Pin.h index ca639eb849a62..4e21a14cd860d 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.h +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.h @@ -34,9 +34,8 @@ #include "include/component/sercom.h" typedef struct { - Sercom *const sercom; // SERCOM0, SERCOM1, etc. - uint8_t index; // 0, 1, etc. corresponding to SERCOM. - uint8_t pad; // which of the four SERCOM pads to use + uint8_t index:6; // 0, 1, etc. corresponding to SERCOM. + uint8_t pad:2; // which of the four SERCOM pads to use } pin_sercom_t; typedef struct { diff --git a/ports/atmel-samd/peripherals.h b/ports/atmel-samd/peripherals.h index bb01bc1acd277..18c7f44d5c278 100644 --- a/ports/atmel-samd/peripherals.h +++ b/ports/atmel-samd/peripherals.h @@ -35,6 +35,8 @@ 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); +Sercom* sercom_insts[SERCOM_INST_NUM]; + #ifdef SAMD21 #include "samd21_peripherals.h" #endif diff --git a/ports/atmel-samd/samd21_peripherals.c b/ports/atmel-samd/samd21_peripherals.c index 484c787cb030c..a27e49e0e5e99 100644 --- a/ports/atmel-samd/samd21_peripherals.c +++ b/ports/atmel-samd/samd21_peripherals.c @@ -56,7 +56,8 @@ static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { #endif }; - +Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; + // Clock initialization as done in Atmel START. void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { _pm_enable_bus_clock(PM_BUS_APBC, sercom); diff --git a/ports/atmel-samd/samd21_pins.c b/ports/atmel-samd/samd21_pins.c index a6b19730f7c9f..eafc4b5fb692b 100644 --- a/ports/atmel-samd/samd21_pins.c +++ b/ports/atmel-samd/samd21_pins.c @@ -30,15 +30,13 @@ #define SERCOM(sercom_index, p_pad) \ { \ - .sercom = SERCOM## sercom_index, \ .index = sercom_index, \ .pad = p_pad \ } #define NO_SERCOM \ { \ - .sercom = 0, \ - .index = 0, \ + .index = 0x3f, \ .pad = 0 \ } @@ -92,8 +90,6 @@ const mcu_pin_obj_t pin_## p_name = { \ .sercom = {p_primary_sercom, p_secondary_sercom}, \ } -#define NO_ADC_INPUT (0) - // Pins in datasheet order. // NOTE(tannewt): TC wave out 0 is commented out because the first channel is // used to vary the 16 bit timer's frequency. diff --git a/ports/atmel-samd/samd51_peripherals.c b/ports/atmel-samd/samd51_peripherals.c index e06f7f9df0596..8f37bdfd115d8 100644 --- a/ports/atmel-samd/samd51_peripherals.c +++ b/ports/atmel-samd/samd51_peripherals.c @@ -60,7 +60,8 @@ static const uint8_t SERCOMx_GCLK_ID_SLOW[] = { #endif }; - +Sercom* sercom_insts[SERCOM_INST_NUM] = SERCOM_INSTS; + // Clock initialization as done in Atmel START. void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index) { hri_gclk_write_PCHCTRL_reg(GCLK, diff --git a/ports/atmel-samd/samd51_pins.c b/ports/atmel-samd/samd51_pins.c index 78bdf0553c701..6d597b6e1a0d6 100644 --- a/ports/atmel-samd/samd51_pins.c +++ b/ports/atmel-samd/samd51_pins.c @@ -30,15 +30,13 @@ #define SERCOM(sercom_index, p_pad) \ { \ - .sercom = SERCOM## sercom_index, \ .index = sercom_index, \ .pad = p_pad \ } #define NO_SERCOM \ { \ - .sercom = 0, \ - .index = 0, \ + .index = 0x3f, \ .pad = 0 \ } @@ -91,8 +89,6 @@ const mcu_pin_obj_t pin_## p_name = { \ .sercom = {p_primary_sercom, p_secondary_sercom}, \ } -#define NO_ADC_INPUT (0) - // Pins in datasheet order. // NOTE(tannewt): TC wave out 0 is commented out because the first channel is // used to vary the 16 bit timer's frequency. @@ -1139,7 +1135,7 @@ PIN(PA31, EXTINT_CHANNEL(15), NO_ADC, NO_ADC, NO_TOUCH, #else NO_SERCOM, #endif - SERCOM(1, 23), + SERCOM(1, 3), #ifdef TC6 TC(6, 1), #else pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy