diff --git a/ports/atmel-samd/boards/pewpew70/mpconfigboard.h b/ports/atmel-samd/boards/pewpew70/mpconfigboard.h index 92662bd551..e839bc5ea9 100644 --- a/ports/atmel-samd/boards/pewpew70/mpconfigboard.h +++ b/ports/atmel-samd/boards/pewpew70/mpconfigboard.h @@ -9,4 +9,4 @@ #include "internal_flash.h" -#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x014000) +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - 0x010000) diff --git a/ports/atmel-samd/boards/pewpew70/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew70/mpconfigboard.mk index 1b5d1ff824..f316bfb2ee 100644 --- a/ports/atmel-samd/boards/pewpew70/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew70/mpconfigboard.mk @@ -9,3 +9,5 @@ LONGINT_IMPL = NONE CHIP_VARIANT = SAMD21E18A CHIP_FAMILY = samd21 + +FROZEN_MPY_DIRS += $(TOP)/frozen/pewpew70 diff --git a/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld b/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld index bc4b53ae9c..2adf4fa909 100644 --- a/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld +++ b/ports/atmel-samd/boards/samd21x18-bootloader-crystalless.ld @@ -6,7 +6,7 @@ MEMORY { /* Leave 8KiB for the bootloader, 256b for persistent config (clock), 64k for the flash file system and 256b for the user config. */ - FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 256 - 80K - 256 + FLASH (rx) : ORIGIN = 0x00000000 + 8K, LENGTH = 256K - 8K - 256 - 64K - 256 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } diff --git a/ports/atmel-samd/supervisor/internal_flash.h b/ports/atmel-samd/supervisor/internal_flash.h index d1037012d1..0939a34548 100644 --- a/ports/atmel-samd/supervisor/internal_flash.h +++ b/ports/atmel-samd/supervisor/internal_flash.h @@ -37,7 +37,7 @@ #endif #ifdef SAMD21 -#define TOTAL_INTERNAL_FLASH_SIZE 0x014000 +#define TOTAL_INTERNAL_FLASH_SIZE 0x010000 #endif #define INTERNAL_FLASH_MEM_SEG1_START_ADDR (FLASH_SIZE - TOTAL_INTERNAL_FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE) diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 9b5de88e66..d1e0ae5936 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -72,7 +72,7 @@ #include "shared-module/gamepad/__init__.h" #endif #ifdef CIRCUITPY_PEWPEW_TICKS -#include "shared-module/_pew/__init__.h" +#include "shared-module/_pew/PewPew.h" #endif extern volatile bool mp_msc_enabled; diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c index e1f9c180b6..44b631838e 100644 --- a/ports/atmel-samd/tick.c +++ b/ports/atmel-samd/tick.c @@ -55,11 +55,6 @@ void SysTick_Handler(void) { gamepad_tick(); } #endif - #ifdef CIRCUITPY_PEWPEW_TICKS - if (!(ticks_ms & CIRCUITPY_PEWPEW_TICKS)) { - pew_tick(); - } - #endif } void tick_init() { diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c index c819dd8616..c9322100fa 100644 --- a/shared-bindings/_pew/PewPew.c +++ b/shared-bindings/_pew/PewPew.c @@ -110,8 +110,6 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, pew->rows_size = rows_size; pew->cols = cols; pew->cols_size = cols_size; - pew->col = 0; - pew->turn = 0; pew_init(); return MP_OBJ_FROM_PTR(pew); diff --git a/shared-module/_pew/PewPew.c b/shared-module/_pew/PewPew.c index ede8ed9bb9..de1224a37f 100644 --- a/shared-module/_pew/PewPew.c +++ b/shared-module/_pew/PewPew.c @@ -27,14 +27,30 @@ #include #include "py/mpstate.h" +#include "py/runtime.h" #include "__init__.h" #include "PewPew.h" #include "shared-bindings/digitalio/Pull.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/util.h" +#include "samd/timers.h" +static uint8_t pewpew_tc_index = 0xff; + + +void pewpew_interrupt_handler(uint8_t index) { + if (index != pewpew_tc_index) return; + Tc* tc = tc_insts[index]; + if (!tc->COUNT16.INTFLAG.bit.MC0) return; + + pew_tick(); + + // Clear the interrupt bit. + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; +} + void pew_init() { pew_obj_t* pew_singleton = MP_STATE_VM(pew_singleton); for (size_t i = 0; i < pew_singleton->rows_size; ++i) { @@ -49,4 +65,57 @@ void pew_init() { common_hal_digitalio_digitalinout_switch_to_output(pin, true, DRIVE_MODE_OPEN_DRAIN); } + if (pewpew_tc_index == 0xff) { + // Find a spare timer. + Tc *tc = NULL; + int8_t index = TC_INST_NUM - 1; + for (; index >= 0; index--) { + if (tc_insts[index]->COUNT16.CTRLA.bit.ENABLE == 0) { + tc = tc_insts[index]; + break; + } + } + if (tc == NULL) { + mp_raise_RuntimeError("All timers in use"); + } + + pewpew_tc_index = index; + + // We use GCLK0 for SAMD21 and GCLK1 for SAMD51 because they both run + // at 48mhz making our math the same across the boards. + #ifdef SAMD21 + turn_on_clocks(true, index, 0); + #endif + #ifdef SAMD51 + turn_on_clocks(true, index, 1); + #endif + + + #ifdef SAMD21 + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | + TC_CTRLA_PRESCALER_DIV64 | + TC_CTRLA_WAVEGEN_MFRQ; + #endif + #ifdef SAMD51 + tc_reset(tc); + tc_set_enable(tc, false); + tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 + | TC_CTRLA_PRESCALER_DIV64; + tc->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; + #endif + + tc_set_enable(tc, true); + //tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_STOP; + tc->COUNT16.CC[0].reg = 160; + + // Clear our interrupt in case it was set earlier + tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; + tc->COUNT16.INTENSET.reg = TC_INTENSET_MC0; + tc_enable_interrupts(pewpew_tc_index); + } +} + +void pew_reset(void) { + MP_STATE_VM(pew_singleton) = NULL; + pewpew_tc_index = 0xff; } diff --git a/shared-module/_pew/PewPew.h b/shared-module/_pew/PewPew.h index b21ff01372..2f25f9ce2d 100644 --- a/shared-module/_pew/PewPew.h +++ b/shared-module/_pew/PewPew.h @@ -29,19 +29,17 @@ #include -#include "shared-bindings/digitalio/DigitalInOut.h" - typedef struct { mp_obj_base_t base; uint8_t* buffer; mp_obj_t* rows; mp_obj_t* cols; - size_t rows_size; - size_t cols_size; - volatile uint8_t col; - volatile uint8_t turn; + uint8_t rows_size; + uint8_t cols_size; } pew_obj_t; void pew_init(void); +void pewpew_interrupt_handler(uint8_t index); +void pew_reset(void); #endif // MICROPY_INCLUDED_PEW_PEWPEW_H diff --git a/shared-module/_pew/__init__.c b/shared-module/_pew/__init__.c index 92637a04dd..2e09932f3a 100644 --- a/shared-module/_pew/__init__.c +++ b/shared-module/_pew/__init__.c @@ -34,39 +34,44 @@ void pew_tick(void) { + static uint8_t col = 0; + static uint8_t turn = 0; digitalio_digitalinout_obj_t *pin; + pew_obj_t* pew = MP_STATE_VM(pew_singleton); if (!pew) { return; } - pin = MP_OBJ_TO_PTR(pew->cols[pew->col]); - common_hal_digitalio_digitalinout_set_value(pin, true); - pew->col += 1; - if (pew->col >= pew->cols_size) { - pew->col = 0; - pew->turn += 1; - if (pew->turn >= 4) { - pew->turn = 0; + pin = MP_OBJ_TO_PTR(pew->cols[col]); + ++col; + if (col >= pew->cols_size) { + col = 0; + ++turn; + if (turn >= 8) { + turn = 0; } } + common_hal_digitalio_digitalinout_set_value(pin, true); for (size_t x = 0; x < pew->rows_size; ++x) { pin = MP_OBJ_TO_PTR(pew->rows[x]); - uint8_t color = pew->buffer[(pew->col) * (pew->rows_size) + x]; - bool value = true; - switch (pew->turn) { - case 0: - if (color & 0x03) { value = true; } + uint8_t color = pew->buffer[col * (pew->rows_size) + x]; + bool value = false; + switch (color & 0x03) { + case 3: + value = true; break; - case 1: case 2: - if (color & 0x02) { value = true; } + if (turn == 2 || turn == 4 || turn == 6) { + value = true; + } + case 1: + if (turn == 0) { + value = true; + } + case 0: break; } common_hal_digitalio_digitalinout_set_value(pin, value); } - pin = MP_OBJ_TO_PTR(pew->cols[pew->col]); + pin = MP_OBJ_TO_PTR(pew->cols[col]); common_hal_digitalio_digitalinout_set_value(pin, false); } - -void pew_reset(void) { - MP_STATE_VM(pew_singleton) = NULL; -} diff --git a/shared-module/_pew/__init__.h b/shared-module/_pew/__init__.h index 30c9c8c930..f85dec7491 100644 --- a/shared-module/_pew/__init__.h +++ b/shared-module/_pew/__init__.h @@ -28,6 +28,5 @@ #define MICROPY_INCLUDED_PEW_H void pew_tick(void); -void pew_reset(void); #endif // MICROPY_INCLUDED_PEW_H