Merge pull request #49 from adafruit/upstream-merge-2019-04
Merge from microsoft/uf2-samdx1; fuse repair
This commit is contained in:
commit
b9e9e70e98
29 changed files with 1283 additions and 36 deletions
25
Makefile
25
Makefile
|
|
@ -42,7 +42,7 @@ endif
|
|||
|
||||
LDFLAGS= $(COMMON_FLAGS) \
|
||||
-Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common \
|
||||
-Wl,--warn-section-align -Wl,--warn-unresolved-symbols \
|
||||
-Wl,--warn-section-align \
|
||||
-save-temps -nostartfiles \
|
||||
--specs=nano.specs --specs=nosys.specs
|
||||
BUILD_PATH=build/$(BOARD)
|
||||
|
|
@ -64,6 +64,8 @@ COMMON_SRC = \
|
|||
src/init_$(CHIP_FAMILY).c \
|
||||
src/startup_$(CHIP_FAMILY).c \
|
||||
src/usart_sam_ba.c \
|
||||
src/screen.c \
|
||||
src/images.c \
|
||||
src/utils.c
|
||||
|
||||
SOURCES = $(COMMON_SRC) \
|
||||
|
|
@ -100,6 +102,27 @@ burn: all
|
|||
|
||||
run: burn wait logs
|
||||
|
||||
# This currently only works on macOS with a BMP debugger attached.
|
||||
# It's meant to flash the bootloader in a loop.
|
||||
BMP = $(shell ls -1 /dev/cu.usbmodem* | head -1)
|
||||
BMP_ARGS = --nx -ex "set mem inaccessible-by-default off" -ex "set confirm off" -ex "target extended-remote $(BMP)" -ex "mon swdp_scan" -ex "attach 1"
|
||||
GDB = arm-none-eabi-gdb
|
||||
|
||||
bmp-flash: $(BUILD_PATH)/$(NAME).bin
|
||||
@test "X$(BMP)" != "X"
|
||||
$(GDB) $(BMP_ARGS) -ex "load" -ex "quit" $(BUILD_PATH)/$(NAME).elf | tee build/flash.log
|
||||
@grep -q "Transfer rate" build/flash.log
|
||||
|
||||
bmp-flashone:
|
||||
while : ; do $(MAKE) bmp-flash && exit 0 ; sleep 1 ; done
|
||||
afplay /System/Library/PrivateFrameworks/ScreenReader.framework/Versions/A/Resources/Sounds/Error.aiff
|
||||
|
||||
bmp-loop:
|
||||
while : ; do $(MAKE) bmp-flashone ; sleep 5 ; done
|
||||
|
||||
bmp-gdb: $(BUILD_PATH)/$(NAME).bin
|
||||
$(GDB) $(BMP_ARGS) $(BUILD_PATH)/$(NAME).elf
|
||||
|
||||
wait:
|
||||
sleep 5
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ to temporarily turn off the protection. In gdb the command is:
|
|||
|
||||
* `make` and an Unix environment
|
||||
* `node`.js in path (optional)
|
||||
* `arm-none-eabi-gcc` in the path (the one coming with Yotta will do just fine)
|
||||
* `arm-none-eabi-gcc` in the path (the one coming with Yotta will do just fine). You can get the latest version from ARM: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
|
||||
* `openocd` - you can use the one coming with Arduino (after your install the M0 board support)
|
||||
|
||||
Atmel Studio is not supported.
|
||||
|
|
|
|||
2
boards/CC03/board.mk
Normal file
2
boards/CC03/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd21
|
||||
CHIP_VARIANT = SAMD21G18A
|
||||
16
boards/CC03/board_config.h
Normal file
16
boards/CC03/board_config.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "XinaBox Limited"
|
||||
#define PRODUCT_NAME "CC03"
|
||||
#define VOLUME_LABEL "CC03"
|
||||
#define INDEX_URL "https://xinabox.cc/products/cc03"
|
||||
|
||||
#define BOARD_ID "SAMD21G18A-CC03-v0"
|
||||
|
||||
//#define USB_VID 0x2341
|
||||
//#define USB_PID 0x024D
|
||||
|
||||
#define LED_PIN PIN_PA07
|
||||
|
||||
#endif
|
||||
2
boards/CS11/board.mk
Normal file
2
boards/CS11/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd21
|
||||
CHIP_VARIANT = SAMD21G18A
|
||||
16
boards/CS11/board_config.h
Normal file
16
boards/CS11/board_config.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "XinaBox Limited"
|
||||
#define PRODUCT_NAME "CS11"
|
||||
#define VOLUME_LABEL "CS11"
|
||||
#define INDEX_URL "https://xinabox.cc/products/cc11"
|
||||
|
||||
#define BOARD_ID "SAMD21G18A-CS11-v0"
|
||||
|
||||
//#define USB_VID 0x2341
|
||||
//#define USB_PID 0x024D
|
||||
|
||||
#define LED_PIN PIN_PA08
|
||||
|
||||
#endif
|
||||
2
boards/arcade_badge/board.mk
Normal file
2
boards/arcade_badge/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd51
|
||||
CHIP_VARIANT = SAMD51J19A
|
||||
110
boards/arcade_badge/board_config.h
Normal file
110
boards/arcade_badge/board_config.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "Adafruit Industries"
|
||||
#define PRODUCT_NAME "Arcade D51"
|
||||
#define VOLUME_LABEL "ARCADE-D5"
|
||||
#define INDEX_URL "http://adafru.it/"
|
||||
#define BOARD_ID "SAMD51J19A-Arcade-D51"
|
||||
|
||||
#define USB_VID 0x239A
|
||||
#define USB_PID 0x002B
|
||||
|
||||
#define LED_PIN PIN_PA23
|
||||
|
||||
#define BOARD_NEOPIXEL_PIN PIN_PA15
|
||||
#define BOARD_NEOPIXEL_COUNT 5
|
||||
|
||||
#define BOARD_SCREEN 1
|
||||
|
||||
#define BOOT_USART_MODULE SERCOM3
|
||||
#define BOOT_USART_MASK APBAMASK
|
||||
#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBBMASK_SERCOM3
|
||||
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD1_TX_PAD0
|
||||
#define BOOT_USART_PAD3 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD2 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD1 PINMUX_PA22C_SERCOM3_PAD0
|
||||
#define BOOT_USART_PAD0 PINMUX_PA23C_SERCOM3_PAD1
|
||||
#define BOOT_GCLK_ID_CORE SERCOM3_GCLK_ID_CORE
|
||||
#define BOOT_GCLK_ID_SLOW SERCOM3_GCLK_ID_SLOW
|
||||
|
||||
|
||||
#define HAS_CONFIG_DATA 1
|
||||
|
||||
// This configuration data should be edited at https://microsoft.github.io/uf2/patcher/
|
||||
// Just drop this file there.
|
||||
// Alternatively, it can be also binary edited there after the bootloader is compiled.
|
||||
|
||||
#ifdef DEFINE_CONFIG_DATA
|
||||
const uint32_t config_data[] = {
|
||||
/* CF2 START */
|
||||
513675505, 539130489, // magic
|
||||
60, 100, // used entries, total entries
|
||||
1, 0x2e, // PIN_ACCELEROMETER_INT = PB14
|
||||
2, 0xd, // PIN_ACCELEROMETER_SCL = PIN_SCL
|
||||
3, 0xc, // PIN_ACCELEROMETER_SDA = PIN_SDA
|
||||
4, 0x3ef, // PIN_BTN_A = P_1007
|
||||
5, 0x3ee, // PIN_BTN_B = P_1006
|
||||
13, 0x17, // PIN_LED = PIN_D13
|
||||
18, 0x36, // PIN_MISO = PB22
|
||||
19, 0x37, // PIN_MOSI = PB23
|
||||
20, 0xf, // PIN_NEOPIXEL = PA15
|
||||
21, 0x11, // PIN_RX = PA17
|
||||
23, 0x11, // PIN_SCK = PA17
|
||||
24, 0xd, // PIN_SCL = PA13
|
||||
25, 0xc, // PIN_SDA = PA12
|
||||
28, 0x10, // PIN_TX = PA16
|
||||
32, 0x2d, // PIN_DISPLAY_SCK = PB13
|
||||
34, 0x2c, // PIN_DISPLAY_MOSI = PB12
|
||||
35, 0x27, // PIN_DISPLAY_CS = PB07
|
||||
36, 0x25, // PIN_DISPLAY_DC = PB05
|
||||
37, 0xa0, // DISPLAY_WIDTH = 160
|
||||
38, 0x80, // DISPLAY_HEIGHT = 128
|
||||
39, 0x80, // DISPLAY_CFG0 = 0x80
|
||||
40, 0x12c2d, // DISPLAY_CFG1 = 0x12c2d
|
||||
41, 0x18, // DISPLAY_CFG2 = 0x18
|
||||
43, 0x1, // PIN_DISPLAY_RST = PA01
|
||||
44, 0x0, // PIN_DISPLAY_BL = PA00
|
||||
47, 0x3e8, // PIN_BTN_LEFT = P_1000
|
||||
48, 0x3eb, // PIN_BTN_RIGHT = P_1003
|
||||
49, 0x3e9, // PIN_BTN_UP = P_1001
|
||||
50, 0x3ea, // PIN_BTN_DOWN = P_1002
|
||||
51, 0x3ec, // PIN_BTN_MENU = P_1004
|
||||
59, 0x200, // SPEAKER_VOLUME = 512
|
||||
60, 0x10, // PIN_JACK_TX = PIN_D5
|
||||
65, 0x2, // PIN_JACK_SND = PIN_A0
|
||||
69, 0x3ed, // PIN_BTN_SOFT_RESET = P_1005
|
||||
70, 0x32, // ACCELEROMETER_TYPE = LIS3DH
|
||||
71, 0x20, // PIN_BTNMX_LATCH = PB00
|
||||
72, 0x3f, // PIN_BTNMX_CLOCK = PB31
|
||||
73, 0x3e, // PIN_BTNMX_DATA = PB30
|
||||
100, 0x2, // PIN_A0 = PA02
|
||||
101, 0x5, // PIN_A1 = PA05
|
||||
102, 0x28, // PIN_A2 = PB08
|
||||
103, 0x29, // PIN_A3 = PB09
|
||||
104, 0x4, // PIN_A4 = PA04
|
||||
105, 0x6, // PIN_A5 = PA06
|
||||
152, 0x23, // PIN_D2 = PB03
|
||||
153, 0x22, // PIN_D3 = PB02
|
||||
154, 0xe, // PIN_D4 = PA14
|
||||
155, 0x10, // PIN_D5 = PA16
|
||||
156, 0x12, // PIN_D6 = PA18
|
||||
159, 0x13, // PIN_D9 = PA19
|
||||
160, 0x14, // PIN_D10 = PA20
|
||||
161, 0x15, // PIN_D11 = PA21
|
||||
162, 0x16, // PIN_D12 = PA22
|
||||
163, 0x17, // PIN_D13 = PA23
|
||||
200, 0x5, // NUM_NEOPIXELS = 5
|
||||
204, 0x80000, // FLASH_BYTES = 0x80000
|
||||
205, 0x30000, // RAM_BYTES = 0x30000
|
||||
208, 0x18591ab9, // BOOTLOADER_BOARD_ID = 0x18591ab9
|
||||
209, 0x55114460, // UF2_FAMILY = ATSAMD51
|
||||
210, 0x20, // PINS_PORT_SIZE = PA_32
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* CF2 END */
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
boards/arcade_feather_m4/board.mk
Normal file
2
boards/arcade_feather_m4/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd51
|
||||
CHIP_VARIANT = SAMD51J19A
|
||||
106
boards/arcade_feather_m4/board_config.h
Normal file
106
boards/arcade_feather_m4/board_config.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "Adafruit Industries"
|
||||
#define PRODUCT_NAME "Feather Arcade D51"
|
||||
#define VOLUME_LABEL "ARCADE-D5"
|
||||
#define INDEX_URL "https://arcade.makecode.com/"
|
||||
#define BOARD_ID "SAMD51J19A-Feather-Arcade-D51"
|
||||
|
||||
|
||||
#define USB_VID 0x239A
|
||||
#define USB_PID 0x0022
|
||||
|
||||
#define LED_PIN PIN_PA23
|
||||
|
||||
#define BOARD_NEOPIXEL_PIN PIN_PB03
|
||||
#define BOARD_NEOPIXEL_COUNT 1
|
||||
|
||||
#define BOOT_USART_MODULE SERCOM0
|
||||
#define BOOT_USART_MASK APBAMASK
|
||||
#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBAMASK_SERCOM0
|
||||
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD0
|
||||
#define BOOT_USART_PAD3 PINMUX_PA07D_SERCOM0_PAD3
|
||||
#define BOOT_USART_PAD2 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD1 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD0 PINMUX_PA04D_SERCOM0_PAD0
|
||||
#define BOOT_GCLK_ID_CORE SERCOM0_GCLK_ID_CORE
|
||||
#define BOOT_GCLK_ID_SLOW SERCOM0_GCLK_ID_SLOW
|
||||
|
||||
#define HAS_CONFIG_DATA 1
|
||||
#define BOARD_SCREEN 1
|
||||
|
||||
|
||||
// This configuration data should be edited at https://microsoft.github.io/uf2/patcher/
|
||||
// Just drop this file there.
|
||||
// Alternatively, it can be also binary edited there after the bootloader is compiled.
|
||||
|
||||
#ifdef DEFINE_CONFIG_DATA
|
||||
const uint32_t config_data[] = {
|
||||
/* CF2 START */
|
||||
513675505, 539130489, // magic
|
||||
53, 100, // used entries, total entries
|
||||
4, 0xd, // PIN_BTN_A = PIN_SCL
|
||||
5, 0x12, // PIN_BTN_B = PIN_D6
|
||||
13, 0x17, // PIN_LED = PIN_D13
|
||||
18, 0x36, // PIN_MISO = PB22
|
||||
19, 0x37, // PIN_MOSI = PB23
|
||||
20, 0x23, // PIN_NEOPIXEL = PB03
|
||||
21, 0x31, // PIN_RX = PB17
|
||||
23, 0x11, // PIN_SCK = PA17
|
||||
24, 0xd, // PIN_SCL = PA13
|
||||
25, 0xc, // PIN_SDA = PA12
|
||||
26, 0xe, // PIN_SPEAKER_AMP = PIN_D4
|
||||
28, 0x30, // PIN_TX = PB16
|
||||
32, 0x11, // PIN_DISPLAY_SCK = PIN_SCK
|
||||
33, 0x36, // PIN_DISPLAY_MISO = PIN_MISO
|
||||
34, 0x37, // PIN_DISPLAY_MOSI = PIN_MOSI
|
||||
35, 0x28, // PIN_DISPLAY_CS = PIN_A2
|
||||
36, 0x29, // PIN_DISPLAY_DC = PIN_A3
|
||||
37, 0xa0, // DISPLAY_WIDTH = 160
|
||||
38, 0x80, // DISPLAY_HEIGHT = 128
|
||||
39, 0x90, // DISPLAY_CFG0 = 0x90
|
||||
40, 0xe14ff, // DISPLAY_CFG1 = 0xe14ff
|
||||
41, 0x18, // DISPLAY_CFG2 = 0x18
|
||||
43, 0x4, // PIN_DISPLAY_RST = PIN_A4
|
||||
44, 0x6, // PIN_DISPLAY_BL = PIN_A5
|
||||
47, 0x15, // PIN_BTN_LEFT = PIN_D11
|
||||
48, 0x13, // PIN_BTN_RIGHT = PIN_D9
|
||||
49, 0x14, // PIN_BTN_UP = PIN_D10
|
||||
50, 0x16, // PIN_BTN_DOWN = PIN_D12
|
||||
51, 0xc, // PIN_BTN_MENU = PIN_SDA
|
||||
59, 0x200, // SPEAKER_VOLUME = 512
|
||||
60, 0x30, // PIN_JACK_TX = PIN_D1
|
||||
100, 0x2, // PIN_A0 = PA02
|
||||
101, 0x5, // PIN_A1 = PA05
|
||||
102, 0x28, // PIN_A2 = PB08
|
||||
103, 0x29, // PIN_A3 = PB09
|
||||
104, 0x4, // PIN_A4 = PA04
|
||||
105, 0x6, // PIN_A5 = PA06
|
||||
150, 0x31, // PIN_D0 = PB17
|
||||
151, 0x30, // PIN_D1 = PB16
|
||||
154, 0xe, // PIN_D4 = PA14
|
||||
155, 0x10, // PIN_D5 = PA16
|
||||
156, 0x12, // PIN_D6 = PA18
|
||||
159, 0x13, // PIN_D9 = PA19
|
||||
160, 0x14, // PIN_D10 = PA20
|
||||
161, 0x15, // PIN_D11 = PA21
|
||||
162, 0x16, // PIN_D12 = PA22
|
||||
163, 0x17, // PIN_D13 = PA23
|
||||
200, 0x1, // NUM_NEOPIXELS = 1
|
||||
204, 0x80000, // FLASH_BYTES = 0x80000
|
||||
205, 0x30000, // RAM_BYTES = 0x30000
|
||||
208, 0x2b9e3d05, // BOOTLOADER_BOARD_ID = 0x2b9e3d05
|
||||
209, 0x55114460, // UF2_FAMILY = ATSAMD51
|
||||
210, 0x20, // PINS_PORT_SIZE = PA_32
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* CF2 END */
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
7
boards/arcade_itsybitsy_m4/altkeys.cf2
Normal file
7
boards/arcade_itsybitsy_m4/altkeys.cf2
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
PIN_BTN_A = PIN_D10
|
||||
PIN_BTN_B = PIN_D11
|
||||
PIN_BTN_LEFT = PIN_SDA
|
||||
PIN_BTN_UP = PIN_D7
|
||||
PIN_BTN_RIGHT = PIN_SCL
|
||||
PIN_BTN_DOWN = PIN_D9
|
||||
PIN_BTN_MENU = PIN_D12
|
||||
2
boards/arcade_itsybitsy_m4/altscreen.cf2
Normal file
2
boards/arcade_itsybitsy_m4/altscreen.cf2
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
DISPLAY_CFG0 = 0x01000080
|
||||
DISPLAY_CFG1 = 0x00000603
|
||||
2
boards/arcade_itsybitsy_m4/board.mk
Normal file
2
boards/arcade_itsybitsy_m4/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd51
|
||||
CHIP_VARIANT = SAMD51G19A
|
||||
108
boards/arcade_itsybitsy_m4/board_config.h
Normal file
108
boards/arcade_itsybitsy_m4/board_config.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "Adafruit Industries"
|
||||
#define PRODUCT_NAME "Itsy Arcade D51"
|
||||
#define VOLUME_LABEL "ARCADE-D5"
|
||||
#define INDEX_URL "https://arcade.makecode.com/"
|
||||
#define BOARD_ID "SAMD51G19A-Itsy-Arcade-D51"
|
||||
|
||||
#define USB_VID 0x239A
|
||||
#define USB_PID 0x002B
|
||||
|
||||
#define LED_PIN PIN_PA22
|
||||
|
||||
#define BOARD_RGBLED_CLOCK_PIN PIN_PB02
|
||||
#define BOARD_RGBLED_DATA_PIN PIN_PB03
|
||||
|
||||
#define BOOT_USART_MODULE SERCOM3
|
||||
#define BOOT_USART_MASK APBAMASK
|
||||
#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBBMASK_SERCOM3
|
||||
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD1_TX_PAD0
|
||||
#define BOOT_USART_PAD3 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD2 PINMUX_UNUSED
|
||||
#define BOOT_USART_PAD1 PINMUX_PA22C_SERCOM3_PAD0
|
||||
#define BOOT_USART_PAD0 PINMUX_PA23C_SERCOM3_PAD1
|
||||
#define BOOT_GCLK_ID_CORE SERCOM3_GCLK_ID_CORE
|
||||
#define BOOT_GCLK_ID_SLOW SERCOM3_GCLK_ID_SLOW
|
||||
|
||||
#define HAS_CONFIG_DATA 1
|
||||
#define BOARD_SCREEN 1
|
||||
|
||||
// This configuration data should be edited at https://microsoft.github.io/uf2/patcher/
|
||||
// Just drop this file there.
|
||||
// Alternatively, it can be also binary edited there after the bootloader is compiled.
|
||||
|
||||
#ifdef DEFINE_CONFIG_DATA
|
||||
const uint32_t config_data[] = {
|
||||
/* CF2 START */
|
||||
513675505, 539130489, // magic
|
||||
60, 100, // used entries, total entries
|
||||
4, 0xd, // PIN_BTN_A = PIN_SCL
|
||||
5, 0x12, // PIN_BTN_B = PIN_D7
|
||||
7, 0x22, // PIN_DOTSTAR_CLOCK = PB02
|
||||
8, 0x23, // PIN_DOTSTAR_DATA = PB03
|
||||
9, 0x2b, // PIN_FLASH_CS = PB11
|
||||
10, 0x9, // PIN_FLASH_MISO = PA09
|
||||
11, 0x8, // PIN_FLASH_MOSI = PA08
|
||||
12, 0x2a, // PIN_FLASH_SCK = PB10
|
||||
13, 0x16, // PIN_LED = PIN_D13
|
||||
18, 0x37, // PIN_MISO = PB23
|
||||
19, 0x0, // PIN_MOSI = PA00
|
||||
21, 0x10, // PIN_RX = PA16
|
||||
23, 0x1, // PIN_SCK = PA01
|
||||
24, 0xd, // PIN_SCL = PA13
|
||||
25, 0xc, // PIN_SDA = PA12
|
||||
26, 0x7, // PIN_SPEAKER_AMP = PIN_D2
|
||||
28, 0x11, // PIN_TX = PA17
|
||||
32, 0x1, // PIN_DISPLAY_SCK = PIN_SCK
|
||||
33, 0x37, // PIN_DISPLAY_MISO = PIN_MISO
|
||||
34, 0x0, // PIN_DISPLAY_MOSI = PIN_MOSI
|
||||
35, 0x28, // PIN_DISPLAY_CS = PIN_A2
|
||||
36, 0x29, // PIN_DISPLAY_DC = PIN_A3
|
||||
37, 0xa0, // DISPLAY_WIDTH = 160
|
||||
38, 0x80, // DISPLAY_HEIGHT = 128
|
||||
39, 0x90, // DISPLAY_CFG0 = 0x90
|
||||
40, 0xe14ff, // DISPLAY_CFG1 = 0xe14ff
|
||||
41, 0x18, // DISPLAY_CFG2 = 0x18
|
||||
43, 0x4, // PIN_DISPLAY_RST = PIN_A4
|
||||
44, 0x6, // PIN_DISPLAY_BL = PIN_A5
|
||||
47, 0x15, // PIN_BTN_LEFT = PIN_D11
|
||||
48, 0x13, // PIN_BTN_RIGHT = PIN_D9
|
||||
49, 0x14, // PIN_BTN_UP = PIN_D10
|
||||
50, 0x17, // PIN_BTN_DOWN = PIN_D12
|
||||
51, 0xc, // PIN_BTN_MENU = PIN_SDA
|
||||
59, 0x200, // SPEAKER_VOLUME = 512
|
||||
60, 0x11, // PIN_JACK_TX = PIN_D1
|
||||
100, 0x2, // PIN_A0 = PA02
|
||||
101, 0x5, // PIN_A1 = PA05
|
||||
102, 0x28, // PIN_A2 = PB08
|
||||
103, 0x29, // PIN_A3 = PB09
|
||||
104, 0x4, // PIN_A4 = PA04
|
||||
105, 0x6, // PIN_A5 = PA06
|
||||
150, 0x10, // PIN_D0 = PA16
|
||||
151, 0x11, // PIN_D1 = PA17
|
||||
152, 0x7, // PIN_D2 = PA07
|
||||
153, 0x36, // PIN_D3 = PB22
|
||||
154, 0xe, // PIN_D4 = PA14
|
||||
155, 0xf, // PIN_D5 = PA15
|
||||
157, 0x12, // PIN_D7 = PA18
|
||||
159, 0x13, // PIN_D9 = PA19
|
||||
160, 0x14, // PIN_D10 = PA20
|
||||
161, 0x15, // PIN_D11 = PA21
|
||||
162, 0x17, // PIN_D12 = PA23
|
||||
163, 0x16, // PIN_D13 = PA22
|
||||
201, 0x1, // NUM_DOTSTARS = 1
|
||||
204, 0x80000, // FLASH_BYTES = 0x80000
|
||||
205, 0x30000, // RAM_BYTES = 0x30000
|
||||
208, 0x7a236324, // BOOTLOADER_BOARD_ID = 0x7a236324
|
||||
209, 0x55114460, // UF2_FAMILY = ATSAMD51
|
||||
210, 0x20, // PINS_PORT_SIZE = PA_32
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* CF2 END */
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
boards/mkr1300/board.mk
Normal file
2
boards/mkr1300/board.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CHIP_FAMILY = samd21
|
||||
CHIP_VARIANT = SAMD21G18A
|
||||
15
boards/mkr1300/board_config.h
Normal file
15
boards/mkr1300/board_config.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef BOARD_CONFIG_H
|
||||
#define BOARD_CONFIG_H
|
||||
|
||||
#define VENDOR_NAME "Arduino LLC"
|
||||
#define PRODUCT_NAME "Arduino MKR1300"
|
||||
#define VOLUME_LABEL "MKR1300"
|
||||
|
||||
#define BOARD_ID "SAMD21G18A-MKR1300-v0"
|
||||
|
||||
#define USB_VID 0x2341
|
||||
#define USB_PID 0x8053
|
||||
|
||||
#define LED_PIN PIN_PA20
|
||||
|
||||
#endif
|
||||
149
inc/configkeys.h
Normal file
149
inc/configkeys.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#ifndef __CONFIGKEYS_H
|
||||
#define __CONFIGKEYS_H 1
|
||||
|
||||
#define CFG_MAGIC0 0x1e9e10f1
|
||||
#define CFG_MAGIC1 0x20227a79
|
||||
|
||||
#define CFG_PIN_ACCELEROMETER_INT 1
|
||||
#define CFG_PIN_ACCELEROMETER_SCL 2
|
||||
#define CFG_PIN_ACCELEROMETER_SDA 3
|
||||
#define CFG_PIN_BTN_A 4
|
||||
#define CFG_PIN_BTN_B 5
|
||||
#define CFG_PIN_BTN_SLIDE 6
|
||||
#define CFG_PIN_DOTSTAR_CLOCK 7
|
||||
#define CFG_PIN_DOTSTAR_DATA 8
|
||||
#define CFG_PIN_FLASH_CS 9
|
||||
#define CFG_PIN_FLASH_MISO 10
|
||||
#define CFG_PIN_FLASH_MOSI 11
|
||||
#define CFG_PIN_FLASH_SCK 12
|
||||
#define CFG_PIN_LED 13
|
||||
#define CFG_PIN_LIGHT 14
|
||||
#define CFG_PIN_MICROPHONE 15
|
||||
#define CFG_PIN_MIC_CLOCK 16
|
||||
#define CFG_PIN_MIC_DATA 17
|
||||
#define CFG_PIN_MISO 18
|
||||
#define CFG_PIN_MOSI 19
|
||||
#define CFG_PIN_NEOPIXEL 20
|
||||
#define CFG_PIN_RX 21
|
||||
#define CFG_PIN_RXLED 22
|
||||
#define CFG_PIN_SCK 23
|
||||
#define CFG_PIN_SCL 24
|
||||
#define CFG_PIN_SDA 25
|
||||
#define CFG_PIN_SPEAKER_AMP 26
|
||||
#define CFG_PIN_TEMPERATURE 27
|
||||
#define CFG_PIN_TX 28
|
||||
#define CFG_PIN_TXLED 29
|
||||
#define CFG_PIN_IR_OUT 30
|
||||
#define CFG_PIN_IR_IN 31
|
||||
#define CFG_PIN_DISPLAY_SCK 32
|
||||
#define CFG_PIN_DISPLAY_MISO 33
|
||||
#define CFG_PIN_DISPLAY_MOSI 34
|
||||
#define CFG_PIN_DISPLAY_CS 35
|
||||
#define CFG_PIN_DISPLAY_DC 36
|
||||
#define CFG_DISPLAY_WIDTH 37
|
||||
#define CFG_DISPLAY_HEIGHT 38
|
||||
#define CFG_DISPLAY_CFG0 39
|
||||
#define CFG_DISPLAY_CFG1 40
|
||||
#define CFG_DISPLAY_CFG2 41
|
||||
#define CFG_DISPLAY_CFG3 42
|
||||
#define CFG_PIN_DISPLAY_RST 43
|
||||
#define CFG_PIN_DISPLAY_BL 44
|
||||
#define CFG_PIN_SERVO_1 45
|
||||
#define CFG_PIN_SERVO_2 46
|
||||
#define CFG_PIN_BTN_LEFT 47
|
||||
#define CFG_PIN_BTN_RIGHT 48
|
||||
#define CFG_PIN_BTN_UP 49
|
||||
#define CFG_PIN_BTN_DOWN 50
|
||||
#define CFG_PIN_BTN_MENU 51
|
||||
#define CFG_PIN_LED_R 52
|
||||
#define CFG_PIN_LED_G 53
|
||||
#define CFG_PIN_LED_B 54
|
||||
#define CFG_PIN_LED1 55
|
||||
#define CFG_PIN_LED2 56
|
||||
#define CFG_PIN_LED3 57
|
||||
#define CFG_PIN_LED4 58
|
||||
#define CFG_SPEAKER_VOLUME 59
|
||||
#define CFG_PIN_JACK_TX 60
|
||||
#define CFG_PIN_JACK_SENSE 61
|
||||
#define CFG_PIN_JACK_HPEN 62
|
||||
#define CFG_PIN_JACK_BZEN 63
|
||||
#define CFG_PIN_JACK_PWREN 64
|
||||
#define CFG_PIN_JACK_SND 65
|
||||
#define CFG_PIN_JACK_BUSLED 66
|
||||
#define CFG_PIN_JACK_COMMLED 67
|
||||
#define CFG_PIN_BTNMX_LATCH 66
|
||||
#define CFG_PIN_BTNMX_CLOCK 67
|
||||
#define CFG_PIN_BTNMX_DATA 68
|
||||
#define CFG_PIN_BTN_SOFT_RESET 69
|
||||
#define CFG_ACCELEROMETER_TYPE 70
|
||||
#define CFG_PIN_A0 100
|
||||
#define CFG_PIN_A1 101
|
||||
#define CFG_PIN_A2 102
|
||||
#define CFG_PIN_A3 103
|
||||
#define CFG_PIN_A4 104
|
||||
#define CFG_PIN_A5 105
|
||||
#define CFG_PIN_A6 106
|
||||
#define CFG_PIN_A7 107
|
||||
#define CFG_PIN_A8 108
|
||||
#define CFG_PIN_A9 109
|
||||
#define CFG_PIN_A10 110
|
||||
#define CFG_PIN_A11 111
|
||||
#define CFG_PIN_A12 112
|
||||
#define CFG_PIN_A13 113
|
||||
#define CFG_PIN_A14 114
|
||||
#define CFG_PIN_A15 115
|
||||
#define CFG_PIN_D0 150
|
||||
#define CFG_PIN_D1 151
|
||||
#define CFG_PIN_D2 152
|
||||
#define CFG_PIN_D3 153
|
||||
#define CFG_PIN_D4 154
|
||||
#define CFG_PIN_D5 155
|
||||
#define CFG_PIN_D6 156
|
||||
#define CFG_PIN_D7 157
|
||||
#define CFG_PIN_D8 158
|
||||
#define CFG_PIN_D9 159
|
||||
#define CFG_PIN_D10 160
|
||||
#define CFG_PIN_D11 161
|
||||
#define CFG_PIN_D12 162
|
||||
#define CFG_PIN_D13 163
|
||||
#define CFG_PIN_D14 164
|
||||
#define CFG_PIN_D15 165
|
||||
#define CFG_NUM_NEOPIXELS 200
|
||||
#define CFG_NUM_DOTSTARS 201
|
||||
#define CFG_DEFAULT_BUTTON_MODE 202
|
||||
#define CFG_SWD_ENABLED 203
|
||||
#define CFG_FLASH_BYTES 204
|
||||
#define CFG_RAM_BYTES 205
|
||||
#define CFG_SYSTEM_HEAP_BYTES 206
|
||||
#define CFG_LOW_MEM_SIMULATION_KB 207
|
||||
#define CFG_BOOTLOADER_BOARD_ID 208
|
||||
#define CFG_UF2_FAMILY 209
|
||||
#define CFG_PINS_PORT_SIZE 210
|
||||
|
||||
#define ACCELEROMETER_TYPE_LIS3DH 0x32
|
||||
#define ACCELEROMETER_TYPE_MMA8453 0x38
|
||||
#define ACCELEROMETER_TYPE_FXOS8700 0x3c
|
||||
#define ACCELEROMETER_TYPE_MMA8653 0x3a
|
||||
#define ACCELEROMETER_TYPE_MSA300 0x4c
|
||||
|
||||
#define UF2_FAMILY_ATSAMD21 0x68ed2b88
|
||||
#define UF2_FAMILY_ATSAMD51 0x55114460
|
||||
#define UF2_FAMILY_NRF52840 0x1b57745f
|
||||
#define UF2_FAMILY_STM32F103 0x5ee21072
|
||||
#define UF2_FAMILY_STM32F401 0x57755a57
|
||||
#define UF2_FAMILY_ATMEGA32 0x16573617
|
||||
#define UF2_FAMILY_CYPRESS_FX2 0x5a18069b
|
||||
|
||||
#define PINS_PORT_SIZE_PA_16 0x10
|
||||
#define PINS_PORT_SIZE_PA_32 0x20
|
||||
#define PINS_PORT_SIZE_P0_16 0x1010
|
||||
#define PINS_PORT_SIZE_P0_32 0x1020
|
||||
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_DOWN 0x11
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_UP 0x21
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_HIGH_PULL_NONE 0x31
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_DOWN 0x10
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_UP 0x20
|
||||
#define DEFAULT_BUTTON_MODE_ACTIVE_LOW_PULL_NONE 0x30
|
||||
|
||||
#endif // __CONFIGKEYS_H
|
||||
39
inc/uf2.h
39
inc/uf2.h
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef UF2_H
|
||||
#define UF2_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include "board_config.h"
|
||||
|
||||
#include "sam.h"
|
||||
|
|
@ -14,10 +15,14 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "configkeys.h"
|
||||
|
||||
|
||||
#undef DISABLE
|
||||
#undef ENABLE
|
||||
|
||||
// always go for crystalless - smaller and more compatiable
|
||||
// always go for crystalless - smaller and more compatible
|
||||
#ifndef CRYSTALLESS
|
||||
#define CRYSTALLESS 1
|
||||
#endif
|
||||
|
|
@ -55,6 +60,12 @@
|
|||
// Doesn't yet disable code, just enumeration
|
||||
#define USE_MSC 1
|
||||
|
||||
#ifdef BOARD_SCREEN
|
||||
#define USE_SCREEN 1
|
||||
#else
|
||||
#define USE_SCREEN 0
|
||||
#endif
|
||||
|
||||
// If enabled, bootloader will start on power-on and every reset. A second reset
|
||||
// will start the app. This only happens if the app says it wants that (see SINGLE_RESET() below).
|
||||
// If disabled here or by the app, the bootloader will only start with double-click of the reset
|
||||
|
|
@ -125,7 +136,13 @@
|
|||
// End of config
|
||||
|
||||
#define USE_MONITOR (USE_CDC || USE_UART)
|
||||
|
||||
#ifdef SAMD51
|
||||
// 51 also runs at 48MHz in bootloader mode, but it's still faster
|
||||
#define TIMER_STEP 2000
|
||||
#else
|
||||
#define TIMER_STEP 1500
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_NEOPIXEL_PIN
|
||||
#define COLOR_START 0x040000
|
||||
|
|
@ -233,8 +250,13 @@ void padded_memcpy(char *dst, const char *src, int len);
|
|||
#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef
|
||||
|
||||
#if USE_SINGLE_RESET
|
||||
#ifdef SAMD21
|
||||
#define SINGLE_RESET() (*((uint32_t *)0x20B4) == 0x87eeb07c)
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#define SINGLE_RESET() (*((uint32_t *)0x4268) == 0x87eeb07c)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void resetIntoApp(void);
|
||||
void resetIntoBootloader(void);
|
||||
|
|
@ -249,9 +271,16 @@ void led_signal(void);
|
|||
void led_init(void);
|
||||
void RGBLED_set_color(uint32_t color);
|
||||
|
||||
// Not all targets have a LED
|
||||
#if defined(LED_PIN)
|
||||
#define LED_MSC_OFF() PINOP(LED_PIN, OUTCLR)
|
||||
#define LED_MSC_ON() PINOP(LED_PIN, OUTSET)
|
||||
#define LED_MSC_TGL() PINOP(LED_PIN, OUTTGL)
|
||||
#else
|
||||
#define LED_MSC_OFF()
|
||||
#define LED_MSC_ON()
|
||||
#define LED_MSC_TGL()
|
||||
#endif
|
||||
|
||||
extern uint32_t timerHigh, resetHorizon;
|
||||
void timerTick(void);
|
||||
|
|
@ -271,4 +300,12 @@ STATIC_ASSERT(FLASH_NUM_ROWS * 4 == FLASH_NB_OF_PAGES);
|
|||
|
||||
extern const char infoUf2File[];
|
||||
|
||||
#if USE_SCREEN
|
||||
void draw_screen(void);
|
||||
void draw_hf2(void);
|
||||
void draw_drag(void);
|
||||
void screen_init(void);
|
||||
void screen_early_init(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
// if you increase that, you will also need to update the linker script file
|
||||
#ifdef SAMD21
|
||||
#define APP_START_ADDRESS 0x00002000
|
||||
#define UF2_FAMILY 0x68ed2b88
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
#define APP_START_ADDRESS 0x00004000
|
||||
#define UF2_FAMILY 0x55114460
|
||||
#endif
|
||||
|
||||
#define UF2_MAGIC_START0 0x0A324655UL // "UF2\n"
|
||||
|
|
@ -20,6 +22,10 @@
|
|||
|
||||
// If set, the block is "comment" and should not be flashed to the device
|
||||
#define UF2_FLAG_NOFLASH 0x00000001
|
||||
#define UF2_FLAG_FAMILYID_PRESENT 0x00002000
|
||||
|
||||
#define UF2_IS_MY_FAMILY(bl) \
|
||||
(((bl)->flags & UF2_FLAG_FAMILYID_PRESENT) == 0 || (bl)->familyID == UF2_FAMILY)
|
||||
|
||||
typedef struct {
|
||||
// 32 byte header
|
||||
|
|
@ -30,7 +36,7 @@ typedef struct {
|
|||
uint32_t payloadSize;
|
||||
uint32_t blockNo;
|
||||
uint32_t numBlocks;
|
||||
uint32_t reserved;
|
||||
uint32_t familyID;
|
||||
|
||||
// raw data;
|
||||
uint8_t data[476];
|
||||
|
|
@ -54,7 +60,7 @@ typedef void (*UF2_HID_Handover_Handler)(int ep);
|
|||
|
||||
// this is required to be exactly 16 bytes long by the linker script
|
||||
typedef struct {
|
||||
void *reserved0;
|
||||
const uint32_t *config_data;
|
||||
UF2_HID_Handover_Handler handoverHID;
|
||||
UF2_MSC_Handover_Handler handoverMSC;
|
||||
const char *info_uf2;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct HF2_BININFO_Result {
|
|||
uint32_t flash_page_size;
|
||||
uint32_t flash_num_pages;
|
||||
uint32_t max_message_size;
|
||||
uint32_t uf2_family;
|
||||
};
|
||||
|
||||
#define HF2_CMD_INFO 0x0002
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ static char msOS20Descriptor[] = {
|
|||
//
|
||||
'{', 0, '9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0, '9', 0, 'C', 0,
|
||||
'7', 0, '7', 0, '-', 0, '4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0, '9', 0, '3', 0, '3', 0, 'B', 0,
|
||||
'-', 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0,
|
||||
'-', 0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'B', 0, 'B', 0, '3', 0, 'B', 0,
|
||||
'9', 0, '}', 0, 0, 0, 0, 0};
|
||||
|
||||
STATIC_ASSERT(sizeof(msOS20Descriptor) == WINUSB_SIZE);
|
||||
|
|
|
|||
46
src/fat.c
46
src/fat.c
|
|
@ -72,6 +72,8 @@ const char indexFile[] = //
|
|||
"</html>\n";
|
||||
#endif
|
||||
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and requires it be the last element of the array
|
||||
static const struct TextFile info[] = {
|
||||
{.name = "INFO_UF2TXT", .content = infoUf2File},
|
||||
#if USE_INDEX_HTM
|
||||
|
|
@ -79,11 +81,12 @@ static const struct TextFile info[] = {
|
|||
#endif
|
||||
{.name = "CURRENT UF2"},
|
||||
};
|
||||
#define NUM_INFO (sizeof(info) / sizeof(info[0]))
|
||||
#define NUM_FILES (sizeof(info) / sizeof(info[0]))
|
||||
#define NUM_DIRENTRIES (NUM_FILES + 1) // Code adds volume label as first root directory entry
|
||||
|
||||
#define UF2_SIZE (FLASH_SIZE * 2)
|
||||
#define UF2_SECTORS (UF2_SIZE / 512)
|
||||
#define UF2_FIRST_SECTOR (NUM_INFO + 1)
|
||||
#define UF2_FIRST_SECTOR (NUM_FILES + 1) // WARNING -- code presumes each non-UF2 file content fits in single sector
|
||||
#define UF2_LAST_SECTOR (UF2_FIRST_SECTOR + UF2_SECTORS - 1)
|
||||
#endif
|
||||
|
||||
|
|
@ -96,6 +99,12 @@ static const struct TextFile info[] = {
|
|||
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
|
||||
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
|
||||
|
||||
// all directory entries must fit in a single sector
|
||||
// because otherwise current code overflows buffer
|
||||
#define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
|
||||
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
|
||||
|
||||
|
||||
static const FAT_BootBlock BootBlock = {
|
||||
.JumpInstruction = {0xeb, 0x3c, 0x90},
|
||||
.OEMInfo = "UF2 UF2 ",
|
||||
|
|
@ -103,12 +112,13 @@ static const FAT_BootBlock BootBlock = {
|
|||
.SectorsPerCluster = 1,
|
||||
.ReservedSectors = RESERVED_SECTORS,
|
||||
.FATCopies = 2,
|
||||
.RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32),
|
||||
.RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
|
||||
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
|
||||
.MediaDescriptor = 0xF8,
|
||||
.SectorsPerFAT = SECTORS_PER_FAT,
|
||||
.SectorsPerTrack = 1,
|
||||
.Heads = 1,
|
||||
.PhysicalDriveNum = 0x80, // to match MediaDescriptor of 0xF8
|
||||
.ExtendedBootSig = 0x29,
|
||||
.VolumeSerialNumber = 0x00420042,
|
||||
.VolumeLabel = VOLUME_LABEL,
|
||||
|
|
@ -129,24 +139,27 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
|||
memset(data, 0, 512);
|
||||
uint32_t sectionIdx = block_no;
|
||||
|
||||
if (block_no == 0) {
|
||||
if (block_no == 0) { // Requested boot block
|
||||
memcpy(data, &BootBlock, sizeof(BootBlock));
|
||||
data[510] = 0x55;
|
||||
data[511] = 0xaa;
|
||||
// logval("data[0]", data[0]);
|
||||
} else if (block_no < START_ROOTDIR) {
|
||||
} else if (block_no < START_ROOTDIR) { // Requested FAT table sector
|
||||
sectionIdx -= START_FAT0;
|
||||
// logval("sidx", sectionIdx);
|
||||
if (sectionIdx >= SECTORS_PER_FAT)
|
||||
sectionIdx -= SECTORS_PER_FAT;
|
||||
sectionIdx -= SECTORS_PER_FAT; // second FAT is same as the first...
|
||||
#if USE_FAT
|
||||
if (sectionIdx == 0) {
|
||||
data[0] = 0xf0;
|
||||
for (int i = 1; i < NUM_INFO * 2 + 4; ++i) {
|
||||
// WARNING -- code presumes only one NULL .content for .UF2 file
|
||||
// and all non-NULL .content fit in one sector
|
||||
// and requires it be the last element of the array
|
||||
for (int i = 1; i < NUM_FILES * 2 + 4; ++i) {
|
||||
data[i] = 0xff;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
for (int i = 0; i < 256; ++i) { // Generate the FAT chain for the firmware "file"
|
||||
uint32_t v = sectionIdx * 256 + i;
|
||||
if (UF2_FIRST_SECTOR <= v && v <= UF2_LAST_SECTOR)
|
||||
((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1;
|
||||
|
|
@ -157,26 +170,29 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
|||
#endif
|
||||
}
|
||||
#if USE_FAT
|
||||
else if (block_no < START_CLUSTERS) {
|
||||
else if (block_no < START_CLUSTERS) { // Requested sector of the root directory
|
||||
sectionIdx -= START_ROOTDIR;
|
||||
if (sectionIdx == 0) {
|
||||
DirEntry *d = (void *)data;
|
||||
padded_memcpy(d->name, BootBlock.VolumeLabel, 11);
|
||||
d->attrs = 0x28;
|
||||
for (int i = 0; i < NUM_INFO; ++i) {
|
||||
for (int i = 0; i < NUM_FILES; ++i) {
|
||||
d++;
|
||||
const struct TextFile *inf = &info[i];
|
||||
d->size = inf->content ? strlen(inf->content) : UF2_SIZE;
|
||||
d->startCluster = i + 2;
|
||||
padded_memcpy(d->name, inf->name, 11);
|
||||
d->createDate = 0x4d99;
|
||||
d->updateDate = 0x4d99;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else { // Requested sector from file space
|
||||
sectionIdx -= START_CLUSTERS;
|
||||
if (sectionIdx < NUM_INFO - 1) {
|
||||
// WARNING -- code presumes all but last file take exactly one sector
|
||||
if (sectionIdx < NUM_FILES - 1) {
|
||||
memcpy(data, info[sectionIdx].content, strlen(info[sectionIdx].content));
|
||||
} else {
|
||||
sectionIdx -= NUM_INFO - 1;
|
||||
sectionIdx -= NUM_FILES - 1;
|
||||
uint32_t addr = sectionIdx * 256;
|
||||
if (addr < FLASH_SIZE) {
|
||||
UF2_Block *bl = (void *)data;
|
||||
|
|
@ -187,6 +203,8 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
|||
bl->numBlocks = FLASH_SIZE / 256;
|
||||
bl->targetAddr = addr;
|
||||
bl->payloadSize = 256;
|
||||
bl->flags |= UF2_FLAG_FAMILYID_PRESENT;
|
||||
bl->familyID = UF2_FAMILY;
|
||||
memcpy(bl->data, (void *)addr, bl->payloadSize);
|
||||
}
|
||||
}
|
||||
|
|
@ -196,7 +214,7 @@ void read_block(uint32_t block_no, uint8_t *data) {
|
|||
|
||||
void write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state) {
|
||||
UF2_Block *bl = (void *)data;
|
||||
if (!is_uf2_block(bl)) {
|
||||
if (!is_uf2_block(bl) || !UF2_IS_MY_FAMILY(bl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ void process_core(HID_InBuffer *pkt) {
|
|||
resp->bininfo.flash_page_size = FLASH_ROW_SIZE;
|
||||
resp->bininfo.flash_num_pages = FLASH_SIZE / FLASH_ROW_SIZE;
|
||||
resp->bininfo.max_message_size = sizeof(pkt->buf);
|
||||
resp->bininfo.uf2_family = UF2_FAMILY;
|
||||
send_hf2_response(pkt, sizeof(resp->bininfo));
|
||||
return;
|
||||
|
||||
|
|
|
|||
118
src/images.c
Normal file
118
src/images.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#include <stdint.h>
|
||||
|
||||
// all https://makecode.com/_VrfEKzV4xfvq
|
||||
|
||||
// https://makecode.com/_7VxXm3JMPXfM - file
|
||||
// https://makecode.com/_LuEUCsPEKUbs - download
|
||||
const uint8_t fileLogo[] = {
|
||||
32, 32, 71, 140, 201, 151, 1, 2, 146, 1, 2, 146, 63, 2, 151, 9, 153, 9, 153, 9, 146, 1, 9, 146, 3, 9, 146, 7, 9, 137, 205, 72, 140, 206, 36, 139, 207, 18, 138, 206, 36, 139, 205, 72, 149, 7, 9, 146, 3, 9, 146, 1, 9, 153, 9, 153, 9, 153, 9, 148, 63, 2, 146, 1, 2, 146, 1, 2, 146, 201, 191, 191, 191, 174
|
||||
};
|
||||
|
||||
// https://makecode.com/_9b0RcK5yRa12
|
||||
const uint8_t pendriveLogo[] = {
|
||||
32, 32, 59, 137, 215, 137, 1, 143, 1, 8, 146, 203, 149, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 115, 8, 146, 115, 8, 146, 3, 8, 146, 3, 8, 146, 203, 149, 1, 8, 146, 1, 8, 146, 1, 120, 211, 191, 191, 191, 191, 191, 191, 191, 135
|
||||
};
|
||||
|
||||
// https://makecode.com/_TTqbj705L4mr
|
||||
const uint8_t arrowLogo[] = {
|
||||
32, 32, 54, 137, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 151, 201, 146, 211, 142, 209, 144, 207, 146, 205, 148, 203, 150, 201, 152, 199, 154, 31, 154, 7, 154, 1, 191, 191, 191, 175
|
||||
};
|
||||
|
||||
const uint8_t font8[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00,
|
||||
0x28, 0xfe, 0x28, 0xfe, 0x28, 0x00,
|
||||
0x4c, 0x92, 0xff, 0x92, 0x64, 0x00,
|
||||
0x02, 0x65, 0x12, 0x48, 0xa6, 0x40,
|
||||
0x6c, 0x92, 0x92, 0x6c, 0xa0, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0x82, 0x00, 0x00,
|
||||
0x00, 0x00, 0x82, 0x7c, 0x00, 0x00,
|
||||
0x54, 0x38, 0x10, 0x38, 0x54, 0x00,
|
||||
0x10, 0x10, 0x7c, 0x10, 0x10, 0x00,
|
||||
0x00, 0x00, 0x90, 0x70, 0x00, 0x00,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
|
||||
0x00, 0x60, 0x10, 0x08, 0x06, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x44, 0x7e, 0x40, 0x00, 0x00,
|
||||
0x00, 0x44, 0x62, 0x52, 0x4c, 0x00,
|
||||
0x00, 0x42, 0x4a, 0x4e, 0x32, 0x00,
|
||||
0x30, 0x28, 0x24, 0x7e, 0x20, 0x00,
|
||||
0x00, 0x4e, 0x4a, 0x4a, 0x32, 0x00,
|
||||
0x00, 0x3c, 0x4a, 0x4a, 0x30, 0x00,
|
||||
0x00, 0x02, 0x62, 0x12, 0x0e, 0x00,
|
||||
0x00, 0x34, 0x4a, 0x4a, 0x34, 0x00,
|
||||
0x00, 0x0c, 0x52, 0x52, 0x3c, 0x00,
|
||||
0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x96, 0x76, 0x00, 0x00,
|
||||
0x10, 0x28, 0x28, 0x44, 0x44, 0x00,
|
||||
0x28, 0x28, 0x28, 0x28, 0x28, 0x00,
|
||||
0x44, 0x44, 0x28, 0x28, 0x10, 0x00,
|
||||
0x00, 0x02, 0x59, 0x09, 0x06, 0x00,
|
||||
0x3c, 0x42, 0x5a, 0x56, 0x08, 0x00,
|
||||
0x78, 0x14, 0x12, 0x14, 0x78, 0x00,
|
||||
0x7e, 0x4a, 0x4a, 0x4a, 0x34, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x42, 0x24, 0x00,
|
||||
0x00, 0x7e, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x7e, 0x4a, 0x4a, 0x42, 0x00,
|
||||
0x00, 0x7e, 0x0a, 0x0a, 0x02, 0x00,
|
||||
0x00, 0x3c, 0x42, 0x52, 0x34, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x08, 0x7e, 0x00,
|
||||
0x00, 0x42, 0x7e, 0x42, 0x00, 0x00,
|
||||
0x20, 0x40, 0x42, 0x3e, 0x02, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x14, 0x62, 0x00,
|
||||
0x00, 0x7e, 0x40, 0x40, 0x40, 0x00,
|
||||
0x7e, 0x04, 0x18, 0x04, 0x7e, 0x00,
|
||||
0x00, 0x7e, 0x04, 0x08, 0x7e, 0x00,
|
||||
0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00,
|
||||
0x00, 0x7e, 0x12, 0x12, 0x0c, 0x00,
|
||||
0x00, 0x3c, 0x52, 0x62, 0xbc, 0x00,
|
||||
0x00, 0x7e, 0x12, 0x12, 0x6c, 0x00,
|
||||
0x00, 0x24, 0x4a, 0x52, 0x24, 0x00,
|
||||
0x02, 0x02, 0x7e, 0x02, 0x02, 0x00,
|
||||
0x00, 0x3e, 0x40, 0x40, 0x3e, 0x00,
|
||||
0x00, 0x1e, 0x70, 0x70, 0x1e, 0x00,
|
||||
0x7e, 0x20, 0x18, 0x20, 0x7e, 0x00,
|
||||
0x42, 0x24, 0x18, 0x24, 0x42, 0x00,
|
||||
0x06, 0x08, 0x70, 0x08, 0x06, 0x00,
|
||||
0x00, 0x62, 0x52, 0x4a, 0x46, 0x00,
|
||||
0x00, 0x7e, 0x42, 0x42, 0x00, 0x00,
|
||||
0x00, 0x06, 0x08, 0x10, 0x60, 0x00,
|
||||
0x00, 0x42, 0x42, 0x7e, 0x00, 0x00,
|
||||
0x08, 0x04, 0x02, 0x04, 0x08, 0x00,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
|
||||
0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x78, 0x00,
|
||||
0x00, 0x7e, 0x48, 0x48, 0x30, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x48, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x7e, 0x00,
|
||||
0x00, 0x30, 0x68, 0x58, 0x50, 0x00,
|
||||
0x00, 0x10, 0x7c, 0x12, 0x04, 0x00,
|
||||
0x00, 0x18, 0xa4, 0xa4, 0x78, 0x00,
|
||||
0x00, 0x7e, 0x08, 0x08, 0x70, 0x00,
|
||||
0x00, 0x48, 0x7a, 0x40, 0x00, 0x00,
|
||||
0x00, 0x40, 0x84, 0x7d, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x10, 0x28, 0x40, 0x00,
|
||||
0x00, 0x42, 0x7e, 0x40, 0x00, 0x00,
|
||||
0x78, 0x08, 0x30, 0x08, 0x70, 0x00,
|
||||
0x00, 0x78, 0x08, 0x08, 0x70, 0x00,
|
||||
0x00, 0x30, 0x48, 0x48, 0x30, 0x00,
|
||||
0x00, 0xfc, 0x24, 0x24, 0x18, 0x00,
|
||||
0x00, 0x18, 0x24, 0x24, 0xfc, 0x00,
|
||||
0x00, 0x78, 0x10, 0x08, 0x10, 0x00,
|
||||
0x00, 0x50, 0x58, 0x68, 0x28, 0x00,
|
||||
0x00, 0x08, 0x3e, 0x48, 0x20, 0x00,
|
||||
0x00, 0x38, 0x40, 0x40, 0x78, 0x00,
|
||||
0x00, 0x18, 0x60, 0x60, 0x18, 0x00,
|
||||
0x38, 0x40, 0x30, 0x40, 0x38, 0x00,
|
||||
0x00, 0x48, 0x30, 0x30, 0x48, 0x00,
|
||||
0x00, 0x5c, 0xa0, 0xa0, 0x7c, 0x00,
|
||||
0x00, 0x48, 0x68, 0x58, 0x48, 0x00,
|
||||
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
|
||||
0x00, 0x08, 0x04, 0x08, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
21
src/main.c
21
src/main.c
|
|
@ -72,7 +72,7 @@
|
|||
* to use the interrupt vectors of the application @0x2000.<- not required as
|
||||
* application code is taking care of this
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "uf2.h"
|
||||
|
||||
|
|
@ -109,13 +109,12 @@ static void check_start_application(void) {
|
|||
|
||||
#if USE_SINGLE_RESET
|
||||
if (SINGLE_RESET()) {
|
||||
if (RESET_CONTROLLER->RCAUSE.bit.POR ||
|
||||
*DBL_TAP_PTR != DBL_TAP_MAGIC_QUICK_BOOT) {
|
||||
if (RESET_CONTROLLER->RCAUSE.bit.POR || *DBL_TAP_PTR != DBL_TAP_MAGIC_QUICK_BOOT) {
|
||||
// the second tap on reset will go into app
|
||||
*DBL_TAP_PTR = DBL_TAP_MAGIC_QUICK_BOOT;
|
||||
// this will be cleared after succesful USB enumeration
|
||||
// this is around 1.5s
|
||||
resetHorizon = timerHigh + 300;
|
||||
resetHorizon = timerHigh + 50;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +161,7 @@ int main(void) {
|
|||
while (1) {
|
||||
}
|
||||
|
||||
#if (USB_VID == 0x239a) && (USB_PID == 0x0013) // Adafruit Metro M0
|
||||
#if (USB_VID == 0x239a) && (USB_PID == 0x0013) // Adafruit Metro M0
|
||||
// Delay a bit so SWD programmer can have time to attach.
|
||||
delay(15);
|
||||
#endif
|
||||
|
|
@ -209,6 +208,11 @@ int main(void) {
|
|||
#endif
|
||||
RGBLED_set_color(COLOR_USB);
|
||||
led_tick_step = 1;
|
||||
|
||||
#if USE_SCREEN
|
||||
screen_init();
|
||||
draw_drag();
|
||||
#endif
|
||||
}
|
||||
|
||||
main_b_cdc_enable = true;
|
||||
|
|
@ -240,5 +244,12 @@ int main(void) {
|
|||
process_msc();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!main_b_cdc_enable) {
|
||||
// get more predictable timings before the USB is enumerated
|
||||
for (int i = 1; i < 256; ++i) {
|
||||
asm("nop");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#define DEFINE_CONFIG_DATA 1
|
||||
|
||||
#include "uf2.h"
|
||||
|
||||
#include "lib/usb_msc/sbc_protocol.h"
|
||||
|
|
@ -864,6 +866,9 @@ static void handover(UF2_HandoverArgs *args) {
|
|||
#endif
|
||||
|
||||
__attribute__((section(".binfo"))) __attribute__((__used__)) const UF2_BInfo binfo = {
|
||||
#ifdef HAS_CONFIG_DATA
|
||||
.config_data = config_data,
|
||||
#endif
|
||||
#if USE_MSC_HANDOVER
|
||||
.handoverMSC = handover,
|
||||
#endif
|
||||
|
|
|
|||
455
src/screen.c
Normal file
455
src/screen.c
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
#include "uf2.h"
|
||||
|
||||
#if USE_SCREEN
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define DISPLAY_WIDTH 160
|
||||
#define DISPLAY_HEIGHT 128
|
||||
|
||||
#define ST7735_NOP 0x00
|
||||
#define ST7735_SWRESET 0x01
|
||||
#define ST7735_RDDID 0x04
|
||||
#define ST7735_RDDST 0x09
|
||||
|
||||
#define ST7735_SLPIN 0x10
|
||||
#define ST7735_SLPOUT 0x11
|
||||
#define ST7735_PTLON 0x12
|
||||
#define ST7735_NORON 0x13
|
||||
|
||||
#define ST7735_INVOFF 0x20
|
||||
#define ST7735_INVON 0x21
|
||||
#define ST7735_DISPOFF 0x28
|
||||
#define ST7735_DISPON 0x29
|
||||
#define ST7735_CASET 0x2A
|
||||
#define ST7735_RASET 0x2B
|
||||
#define ST7735_RAMWR 0x2C
|
||||
#define ST7735_RAMRD 0x2E
|
||||
|
||||
#define ST7735_PTLAR 0x30
|
||||
#define ST7735_COLMOD 0x3A
|
||||
#define ST7735_MADCTL 0x36
|
||||
|
||||
#define ST7735_FRMCTR1 0xB1
|
||||
#define ST7735_FRMCTR2 0xB2
|
||||
#define ST7735_FRMCTR3 0xB3
|
||||
#define ST7735_INVCTR 0xB4
|
||||
#define ST7735_DISSET5 0xB6
|
||||
|
||||
#define ST7735_PWCTR1 0xC0
|
||||
#define ST7735_PWCTR2 0xC1
|
||||
#define ST7735_PWCTR3 0xC2
|
||||
#define ST7735_PWCTR4 0xC3
|
||||
#define ST7735_PWCTR5 0xC4
|
||||
#define ST7735_VMCTR1 0xC5
|
||||
|
||||
#define ST7735_RDID1 0xDA
|
||||
#define ST7735_RDID2 0xDB
|
||||
#define ST7735_RDID3 0xDC
|
||||
#define ST7735_RDID4 0xDD
|
||||
|
||||
#define ST7735_PWCTR6 0xFC
|
||||
|
||||
#define ST7735_GMCTRP1 0xE0
|
||||
#define ST7735_GMCTRN1 0xE1
|
||||
|
||||
uint32_t lookupCfg(uint32_t key, uint32_t defl);
|
||||
#define CFG(v) lookupCfg(CFG_##v, 0x42)
|
||||
|
||||
uint32_t lookupCfg(uint32_t key, uint32_t defl) {
|
||||
const uint32_t *ptr = UF2_BINFO->config_data;
|
||||
if (!ptr || (((uint32_t)ptr) & 3) || *ptr != CFG_MAGIC0) {
|
||||
// no config data!
|
||||
} else {
|
||||
ptr += 4;
|
||||
while (*ptr) {
|
||||
if (*ptr == key)
|
||||
return ptr[1];
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
if (defl == 0x42)
|
||||
while (1)
|
||||
;
|
||||
return defl;
|
||||
}
|
||||
|
||||
void pin_set(int pincfg, int v) {
|
||||
int pin = lookupCfg(pincfg, -1);
|
||||
if (pin < 0)
|
||||
return;
|
||||
if (v) {
|
||||
PINOP(pin, OUTSET);
|
||||
} else {
|
||||
PINOP(pin, OUTCLR);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_output_pin(int pincfg) {
|
||||
int pin = lookupCfg(pincfg, -1);
|
||||
if (pin < 0)
|
||||
return;
|
||||
PINOP(pin, DIRSET);
|
||||
PINOP(pin, OUTCLR);
|
||||
}
|
||||
|
||||
#define PINPORT(pin) PORT->Group[(pin) / 32]
|
||||
#define pinmask(pin) (1 << (pin & 0x1f))
|
||||
|
||||
void transfer(uint8_t *ptr, uint32_t len) {
|
||||
int mosi = CFG(PIN_DISPLAY_MOSI);
|
||||
int sck = CFG(PIN_DISPLAY_SCK);
|
||||
|
||||
volatile uint32_t *mosi_set = &PINPORT(mosi).OUTSET.reg;
|
||||
volatile uint32_t *mosi_clr = &PINPORT(mosi).OUTCLR.reg;
|
||||
volatile uint32_t *sck_tgl = &PINPORT(sck).OUTTGL.reg;
|
||||
|
||||
uint32_t mosi_mask = pinmask(mosi);
|
||||
uint32_t sck_mask = pinmask(sck);
|
||||
|
||||
PINOP(sck, OUTCLR);
|
||||
|
||||
uint8_t mask = 0, b;
|
||||
for (;;) {
|
||||
if (!mask) {
|
||||
if (!len--)
|
||||
break;
|
||||
mask = 0x80;
|
||||
b = *ptr++;
|
||||
}
|
||||
if (b & mask)
|
||||
*mosi_set = mosi_mask;
|
||||
else
|
||||
*mosi_clr = mosi_mask;
|
||||
*sck_tgl = sck_mask;
|
||||
mask >>= 1;
|
||||
*sck_tgl = sck_mask;
|
||||
}
|
||||
}
|
||||
|
||||
#define DELAY 0x80
|
||||
|
||||
// clang-format off
|
||||
static const uint8_t initCmds[] = {
|
||||
ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay
|
||||
120, // 150 ms delay
|
||||
ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay
|
||||
120, // 500 ms delay
|
||||
ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay
|
||||
ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay:
|
||||
0x05, // 16-bit color
|
||||
ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay:
|
||||
0x02, 0x1c, 0x07, 0x12,
|
||||
0x37, 0x32, 0x29, 0x2d,
|
||||
0x29, 0x25, 0x2B, 0x39,
|
||||
0x00, 0x01, 0x03, 0x10,
|
||||
ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay
|
||||
10, // 10 ms delay
|
||||
ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay
|
||||
10,
|
||||
0, 0 // END
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static uint8_t cmdBuf[20];
|
||||
|
||||
#define SET_DC(v) pin_set(CFG_PIN_DISPLAY_DC, v)
|
||||
#define SET_CS(v) pin_set(CFG_PIN_DISPLAY_CS, v)
|
||||
|
||||
static void scr_delay(unsigned msec) {
|
||||
int k = msec * 15000;
|
||||
while (k--)
|
||||
asm("nop");
|
||||
}
|
||||
|
||||
static void sendCmd(uint8_t *buf, int len) {
|
||||
// make sure cmd isn't on stack
|
||||
if (buf != cmdBuf)
|
||||
memcpy(cmdBuf, buf, len);
|
||||
buf = cmdBuf;
|
||||
|
||||
SET_DC(0);
|
||||
SET_CS(0);
|
||||
|
||||
transfer(buf, 1);
|
||||
|
||||
SET_DC(1);
|
||||
|
||||
len--;
|
||||
buf++;
|
||||
if (len > 0)
|
||||
transfer(buf, len);
|
||||
|
||||
SET_CS(1);
|
||||
}
|
||||
|
||||
static void sendCmdSeq(const uint8_t *buf) {
|
||||
while (*buf) {
|
||||
cmdBuf[0] = *buf++;
|
||||
int v = *buf++;
|
||||
int len = v & ~DELAY;
|
||||
// note that we have to copy to RAM
|
||||
memcpy(cmdBuf + 1, buf, len);
|
||||
sendCmd(cmdBuf, len + 1);
|
||||
buf += len;
|
||||
if (v & DELAY) {
|
||||
scr_delay(*buf++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t palXOR;
|
||||
|
||||
static void setAddrWindow(int x, int y, int w, int h) {
|
||||
uint8_t cmd0[] = {ST7735_RASET, 0, (uint8_t)x, 0, (uint8_t)(x + w - 1)};
|
||||
uint8_t cmd1[] = {ST7735_CASET, 0, (uint8_t)y, 0, (uint8_t)(y + h - 1)};
|
||||
sendCmd(cmd1, sizeof(cmd1));
|
||||
sendCmd(cmd0, sizeof(cmd0));
|
||||
}
|
||||
|
||||
static void configure(uint8_t madctl, uint32_t frmctr1) {
|
||||
uint8_t cmd0[] = {ST7735_MADCTL, madctl};
|
||||
uint8_t cmd1[] = {ST7735_FRMCTR1, (uint8_t)(frmctr1 >> 16), (uint8_t)(frmctr1 >> 8),
|
||||
(uint8_t)frmctr1};
|
||||
sendCmd(cmd0, sizeof(cmd0));
|
||||
sendCmd(cmd1, cmd1[3] == 0xff ? 3 : 4);
|
||||
}
|
||||
|
||||
#define COL0(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
|
||||
#define COL(c) COL0((c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
|
||||
|
||||
const uint16_t palette[] = {
|
||||
COL(0x000000), // 0
|
||||
COL(0xffffff), // 1
|
||||
COL(0xff2121), // 2
|
||||
COL(0xff93c4), // 3
|
||||
COL(0xff8135), // 4
|
||||
COL(0xfff609), // 5
|
||||
COL(0x249ca3), // 6
|
||||
COL(0x78dc52), // 7
|
||||
COL(0x003fad), // 8
|
||||
COL(0x87f2ff), // 9
|
||||
COL(0x8e2ec4), // 10
|
||||
COL(0xa4839f), // 11
|
||||
COL(0x5c406c), // 12
|
||||
COL(0xe5cdc4), // 13
|
||||
COL(0x91463d), // 14
|
||||
COL(0x000000), // 15
|
||||
};
|
||||
|
||||
uint8_t fb[168 * 128];
|
||||
extern const uint8_t font8[];
|
||||
extern const uint8_t fileLogo[];
|
||||
extern const uint8_t pendriveLogo[];
|
||||
extern const uint8_t arrowLogo[];
|
||||
|
||||
static void printch(int x, int y, int col, const uint8_t *fnt) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
uint8_t *p = fb + (x + i) * DISPLAY_HEIGHT + y;
|
||||
uint8_t mask = 0x01;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
if (*fnt & mask)
|
||||
*p = col;
|
||||
p++;
|
||||
mask <<= 1;
|
||||
}
|
||||
fnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static void printch4(int x, int y, int col, const uint8_t *fnt) {
|
||||
for (int i = 0; i < 6 * 4; ++i) {
|
||||
uint8_t *p = fb + (x + i) * DISPLAY_HEIGHT + y;
|
||||
uint8_t mask = 0x01;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
if (*fnt & mask)
|
||||
*p = col;
|
||||
p++;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
if ((i & 3) == 3)
|
||||
fnt++;
|
||||
}
|
||||
}
|
||||
|
||||
void printicon(int x, int y, int col, const uint8_t *icon) {
|
||||
int w = *icon++;
|
||||
int h = *icon++;
|
||||
int sz = *icon++;
|
||||
|
||||
uint8_t mask = 0x80;
|
||||
int runlen = 0;
|
||||
int runbit = 0;
|
||||
uint8_t lastb = 0x00;
|
||||
|
||||
for (int i = 0; i < w; ++i) {
|
||||
uint8_t *p = fb + (x + i) * DISPLAY_HEIGHT + y;
|
||||
for (int j = 0; j < h; ++j) {
|
||||
int c = 0;
|
||||
if (mask != 0x80) {
|
||||
if (lastb & mask)
|
||||
c = 1;
|
||||
mask <<= 1;
|
||||
} else if (runlen) {
|
||||
if (runbit)
|
||||
c = 1;
|
||||
runlen--;
|
||||
} else {
|
||||
if (sz-- <= 0)
|
||||
panic(10);
|
||||
lastb = *icon++;
|
||||
if (lastb & 0x80) {
|
||||
runlen = lastb & 63;
|
||||
runbit = lastb & 0x40;
|
||||
} else {
|
||||
mask = 0x01;
|
||||
}
|
||||
--j;
|
||||
continue; // restart
|
||||
}
|
||||
if (c)
|
||||
*p = col;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print(int x, int y, int col, const char *text) {
|
||||
int x0 = x;
|
||||
while (*text) {
|
||||
char c = *text++;
|
||||
if (c == '\r')
|
||||
continue;
|
||||
if (c == '\n') {
|
||||
x = x0;
|
||||
y += 10;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
if (x + 8 > DISPLAY_WIDTH) {
|
||||
x = x0;
|
||||
y += 10;
|
||||
}
|
||||
*/
|
||||
if (c < ' ')
|
||||
c = '?';
|
||||
if (c >= 0x7f)
|
||||
c = '?';
|
||||
c -= ' ';
|
||||
printch(x, y, col, &font8[c * 6]);
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
void print4(int x, int y, int col, const char *text) {
|
||||
while (*text) {
|
||||
char c = *text++;
|
||||
c -= ' ';
|
||||
printch4(x, y, col, &font8[c * 6]);
|
||||
x += 6 * 4;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_screen() {
|
||||
if (lookupCfg(CFG_PIN_DISPLAY_SCK, 1000) == 1000)
|
||||
return;
|
||||
|
||||
cmdBuf[0] = ST7735_RAMWR;
|
||||
sendCmd(cmdBuf, 1);
|
||||
|
||||
SET_DC(1);
|
||||
SET_CS(0);
|
||||
|
||||
uint8_t *p = fb;
|
||||
for (int i = 0; i < DISPLAY_WIDTH; ++i) {
|
||||
uint8_t cc[DISPLAY_HEIGHT * 2];
|
||||
uint32_t dst = 0;
|
||||
for (int j = 0; j < DISPLAY_HEIGHT; ++j) {
|
||||
uint16_t color = palette[*p++ & 0xf];
|
||||
cc[dst++] = color >> 8;
|
||||
cc[dst++] = color & 0xff;
|
||||
}
|
||||
transfer(cc, sizeof(cc));
|
||||
}
|
||||
|
||||
SET_CS(1);
|
||||
}
|
||||
|
||||
void drawBar(int y, int h, int c) {
|
||||
for (int x = 0; x < DISPLAY_WIDTH; ++x) {
|
||||
memset(fb + x * DISPLAY_HEIGHT + y, c, h);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_hf2() {
|
||||
print4(20, 22, 5, "<-->");
|
||||
print(40, 110, 7, "flashing...");
|
||||
draw_screen();
|
||||
}
|
||||
|
||||
void draw_drag() {
|
||||
drawBar(0, 52, 7);
|
||||
drawBar(52, 55, 8);
|
||||
drawBar(107, 14, 4);
|
||||
|
||||
print4(108, 5, 1, "D5");
|
||||
print(112, 40, 6, UF2_VERSION_BASE);
|
||||
print(23, 110, 1, "arcade.makecode.com");
|
||||
|
||||
#define DRAG 70
|
||||
#define DRAGX 10
|
||||
printicon(DRAGX + 20, DRAG + 5, 1, fileLogo);
|
||||
printicon(DRAGX + 66, DRAG, 1, arrowLogo);
|
||||
printicon(DRAGX + 108, DRAG, 1, pendriveLogo);
|
||||
print(10, DRAG - 12, 1, "arcade.uf2");
|
||||
print(98, DRAG - 12, 1, "ARCADE-D5");
|
||||
|
||||
draw_screen();
|
||||
}
|
||||
|
||||
void screen_early_init() {
|
||||
setup_output_pin(CFG_PIN_DISPLAY_BL);
|
||||
}
|
||||
|
||||
void screen_init() {
|
||||
if (lookupCfg(CFG_PIN_DISPLAY_SCK, 1000) == 1000)
|
||||
return;
|
||||
|
||||
setup_output_pin(CFG_PIN_DISPLAY_SCK);
|
||||
setup_output_pin(CFG_PIN_DISPLAY_MOSI);
|
||||
setup_output_pin(CFG_PIN_DISPLAY_BL);
|
||||
setup_output_pin(CFG_PIN_DISPLAY_DC);
|
||||
setup_output_pin(CFG_PIN_DISPLAY_RST);
|
||||
setup_output_pin(CFG_PIN_DISPLAY_CS);
|
||||
|
||||
SET_CS(1);
|
||||
SET_DC(1);
|
||||
|
||||
pin_set(CFG_PIN_DISPLAY_BL, 1);
|
||||
|
||||
pin_set(CFG_PIN_DISPLAY_RST, 0);
|
||||
scr_delay(20);
|
||||
pin_set(CFG_PIN_DISPLAY_RST, 1);
|
||||
scr_delay(20);
|
||||
|
||||
sendCmdSeq(initCmds);
|
||||
|
||||
uint32_t cfg0 = CFG(DISPLAY_CFG0);
|
||||
//uint32_t cfg2 = CFG(DISPLAY_CFG2);
|
||||
uint32_t frmctr1 = CFG(DISPLAY_CFG1);
|
||||
palXOR = (cfg0 & 0x1000000) ? 0xffffff : 0x000000;
|
||||
uint32_t madctl = cfg0 & 0xff;
|
||||
uint32_t offX = (cfg0 >> 8) & 0xff;
|
||||
uint32_t offY = (cfg0 >> 16) & 0xff;
|
||||
//uint32_t freq = (cfg2 & 0xff);
|
||||
|
||||
// DMESG("configure screen: FRMCTR1=%p MADCTL=%p SPI at %dMHz", frmctr1, madctl, freq);
|
||||
configure(madctl, frmctr1);
|
||||
setAddrWindow(offX, offY, CFG(DISPLAY_WIDTH), CFG(DISPLAY_HEIGHT));
|
||||
|
||||
memset(fb, 0, sizeof(fb));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -47,15 +47,37 @@ void setBootProt(int v) {
|
|||
fuses[0] = *((uint32_t *)NVM_FUSE_ADDR);
|
||||
fuses[1] = *(((uint32_t *)NVM_FUSE_ADDR) + 1);
|
||||
|
||||
bool repair_fuses = false;
|
||||
// Check for damaged fuses. If the NVM user page was accidentally erased, there
|
||||
// will be 1's in wrong places. This would enable the watchdog timer and cause other
|
||||
// problems. So check for all ones outside of the SAMD21/51 BOOTPROT fields, or all ones
|
||||
// in fuses[1]. If it appears the fuses page was erased, replace fuses with reasonable values.
|
||||
if ((fuses[0] & 0x03fffff0) == 0x03fffff0 || fuses[1] == 0xffffffff) {
|
||||
repair_fuses = true;
|
||||
|
||||
// These canonical fuse values taken from working Adafruit SAMD21 and SAMD51 boards.
|
||||
#ifdef SAMD21
|
||||
fuses[0] = 0xD8E0C7FA;
|
||||
fuses[1] = 0xFFFFFC5D;
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
fuses[0] = 0xF69A9239;
|
||||
fuses[1] = 0xAEECFF80;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t bootprot = (fuses[0] & NVMCTRL_FUSES_BOOTPROT_Msk) >> NVMCTRL_FUSES_BOOTPROT_Pos;
|
||||
|
||||
logval("repair_fuses", repair_fuses);
|
||||
logval("fuse0", fuses[0]);
|
||||
logval("fuse1", fuses[1]);
|
||||
logval("bootprot", bootprot);
|
||||
logval("needed", v);
|
||||
|
||||
if (bootprot == v)
|
||||
// Don't write if nothing will be changed.
|
||||
if (bootprot == v && !repair_fuses) {
|
||||
return;
|
||||
}
|
||||
|
||||
fuses[0] = (fuses[0] & ~NVMCTRL_FUSES_BOOTPROT_Msk) | (v << NVMCTRL_FUSES_BOOTPROT_Pos);
|
||||
|
||||
|
|
@ -102,14 +124,15 @@ int main(void) {
|
|||
logmsg("Before main loop");
|
||||
|
||||
#ifdef SAMD21
|
||||
setBootProt(7); // 0k
|
||||
// Disable BOOTPROT while updating bootloader.
|
||||
setBootProt(7); // 0k - See "Table 22-2 Boot Loader Size" in datasheet.
|
||||
#endif
|
||||
#ifdef SAMD51
|
||||
// We only need to set the BOOTPROT once on the SAMD51. For updates, we can
|
||||
// temporarily turn the protection off instead.
|
||||
if (NVMCTRL->STATUS.bit.BOOTPROT != 13) {
|
||||
setBootProt(13); // 16k
|
||||
}
|
||||
// setBootProt() will only write BOOTPROT if it is not already correct.
|
||||
// setBootProt() will also fix the fuse values if they appear to be all ones.
|
||||
setBootProt(13); // 16k. See "Table 25-10 Boot Loader Size" in datasheet.
|
||||
exec_cmd(NVMCTRL_CTRLB_CMD_SBPDIS);
|
||||
NVMCTRL->CTRLA.bit.CACHEDIS0 = true;
|
||||
NVMCTRL->CTRLA.bit.CACHEDIS1 = true;
|
||||
|
|
@ -155,6 +178,7 @@ int main(void) {
|
|||
LED_MSC_OFF();
|
||||
|
||||
#ifdef SAMD21
|
||||
// Re-enable BOOTPROT
|
||||
setBootProt(2); // 8k
|
||||
#endif
|
||||
// For the SAMD51, the boot protection will automatically be re-enabled on
|
||||
|
|
|
|||
19
src/utils.c
19
src/utils.c
|
|
@ -5,14 +5,14 @@ static uint32_t timerLow;
|
|||
uint32_t timerHigh, resetHorizon;
|
||||
|
||||
void delay(uint32_t ms) {
|
||||
// SAMD21 starts up at 1mhz by default.
|
||||
#ifdef SAMD21
|
||||
// SAMD21 starts up at 1mhz by default.
|
||||
#ifdef SAMD21
|
||||
ms <<= 8;
|
||||
#endif
|
||||
// SAMD51 starts up at 48mhz by default.
|
||||
#ifdef SAMD51
|
||||
#endif
|
||||
// SAMD51 starts up at 48mhz by default.
|
||||
#ifdef SAMD51
|
||||
ms <<= 12;
|
||||
#endif
|
||||
#endif
|
||||
for (int i = 1; i < ms; ++i) {
|
||||
asm("nop");
|
||||
}
|
||||
|
|
@ -141,7 +141,9 @@ void led_signal() {
|
|||
}
|
||||
|
||||
void led_init() {
|
||||
#if defined(LED_PIN)
|
||||
PINOP(LED_PIN, DIRSET);
|
||||
#endif
|
||||
LED_MSC_ON();
|
||||
|
||||
#if defined(BOARD_RGBLED_CLOCK_PIN)
|
||||
|
|
@ -152,6 +154,11 @@ void led_init() {
|
|||
// This won't work for neopixel, because we're running at 1MHz or thereabouts...
|
||||
RGBLED_set_color(COLOR_LEAVE);
|
||||
#endif
|
||||
|
||||
#if USE_SCREEN
|
||||
// turn display backlight
|
||||
screen_early_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOARD_RGBLED_CLOCK_PIN)
|
||||
|
|
|
|||
Loading…
Reference in a new issue