atmel-samd: Re-org helper peripheral files into their own subdirectory.
Ideally in the future they won't depend on ASF4 or MicroPython.
This commit is contained in:
parent
ae31c4ac18
commit
fd71e56891
1
conf.py
1
conf.py
@ -101,6 +101,7 @@ exclude_patterns = ["**/build*",
|
||||
"ports/atmel-samd/asf4_conf",
|
||||
"ports/atmel-samd/external_flash",
|
||||
"ports/atmel-samd/freetouch",
|
||||
"ports/atmel-samd/peripherals",
|
||||
"ports/atmel-samd/QTouch",
|
||||
"ports/atmel-samd/tools",
|
||||
"ports/bare-arm",
|
||||
|
@ -242,19 +242,24 @@ SRC_C = \
|
||||
audio_dma.c \
|
||||
board_busses.c \
|
||||
background.c \
|
||||
clocks.c \
|
||||
$(CHIP_FAMILY)_clocks.c \
|
||||
events.c \
|
||||
fatfs_port.c \
|
||||
flash_api.c \
|
||||
mphalport.c \
|
||||
reset.c \
|
||||
$(CHIP_FAMILY)_peripherals.c \
|
||||
peripherals.c \
|
||||
$(CHIP_FAMILY)_pins.c \
|
||||
shared_dma.c \
|
||||
peripherals/clocks.c \
|
||||
peripherals/dma.c \
|
||||
peripherals/events.c \
|
||||
peripherals/sercom.c \
|
||||
peripherals/timers.c \
|
||||
peripherals/$(CHIP_FAMILY)/adc.c \
|
||||
peripherals/$(CHIP_FAMILY)/cache.c \
|
||||
peripherals/$(CHIP_FAMILY)/clocks.c \
|
||||
peripherals/$(CHIP_FAMILY)/dma.c \
|
||||
peripherals/$(CHIP_FAMILY)/events.c \
|
||||
peripherals/$(CHIP_FAMILY)/pins.c \
|
||||
peripherals/$(CHIP_FAMILY)/sercom.c \
|
||||
peripherals/$(CHIP_FAMILY)/timers.c \
|
||||
tick.c \
|
||||
timers.c \
|
||||
usb.c \
|
||||
usb_mass_storage.c \
|
||||
bindings/samd/__init__.c \
|
||||
@ -301,6 +306,8 @@ SRC_COMMON_HAL = \
|
||||
microcontroller/Processor.c \
|
||||
neopixel_write/__init__.c \
|
||||
os/__init__.c \
|
||||
rotaryio/__init__.c \
|
||||
rotaryio/IncrementalEncoder.c \
|
||||
rtc/__init__.c \
|
||||
rtc/RTC.c \
|
||||
storage/__init__.c \
|
||||
@ -391,7 +398,7 @@ ifneq ($(CHIP_VARIANT),SAMD51G18A)
|
||||
audiobusio/__init__.c \
|
||||
audiobusio/I2SOut.c \
|
||||
audiobusio/PDMIn.c
|
||||
SRC_C += i2s.c
|
||||
SRC_C += peripherals/i2s.c peripherals/$(CHIP_FAMILY)/i2s.c
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -25,9 +25,9 @@
|
||||
*/
|
||||
|
||||
#include "audio_dma.h"
|
||||
#include "clocks.h"
|
||||
#include "events.h"
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/clocks.h"
|
||||
#include "peripherals/events.h"
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include "shared-bindings/audioio/RawSample.h"
|
||||
#include "shared-bindings/audioio/WaveFile.h"
|
||||
|
@ -24,9 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "clocks.h"
|
||||
#include "bindings/samd/Clock.h"
|
||||
|
||||
#include "peripherals/clocks.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
|
@ -30,11 +30,9 @@
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "mpconfigboard.h"
|
||||
#include "pins.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
|
||||
|
||||
#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL)
|
||||
STATIC mp_obj_t board_i2c(void) {
|
||||
mp_raise_NotImplementedError("No default I2C bus");
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "samd21_pins.h"
|
||||
#include "board_busses.h"
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) },
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/neopixel_write/__init__.h"
|
||||
#include "samd21_pins.h"
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/neopixel_write/__init__.h"
|
||||
#include "samd21_pins.h"
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd51_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd51_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
// This mapping only includes functional names because pins broken
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd51_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
// This mapping only includes functional names because pins broken
|
||||
|
@ -1,72 +0,0 @@
|
||||
// This is for Rev B which a larger run was done and sent to Adafruit community
|
||||
// members.
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "Metro M4 Express Rev B (Black)"
|
||||
#define MICROPY_HW_MCU_NAME "samd51j19"
|
||||
|
||||
#define CIRCUITPY_MCU_FAMILY samd51
|
||||
|
||||
#define MICROPY_HW_LED_TX PIN_PA27
|
||||
#define MICROPY_HW_LED_RX PIN_PB06
|
||||
|
||||
#define MICROPY_HW_NEOPIXEL (&pin_PB17)
|
||||
|
||||
#define SPI_FLASH_BAUDRATE (60000000)
|
||||
|
||||
// Rev B: single channel SPI
|
||||
// Rev C will be QSPI
|
||||
#define SPI_FLASH_MOSI_PIN PIN_PB08
|
||||
#define SPI_FLASH_MISO_PIN PIN_PB11
|
||||
#define SPI_FLASH_SCK_PIN PIN_PB09
|
||||
#define SPI_FLASH_CS_PIN PIN_PB10
|
||||
#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PB08D_SERCOM4_PAD0
|
||||
#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PB11D_SERCOM4_PAD3
|
||||
#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PB09D_SERCOM4_PAD1
|
||||
#define SPI_FLASH_SERCOM SERCOM4
|
||||
#define SPI_FLASH_SERCOM_INDEX 4
|
||||
#define SPI_FLASH_MOSI_PAD 0
|
||||
#define SPI_FLASH_MISO_PAD 3
|
||||
#define SPI_FLASH_SCK_PAD 1
|
||||
// <o> Transmit Data Pinout
|
||||
// <0x0=>PAD[0,1]_DO_SCK
|
||||
// <0x1=>PAD[2,3]_DO_SCK
|
||||
// <0x2=>PAD[3,1]_DO_SCK
|
||||
// <0x3=>PAD[0,3]_DO_SCK
|
||||
#define SPI_FLASH_DOPO 0
|
||||
#define SPI_FLASH_DIPO 3 // same as MISO pad
|
||||
|
||||
// These are pins not to reset.
|
||||
// Pin for TX LED
|
||||
#define MICROPY_PORT_A (PORT_PA27)
|
||||
// Pins for RX LED, SPI flash and neopixel
|
||||
#define MICROPY_PORT_B (PORT_PB06 | PORT_PB08 | PORT_PB09 | PORT_PB10 | PORT_PB11 | PORT_PB17)
|
||||
#define MICROPY_PORT_C (0)
|
||||
#define MICROPY_PORT_D (0)
|
||||
|
||||
#define AUTORESET_DELAY_MS 500
|
||||
|
||||
#include "external_flash/external_flash.h"
|
||||
|
||||
// If you change this, then make sure to update the linker scripts as well to
|
||||
// make sure you don't overwrite code
|
||||
#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
|
||||
|
||||
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
|
||||
|
||||
#include "external_flash/devices.h"
|
||||
|
||||
#define EXTERNAL_FLASH_DEVICE_COUNT 2
|
||||
#define EXTERNAL_FLASH_DEVICES S25FL216K, \
|
||||
GD25Q16C
|
||||
|
||||
#include "external_flash/external_flash.h"
|
||||
|
||||
#define DEFAULT_I2C_BUS_SCL (&pin_PB03)
|
||||
#define DEFAULT_I2C_BUS_SDA (&pin_PB02)
|
||||
|
||||
#define DEFAULT_SPI_BUS_SCK (&pin_PA13)
|
||||
#define DEFAULT_SPI_BUS_MOSI (&pin_PA12)
|
||||
#define DEFAULT_SPI_BUS_MISO (&pin_PA15)
|
||||
|
||||
#define DEFAULT_UART_BUS_RX (&pin_PA23)
|
||||
#define DEFAULT_UART_BUS_TX (&pin_PA22)
|
@ -1,11 +0,0 @@
|
||||
LD_FILE = boards/samd51x19-bootloader-external-flash.ld
|
||||
USB_VID = 0x239A
|
||||
USB_PID = 0x8021
|
||||
USB_PRODUCT = "Metro M4 Express Rev B (Black)"
|
||||
USB_MANUFACTURER = "Adafruit Industries LLC"
|
||||
|
||||
SPI_FLASH_FILESYSTEM = 1
|
||||
LONGINT_IMPL = MPZ
|
||||
|
||||
CHIP_VARIANT = SAMD51J19A
|
||||
CHIP_FAMILY = samd51
|
@ -1,48 +0,0 @@
|
||||
#include "samd51_pins.h"
|
||||
#include "board_busses.h"
|
||||
|
||||
// This mapping only includes functional names because pins broken
|
||||
// out on connectors are labeled with their MCU name available from
|
||||
// microcontroller.pin.
|
||||
STATIC const mp_map_elem_t board_global_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A0), (mp_obj_t)&pin_PA02 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A1), (mp_obj_t)&pin_PA05 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A2), (mp_obj_t)&pin_PA06 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A3), (mp_obj_t)&pin_PA04 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A4), (mp_obj_t)&pin_PA11 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A5), (mp_obj_t)&pin_PA07 },
|
||||
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D0), (mp_obj_t)&pin_PA23 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RX), (mp_obj_t)&pin_PA23 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D1), (mp_obj_t)&pin_PA22 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_TX), (mp_obj_t)&pin_PA22 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D2), (mp_obj_t)&pin_PA08 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D3), (mp_obj_t)&pin_PA10 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D4), (mp_obj_t)&pin_PB12 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D5), (mp_obj_t)&pin_PB14 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D6), (mp_obj_t)&pin_PB15 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D7), (mp_obj_t)&pin_PA14 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D8), (mp_obj_t)&pin_PA16 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D9), (mp_obj_t)&pin_PA17 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D10), (mp_obj_t)&pin_PA18 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D11), (mp_obj_t)&pin_PA19 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D12), (mp_obj_t)&pin_PA20 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_D13), (mp_obj_t)&pin_PA21 },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA), (mp_obj_t)&pin_PB02 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCL), (mp_obj_t)&pin_PB03 },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), (mp_obj_t)&pin_PB17 },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SCK), (mp_obj_t)&pin_PA13 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), (mp_obj_t)&pin_PA12 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MISO), (mp_obj_t)&pin_PA15 },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), (mp_obj_t)&pin_PB06 },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), (mp_obj_t)&pin_PA27 },
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "board_busses.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "py/binary.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "peripherals/adc.h"
|
||||
#include "shared-bindings/analogio/AnalogIn.h"
|
||||
|
||||
#include "atmel_start_pins.h"
|
||||
|
@ -42,10 +42,6 @@
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
#include "samd51_pins.h"
|
||||
#endif
|
||||
|
||||
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
|
||||
const mcu_pin_obj_t *pin) {
|
||||
if (pin->pin != PIN_PA02
|
||||
|
@ -45,13 +45,14 @@
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
#include "peripherals/clocks.h"
|
||||
#include "peripherals/dma.h"
|
||||
#include "peripherals/events.h"
|
||||
#include "peripherals/i2s.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "peripherals/timers.h"
|
||||
|
||||
#include "audio_dma.h"
|
||||
#include "clocks.h"
|
||||
#include "events.h"
|
||||
#include "i2s.h"
|
||||
#include "pins.h"
|
||||
#include "shared_dma.h"
|
||||
#include "timers.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#define SERCTRL(name) I2S_SERCTRL_ ## name
|
||||
|
@ -41,12 +41,13 @@
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "hal/utils/include/utils.h"
|
||||
|
||||
#include "peripherals/clocks.h"
|
||||
#include "peripherals/events.h"
|
||||
#include "peripherals/i2s.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include "audio_dma.h"
|
||||
#include "clocks.h"
|
||||
#include "events.h"
|
||||
#include "i2s.h"
|
||||
#include "pins.h"
|
||||
#include "shared_dma.h"
|
||||
#include "tick.h"
|
||||
|
||||
#define OVERSAMPLING 64
|
||||
|
@ -45,10 +45,11 @@
|
||||
#endif
|
||||
|
||||
#include "audio_dma.h"
|
||||
#include "events.h"
|
||||
#include "samd21_pins.h"
|
||||
#include "shared_dma.h"
|
||||
#include "timers.h"
|
||||
|
||||
#include "peripherals/dma.h"
|
||||
#include "peripherals/events.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "peripherals/timers.h"
|
||||
|
||||
void audioout_reset(void) {
|
||||
}
|
||||
|
@ -32,8 +32,7 @@
|
||||
#include "hal/include/hal_i2c_m_sync.h"
|
||||
#include "hal/include/hpl_i2c_m_sync.h"
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "pins.h"
|
||||
#include "peripherals/sercom.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
|
||||
|
@ -36,9 +36,9 @@
|
||||
#include "hal/include/hpl_spi_m_sync.h"
|
||||
#include "supervisor/shared/rgb_led_status.h"
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "pins.h"
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/dma.h"
|
||||
//#include "peripherals/pins.h"
|
||||
#include "peripherals/sercom.h"
|
||||
|
||||
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
||||
|
@ -42,8 +42,7 @@
|
||||
#include "hal/include/hal_usart_async.h"
|
||||
#include "hal/include/hpl_usart_async.h"
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "pins.h"
|
||||
#include "peripherals/sercom.h"
|
||||
|
||||
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
|
||||
// See comment below re usart_async_register_callback()
|
||||
|
@ -29,13 +29,8 @@
|
||||
#include "atmel_start_pins.h"
|
||||
#include "hal/include/hal_gpio.h"
|
||||
|
||||
#include "peripherals/pins.h"
|
||||
#include "supervisor/shared/rgb_led_status.h"
|
||||
#ifdef SAMD21
|
||||
#include "samd21_pins.h"
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#include "samd51_pins.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROPY_HW_NEOPIXEL
|
||||
bool neopixel_in_use;
|
||||
|
@ -81,4 +81,6 @@ void reset_all_pins(void);
|
||||
void reset_pin(uint8_t pin);
|
||||
void claim_pin(const mcu_pin_obj_t* pin);
|
||||
|
||||
#include "peripherals/pins.h"
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
#include "common-hal/microcontroller/Processor.h"
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "peripherals/adc.h"
|
||||
|
||||
#include "peripheral_clk_config.h"
|
||||
|
||||
|
@ -30,10 +30,10 @@
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "reset.h"
|
||||
#include "samd21_pins.h"
|
||||
|
||||
#include "shared-bindings/nvm/ByteArray.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Processor.h"
|
||||
|
||||
void common_hal_mcu_delay_us(uint32_t delay) {
|
||||
|
@ -34,9 +34,9 @@
|
||||
|
||||
#include "atmel_start_pins.h"
|
||||
#include "hal/utils/include/utils_repeat_macro.h"
|
||||
#include "timers.h"
|
||||
#include "peripherals/timers.h"
|
||||
|
||||
#include "samd21_pins.h"
|
||||
#include "peripherals/pins.h"
|
||||
|
||||
#undef ENABLE
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
* Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -34,7 +34,7 @@
|
||||
#include "mpconfigport.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "samd21_pins.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/pulseio/PulseIn.h"
|
||||
|
||||
|
@ -31,11 +31,11 @@
|
||||
#include "hal/include/hal_gpio.h"
|
||||
|
||||
#include "mpconfigport.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "peripherals/timers.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "samd21_pins.h"
|
||||
#include "shared-bindings/pulseio/PulseOut.h"
|
||||
#include "timers.h"
|
||||
|
||||
// This timer is shared amongst all PulseOut objects under the assumption that
|
||||
// the code is single threaded.
|
||||
|
158
ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
Normal file
158
ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "common-hal/rotaryio/IncrementalEncoder.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "atmel_start_pins.h"
|
||||
#include "hal/include/hal_gpio.h"
|
||||
|
||||
#include "mpconfigport.h"
|
||||
#include "peripherals/pins.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#endif
|
||||
|
||||
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
|
||||
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
|
||||
// if (!pin->has_extint) {
|
||||
// mp_raise_RuntimeError("No hardware support on pin");
|
||||
// }
|
||||
// uint32_t mask = 1 << pin->extint_channel;
|
||||
// if (active_incrementalencoders[pin->extint_channel] != NULL ||
|
||||
// (eic_get_enable() == 1 &&
|
||||
// #ifdef SAMD51
|
||||
// ((EIC->INTENSET.bit.EXTINT & mask) != 0 ||
|
||||
// (EIC->EVCTRL.bit.EXTINTEO & mask) != 0))) {
|
||||
// #endif
|
||||
// #ifdef SAMD21
|
||||
// ((EIC->INTENSET.vec.EXTINT & mask) != 0 ||
|
||||
// (EIC->EVCTRL.vec.EXTINTEO & mask) != 0))) {
|
||||
// #endif
|
||||
// mp_raise_RuntimeError("EXTINT channel already in use");
|
||||
// }
|
||||
//
|
||||
// self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
|
||||
// if (self->buffer == NULL) {
|
||||
// mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t));
|
||||
// }
|
||||
// self->channel = pin->extint_channel;
|
||||
// self->pin = pin->pin;
|
||||
// self->maxlen = maxlen;
|
||||
// self->idle_state = idle_state;
|
||||
// self->start = 0;
|
||||
// self->len = 0;
|
||||
// self->first_edge = true;
|
||||
//
|
||||
// active_incrementalencoders[pin->extint_channel] = self;
|
||||
//
|
||||
// // Check to see if the EIC is enabled and start it up if its not.'
|
||||
// // SAMD51 EIC can only be clocked up to 100mhz so we use the 48mhz clock.
|
||||
// if (eic_get_enable() == 0) {
|
||||
// #ifdef SAMD51
|
||||
// MCLK->APBAMASK.bit.EIC_ = true;
|
||||
// hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID,
|
||||
// GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
// #endif
|
||||
//
|
||||
// #ifdef SAMD21
|
||||
// PM->APBAMASK.bit.EIC_ = true;
|
||||
// _gclk_enable_channel(EIC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
|
||||
// #endif
|
||||
//
|
||||
//
|
||||
// #ifdef SAMD21
|
||||
// NVIC_DisableIRQ(EIC_IRQn);
|
||||
// NVIC_ClearPendingIRQ(EIC_IRQn);
|
||||
// NVIC_EnableIRQ(EIC_IRQn);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// gpio_set_pin_function(pin->pin, GPIO_PIN_FUNCTION_A);
|
||||
//
|
||||
// #ifdef SAMD51
|
||||
// NVIC_DisableIRQ(EIC_0_IRQn + self->channel);
|
||||
// NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel);
|
||||
// NVIC_EnableIRQ(EIC_0_IRQn + self->channel);
|
||||
// #endif
|
||||
//
|
||||
// // Set config will enable the EIC.
|
||||
// incrementalencoder_set_config(self, true);
|
||||
// EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos;
|
||||
}
|
||||
|
||||
bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self) {
|
||||
//return self->pin == NO_PIN;
|
||||
return true;
|
||||
}
|
||||
|
||||
void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self) {
|
||||
// if (common_hal_rotaryio_incrementalencoder_deinited(self)) {
|
||||
// return;
|
||||
// }
|
||||
// uint32_t mask = 1 << self->channel;
|
||||
// EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos;
|
||||
// #ifdef SAMD51
|
||||
// NVIC_DisableIRQ(EIC_0_IRQn + self->channel);
|
||||
// NVIC_ClearPendingIRQ(EIC_0_IRQn + self->channel);
|
||||
// #endif
|
||||
// active_incrementalencoders[self->channel] = NULL;
|
||||
// reset_pin(self->pin);
|
||||
// self->pin = NO_PIN;
|
||||
//
|
||||
// bool all_null = true;
|
||||
// for (uint8_t i = 0; all_null && i < 16; i++) {
|
||||
// all_null = all_null && active_incrementalencoders[i] == NULL;
|
||||
// }
|
||||
// #ifdef SAMD21
|
||||
// if (all_null && EIC->INTENSET.reg == 0) {
|
||||
// NVIC_DisableIRQ(EIC_IRQn);
|
||||
// NVIC_ClearPendingIRQ(EIC_IRQn);
|
||||
// }
|
||||
// #endif
|
||||
// // Test if all channels are null and deinit everything if they are.
|
||||
// if (all_null && EIC->EVCTRL.reg == 0 && EIC->INTENSET.reg == 0) {
|
||||
// eic_set_enable(false);
|
||||
// #ifdef SAMD51
|
||||
// MCLK->APBAMASK.bit.EIC_ = false;
|
||||
// hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, 0);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef SAMD21
|
||||
// PM->APBAMASK.bit.EIC_ = false;
|
||||
// hri_gclk_write_CLKCTRL_reg(GCLK, GCLK_CLKCTRL_ID(EIC_GCLK_ID));
|
||||
// #endif
|
||||
// }
|
||||
}
|
||||
|
||||
mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self) {
|
||||
return 0;
|
||||
}
|
40
ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h
Normal file
40
ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint8_t pin_a;
|
||||
uint8_t pin_b;
|
||||
} rotaryio_incrementalencoder_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H
|
1
ports/atmel-samd/common-hal/rotaryio/__init__.c
Normal file
1
ports/atmel-samd/common-hal/rotaryio/__init__.c
Normal file
@ -0,0 +1 @@
|
||||
// No pulseio module functions.
|
@ -37,10 +37,10 @@
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
#include "clocks.h"
|
||||
#include "samd21_pins.h"
|
||||
#include "tick.h"
|
||||
#include "peripherals/clocks.h"
|
||||
#include "peripherals/pins.h"
|
||||
|
||||
#include "tick.h"
|
||||
#include "adafruit_ptc.h"
|
||||
|
||||
bool touch_enabled = false;
|
||||
|
@ -36,12 +36,10 @@
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "peripherals.h"
|
||||
//#include "peripherals.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "supervisor/shared/rgb_led_status.h"
|
||||
|
||||
//#include "shared_dma.h"
|
||||
|
||||
#include "hal_gpio.h"
|
||||
#include "hal_spi_m_sync.h"
|
||||
|
||||
|
@ -32,8 +32,8 @@
|
||||
#include "mpconfigboard.h" // for EXTERNAL_FLASH_QSPI_DUAL
|
||||
|
||||
#include "external_flash/common_commands.h"
|
||||
#include "peripherals.h"
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/cache.h"
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include "atmel_start_pins.h"
|
||||
#include "hal_gpio.h"
|
||||
|
@ -29,8 +29,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "external_flash/common_commands.h"
|
||||
#include "peripherals.h"
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/sercom.h"
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
#include "hal_gpio.h"
|
||||
#include "hal_spi_m_sync.h"
|
||||
|
@ -174,6 +174,7 @@ extern const struct _mp_obj_module_t board_module;
|
||||
extern const struct _mp_obj_module_t math_module;
|
||||
extern const struct _mp_obj_module_t os_module;
|
||||
extern const struct _mp_obj_module_t random_module;
|
||||
extern const struct _mp_obj_module_t rotaryio_module;
|
||||
extern const struct _mp_obj_module_t rtc_module;
|
||||
extern const struct _mp_obj_module_t samd_module;
|
||||
extern const struct _mp_obj_module_t storage_module;
|
||||
@ -220,6 +221,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \
|
||||
AUDIOBUSIO_MODULE \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rotaryio), (mp_obj_t)&rotaryio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }
|
||||
#endif
|
||||
#define EXPRESS_BOARD
|
||||
@ -304,7 +306,7 @@ extern const struct _mp_obj_module_t usb_hid_module;
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8]; \
|
||||
|
@ -24,15 +24,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
|
||||
|
||||
#include "include/sam.h"
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
|
||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
|
||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
|
||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SAMD21_PERIPHERALS_H
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_ADC_H
|
@ -27,14 +27,6 @@
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PERIPHERALS_H
|
||||
|
||||
#include "sam.h"
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
|
||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
|
||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
|
||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance);
|
||||
|
||||
void samd_peripherals_disable_and_clear_cache(void);
|
||||
void samd_peripherals_enable_cache(void);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "shared_dma.h"
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -48,164 +48,6 @@ COMPILER_ALIGNED(16) static DmacDescriptor write_back_descriptors[DMA_CHANNEL_CO
|
||||
#define FIRST_SERCOM_TX_TRIGSRC 0x05
|
||||
#endif
|
||||
|
||||
static uint8_t sercom_index(Sercom* sercom) {
|
||||
#ifdef SAMD21
|
||||
return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400;
|
||||
#else
|
||||
const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS;
|
||||
for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) {
|
||||
if (sercoms[i] == sercom) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
||||
DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
||||
DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number));
|
||||
uint32_t event_output_enable = 0;
|
||||
if (output_event) {
|
||||
event_output_enable = DMAC_CHCTRLB_EVOE;
|
||||
}
|
||||
DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 |
|
||||
DMAC_CHCTRLB_TRIGSRC(trigsrc) |
|
||||
DMAC_CHCTRLB_TRIGACT_BEAT |
|
||||
event_output_enable;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
||||
if (output_event) {
|
||||
channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE;
|
||||
}
|
||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) |
|
||||
DMAC_CHCTRLA_TRIGACT_BURST |
|
||||
DMAC_CHCTRLA_BURSTLEN_SINGLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dma_enable_channel(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
// Clear any previous interrupts.
|
||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
||||
DMAC->CHCTRLA.bit.ENABLE = true;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.bit.ENABLE = true;
|
||||
// Clear any previous interrupts.
|
||||
channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dma_disable_channel(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLA.bit.ENABLE = false;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.bit.ENABLE = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dma_suspend_channel(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND;
|
||||
#endif
|
||||
}
|
||||
|
||||
void dma_resume_channel(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val;
|
||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool dma_channel_enabled(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
bool enabled = DMAC->CHCTRLA.bit.ENABLE;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return enabled;
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHCTRLA.bit.ENABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t dma_transfer_status(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
uint8_t status = DMAC->CHINTFLAG.reg;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return status;
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHINTFLAG.reg;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool channel_free(uint8_t channel_number) {
|
||||
#ifdef SAMD21
|
||||
common_hal_mcu_disable_interrupts();
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
bool channel_free = DMAC->CHSTATUS.reg == 0;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return channel_free;
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHSTATUS.reg == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_shared_dma(void) {
|
||||
// Turn on the clocks
|
||||
#ifdef SAMD51
|
||||
@ -237,8 +79,8 @@ static int32_t shared_dma_transfer(void* peripheral,
|
||||
const uint8_t* buffer_out, volatile uint32_t* dest,
|
||||
volatile uint32_t* src, uint8_t* buffer_in,
|
||||
uint32_t length, uint8_t tx) {
|
||||
if (!channel_free(SHARED_TX_CHANNEL) ||
|
||||
(buffer_in != NULL && !channel_free(SHARED_RX_CHANNEL))) {
|
||||
if (!dma_channel_free(SHARED_TX_CHANNEL) ||
|
||||
(buffer_in != NULL && !dma_channel_free(SHARED_RX_CHANNEL))) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -24,8 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@ -49,6 +49,8 @@ int32_t qspi_dma_write(uint32_t address, const uint8_t* buffer, uint32_t length)
|
||||
int32_t qspi_dma_read(uint32_t address, uint8_t* buffer, uint32_t length);
|
||||
#endif
|
||||
|
||||
uint8_t sercom_index(Sercom* sercom);
|
||||
|
||||
int32_t sercom_dma_write(Sercom* sercom, const uint8_t* buffer, uint32_t length);
|
||||
int32_t sercom_dma_read(Sercom* sercom, uint8_t* buffer, uint32_t length, uint8_t tx);
|
||||
int32_t sercom_dma_transfer(Sercom* sercom, const uint8_t* buffer_out, uint8_t* buffer_in, uint32_t length);
|
||||
@ -58,8 +60,9 @@ void dma_enable_channel(uint8_t channel_number);
|
||||
void dma_disable_channel(uint8_t channel_number);
|
||||
void dma_suspend_channel(uint8_t channel_number);
|
||||
void dma_resume_channel(uint8_t channel_number);
|
||||
bool dma_channel_free(uint8_t channel_number);
|
||||
bool dma_channel_enabled(uint8_t channel_number);
|
||||
uint8_t dma_transfer_status(uint8_t channel_number);
|
||||
DmacDescriptor* dma_descriptor(uint8_t channel_number);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_SHARED_DMA_H
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_DMA_H
|
62
ports/atmel-samd/peripherals/events.c
Normal file
62
ports/atmel-samd/peripherals/events.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "peripherals/events.h"
|
||||
//
|
||||
// #include "clocks.h"
|
||||
//
|
||||
#include "py/runtime.h"
|
||||
|
||||
uint8_t find_async_event_channel(void) {
|
||||
int8_t channel;
|
||||
for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) {
|
||||
if (event_channel_free(channel)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel < 0) {
|
||||
mp_raise_RuntimeError("All event channels in use");
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
#ifdef SAMD21
|
||||
#define EVSYS_SYNCH_NUM EVSYS_CHANNELS
|
||||
#endif
|
||||
uint8_t find_sync_event_channel(void) {
|
||||
uint8_t channel;
|
||||
for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) {
|
||||
if (event_channel_free(channel)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel >= EVSYS_SYNCH_NUM) {
|
||||
mp_raise_RuntimeError("All sync event channels in use");
|
||||
}
|
||||
return channel;
|
||||
}
|
@ -44,4 +44,6 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat
|
||||
bool event_interrupt_active(uint8_t channel);
|
||||
bool event_interrupt_overflow(uint8_t channel);
|
||||
|
||||
bool event_channel_free(uint8_t channel);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_EVENTS_H
|
46
ports/atmel-samd/peripherals/i2s.c
Normal file
46
ports/atmel-samd/peripherals/i2s.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "i2s.h"
|
||||
|
||||
#include "clocks.h"
|
||||
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#ifdef SAMD21
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
void i2s_set_enable(bool enable) {
|
||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
||||
I2S->CTRLA.bit.ENABLE = enable;
|
||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
||||
}
|
||||
|
||||
void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) {
|
||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
||||
I2S->CTRLA.vec.CKEN = 1 << clock_unit;
|
||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
||||
}
|
42
ports/atmel-samd/peripherals/pins.h
Normal file
42
ports/atmel-samd/peripherals/pins.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
||||
// that all necessary includes are already included.
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "peripherals/samd21/pins.h"
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#include "peripherals/samd51/pins.h"
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_PINS_H
|
47
ports/atmel-samd/peripherals/samd21/adc.c
Normal file
47
ports/atmel-samd/peripherals/samd21/adc.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
|
||||
// Do initialization and calibration setup needed for any use of the ADC.
|
||||
// The reference and resolution should be set by the caller.
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
||||
// Turn the clocks on.
|
||||
_pm_enable_bus_clock(PM_BUS_APBC, ADC);
|
||||
_gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
|
||||
|
||||
adc_sync_init(adc, instance, (void *)NULL);
|
||||
|
||||
// Load the factory calibration
|
||||
hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
|
||||
// Bits 7:5
|
||||
uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
|
||||
// Bits 4:0
|
||||
linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
|
||||
hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -24,16 +24,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
|
||||
// The SAMD21 doesn't have a cache so we have nothing to do.
|
||||
void samd_peripherals_disable_and_clear_cache(void) {
|
||||
}
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "samd21_pins.h"
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#include "samd51_pins.h"
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PINS_H
|
||||
void samd_peripherals_enable_cache(void) {
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "clocks.h"
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
#include "hpl_gclk_config.h"
|
||||
|
118
ports/atmel-samd/peripherals/samd21/dma.c
Normal file
118
ports/atmel-samd/peripherals/samd21/dma.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017-2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/mpstate.h"
|
||||
|
||||
#include "hal/utils/include/utils.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
uint8_t sercom_index(Sercom* sercom) {
|
||||
return ((uint32_t) sercom - (uint32_t) SERCOM0) / 0x400;
|
||||
}
|
||||
|
||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
||||
DMAC->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
||||
DMAC->SWTRIGCTRL.reg &= (uint32_t)(~(1 << channel_number));
|
||||
uint32_t event_output_enable = 0;
|
||||
if (output_event) {
|
||||
event_output_enable = DMAC_CHCTRLB_EVOE;
|
||||
}
|
||||
DMAC->CHCTRLB.reg = DMAC_CHCTRLB_LVL_LVL0 |
|
||||
DMAC_CHCTRLB_TRIGSRC(trigsrc) |
|
||||
DMAC_CHCTRLB_TRIGACT_BEAT |
|
||||
event_output_enable;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
void dma_enable_channel(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
// Clear any previous interrupts.
|
||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
||||
DMAC->CHCTRLA.bit.ENABLE = true;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
void dma_disable_channel(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLA.bit.ENABLE = false;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
void dma_suspend_channel(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_SUSPEND_Val;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
void dma_resume_channel(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
DMAC->CHCTRLB.bit.CMD = DMAC_CHCTRLB_CMD_RESUME_Val;
|
||||
DMAC->CHINTFLAG.reg = DMAC_CHINTFLAG_SUSP;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
bool dma_channel_enabled(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
bool enabled = DMAC->CHCTRLA.bit.ENABLE;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
uint8_t dma_transfer_status(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
/** Select the DMA channel and clear software trigger */
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
uint8_t status = DMAC->CHINTFLAG.reg;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return status;
|
||||
}
|
||||
|
||||
bool dma_channel_free(uint8_t channel_number) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
DMAC->CHID.reg = DMAC_CHID_ID(channel_number);
|
||||
bool channel_free = DMAC->CHSTATUS.reg == 0;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return channel_free;
|
||||
}
|
@ -24,131 +24,52 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "events.h"
|
||||
#include "peripherals/events.h"
|
||||
|
||||
#include "clocks.h"
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
#endif
|
||||
|
||||
void turn_on_event_system(void) {
|
||||
#ifdef SAMD51
|
||||
hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
|
||||
#endif
|
||||
|
||||
#ifdef SAMD21
|
||||
_pm_enable_bus_clock(PM_BUS_APBC, EVSYS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void reset_event_system(void) {
|
||||
#ifdef SAMD51
|
||||
EVSYS->CTRLA.bit.SWRST = true;
|
||||
hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK);
|
||||
#endif
|
||||
|
||||
#ifdef SAMD21
|
||||
EVSYS->CTRL.bit.SWRST = true;
|
||||
_pm_disable_bus_clock(PM_BUS_APBC, EVSYS);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool channel_free(int8_t channel) {
|
||||
bool event_channel_free(uint8_t channel) {
|
||||
uint8_t generator;
|
||||
#ifdef SAMD51
|
||||
generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
// Explicitly do a byte write so the peripheral knows we're just wanting to read the channel
|
||||
// rather than write to it.
|
||||
*((uint8_t*) &EVSYS->CHANNEL.reg) = channel;
|
||||
generator = (EVSYS->CHANNEL.reg & EVSYS_CHANNEL_EVGEN_Msk) >> EVSYS_CHANNEL_EVGEN_Pos;
|
||||
#endif
|
||||
return generator == 0;
|
||||
}
|
||||
|
||||
uint8_t find_async_event_channel(void) {
|
||||
int8_t channel;
|
||||
for (channel = EVSYS_CHANNELS - 1; channel > 0; channel--) {
|
||||
if (channel_free(channel)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel < 0) {
|
||||
mp_raise_RuntimeError("All event channels in use");
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
#ifdef SAMD21
|
||||
#define EVSYS_SYNCH_NUM EVSYS_CHANNELS
|
||||
#endif
|
||||
uint8_t find_sync_event_channel(void) {
|
||||
uint8_t channel;
|
||||
for (channel = 0; channel < EVSYS_SYNCH_NUM; channel++) {
|
||||
if (channel_free(channel)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel >= EVSYS_SYNCH_NUM) {
|
||||
mp_raise_RuntimeError("All sync event channels in use");
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
void disable_event_channel(uint8_t channel_number) {
|
||||
#ifdef SAMD51
|
||||
EVSYS->Channel[channel_number].CHANNEL.reg = 0;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
void disable_event_user(uint8_t user_number) {
|
||||
#ifdef SAMD51
|
||||
EVSYS->USER[user_number].reg = 0;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
EVSYS->USER.reg = EVSYS_USER_USER(user_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
|
||||
#ifdef SAMD51
|
||||
EVSYS->USER[user].reg = channel + 1;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
EVSYS->USER.reg = EVSYS_USER_USER(user) | EVSYS_USER_CHANNEL(channel + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_async_event_channel(uint8_t channel, uint8_t generator) {
|
||||
#ifdef SAMD51
|
||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
||||
#endif
|
||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
|
||||
EVSYS_CHANNEL_EVGEN(generator) |
|
||||
EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
||||
}
|
||||
|
||||
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
|
||||
connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
|
||||
#ifdef SAMD51
|
||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) |
|
||||
EVSYS_CHANNEL_PATH_SYNCHRONOUS |
|
||||
EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
|
||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
||||
EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR;
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) |
|
||||
EVSYS_CHANNEL_EVGEN(generator) |
|
||||
EVSYS_CHANNEL_PATH_RESYNCHRONIZED |
|
||||
@ -162,12 +83,10 @@ void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generat
|
||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
|
||||
EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD(value) | EVSYS_INTENSET_OVR(value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool event_interrupt_active(uint8_t channel) {
|
||||
bool active = false;
|
||||
#ifdef SAMD21
|
||||
if (channel > 7) {
|
||||
uint8_t value = 1 << (channel - 7);
|
||||
active = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_EVDp8(value)) != 0;
|
||||
@ -183,21 +102,11 @@ bool event_interrupt_active(uint8_t channel) {
|
||||
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD(value) | EVSYS_INTFLAG_OVR(value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD;
|
||||
// Only clear if we know its active, otherwise there is the possibility it becomes after we
|
||||
// check but before we clear.
|
||||
if (active) {
|
||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
||||
}
|
||||
#endif
|
||||
return active;
|
||||
}
|
||||
|
||||
bool event_interrupt_overflow(uint8_t channel) {
|
||||
bool overflow = false;
|
||||
#ifdef SAMD21
|
||||
if (channel > 7) {
|
||||
uint8_t value = 1 << (channel - 7);
|
||||
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVRp8(value)) != 0;
|
||||
@ -205,9 +114,5 @@ bool event_interrupt_overflow(uint8_t channel) {
|
||||
uint8_t value = 1 << channel;
|
||||
overflow = (EVSYS->INTFLAG.reg & EVSYS_INTFLAG_OVR(value)) != 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
overflow = EVSYS->Channel[channel].CHINTFLAG.bit.OVR;
|
||||
#endif
|
||||
return overflow;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -24,23 +24,23 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "boards/board.h"
|
||||
#include "mpconfigboard.h"
|
||||
#include "hal/include/hal_gpio.h"
|
||||
#include "peripherals/i2s.h"
|
||||
|
||||
void board_init(void) {
|
||||
gpio_set_pin_function(MICROPY_HW_LED_TX, GPIO_PIN_FUNCTION_OFF);
|
||||
gpio_set_pin_direction(MICROPY_HW_LED_TX, GPIO_DIRECTION_OUT);
|
||||
gpio_set_pin_level(MICROPY_HW_LED_TX, true);
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
gpio_set_pin_function(MICROPY_HW_LED_RX, GPIO_PIN_FUNCTION_OFF);
|
||||
gpio_set_pin_direction(MICROPY_HW_LED_RX, GPIO_DIRECTION_OUT);
|
||||
gpio_set_pin_level(MICROPY_HW_LED_RX, true);
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
|
||||
void turn_on_i2s(void) {
|
||||
_pm_enable_bus_clock(PM_BUS_APBC, I2S);
|
||||
}
|
||||
|
||||
bool board_requests_safe_mode(void) {
|
||||
return false;
|
||||
void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
|
||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
||||
if (enable) {
|
||||
I2S->CTRLA.vec.SEREN = 1 << serializer;
|
||||
} else {
|
||||
I2S->CTRLA.vec.SEREN &= ~(1 << serializer);
|
||||
}
|
||||
|
||||
void reset_board(void) {
|
||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
||||
}
|
@ -26,8 +26,6 @@
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#include "samd21_pins.h"
|
||||
|
||||
#define SERCOM(sercom_index, p_pad) \
|
||||
{ \
|
||||
.index = sercom_index, \
|
@ -24,13 +24,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
|
||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
||||
// that all necessary includes are already included.
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
||||
|
||||
#include "include/sam.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
void reset_pin(uint8_t pin);
|
||||
|
||||
#define MUX_C 2
|
||||
@ -201,4 +202,4 @@ extern const mcu_pin_obj_t pin_PB02;
|
||||
extern const mcu_pin_obj_t pin_PB03;
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARDS_SAMD21_PINS_H
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SAMD21_PINS_H
|
@ -24,11 +24,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
|
||||
|
||||
// The clock initializer values are rather random, so we need to put them in
|
||||
// tables for lookup. We can't compute them.
|
||||
|
||||
@ -93,21 +91,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
|
||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
|
||||
return clock_pad == 1 || clock_pad == 3;
|
||||
}
|
||||
|
||||
// Do initialization and calibration setup needed for any use of the ADC.
|
||||
// The reference and resolution should be set by the caller.
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
||||
// Turn the clocks on.
|
||||
_pm_enable_bus_clock(PM_BUS_APBC, ADC);
|
||||
_gclk_enable_channel(ADC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK0_Val);
|
||||
|
||||
adc_sync_init(adc, instance, (void *)NULL);
|
||||
|
||||
// Load the factory calibration
|
||||
hri_adc_write_CALIB_BIAS_CAL_bf(ADC, (*((uint32_t*) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos);
|
||||
// Bits 7:5
|
||||
uint16_t linearity = ((*((uint32_t*) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;
|
||||
// Bits 4:0
|
||||
linearity |= (*((uint32_t*) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
|
||||
hri_adc_write_CALIB_LINEARITY_CAL_bf(ADC, linearity);
|
||||
}
|
75
ports/atmel-samd/peripherals/samd21/timers.c
Normal file
75
ports/atmel-samd/peripherals/samd21/timers.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "peripherals/timers.h"
|
||||
|
||||
//#include "common-hal/pulseio/PulseOut.h"
|
||||
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
|
||||
const uint8_t tcc_cc_num[3] = {4, 2, 2};
|
||||
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
|
||||
TC4_GCLK_ID,
|
||||
TC5_GCLK_ID,
|
||||
#ifdef TC6_GCLK_ID
|
||||
TC6_GCLK_ID,
|
||||
#endif
|
||||
#ifdef TC7_GCLK_ID
|
||||
TC7_GCLK_ID,
|
||||
#endif
|
||||
};
|
||||
const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
|
||||
|
||||
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
||||
uint8_t gclk_id;
|
||||
if (is_tc) {
|
||||
gclk_id = tc_gclk_ids[index];
|
||||
} else {
|
||||
gclk_id = tcc_gclk_ids[index];
|
||||
}
|
||||
// Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in.
|
||||
uint8_t clock_slot = 8 + index;
|
||||
// We index TCs starting at zero but in memory they begin at three so we have to add three.
|
||||
if (is_tc) {
|
||||
clock_slot += 3;
|
||||
}
|
||||
PM->APBCMASK.reg |= 1 << clock_slot;
|
||||
_gclk_enable_channel(gclk_id, gclk_index);
|
||||
}
|
||||
|
||||
void tc_set_enable(Tc* tc, bool enable) {
|
||||
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
|
||||
/* Wait for sync */
|
||||
}
|
||||
}
|
||||
|
||||
void tc_wait_for_sync(Tc* tc) {
|
||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
|
||||
}
|
61
ports/atmel-samd/peripherals/samd51/adc.c
Normal file
61
ports/atmel-samd/peripherals/samd51/adc.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hal/include/hal_adc_sync.h"
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
|
||||
// Do initialization and calibration setup needed for any use of the ADC.
|
||||
// The reference and resolution should be set by the caller.
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
||||
// Turn the clocks on.
|
||||
if (instance == ADC0) {
|
||||
hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
} else if (instance == ADC1) {
|
||||
hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
}
|
||||
|
||||
adc_sync_init(adc, instance, (void *)NULL);
|
||||
|
||||
// SAMD51 has a CALIB register but doesn't have documented fuses for them.
|
||||
uint8_t biasrefbuf;
|
||||
uint8_t biasr2r;
|
||||
uint8_t biascomp;
|
||||
if (instance == ADC0) {
|
||||
biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
|
||||
biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
|
||||
biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
|
||||
} else {
|
||||
biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
|
||||
biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
|
||||
biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
|
||||
}
|
||||
hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
|
||||
hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
|
||||
hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
|
||||
}
|
39
ports/atmel-samd/peripherals/samd51/cache.c
Normal file
39
ports/atmel-samd/peripherals/samd51/cache.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sam.h"
|
||||
|
||||
// Turn off cache and invalidate all data in it.
|
||||
void samd_peripherals_disable_and_clear_cache(void) {
|
||||
CMCC->CTRL.bit.CEN = 0;
|
||||
while (CMCC->SR.bit.CSTS) {}
|
||||
CMCC->MAINT0.bit.INVALL = 1;
|
||||
}
|
||||
|
||||
// Enable cache
|
||||
void samd_peripherals_enable_cache(void) {
|
||||
CMCC->CTRL.bit.CEN = 1;
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "clocks.h"
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
#include "hpl_gclk_config.h"
|
||||
|
94
ports/atmel-samd/peripherals/samd51/dma.c
Normal file
94
ports/atmel-samd/peripherals/samd51/dma.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "peripherals/dma.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/mpstate.h"
|
||||
|
||||
#include "hal/utils/include/utils.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
uint8_t sercom_index(Sercom* sercom) {
|
||||
const Sercom* sercoms[SERCOM_INST_NUM] = SERCOM_INSTS;
|
||||
for (uint8_t i = 0; i < SERCOM_INST_NUM; i++) {
|
||||
if (sercoms[i] == sercom) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dma_configure(uint8_t channel_number, uint8_t trigsrc, bool output_event) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.reg &= ~DMAC_CHCTRLA_ENABLE;
|
||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_SWRST;
|
||||
if (output_event) {
|
||||
channel->CHEVCTRL.reg = DMAC_CHEVCTRL_EVOE;
|
||||
}
|
||||
channel->CHCTRLA.reg = DMAC_CHCTRLA_TRIGSRC(trigsrc) |
|
||||
DMAC_CHCTRLA_TRIGACT_BURST |
|
||||
DMAC_CHCTRLA_BURSTLEN_SINGLE;
|
||||
}
|
||||
|
||||
void dma_enable_channel(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.bit.ENABLE = true;
|
||||
// Clear any previous interrupts.
|
||||
channel->CHINTFLAG.reg = DMAC_CHINTFLAG_MASK;
|
||||
}
|
||||
|
||||
void dma_disable_channel(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLA.bit.ENABLE = false;
|
||||
}
|
||||
|
||||
void dma_suspend_channel(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_SUSPEND;
|
||||
}
|
||||
|
||||
void dma_resume_channel(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
channel->CHCTRLB.reg = DMAC_CHCTRLB_CMD_RESUME;
|
||||
}
|
||||
|
||||
bool dma_channel_enabled(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHCTRLA.bit.ENABLE;
|
||||
}
|
||||
|
||||
uint8_t dma_transfer_status(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHINTFLAG.reg;
|
||||
}
|
||||
|
||||
bool dma_channel_free(uint8_t channel_number) {
|
||||
DmacChannel* channel = &DMAC->Channel[channel_number];
|
||||
return channel->CHSTATUS.reg == 0;
|
||||
}
|
88
ports/atmel-samd/peripherals/samd51/events.c
Normal file
88
ports/atmel-samd/peripherals/samd51/events.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "peripherals/events.h"
|
||||
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
|
||||
void turn_on_event_system(void) {
|
||||
hri_mclk_set_APBBMASK_EVSYS_bit(MCLK);
|
||||
}
|
||||
|
||||
void reset_event_system(void) {
|
||||
EVSYS->CTRLA.bit.SWRST = true;
|
||||
hri_mclk_clear_APBBMASK_EVSYS_bit(MCLK);
|
||||
}
|
||||
|
||||
bool event_channel_free(uint8_t channel) {
|
||||
uint8_t generator;
|
||||
generator = EVSYS->Channel[channel].CHANNEL.bit.EVGEN;
|
||||
return generator == 0;
|
||||
}
|
||||
|
||||
void disable_event_channel(uint8_t channel_number) {
|
||||
EVSYS->Channel[channel_number].CHANNEL.reg = 0;
|
||||
}
|
||||
|
||||
void disable_event_user(uint8_t user_number) {
|
||||
EVSYS->USER[user_number].reg = 0;
|
||||
}
|
||||
|
||||
void connect_event_user_to_channel(uint8_t user, uint8_t channel) {
|
||||
EVSYS->USER[user].reg = channel + 1;
|
||||
}
|
||||
|
||||
void init_async_event_channel(uint8_t channel, uint8_t generator) {
|
||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) | EVSYS_CHANNEL_PATH_ASYNCHRONOUS;
|
||||
}
|
||||
|
||||
void init_event_channel_interrupt(uint8_t channel, uint8_t gclk, uint8_t generator) {
|
||||
connect_gclk_to_peripheral(gclk, EVSYS_GCLK_ID_0 + channel);
|
||||
EVSYS->Channel[channel].CHANNEL.reg = EVSYS_CHANNEL_EVGEN(generator) |
|
||||
EVSYS_CHANNEL_PATH_SYNCHRONOUS |
|
||||
EVSYS_CHANNEL_EDGSEL_RISING_EDGE;
|
||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
||||
EVSYS->Channel[channel].CHINTENSET.reg = EVSYS_CHINTENSET_EVD | EVSYS_CHINTENSET_OVR;
|
||||
}
|
||||
|
||||
bool event_interrupt_active(uint8_t channel) {
|
||||
bool active = false;
|
||||
active = EVSYS->Channel[channel].CHINTFLAG.bit.EVD;
|
||||
// Only clear if we know its active, otherwise there is the possibility it becomes after we
|
||||
// check but before we clear.
|
||||
if (active) {
|
||||
EVSYS->Channel[channel].CHINTFLAG.reg = EVSYS_CHINTFLAG_EVD | EVSYS_CHINTFLAG_OVR;
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
bool event_interrupt_overflow(uint8_t channel) {
|
||||
return EVSYS->Channel[channel].CHINTFLAG.bit.OVR;
|
||||
}
|
@ -24,53 +24,22 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "i2s.h"
|
||||
#include "peripherals/i2s.h"
|
||||
|
||||
#include "clocks.h"
|
||||
#include "peripherals/clocks.h"
|
||||
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#ifdef SAMD21
|
||||
#include "hpl/pm/hpl_pm_base.h"
|
||||
#endif
|
||||
|
||||
void turn_on_i2s(void) {
|
||||
// Make sure the I2S peripheral is running so we can see if the resources we need are free.
|
||||
#ifdef SAMD51
|
||||
hri_mclk_set_APBDMASK_I2S_bit(MCLK);
|
||||
|
||||
// Connect the clock units to the 2mhz clock by default. They can't reset without it.
|
||||
connect_gclk_to_peripheral(5, I2S_GCLK_ID_0);
|
||||
connect_gclk_to_peripheral(5, I2S_GCLK_ID_1);
|
||||
#endif
|
||||
|
||||
#ifdef SAMD21
|
||||
_pm_enable_bus_clock(PM_BUS_APBC, I2S);
|
||||
#endif
|
||||
}
|
||||
|
||||
void i2s_set_enable(bool enable) {
|
||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
||||
I2S->CTRLA.bit.ENABLE = enable;
|
||||
while (I2S->SYNCBUSY.bit.ENABLE == 1) {}
|
||||
}
|
||||
|
||||
void i2s_set_clock_unit_enable(uint8_t clock_unit, bool enable) {
|
||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
||||
I2S->CTRLA.vec.CKEN = 1 << clock_unit;
|
||||
while ((I2S->SYNCBUSY.vec.CKEN & (1 << clock_unit)) != 0) {}
|
||||
}
|
||||
|
||||
void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
|
||||
#ifdef SAMD21
|
||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
||||
if (enable) {
|
||||
I2S->CTRLA.vec.SEREN = 1 << serializer;
|
||||
} else {
|
||||
I2S->CTRLA.vec.SEREN &= ~(1 << serializer);
|
||||
}
|
||||
while ((I2S->SYNCBUSY.vec.SEREN & (1 << serializer)) != 0) {}
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
if (serializer == 0) {
|
||||
while (I2S->SYNCBUSY.bit.TXEN == 1) {}
|
||||
I2S->CTRLA.bit.TXEN = enable;
|
||||
@ -80,5 +49,4 @@ void i2s_set_serializer_enable(uint8_t serializer, bool enable) {
|
||||
I2S->CTRLA.bit.RXEN = enable;
|
||||
while (I2S->SYNCBUSY.bit.RXEN == 1) {}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -26,8 +26,6 @@
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#include "samd51_pins.h"
|
||||
|
||||
#define SERCOM(sercom_index, p_pad) \
|
||||
{ \
|
||||
.index = sercom_index, \
|
@ -24,13 +24,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// DO NOT include this file directly. Use shared-bindings/microcontroller/Pin.h instead to ensure
|
||||
// that all necessary includes are already included.
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_SAMD51_PINS_H
|
||||
|
||||
#include "include/sam.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
void reset_pin(uint8_t pin);
|
||||
|
||||
#define MUX_C 2
|
@ -28,6 +28,8 @@
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#include "hri/hri_mclk_d51.h"
|
||||
|
||||
// FIXME(tannewt): Should this be called sercom.c?
|
||||
|
||||
// The clock initializer values are rather random, so we need to put them in
|
||||
// tables for lookup. We can't compute them.
|
||||
|
||||
@ -131,47 +133,3 @@ uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad) {
|
||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad) {
|
||||
return clock_pad == 1;
|
||||
}
|
||||
|
||||
// Do initialization and calibration setup needed for any use of the ADC.
|
||||
// The reference and resolution should be set by the caller.
|
||||
void samd_peripherals_adc_setup(struct adc_sync_descriptor *adc, Adc *instance) {
|
||||
// Turn the clocks on.
|
||||
if (instance == ADC0) {
|
||||
hri_mclk_set_APBDMASK_ADC0_bit(MCLK);
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
} else if (instance == ADC1) {
|
||||
hri_mclk_set_APBDMASK_ADC1_bit(MCLK);
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC1_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
}
|
||||
|
||||
adc_sync_init(adc, instance, (void *)NULL);
|
||||
|
||||
// SAMD51 has a CALIB register but doesn't have documented fuses for them.
|
||||
uint8_t biasrefbuf;
|
||||
uint8_t biasr2r;
|
||||
uint8_t biascomp;
|
||||
if (instance == ADC0) {
|
||||
biasrefbuf = ((*(uint32_t*) ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
|
||||
biasr2r = ((*(uint32_t*) ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
|
||||
biascomp = ((*(uint32_t*) ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
|
||||
} else {
|
||||
biasrefbuf = ((*(uint32_t*) ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
|
||||
biasr2r = ((*(uint32_t*) ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
|
||||
biascomp = ((*(uint32_t*) ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
|
||||
}
|
||||
hri_adc_write_CALIB_BIASREFBUF_bf(instance, biasrefbuf);
|
||||
hri_adc_write_CALIB_BIASR2R_bf(instance, biasr2r);
|
||||
hri_adc_write_CALIB_BIASCOMP_bf(instance, biascomp);
|
||||
}
|
||||
|
||||
// Turn off cache and invalidate all data in it.
|
||||
void samd_peripherals_disable_and_clear_cache(void) {
|
||||
CMCC->CTRL.bit.CEN = 0;
|
||||
while (CMCC->SR.bit.CSTS) {}
|
||||
CMCC->MAINT0.bit.INVALL = 1;
|
||||
}
|
||||
|
||||
// Enable cache
|
||||
void samd_peripherals_enable_cache(void) {
|
||||
CMCC->CTRL.bit.CEN = 1;
|
||||
}
|
@ -27,36 +27,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "timers.h"
|
||||
#include "peripherals/timers.h"
|
||||
|
||||
#include "common-hal/pulseio/PulseOut.h"
|
||||
//#include "common-hal/pulseio/PulseOut.h"
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "hpl/gclk/hpl_gclk_base.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
#include "hri/hri_gclk_d51.h"
|
||||
#endif
|
||||
|
||||
const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
|
||||
|
||||
// This bitmask keeps track of which channels of a TCC are currently claimed.
|
||||
#ifdef SAMD21
|
||||
const uint8_t tcc_cc_num[3] = {4, 2, 2};
|
||||
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
|
||||
TC4_GCLK_ID,
|
||||
TC5_GCLK_ID,
|
||||
#ifdef TC6_GCLK_ID
|
||||
TC6_GCLK_ID,
|
||||
#endif
|
||||
#ifdef TC7_GCLK_ID
|
||||
TC7_GCLK_ID,
|
||||
#endif
|
||||
};
|
||||
const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
const uint8_t tcc_cc_num[5] = {6, 4, 3, 2, 2};
|
||||
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC0_GCLK_ID,
|
||||
TC1_GCLK_ID,
|
||||
@ -85,36 +61,6 @@ const uint8_t tcc_gclk_ids[TCC_INST_NUM] = {TCC0_GCLK_ID,
|
||||
TCC4_GCLK_ID
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
Tc* const tc_insts[TC_INST_NUM] = TC_INSTS;
|
||||
Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS;
|
||||
|
||||
IRQn_Type const tc_irq[TC_INST_NUM] = {
|
||||
#ifdef TC0
|
||||
TC0_IRQn,
|
||||
#endif
|
||||
#ifdef TC1
|
||||
TC1_IRQn,
|
||||
#endif
|
||||
#ifdef TC2
|
||||
TC2_IRQn,
|
||||
#endif
|
||||
#ifdef TC3
|
||||
TC3_IRQn,
|
||||
#endif
|
||||
#ifdef TC4
|
||||
TC4_IRQn,
|
||||
#endif
|
||||
#ifdef TC5
|
||||
TC5_IRQn,
|
||||
#endif
|
||||
#ifdef TC6
|
||||
TC6_IRQn,
|
||||
#endif
|
||||
#ifdef TC7
|
||||
TC7_IRQn,
|
||||
#endif
|
||||
};
|
||||
|
||||
void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
||||
uint8_t gclk_id;
|
||||
@ -124,7 +70,6 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
||||
gclk_id = tcc_gclk_ids[index];
|
||||
}
|
||||
// Turn on the clocks for the peripherals.
|
||||
#ifdef SAMD51
|
||||
if (is_tc) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
@ -180,122 +125,15 @@ void turn_on_clocks(bool is_tc, uint8_t index, uint32_t gclk_index) {
|
||||
|
||||
hri_gclk_write_PCHCTRL_reg(GCLK, gclk_id,
|
||||
gclk_index | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||
#endif
|
||||
|
||||
#ifdef SAMD21
|
||||
// Determine the clock slot on the APBC bus. TCC0 is the first and 8 slots in.
|
||||
uint8_t clock_slot = 8 + index;
|
||||
// We index TCs starting at zero but in memory they begin at three so we have to add three.
|
||||
if (is_tc) {
|
||||
clock_slot += 3;
|
||||
}
|
||||
PM->APBCMASK.reg |= 1 << clock_slot;
|
||||
_gclk_enable_channel(gclk_id, gclk_index);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tc_set_enable(Tc* tc, bool enable) {
|
||||
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
||||
#ifdef SAMD21
|
||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
|
||||
/* Wait for sync */
|
||||
}
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
|
||||
/* Wait for sync */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tc_enable_interrupts(uint8_t tc_index) {
|
||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
||||
NVIC_EnableIRQ(tc_irq[tc_index]);
|
||||
}
|
||||
|
||||
void tc_disable_interrupts(uint8_t tc_index) {
|
||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
||||
}
|
||||
|
||||
void tcc_set_enable(Tcc* tcc, bool enable) {
|
||||
tcc->CTRLA.bit.ENABLE = enable;
|
||||
while (tcc->SYNCBUSY.bit.ENABLE != 0) {
|
||||
/* Wait for sync */
|
||||
}
|
||||
}
|
||||
|
||||
void tc_wait_for_sync(Tc* tc) {
|
||||
#ifdef SAMD21
|
||||
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
while (tc->COUNT16.SYNCBUSY.reg != 0) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tc_reset(Tc* tc) {
|
||||
tc->COUNT16.CTRLA.bit.SWRST = 1;
|
||||
while (tc->COUNT16.CTRLA.bit.SWRST == 1) {
|
||||
}
|
||||
}
|
||||
|
||||
void shared_timer_handler(bool is_tc, uint8_t index) {
|
||||
// Add calls to interrupt handlers for specific functionality here.
|
||||
if (is_tc) {
|
||||
pulseout_interrupt_handler(index);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SAMD51
|
||||
#define TC_OFFSET 0
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
#define TC_OFFSET 3
|
||||
#endif
|
||||
|
||||
void TCC0_Handler(void) {
|
||||
shared_timer_handler(false, 0);
|
||||
}
|
||||
void TCC1_Handler(void) {
|
||||
shared_timer_handler(false, 1);
|
||||
}
|
||||
void TCC2_Handler(void) {
|
||||
shared_timer_handler(false, 2);
|
||||
}
|
||||
// TC0 - TC2 only exist on the SAMD51
|
||||
#ifdef TC0
|
||||
void TC0_Handler(void) {
|
||||
shared_timer_handler(true, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC1
|
||||
void TC1_Handler(void) {
|
||||
shared_timer_handler(true, 1);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC2
|
||||
void TC2_Handler(void) {
|
||||
shared_timer_handler(true, 2);
|
||||
}
|
||||
#endif
|
||||
void TC3_Handler(void) {
|
||||
shared_timer_handler(true, 3 - TC_OFFSET);
|
||||
}
|
||||
void TC4_Handler(void) {
|
||||
shared_timer_handler(true, 4 - TC_OFFSET);
|
||||
}
|
||||
void TC5_Handler(void) {
|
||||
shared_timer_handler(true, 5 - TC_OFFSET);
|
||||
}
|
||||
#ifdef TC6
|
||||
void TC6_Handler(void) {
|
||||
shared_timer_handler(true, 6 - TC_OFFSET);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC7
|
||||
void TC7_Handler(void) {
|
||||
shared_timer_handler(true, 7 - TC_OFFSET);
|
||||
}
|
||||
#endif
|
@ -24,7 +24,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "peripherals.h"
|
||||
#include "peripherals/sercom.h"
|
||||
|
||||
#include "hpl_sercom_config.h"
|
||||
|
@ -24,24 +24,19 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
|
||||
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
|
||||
#define MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
// Routines common across chip families.
|
||||
void samd_peripherals_sercom_clock_init(Sercom* sercom, uint8_t sercom_index);
|
||||
uint8_t samd_peripherals_get_spi_dopo(uint8_t clock_pad, uint8_t mosi_pad);
|
||||
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);
|
||||
bool samd_peripherals_valid_spi_clock_pad(uint8_t clock_pad);
|
||||
|
||||
Sercom* sercom_insts[SERCOM_INST_NUM];
|
||||
|
||||
#ifdef SAMD21
|
||||
#include "samd21_peripherals.h"
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#include "samd51_peripherals.h"
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_H
|
||||
#endif // MICROPY_INCLUDED_ATMEL_SAMD_PERIPHERALS_SPI_H
|
147
ports/atmel-samd/peripherals/timers.c
Normal file
147
ports/atmel-samd/peripherals/timers.c
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "timers.h"
|
||||
|
||||
#include "common-hal/pulseio/PulseOut.h"
|
||||
|
||||
const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
|
||||
|
||||
Tc* const tc_insts[TC_INST_NUM] = TC_INSTS;
|
||||
Tcc* const tcc_insts[TCC_INST_NUM] = TCC_INSTS;
|
||||
|
||||
IRQn_Type const tc_irq[TC_INST_NUM] = {
|
||||
#ifdef TC0
|
||||
TC0_IRQn,
|
||||
#endif
|
||||
#ifdef TC1
|
||||
TC1_IRQn,
|
||||
#endif
|
||||
#ifdef TC2
|
||||
TC2_IRQn,
|
||||
#endif
|
||||
#ifdef TC3
|
||||
TC3_IRQn,
|
||||
#endif
|
||||
#ifdef TC4
|
||||
TC4_IRQn,
|
||||
#endif
|
||||
#ifdef TC5
|
||||
TC5_IRQn,
|
||||
#endif
|
||||
#ifdef TC6
|
||||
TC6_IRQn,
|
||||
#endif
|
||||
#ifdef TC7
|
||||
TC7_IRQn,
|
||||
#endif
|
||||
};
|
||||
|
||||
void tc_enable_interrupts(uint8_t tc_index) {
|
||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
||||
NVIC_EnableIRQ(tc_irq[tc_index]);
|
||||
}
|
||||
|
||||
void tc_disable_interrupts(uint8_t tc_index) {
|
||||
NVIC_DisableIRQ(tc_irq[tc_index]);
|
||||
NVIC_ClearPendingIRQ(tc_irq[tc_index]);
|
||||
}
|
||||
|
||||
void tcc_set_enable(Tcc* tcc, bool enable) {
|
||||
tcc->CTRLA.bit.ENABLE = enable;
|
||||
while (tcc->SYNCBUSY.bit.ENABLE != 0) {
|
||||
/* Wait for sync */
|
||||
}
|
||||
}
|
||||
|
||||
void tc_reset(Tc* tc) {
|
||||
tc->COUNT16.CTRLA.bit.SWRST = 1;
|
||||
while (tc->COUNT16.CTRLA.bit.SWRST == 1) {
|
||||
}
|
||||
}
|
||||
|
||||
void shared_timer_handler(bool is_tc, uint8_t index) {
|
||||
// Add calls to interrupt handlers for specific functionality here.
|
||||
if (is_tc) {
|
||||
pulseout_interrupt_handler(index);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SAMD51
|
||||
#define TC_OFFSET 0
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
#define TC_OFFSET 3
|
||||
#endif
|
||||
|
||||
void TCC0_Handler(void) {
|
||||
shared_timer_handler(false, 0);
|
||||
}
|
||||
void TCC1_Handler(void) {
|
||||
shared_timer_handler(false, 1);
|
||||
}
|
||||
void TCC2_Handler(void) {
|
||||
shared_timer_handler(false, 2);
|
||||
}
|
||||
// TC0 - TC2 only exist on the SAMD51
|
||||
#ifdef TC0
|
||||
void TC0_Handler(void) {
|
||||
shared_timer_handler(true, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC1
|
||||
void TC1_Handler(void) {
|
||||
shared_timer_handler(true, 1);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC2
|
||||
void TC2_Handler(void) {
|
||||
shared_timer_handler(true, 2);
|
||||
}
|
||||
#endif
|
||||
void TC3_Handler(void) {
|
||||
shared_timer_handler(true, 3 - TC_OFFSET);
|
||||
}
|
||||
void TC4_Handler(void) {
|
||||
shared_timer_handler(true, 4 - TC_OFFSET);
|
||||
}
|
||||
void TC5_Handler(void) {
|
||||
shared_timer_handler(true, 5 - TC_OFFSET);
|
||||
}
|
||||
#ifdef TC6
|
||||
void TC6_Handler(void) {
|
||||
shared_timer_handler(true, 6 - TC_OFFSET);
|
||||
}
|
||||
#endif
|
||||
#ifdef TC7
|
||||
void TC7_Handler(void) {
|
||||
shared_timer_handler(true, 7 - TC_OFFSET);
|
||||
}
|
||||
#endif
|
@ -55,11 +55,11 @@
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
#include "common-hal/touchio/TouchIn.h"
|
||||
#include "common-hal/usb_hid/Device.h"
|
||||
#include "peripherals/cache.h"
|
||||
#include "peripherals/clocks.h"
|
||||
#include "peripherals/events.h"
|
||||
#include "peripherals/dma.h"
|
||||
#include "shared-bindings/rtc/__init__.h"
|
||||
#include "clocks.h"
|
||||
#include "events.h"
|
||||
#include "peripherals.h"
|
||||
#include "shared_dma.h"
|
||||
#include "tick.h"
|
||||
|
||||
#ifdef CIRCUITPY_GAMEPAD_TICKS
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h" // for the pin definitions
|
||||
|
||||
extern const mp_obj_dict_t board_module_globals;
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H
|
||||
|
159
shared-bindings/rotaryio/IncrementalEncoder.c
Normal file
159
shared-bindings/rotaryio/IncrementalEncoder.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/rotaryio/IncrementalEncoder.h"
|
||||
#include "shared-bindings/util.h"
|
||||
|
||||
//| .. currentmodule:: rotaryio
|
||||
//|
|
||||
//| :class:`IncrementalEncoder` -- Read the position of the incremental encoder
|
||||
//| ============================================================================
|
||||
//|
|
||||
//| IncrementalEncoder determines the relative rotational position based on two series of pulses.
|
||||
//|
|
||||
//| .. class:: IncrementalEncoder(pin_a, pin_b)
|
||||
//|
|
||||
//| Create an IncrementalEncoder object associated with the given pins. It tracks the positional
|
||||
//| state of an incremental rotary encoder (also known as a quadrature encoder.) Position is
|
||||
//| relative to the position when the object is contructed.
|
||||
//|
|
||||
//| :param ~microcontroller.Pin pin: First pin to read pulses from.
|
||||
//| :param ~microcontroller.Pin pin: Second pin to read pulses from.
|
||||
//|
|
||||
//| For example::
|
||||
//|
|
||||
//| import rotaryio
|
||||
//| import time
|
||||
//| from board import *
|
||||
//|
|
||||
//| enc = rotaryio.IncrementalEncoder(D1, D2)
|
||||
//| last_position = None
|
||||
//| while True;
|
||||
//| position = enc.position
|
||||
//| if last_position == None or position != last_position:
|
||||
//| print(position)
|
||||
//| last_position = position
|
||||
//|
|
||||
STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||
mp_arg_check_num(n_args, n_kw, 2, 2, true);
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
||||
enum { ARG_pin_a, ARG_pin_b };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_pin_a, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_pin_b, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
assert_pin(args[ARG_pin_a].u_obj, false);
|
||||
const mcu_pin_obj_t* pin_a = MP_OBJ_TO_PTR(args[ARG_pin_a].u_obj);
|
||||
assert_pin_free(pin_a);
|
||||
|
||||
assert_pin(args[ARG_pin_b].u_obj, false);
|
||||
const mcu_pin_obj_t* pin_b = MP_OBJ_TO_PTR(args[ARG_pin_b].u_obj);
|
||||
assert_pin_free(pin_b);
|
||||
|
||||
rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t);
|
||||
self->base.type = &rotaryio_incrementalencoder_type;
|
||||
|
||||
common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
//| .. method:: deinit()
|
||||
//|
|
||||
//| Deinitialises the IncrementalEncoder and releases any hardware resources for reuse.
|
||||
//|
|
||||
STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) {
|
||||
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_rotaryio_incrementalencoder_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit);
|
||||
|
||||
//| .. method:: __enter__()
|
||||
//|
|
||||
//| No-op used by Context Managers.
|
||||
//|
|
||||
// Provided by context manager helper.
|
||||
|
||||
//| .. method:: __exit__()
|
||||
//|
|
||||
//| Automatically deinitializes the hardware when exiting a context. See
|
||||
//| :ref:`lifetime-and-contextmanagers` for more info.
|
||||
//|
|
||||
STATIC mp_obj_t rotaryio_incrementalencoder_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
common_hal_rotaryio_incrementalencoder_deinit(args[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___obj, 4, 4, rotaryio_incrementalencoder_obj___exit__);
|
||||
|
||||
|
||||
//| .. attribute:: position
|
||||
//|
|
||||
//| The current position in terms of pulses. The number of pulses per rotation is defined by the
|
||||
//| specific hardware.
|
||||
//|
|
||||
STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) {
|
||||
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
|
||||
|
||||
return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio_incrementalencoder_obj_get_position);
|
||||
|
||||
const mp_obj_property_t rotaryio_incrementalencoder_position_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&rotaryio_incrementalencoder_get_position_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t rotaryio_incrementalencoder_locals_dict_table[] = {
|
||||
// Methods
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rotaryio_incrementalencoder___exit___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&rotaryio_incrementalencoder_position_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(rotaryio_incrementalencoder_locals_dict, rotaryio_incrementalencoder_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t rotaryio_incrementalencoder_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_IncrementalEncoder,
|
||||
.make_new = rotaryio_incrementalencoder_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&rotaryio_incrementalencoder_locals_dict,
|
||||
};
|
41
shared-bindings/rotaryio/IncrementalEncoder.h
Normal file
41
shared-bindings/rotaryio/IncrementalEncoder.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/rotaryio/IncrementalEncoder.h"
|
||||
|
||||
extern const mp_obj_type_t rotaryio_incrementalencoder_type;
|
||||
|
||||
extern void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t* self,
|
||||
const mcu_pin_obj_t* pin_a, const mcu_pin_obj_t* pin_b);
|
||||
extern void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t* self);
|
||||
extern bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t* self);
|
||||
extern mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t* self);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO_INCREMENTALENCODER_H
|
75
shared-bindings/rotaryio/__init__.c
Normal file
75
shared-bindings/rotaryio/__init__.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/rotaryio/__init__.h"
|
||||
#include "shared-bindings/rotaryio/IncrementalEncoder.h"
|
||||
|
||||
//| :mod:`rotaryio` --- Support for pulse based protocols
|
||||
//| =====================================================
|
||||
//|
|
||||
//| .. module:: rotaryio
|
||||
//| :synopsis: Support for reading rotation sensors
|
||||
//| :platform: SAMD
|
||||
//|
|
||||
//| The `rotaryio` module contains classes to read different rotation encoding schemes. See
|
||||
//| `Wikipedia's Rotary Encoder page <https://en.wikipedia.org/wiki/Rotary_encoder>`_ for more
|
||||
//| background.
|
||||
//|
|
||||
//| Libraries
|
||||
//|
|
||||
//| .. toctree::
|
||||
//| :maxdepth: 3
|
||||
//|
|
||||
//| IncrementalEncoder
|
||||
//|
|
||||
|
||||
//| .. warning:: This module is not available in some SAMD21 (aka M0) builds. See the
|
||||
//| :ref:`module-support-matrix` for more info.
|
||||
//|
|
||||
|
||||
//| All classes change hardware state and should be deinitialized when they
|
||||
//| are no longer needed if the program continues after use. To do so, either
|
||||
//| call :py:meth:`!deinit` or use a context manager. See
|
||||
//| :ref:`lifetime-and-contextmanagers` for more info.
|
||||
//|
|
||||
|
||||
STATIC const mp_rom_map_elem_t rotaryio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rotaryio) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IncrementalEncoder), MP_ROM_PTR(&rotaryio_incrementalencoder_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(rotaryio_module_globals, rotaryio_module_globals_table);
|
||||
|
||||
const mp_obj_module_t rotaryio_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&rotaryio_module_globals,
|
||||
};
|
34
shared-bindings/rotaryio/__init__.h
Normal file
34
shared-bindings/rotaryio/__init__.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
// Nothing now.
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ROTARYIO___INIT___H
|
@ -27,7 +27,6 @@
|
||||
#include "mphalport.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "rgb_led_status.h"
|
||||
#include "pins.h"
|
||||
|
||||
#ifdef MICROPY_HW_NEOPIXEL
|
||||
uint8_t rgb_status_brightness = 63;
|
||||
|
Loading…
Reference in New Issue
Block a user