Miscellaneous updates

remove sparkfun name from IDE option menu
add Arduboy2 library version 6.0.0 changes
add SH1106 I2C display support to Arduboy and Arduboy2 library Thanks to @evgenykzz2
add experimental code for extra X and Y buttons to Arduboy2 library
add alternate wiring support to Arduboy2beep Thanks to @menehune23
update Arduboy2 library HardwareTest sketch
add link to Cathy3K Repo in bootloader folder
add contrast option to IDE option menu
This commit is contained in:
Mr.Blinky 2021-12-05 21:43:40 +01:00
parent 6acc22dfda
commit 75b7421999
36 changed files with 1525 additions and 860 deletions

View File

@ -1,9 +1,10 @@
# Board definitions for Arduboy production v1.0, DevkKit and homemade versions # Board definitions for Arduboy production v1.0, DevkKit and homemade versions
# using Leonardo, Micro and Sparkfun Pro Micro boards. # using Leonardo, Micro and (Sparkfun) Pro Micro boards.
menu.based_on=Based on menu.based_on=Based on
menu.core=Core menu.core=Core
menu.display=Display menu.display=Display
menu.contrast=Display contrast
menu.boot=Bootloader menu.boot=Bootloader
menu.flashselect=Flash select menu.flashselect=Flash select
@ -85,8 +86,8 @@ arduboy-homemade.menu.based_on.micro.org_bootloader_file=caterina/Caterina-Micro
arduboy-homemade.menu.based_on.micro.c3k_bootloader_file=cathy3k/arduboy3k-bootloader-menu-micro{bootloader_display}{bootloader_flashselect}.hex arduboy-homemade.menu.based_on.micro.c3k_bootloader_file=cathy3k/arduboy3k-bootloader-menu-micro{bootloader_display}{bootloader_flashselect}.hex
arduboy-homemade.menu.based_on.micro.c3kg_bootloader_file=cathy3k/arduboy3k-bootloader-game-micro{bootloader_display}{bootloader_flashselect}.hex arduboy-homemade.menu.based_on.micro.c3kg_bootloader_file=cathy3k/arduboy3k-bootloader-game-micro{bootloader_display}{bootloader_flashselect}.hex
# SparkFun Pro Micro 5V # # (SparkFun) Pro Micro 5V #
arduboy-homemade.menu.based_on.promicro=SparkFun Pro Micro 5V - Standard wiring arduboy-homemade.menu.based_on.promicro=Pro Micro 5V - Standard wiring
#arduboy-homemade.menu.based_on.promicro.build.vid=0x1b4f #arduboy-homemade.menu.based_on.promicro.build.vid=0x1b4f
#arduboy-homemade.menu.based_on.promicro.build.pid=0x9206 #arduboy-homemade.menu.based_on.promicro.build.pid=0x9206
#using Leonardo vid,pid for driver simplicity #using Leonardo vid,pid for driver simplicity
@ -99,7 +100,7 @@ arduboy-homemade.menu.based_on.promicro.org_bootloader_file=caterina/Caterina-pr
arduboy-homemade.menu.based_on.promicro.c3k_bootloader_file=cathy3k/arduboy3k-bootloader-menu{bootloader_display}{bootloader_flashselect}.hex arduboy-homemade.menu.based_on.promicro.c3k_bootloader_file=cathy3k/arduboy3k-bootloader-menu{bootloader_display}{bootloader_flashselect}.hex
arduboy-homemade.menu.based_on.promicro.c3kg_bootloader_file=cathy3k/arduboy3k-bootloader-game{bootloader_display}{bootloader_flashselect}.hex arduboy-homemade.menu.based_on.promicro.c3kg_bootloader_file=cathy3k/arduboy3k-bootloader-game{bootloader_display}{bootloader_flashselect}.hex
arduboy-homemade.menu.based_on.promicro_alt=SparkFun Pro Micro 5V - Alternate wiring arduboy-homemade.menu.based_on.promicro_alt=Pro Micro 5V - Alternate wiring
#arduboy-homemade.menu.based_on.promicro_alt.build.vid=0x1b4f #arduboy-homemade.menu.based_on.promicro_alt.build.vid=0x1b4f
#arduboy-homemade.menu.based_on.promicro_alt.build.pid=0x9206 #arduboy-homemade.menu.based_on.promicro_alt.build.pid=0x9206
#using Leonardo vid,pid for driver simplicity #using Leonardo vid,pid for driver simplicity
@ -141,97 +142,103 @@ arduboy-homemade.menu.display.sh1106=SH1106
arduboy-homemade.menu.display.sh1106.build.display=-sh1106 arduboy-homemade.menu.display.sh1106.build.display=-sh1106
arduboy-homemade.menu.display.sh1106.usb_product_postfix=1106 arduboy-homemade.menu.display.sh1106.usb_product_postfix=1106
arduboy-homemade.menu.display.sh1106.bootloader_display=-sh1106 arduboy-homemade.menu.display.sh1106.bootloader_display=-sh1106
arduboy-homemade.menu.display.sh1106.build.extra_flags=-DARDUBOY_10 -DOLED_SH1106 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.sh1106.build.extra_flags=-DARDUBOY_10 -DOLED_SH1106 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.sh1106i2c=SH1106-I2C (2 Mbps)
arduboy-homemade.menu.display.sh1106i2c.build.display=-sh1106i2c
arduboy-homemade.menu.display.sh1106i2c.usb_product_postfix=I2C
arduboy-homemade.menu.display.sh1106i2c.bootloader_display=
arduboy-homemade.menu.display.sh1106i2c.build.extra_flags=-DARDUBOY_10 -DOLED_SH1106_I2C {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.ssd1306=SSD1306 arduboy-homemade.menu.display.ssd1306=SSD1306
arduboy-homemade.menu.display.ssd1306.build.display=-ssd1306 arduboy-homemade.menu.display.ssd1306.build.display=-ssd1306
arduboy-homemade.menu.display.ssd1306.usb_product_postfix=1306 arduboy-homemade.menu.display.ssd1306.usb_product_postfix=1306
arduboy-homemade.menu.display.ssd1306.bootloader_display= arduboy-homemade.menu.display.ssd1306.bootloader_display=
arduboy-homemade.menu.display.ssd1306.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.ssd1306.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.ssd1306i2c=SSD1306-I2C (2 Mbps) arduboy-homemade.menu.display.ssd1306i2c=SSD1306-I2C (2 Mbps)
arduboy-homemade.menu.display.ssd1306i2c.build.display=-ssd1306i2c arduboy-homemade.menu.display.ssd1306i2c.build.display=-ssd1306i2c
arduboy-homemade.menu.display.ssd1306i2c.usb_product_postfix=I2C arduboy-homemade.menu.display.ssd1306i2c.usb_product_postfix=I2C
arduboy-homemade.menu.display.ssd1306i2c.bootloader_display= arduboy-homemade.menu.display.ssd1306i2c.bootloader_display=
arduboy-homemade.menu.display.ssd1306i2c.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2C {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.ssd1306i2c.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2C {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.ssd1306i2cx=SSD1306-I2C (2.66 Mbps) arduboy-homemade.menu.display.ssd1306i2cx=SSD1306-I2C (2.66 Mbps)
arduboy-homemade.menu.display.ssd1306i2cx.build.display=-ssd1306i2cf arduboy-homemade.menu.display.ssd1306i2cx.build.display=-ssd1306i2cf
arduboy-homemade.menu.display.ssd1306i2cx.usb_product_postfix=I2CX arduboy-homemade.menu.display.ssd1306i2cx.usb_product_postfix=I2CX
arduboy-homemade.menu.display.ssd1306i2cx.bootloader_display= arduboy-homemade.menu.display.ssd1306i2cx.bootloader_display=
arduboy-homemade.menu.display.ssd1306i2cx.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2CX {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.ssd1306i2cx.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1306_I2CX {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.ssd1309=SSD1309 arduboy-homemade.menu.display.ssd1309=SSD1309
arduboy-homemade.menu.display.ssd1309.build.display=-ssd1309 arduboy-homemade.menu.display.ssd1309.build.display=-ssd1309
arduboy-homemade.menu.display.ssd1309.usb_product_postfix=1309 arduboy-homemade.menu.display.ssd1309.usb_product_postfix=1309
arduboy-homemade.menu.display.ssd1309.bootloader_display= arduboy-homemade.menu.display.ssd1309.bootloader_display=
arduboy-homemade.menu.display.ssd1309.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1309 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.ssd1309.build.extra_flags=-DARDUBOY_10 -DOLED_SSD1309 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.64x128on96x96=SSD1327/29 (128x64 on 96x96) arduboy-homemade.menu.display.64x128on96x96=SSD1327/29 (128x64 on 96x96)
arduboy-homemade.menu.display.64x128on96x96.build.display=-128x64-on-96x96 arduboy-homemade.menu.display.64x128on96x96.build.display=-128x64-on-96x96
arduboy-homemade.menu.display.64x128on96x96.usb_product_postfix=9696 arduboy-homemade.menu.display.64x128on96x96.usb_product_postfix=9696
arduboy-homemade.menu.display.64x128on96x96.bootloader_display=-ssd132x-96x96 arduboy-homemade.menu.display.64x128on96x96.bootloader_display=-ssd132x-96x96
arduboy-homemade.menu.display.64x128on96x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_96X96 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.64x128on96x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_96X96 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.64x128on128x96=SSD1327/29 (128x64 on 128x96) arduboy-homemade.menu.display.64x128on128x96=SSD1327/29 (128x64 on 128x96)
arduboy-homemade.menu.display.64x128on128x96.build.display=-128x64-on-128x96 arduboy-homemade.menu.display.64x128on128x96.build.display=-128x64-on-128x96
arduboy-homemade.menu.display.64x128on128x96.usb_product_postfix=12896 arduboy-homemade.menu.display.64x128on128x96.usb_product_postfix=12896
arduboy-homemade.menu.display.64x128on128x96.bootloader_display=-ssd132x-128x96 arduboy-homemade.menu.display.64x128on128x96.bootloader_display=-ssd132x-128x96
arduboy-homemade.menu.display.64x128on128x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_128X96 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.64x128on128x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_128X96 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.64x128on128x128=SSD1327/29 (128x64 on 128x128) arduboy-homemade.menu.display.64x128on128x128=SSD1327/29 (128x64 on 128x128)
arduboy-homemade.menu.display.64x128on128x128.build.display=-128x64-on-128x128 arduboy-homemade.menu.display.64x128on128x128.build.display=-128x64-on-128x128
arduboy-homemade.menu.display.64x128on128x128.usb_product_postfix=128128 arduboy-homemade.menu.display.64x128on128x128.usb_product_postfix=128128
arduboy-homemade.menu.display.64x128on128x128.bootloader_display=-ssd132x-128x128 arduboy-homemade.menu.display.64x128on128x128.bootloader_display=-ssd132x-128x128
arduboy-homemade.menu.display.64x128on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_128X128 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.64x128on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X64_ON_128X128 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.128x64on128x128=SSD1327/29 (64x128 on 128x128) arduboy-homemade.menu.display.128x64on128x128=SSD1327/29 (64x128 on 128x128)
arduboy-homemade.menu.display.128x64on128x128.build.display=-64x128-on-128x128 arduboy-homemade.menu.display.128x64on128x128.build.display=-64x128-on-128x128
arduboy-homemade.menu.display.128x64on128x128.usb_product_postfix=64128 arduboy-homemade.menu.display.128x64on128x128.usb_product_postfix=64128
arduboy-homemade.menu.display.128x64on128x128.bootloader_display=-ssd132x-128x128 arduboy-homemade.menu.display.128x64on128x128.bootloader_display=-ssd132x-128x128
arduboy-homemade.menu.display.128x64on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_64X128_ON_128X128 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.128x64on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_64X128_ON_128X128 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.96x96=SSD1327/29 (96x96) arduboy-homemade.menu.display.96x96=SSD1327/29 (96x96)
arduboy-homemade.menu.display.96x96.build.display=-96x96 arduboy-homemade.menu.display.96x96.build.display=-96x96
arduboy-homemade.menu.display.96x96.usb_product_postfix=9696 arduboy-homemade.menu.display.96x96.usb_product_postfix=9696
arduboy-homemade.menu.display.96x96.bootloader_display=-ssd132x-96x96 arduboy-homemade.menu.display.96x96.bootloader_display=-ssd132x-96x96
arduboy-homemade.menu.display.96x96.build.extra_flags=-DARDUBOY_10 -DOLED_96X96 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.96x96.build.extra_flags=-DARDUBOY_10 -DOLED_96X96 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.96x96on128x128=SSD1327/29 (96x96 on 128x128) arduboy-homemade.menu.display.96x96on128x128=SSD1327/29 (96x96 on 128x128)
arduboy-homemade.menu.display.96x96on128x128.build.display=-96x96-on-128x128 arduboy-homemade.menu.display.96x96on128x128.build.display=-96x96-on-128x128
arduboy-homemade.menu.display.96x96on128x128.usb_product_postfix=128128 arduboy-homemade.menu.display.96x96on128x128.usb_product_postfix=128128
arduboy-homemade.menu.display.96x96on128x128.bootloader_display=-ssd132x-128x128 arduboy-homemade.menu.display.96x96on128x128.bootloader_display=-ssd132x-128x128
arduboy-homemade.menu.display.96x96on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_96X96_ON_128X128 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.96x96on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_96X96_ON_128X128 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.128x96=SSD1327/29 (128x96) arduboy-homemade.menu.display.128x96=SSD1327/29 (128x96)
arduboy-homemade.menu.display.128x96.build.display=-128x96 arduboy-homemade.menu.display.128x96.build.display=-128x96
arduboy-homemade.menu.display.128x96.usb_product_postfix=12896 arduboy-homemade.menu.display.128x96.usb_product_postfix=12896
arduboy-homemade.menu.display.128x96.bootloader_display=-ssd132x-128x96 arduboy-homemade.menu.display.128x96.bootloader_display=-ssd132x-128x96
arduboy-homemade.menu.display.128x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X96 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.128x96.build.extra_flags=-DARDUBOY_10 -DOLED_128X96 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.128x96on128x128=SSD1327/29 (128x96 on 128x128) arduboy-homemade.menu.display.128x96on128x128=SSD1327/29 (128x96 on 128x128)
arduboy-homemade.menu.display.128x96on128x128.build.display=-128x96-on-128x128 arduboy-homemade.menu.display.128x96on128x128.build.display=-128x96-on-128x128
arduboy-homemade.menu.display.128x96on128x128.usb_product_postfix=128128 arduboy-homemade.menu.display.128x96on128x128.usb_product_postfix=128128
arduboy-homemade.menu.display.128x96on128x128.bootloader_display=-ssd132x-128x128 arduboy-homemade.menu.display.128x96on128x128.bootloader_display=-ssd132x-128x128
arduboy-homemade.menu.display.128x96on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X96_ON_128X128 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.128x96on128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X96_ON_128X128 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.128x128=SSD1327/29 (128x128) arduboy-homemade.menu.display.128x128=SSD1327/29 (128x128)
arduboy-homemade.menu.display.128x128.build.display=-128x128 arduboy-homemade.menu.display.128x128.build.display=-128x128
arduboy-homemade.menu.display.128x128.usb_product_postfix=128128 arduboy-homemade.menu.display.128x128.usb_product_postfix=128128
arduboy-homemade.menu.display.128x128.bootloader_display=-ssd132x-128x128 arduboy-homemade.menu.display.128x128.bootloader_display=-ssd132x-128x128
arduboy-homemade.menu.display.128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X128 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.128x128.build.extra_flags=-DARDUBOY_10 -DOLED_128X128 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.st7565=LCD ST7565 (backlit) arduboy-homemade.menu.display.st7565=LCD ST7565 (backlit)
arduboy-homemade.menu.display.st7565.build.display=-st7565 arduboy-homemade.menu.display.st7565.build.display=-st7565
arduboy-homemade.menu.display.st7565.usb_product_postfix=lcd arduboy-homemade.menu.display.st7565.usb_product_postfix=lcd
arduboy-homemade.menu.display.st7565.bootloader_display=-st7565 arduboy-homemade.menu.display.st7565.bootloader_display=-st7565
arduboy-homemade.menu.display.st7565.build.extra_flags=-DARDUBOY_10 -DLCD_ST7565 {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.st7565.build.extra_flags=-DARDUBOY_10 -DLCD_ST7565 {build.flash_cs} {build.contrast} {build.usb_flags}
arduboy-homemade.menu.display.gu12864_800b=GU12864-800B arduboy-homemade.menu.display.gu12864_800b=GU12864-800B
arduboy-homemade.menu.display.gu12864_800b.build.display=-gu12864 arduboy-homemade.menu.display.gu12864_800b.build.display=-gu12864
arduboy-homemade.menu.display.gu12864_800b.usb_product_postfix=vfd arduboy-homemade.menu.display.gu12864_800b.usb_product_postfix=vfd
arduboy-homemade.menu.display.gu12864_800b.bootloader_display=-gu12864 arduboy-homemade.menu.display.gu12864_800b.bootloader_display=-gu12864
arduboy-homemade.menu.display.gu12864_800b.build.extra_flags=-DARDUBOY_10 -DGU12864_800B {build.flash_cs} {build.usb_flags} arduboy-homemade.menu.display.gu12864_800b.build.extra_flags=-DARDUBOY_10 -DGU12864_800B {build.flash_cs} {build.contrast} {build.usb_flags}
# External flash chip select pin # # External flash chip select pin #
@ -245,11 +252,28 @@ arduboy-homemade.menu.flashselect.rx.build.flash_cs=-DCART_CS_RX
arduboy-homemade.menu.flashselect.rx.build.flashselect= arduboy-homemade.menu.flashselect.rx.build.flashselect=
arduboy-homemade.menu.flashselect.rx.bootloader_flashselect= arduboy-homemade.menu.flashselect.rx.bootloader_flashselect=
# Display contrast adjustment #
arduboy-homemade.menu.contrast.normal=Normal
arduboy-homemade.menu.contrast.normal.build.contrast=
arduboy-homemade.menu.contrast.dimmed=Dimmed
arduboy-homemade.menu.contrast.dimmed.build.contrast=-DOLED_CONTRAST=0x7F
arduboy-homemade.menu.contrast.low=Low
arduboy-homemade.menu.contrast.low.build.contrast=-DOLED_CONTRAST=0x2F
arduboy-homemade.menu.contrast.lowest=Lowest
arduboy-homemade.menu.contrast.lowest.build.contrast=-DOLED_CONTRAST=0x00
arduboy-homemade.menu.contrast.highest=Highest
arduboy-homemade.menu.contrast.highest.build.contrast=-DOLED_CONTRAST=0xFF
################################################################################ ################################################################################
# Arduboy board # Arduboy board
################################################################################ ################################################################################
arduboy.name=Arduboy arduboy.name=Arduboy (FX)
#Arduino Leonardo #Arduino Leonardo
arduboy.vid.0=0x2341 arduboy.vid.0=0x2341

View File

@ -0,0 +1,3 @@
Source to build the Cathy3K bootloaders can be found at:
https://github.com/MrBlinky/cathy3k

View File

@ -15,7 +15,7 @@ const uint8_t PROGMEM pinBootProgram[] = {
PIN_A_BUTTON, INPUT_PULLUP, PIN_A_BUTTON, INPUT_PULLUP,
PIN_B_BUTTON, INPUT_PULLUP, PIN_B_BUTTON, INPUT_PULLUP,
#if (defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX)) #if (defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C))
//I2C //I2C
SDA, INPUT, SDA, INPUT,
SCL, INPUT, SCL, INPUT,
@ -40,7 +40,7 @@ const uint8_t PROGMEM lcdBootProgram[] = {
0x47, // set brightness 0x47, // set brightness
0x64, 0x00, // set x position 0 0x64, 0x00, // set x position 0
0x84, // address mode set: X increment 0x84, // address mode set: X increment
#elif OLED_SH1106 #elif defined(OLED_SH1106) || defined(OLED_SH1106_I2C)
0x8D, 0x14, // Charge Pump Setting v = enable (0x14) 0x8D, 0x14, // Charge Pump Setting v = enable (0x14)
0xA1, // Set Segment Re-map 0xA1, // Set Segment Re-map
0xC8, // Set COM Output Scan Direction 0xC8, // Set COM Output Scan Direction
@ -245,16 +245,30 @@ void ArduboyCore::displayWrite(uint8_t data)
void ArduboyCore::bootLCD() void ArduboyCore::bootLCD()
{ {
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_CMD); i2c_start(SSD1306_I2C_CMD);
for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++) for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++)
i2c_sendByte(pgm_read_byte(lcdBootProgram + i)); i2c_sendByte(pgm_read_byte(lcdBootProgram + i));
i2c_stop(); i2c_stop();
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX)
i2c_start(SSD1306_I2C_DATA); i2c_start(SSD1306_I2C_DATA);
for (uint16_t i = 0; i < WIDTH * HEIGHT / 8; i++) for (uint16_t i = 0; i < WIDTH * HEIGHT / 8; i++)
i2c_sendByte(0); i2c_sendByte(0);
i2c_stop(); i2c_stop();
#else #else
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI); // only reset hi nibble to zero
i2c_stop();
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(0);
i2c_stop();
}
#endif
#else
// setup the ports we need to talk to the OLED // setup the ports we need to talk to the OLED
csport = portOutputRegister(digitalPinToPort(CS)); csport = portOutputRegister(digitalPinToPort(CS));
cspinmask = digitalPinToBitMask(CS); cspinmask = digitalPinToBitMask(CS);
@ -317,7 +331,7 @@ void ArduboyCore::LCDCommandMode()
// *csport &= ~cspinmask; CS set once at bootLCD // *csport &= ~cspinmask; CS set once at bootLCD
} }
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
void ArduboyCore::i2c_start(uint8_t mode) void ArduboyCore::i2c_start(uint8_t mode)
{ {
I2C_SDA_LOW(); // disable posible internal pullup, ensure SDA low on enabling output I2C_SDA_LOW(); // disable posible internal pullup, ensure SDA low on enabling output
@ -401,11 +415,11 @@ uint8_t ArduboyCore::height() { return HEIGHT; }
void ArduboyCore::paint8Pixels(uint8_t pixels) void ArduboyCore::paint8Pixels(uint8_t pixels)
{ {
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_DATA); i2c_start(SSD1306_I2C_DATA);
i2c_sendByte(pixels); i2c_sendByte(pixels);
i2c_stop(); i2c_stop();
#else #else
SPI.transfer(pixels); SPI.transfer(pixels);
#endif #endif
} }
@ -434,6 +448,19 @@ void ArduboyCore::paintScreen(const unsigned char *image)
for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++) for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++)
i2c_sendByte(pgm_read_byte(image+i)); i2c_sendByte(pgm_read_byte(image+i));
i2c_stop(); i2c_stop();
#elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI); // only reset hi nibble to zero
i2c_stop();
const uint8_t *line = image + page*WIDTH;
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(pgm_read_byte(line+i));
i2c_stop();
}
#elif defined(OLED_SH1106) || defined(LCD_ST7565) #elif defined(OLED_SH1106) || defined(LCD_ST7565)
for (uint8_t i = 0; i < HEIGHT / 8; i++) for (uint8_t i = 0; i < HEIGHT / 8; i++)
{ {
@ -636,7 +663,18 @@ void ArduboyCore::paintScreen(unsigned char image[])
); );
#endif #endif
i2c_stop(); i2c_stop();
#elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI);
i2c_stop();
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(*(image++));
i2c_stop();
}
#elif defined(OLED_SH1106) || defined(LCD_ST7565) #elif defined(OLED_SH1106) || defined(LCD_ST7565)
for (uint8_t i = 0; i < HEIGHT / 8; i++) for (uint8_t i = 0; i < HEIGHT / 8; i++)
{ {
@ -777,7 +815,19 @@ void ArduboyCore::blank()
for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++) for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++)
i2c_sendByte(0); i2c_sendByte(0);
i2c_stop(); i2c_stop();
#else #elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI); // only reset hi nibble to zero
i2c_stop();
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(0);
i2c_stop();
}
#else
#if defined (OLED_SH1106) #if defined (OLED_SH1106)
for (int i = 0; i < (HEIGHT * 132) / 8; i++) for (int i = 0; i < (HEIGHT * 132) / 8; i++)
#elif defined(OLED_96X96) || defined(OLED_128X96) || defined(OLED_128X128) || defined(OLED_128X64_ON_128X96) || defined(OLED_128X64_ON_128X128)|| defined(OLED_128X96_ON_128X128) || defined(OLED_96X96_ON_128X128) || defined(OLED_64X128_ON_128X128) #elif defined(OLED_96X96) || defined(OLED_128X96) || defined(OLED_128X128) || defined(OLED_128X64_ON_128X96) || defined(OLED_128X64_ON_128X128)|| defined(OLED_128X96_ON_128X128) || defined(OLED_96X96_ON_128X128) || defined(OLED_64X128_ON_128X128)
@ -791,7 +841,7 @@ void ArduboyCore::blank()
void ArduboyCore::sendLCDCommand(uint8_t command) void ArduboyCore::sendLCDCommand(uint8_t command)
{ {
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_CMD); i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(command); i2c_sendByte(command);
i2c_stop(); i2c_stop();

View File

@ -43,7 +43,7 @@
#define RST 6 #define RST 6
#endif #endif
#define DC 4 #define DC 4
#if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
//bitbanged I2C pins //bitbanged I2C pins
#define I2C_PORT PORTD #define I2C_PORT PORTD
#define I2C_DDR DDRD #define I2C_DDR DDRD
@ -166,7 +166,7 @@
#define OLED_VERTICAL_NORMAL 0xC8 // normal COM scan direction (Same for SH1106) #define OLED_VERTICAL_NORMAL 0xC8 // normal COM scan direction (Same for SH1106)
#define OLED_SET_PAGE_ADDRESS 0xB0 // (Same for SH1106) #define OLED_SET_PAGE_ADDRESS 0xB0 // (Same for SH1106)
#if defined OLED_SH1106 #if defined(OLED_SH1106) || defined(OLED_SH1106_I2C)
#define OLED_SET_COLUMN_ADDRESS_LO 0x02 //SH1106: 1st pixel starts on column 2 #define OLED_SET_COLUMN_ADDRESS_LO 0x02 //SH1106: 1st pixel starts on column 2
#else #else
#define OLED_SET_COLUMN_ADDRESS_LO 0x00 #define OLED_SET_COLUMN_ADDRESS_LO 0x00
@ -231,7 +231,7 @@ public:
*/ */
void static LCDCommandMode(); void static LCDCommandMode();
#if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
void static i2c_start(uint8_t mode); void static i2c_start(uint8_t mode);
void static inline i2c_stop() __attribute__((always_inline)) void static inline i2c_stop() __attribute__((always_inline))

View File

@ -0,0 +1,30 @@
# Commit message style
When submitting changes via a pull request, or any other means, please format commit messages using ["50/72" guidelines, as suggested by Tim Pope](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
## Summary:
- Maximum 50 character first "title" line, written as a capitalized [imperative sentence](http://examples.yourdictionary.com/imperative-sentence-examples.html).
- If necessary, more detailed explanatory paragraphs following a blank line, with lines wrapped at maximum 72 characters.
- If used, bullet points have a "hanging indent".
## Example 1:
```
Make state variables used by pollButtons() public
The variables currentButtonState and previousButtonState used by
pollButtons(), justPressed() and justReleased() have been made public.
This allows them to be manipulated if circumstances require it.
The documentation added for previousButtonState includes an example.
```
## Example 2:
```
Refactor text code and add char size functions
- Functions write() and drawChar() were refactored for smaller code
size and to make text wrapping operate more like what would normally
be expected.
- A new flag variable, textRaw, has been added, along with functions
setTextRawMode() and getTextRawMode() to set and read it.
```

View File

@ -8,7 +8,7 @@ Software License Agreements
Licensed under the BSD 3-clause license: Licensed under the BSD 3-clause license:
Arduboy2 library: Arduboy2 library:
Copyright (c) 2016-2020, Scott Allen Copyright (c) 2016-2021, Scott Allen
All rights reserved. All rights reserved.
The Arduboy2 library was forked from the Arduboy library: The Arduboy2 library was forked from the Arduboy library:
@ -18,7 +18,8 @@ Copyright (c) 2016, Chris Martinez
Copyright (c) 2016, Josh Goebel Copyright (c) 2016, Josh Goebel
Copyright (c) 2016, Scott Allen Copyright (c) 2016, Scott Allen
All rights reserved. All rights reserved.
which is in turn partially based on the Adafruit_SSD1306 library
- which is in turn partially based on the Adafruit_SSD1306 library
https://github.com/adafruit/Adafruit_SSD1306 https://github.com/adafruit/Adafruit_SSD1306
Copyright (c) 2012, Adafruit Industries Copyright (c) 2012, Adafruit Industries
All rights reserved. All rights reserved.
@ -164,6 +165,9 @@ https://creativecommons.org/publicdomain/zero/1.0/
BeepDemo example sketch: BeepDemo example sketch:
By Scott Allen By Scott Allen
FontDemo example sketch:
By Scott Allen
RGBled example sketch: RGBled example sketch:
By Scott Allen By Scott Allen

View File

@ -6,7 +6,7 @@ The original Arduboy2 library is maintained in a git repository hosted on [GitHu
https://github.com/MLXXXp/Arduboy2 https://github.com/MLXXXp/Arduboy2
The **Arduboy2** library is a fork of the [Arduboy library](https://github.com/Arduboy/Arduboy), which provides a standard *application programming interface* (API) to the display, buttons and other hardware of the Arduino based [Arduboy miniature game system](https://www.arduboy.com/). The **Arduboy2** library is a fork of the [Arduboy library](https://github.com/Arduboy/Arduboy), which provides a standard *application programming interface* (API) to the display, buttons and other hardware of the Arduino based [Arduboy miniature game system](https://www.arduboy.com/). The original *Arduboy* library is no longer being maintained.
The name *Arduboy2* doesn't indicate that it's for a new "next generation" of the Arduboy hardware. The name was changed so it can coexist in the Arduino IDE with the current *Arduboy* library, without conflict. This way, existing sketches can continue to use the *Arduboy* library and class, without changes, while new sketches can be written (or old ones modified) to use and take advantage of the capabilities of the *Arduboy2* class and library. The name *Arduboy2* doesn't indicate that it's for a new "next generation" of the Arduboy hardware. The name was changed so it can coexist in the Arduino IDE with the current *Arduboy* library, without conflict. This way, existing sketches can continue to use the *Arduboy* library and class, without changes, while new sketches can be written (or old ones modified) to use and take advantage of the capabilities of the *Arduboy2* class and library.
@ -49,9 +49,10 @@ A user settable *unit name* can be saved in system EEPROM memory. If set, this n
Once the logo display sequence completes, the sketch continues. Once the logo display sequence completes, the sketch continues.
For developers who wish to quickly begin testing, or impatient users who want to go strait to playing their game, the boot logo sequence can be bypassed by holding the *RIGHT* button while powering up, and then releasing it. Alternatively, the *RIGHT* button can be pressed while the logo is scrolling down. **Note:**
For users who wish to always disable the displaying of the boot logo sequence on boot up, a flag in system EEPROM is available for this. The included *SetSystemEEPROM* example sketch can be used to set this flag. - For developers who wish to quickly begin testing, or impatient users who want to go strait to playing their game, the boot logo sequence can be bypassed by holding the *RIGHT* button while powering up, and then releasing it. Alternatively, the *RIGHT* button can be pressed while the logo is scrolling down.
- For users who wish to always disable the displaying of the boot logo sequence on boot up, a flag in system EEPROM is available for this. The included *SetSystemEEPROM* example sketch can be used to set this flag.
### "Flashlight" mode ### "Flashlight" mode
@ -167,63 +168,99 @@ with
Arduboy2Base arduboy; Arduboy2Base arduboy;
``` ```
#### Remove boot up features #### Substitute or remove boot up features
As previously described, the *begin()* function includes features that are intended to be available to all sketches during boot up. However, if you're looking to gain some code space, you can call *boot()* instead of *begin()*. This will initialize the system but not include any of the extra boot up features. If desired, you can then add back in any of these features by calling the functions that perform them. You will have to trade off between the desirability of having a feature and how much memory you can recover by not including it. As previously described in the _Start up features_ section, the *begin()* function includes features that are intended to be available to all sketches during boot up. However, if you're looking to gain some code space, you can call *boot()* instead of *begin()*. This will initialize the system but not include any of the extra boot up features. You can then add back in any of these features by calling the functions that perform them. You will have to trade off between the desirability of having a feature and how much memory you can recover by not including it.
A good way to use *boot()* instead of *begin()* is to copy the code from the body of the *begin()* function, in file *Arduboy2.cpp*, into your sketch and then edit it to retain the *boot()* call and any feature calls desired. You should at least call either *flashlight()* or *safeMode()* as a safeguard to allow uploading a new sketch when the bootloader "magic key" problem is an issue.
As of this writing, the begin function is: Here is a template that provides the equivalent of *begin()*
```cpp ```cpp
void Arduboy2Base::begin() void setup()
{ {
boot(); // raw hardware // Required to initialize the hardware.
arduboy.boot();
display(); // blank the display (sBuffer is global, so cleared automatically) // This clears the display. (The screen buffer will be all zeros)
// It may not be needed if something clears the display later on but
// "garbage" will be displayed if systemButtons() is used without it.
arduboy.display();
flashlight(); // light the RGB LED and screen if UP button is being held. // flashlight() or safeMode() should always be included to provide
// a method of recovering from the bootloader "magic key" problem.
arduboy.flashlight();
// arduboy.safeMode();
// check for and handle buttons held during start up for system control // This allows sound to be turned on or muted. If the sketch provides
systemButtons(); // its own way of toggling sound, or doesn't produce any sound, this
// function may not be required.
arduboy.systemButtons();
audio.begin(); // This is required to initialize the speaker. It's not needed if
// the sketch doesn't produce any sounds.
arduboy.audio.begin();
bootLogo(); // This displays the boot logo sequence but note that the logo can
// be suppressed by the user, by pressing the RIGHT button or using
// a system EEPROM setting. If not removed entirely, an alternative
// bootLogo...() function may save some memory.
arduboy.bootLogo();
// arduboy.bootLogoCompressed();
// arduboy.bootLogoSpritesSelfMasked();
// arduboy.bootLogoSpritesOverwrite();
// arduboy.bootLogoSpritesBSelfMasked();
// arduboy.bootLogoSpritesBOverwrite();
// arduboy.bootLogoText();
// Wait for all buttons to be released, in case a pressed one might
// cause problems by being acted upon when the actual sketch code
// starts. If neither systemButtons() nor bootLogo() is kept, this
// function isn't required.
arduboy.waitNoButtons();
// Additional setup code...
waitNoButtons(); // wait for all buttons to be released
} }
``` ```
To incorporate it into your sketch just keep *boot()* and whatever feature calls are desired, if any. Comment out or delete the rest. Remember to add the class object name in front of each function call, since they're now being called from outside the class itself. If your sketch uses sound, it's a good idea to keep the call to *audio.begin()*.
For example: Let's say a sketch has its own code to enable, disable and save the *audio on/off* setting, and wants to keep the *flashlight* function. In *setup()* it could replace *begin()* with:
```cpp
arduboy.boot(); // raw hardware
// *** This particular sketch clears the display soon, so it doesn't need this:
// display(); // blank the display (sBuffer is global, so cleared automatically)
arduboy.flashlight(); // light the RGB LED and screen if UP button is being held.
// check for and handle buttons held during start up for system control
// systemButtons();
arduboy.audio.begin();
// bootLogo();
// waitNoButtons(); // wait for all buttons to be released
```
This saves whatever code *display()*, *systemButtons()*, *bootLogo()* and *waitNoButtons()* would use.
There are a few functions provided that are roughly equivalent to the standard functions used by *begin()* but which use less code space. There are a few functions provided that are roughly equivalent to the standard functions used by *begin()* but which use less code space.
- *bootLogoCompressed()*, *bootLogoSpritesSelfMasked()*, *bootLogoSpritesOverwrite()*, *bootLogoSpritesBSelfMasked()* and *bootLogoSpritesBOverwrite()* will do the same as *bootLogo()* but will use *drawCompressed()*, or *Sprites* / *SpritesB* class *drawSelfMasked()* or *drawOverwrite()* functions respectively, instead of *drawBitmask()*, to render the logo. If the sketch uses one of these functions, then using the boot logo function that also uses it may reduce code size. It's best to try each of them to see which one produces the smallest size. - *bootLogoCompressed()*, *bootLogoSpritesSelfMasked()*, *bootLogoSpritesOverwrite()*, *bootLogoSpritesBSelfMasked()* and *bootLogoSpritesBOverwrite()* will do the same as *bootLogo()* but will use *drawCompressed()*, or *Sprites* / *SpritesB* class *drawSelfMasked()* or *drawOverwrite()* functions respectively, instead of *drawBitmap()*, to render the logo. If the sketch uses one of these functions, then using the boot logo function that also uses it may reduce code size. It's best to try each of them to see which one produces the smallest size.
- *bootLogoText()* can be used in place *bootLogo()* in the case where the sketch uses text functions. It renders the logo as text instead of as a bitmap (so doesn't look as good). - *bootLogoText()* can be used in place *bootLogo()* in the case where the sketch uses text functions. It renders the logo as text instead of as a bitmap (so doesn't look as good).
- *safeMode()* can be used in place of *flashlight()* for cases where it's needed to allow uploading a new sketch when the bootloader "magic key" problem is an issue. It only lights the red RGB LED, so you don't get the bright light that is the primary purpose of *flashlight()*. - *safeMode()* can be used in place of *flashlight()* as a safeguard to allow uploading a new sketch when the bootloader "magic key" problem is an issue. It only lights the red RGB LED, so you don't get the bright light that is the primary purpose of *flashlight()*.
It is also possible to replace the boot logo drawing function with one that uses a different bitmap rendering function used elsewhere in your sketch. This may save memory by using this bitmap function for the logo, instead of the logo using a separate function that only ends up being used once. For example, if you use the *ArdBitmap* library's *drawCompressed()* function in your sketch, you could convert the **ARDUBOY** logo to *Ardbitmap* compressed format, and create *drawLogoArdCompressed()* and *bootLogoArdCompressed()* functions:
```cpp
void drawLogoArdCompressed(int16_t y)
{
ardbitmap.drawCompressed(20, y, arduboy_logo_ardbitmap,
WHITE, ALIGN_CENTER, MIRROR_NONE);
}
void bootLogoArdCompressed()
{
if (arduboy.bootLogoShell(drawLogoArdCompressed))
{
arduboy.bootLogoExtra();
}
}
void setup()
{
arduboy.beginDoFirst();
bootLogoArdCompressed();
arduboy.waitNoButtons();
// Additional setup code...
}
```
The **ARDUBOY** logo, in PNG format, is included in the library repository as file:
`extras/assets/arduboy_logo.png`
#### Use the SpritesB class instead of Sprites #### Use the SpritesB class instead of Sprites
@ -248,6 +285,8 @@ The *ARDUBOY_NO_USB* macro is used to eliminate the USB code. The *exitToBootloa
## What's different from Arduboy library V1.1 ## What's different from Arduboy library V1.1
(These notes apply to when the *Arduboy2* library was first released. There will have been many additional changes, enhancements and features added to *Arduboy2* since then.)
A main goal of Arduboy2 is to provide ways in which more code space can be freed for use by large sketches. Another goal is to allow methods other than the *tunes* functions to be used to produce sounds. Arduboy2 remains substantially compatible with [Arduboy library V1.1](https://github.com/Arduboy/Arduboy/releases/tag/v1.1), which was the latest stable release at the time of the fork. Arduboy2 is based on the code targeted for Arduboy library V1.2, which was still in development and unreleased at the time it was forked. A main goal of Arduboy2 is to provide ways in which more code space can be freed for use by large sketches. Another goal is to allow methods other than the *tunes* functions to be used to produce sounds. Arduboy2 remains substantially compatible with [Arduboy library V1.1](https://github.com/Arduboy/Arduboy/releases/tag/v1.1), which was the latest stable release at the time of the fork. Arduboy2 is based on the code targeted for Arduboy library V1.2, which was still in development and unreleased at the time it was forked.
Main differences between Arduboy2 and Arduboy V1.1 are: Main differences between Arduboy2 and Arduboy V1.1 are:
@ -391,7 +430,7 @@ Arduboy2 arduboy;
ArduboyPlaytune tunes(arduboy.audio.enabled); ArduboyPlaytune tunes(arduboy.audio.enabled);
``` ```
The sound channels must then be initialzed and assigned to the speaker pins. This code would go in the *setup()* function: The sound channels must then be initialized and assigned to the speaker pins. This code would go in the *setup()* function:
```cpp ```cpp
// audio setup // audio setup
@ -426,13 +465,13 @@ The benefit of using *ArduboyTones* would be reduced code size and possibly easi
### Sketch uses the beginNoLogo() function instead of begin() ### Sketch uses the beginNoLogo() function instead of begin()
The *beginNoLogo()* function has been removed. Instead, *boot()* can be used with additional functions following it to add back in desired boot functionality. See the information above, under the heading *Remove boot up features*, for more details. Assuming the object is named *arduboy*, a direct replacement for *beginNoLogo()* would be: The *beginNoLogo()* function has been removed. *beginNoLogo()* can be replaced with *begin()*, since users can choose to suppress the logo sequence using the *RIGHT* button or by setting a flag in system EEPROM.
If using *begin()* results in the sketch program memory size being too large, *beginDoFirst()* or *boot()* can be used with additional functions following it to add back in desired boot functionality. See the information above, under the heading *Substitute or remove boot up features*, for more details. Assuming the object is named *arduboy*, an equivalent replacement for *beginNoLogo()* would be:
```cpp ```cpp
arduboy.boot(); arduboy.beginDoFirst();
arduboy.display(); arduboy.waitNoButtons();
arduboy.flashlight();
arduboy.audio.begin();
``` ```
---------- ----------

View File

@ -271,7 +271,7 @@ void moveBall()
topBrick = 6 * row + 1; topBrick = 6 * row + 1;
bottomBrick = 6 * row + 7; bottomBrick = 6 * row + 7;
//If A collison has occured //If A collision has occurred
if (topBall <= bottomBrick && bottomBall >= topBrick && if (topBall <= bottomBrick && bottomBall >= topBrick &&
leftBall <= rightBrick && rightBall >= leftBrick) leftBall <= rightBrick && rightBall >= leftBrick)
{ {
@ -293,7 +293,7 @@ void moveBall()
} }
} }
//Hoizontal collision //Horizontal collision
if (leftBall < leftBrick || rightBall > rightBrick) if (leftBall < leftBrick || rightBall > rightBrick)
{ {
//Only bounce once brick each ball move //Only bounce once brick each ball move
@ -459,7 +459,7 @@ boolean pollFireButton(int n)
return false; return false;
} }
//Function by nootropic design to display highscores //Function by nootropic design to display high scores
boolean displayHighScores(byte file) boolean displayHighScores(byte file)
{ {
byte y = 8; byte y = 8;
@ -736,14 +736,14 @@ void enterHighScore(byte file)
} }
} }
// Play a tone at a frequency coresponding to the specified precomputed count, // Play a tone at a frequency corresponding to the specified precomputed count,
// for the specified number of frames. // for the specified number of frames.
void playTone(uint16_t count, uint8_t frames) void playTone(uint16_t count, uint8_t frames)
{ {
beep.tone(count, frames); beep.tone(count, frames);
} }
// Play a tone at a frequency coresponding to the specified precomputed count, // Play a tone at a frequency corresponding to the specified precomputed count,
// for the specified duration in milliseconds, using a delay. // for the specified duration in milliseconds, using a delay.
// Used when beep.timer() isn't being called. // Used when beep.timer() isn't being called.
void playToneTimed(uint16_t count, uint16_t duration) void playToneTimed(uint16_t count, uint16_t duration)

View File

@ -52,6 +52,8 @@ void loop() {
arduboy.pollButtons(); arduboy.pollButtons();
arduboy.clear();
if (arduboy.justPressed(LEFT_BUTTON)) { if (arduboy.justPressed(LEFT_BUTTON)) {
// Play a 523.251Hz tone (piano note C5) for 5 frames (200ms at 25 FPS) // Play a 523.251Hz tone (piano note C5) for 5 frames (200ms at 25 FPS)
// beep.freq(523.251) is used to convert 523.251Hz to the required count // beep.freq(523.251) is used to convert 523.251Hz to the required count
@ -127,7 +129,7 @@ void loop() {
objectX = 0; objectX = 0;
} }
arduboy.display(CLEAR_BUFFER); arduboy.display();
} }
void commandText(const char* text) { void commandText(const char* text) {

View File

@ -22,10 +22,10 @@ char title[] = "Press Buttons!";
byte x; byte x;
byte y; byte y;
// Width of each charcter including inter-character space // Width of each character including inter-character space
#define CHAR_WIDTH 6 #define CHAR_WIDTH 6
// Height of each charater // Height of each character
#define CHAR_HEIGHT 8 #define CHAR_HEIGHT 8
// To get the number of characters, we subtract 1 from the length of // To get the number of characters, we subtract 1 from the length of
@ -49,7 +49,7 @@ void setup() {
//initiate arduboy instance //initiate arduboy instance
arduboy.begin(); arduboy.begin();
// here we set the framerate to 30, we do not need to run at default 60 and // here we set the frame rate to 30, we do not need to run at default 60 and
// it saves us battery life. // it saves us battery life.
arduboy.setFrameRate(30); arduboy.setFrameRate(30);
@ -101,6 +101,6 @@ void loop() {
// then we print to screen what is stored in our title variable we declared earlier // then we print to screen what is stored in our title variable we declared earlier
arduboy.print(title); arduboy.print(title);
// then we finaly we tell the arduboy to display what we just wrote to the display. // then we finally we tell the arduboy to display what we just wrote to the display.
arduboy.display(); arduboy.display();
} }

View File

@ -1,4 +1,4 @@
Buttons Buttons
======= =======
A an example that demonstrates how to capture input from the buttons. An example that demonstrates how to capture input from the buttons.

View File

@ -0,0 +1,122 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,127 @@
/*
FontDemo.ino
This sketch draws all the characters of the library's font as a 16 x 16 block.
The bottom half of the block will be initially off screen. An information
overlay will be drawn on top of the block showing the X and Y cursor position
of the start of the block, the current text wrap state and the current text
raw mode state.
The block can be moved around and off the screen using the direction buttons,
to view all the characters and show how the wrap and raw modes behave.
Controls:
Direction Buttons: Move the block 1 pixel.
Hold A with Direction Buttons: Continuously move the block.
B Button: Toggle text raw mode on and off.
Hold A, press B: Toggle text wrap mode on and off.
*/
/*
Written in September 2020 by Scott Allen saydisp-git@yahoo.ca
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <Arduboy2.h>
Arduboy2 arduboy;
constexpr uint8_t charWidth = arduboy.getCharacterWidth() + arduboy.getCharacterSpacing();
constexpr uint8_t charHeight = arduboy.getCharacterHeight() + arduboy.getLineSpacing();
constexpr uint16_t infoX = charWidth * 8;
constexpr uint16_t infoY = charHeight * 2;
constexpr uint8_t infoWidth = charWidth * 5;
constexpr uint8_t infoBorder = 1;
int16_t xPos = 0;
int16_t yPos = 0;
void setup() {
arduboy.begin();
arduboy.setFrameRate(20);
arduboy.clear();
arduboy.print(F("DISPLAY AND MOVE FONT\n\n"
" Dpad: move 1\n"
"A + Dpad: repeat move\n"
" B: toggle raw\n"
" A + B: toggle wrap\n\n"
" Press A to start"));
arduboy.display();
while (!arduboy.pressed(A_BUTTON)) {
arduboy.idle();
}
}
void loop() {
if (!arduboy.nextFrame()) {
return;
}
arduboy.pollButtons();
if (arduboy.justPressed(B_BUTTON)) {
if (arduboy.pressed(A_BUTTON)) {
arduboy.setTextWrap(!arduboy.getTextWrap());
}
else {
arduboy.setTextRawMode(!arduboy.getTextRawMode());
}
}
if (arduboy.justPressed(UP_BUTTON) ||
arduboy.pressed(UP_BUTTON + A_BUTTON)) {
--yPos;
}
if (arduboy.justPressed(DOWN_BUTTON) ||
arduboy.pressed(DOWN_BUTTON + A_BUTTON)) {
++yPos;
}
if (arduboy.justPressed(LEFT_BUTTON) ||
arduboy.pressed(LEFT_BUTTON | A_BUTTON)) {
--xPos;
}
if (arduboy.justPressed(RIGHT_BUTTON) ||
arduboy.pressed(RIGHT_BUTTON | A_BUTTON)) {
++xPos;
}
arduboy.clear();
char code = 0;
for (uint8_t i = 0; i < 16; ++i) {
arduboy.setCursor(xPos, yPos + (charHeight * i));
for (uint8_t j = 0; j < 16; ++j) {
arduboy.print(code);
++code;
}
}
arduboy.fillRect(infoX - infoBorder, infoY - infoBorder,
infoWidth + infoBorder, charHeight * 4 + infoBorder);
arduboy.setTextColor(BLACK);
arduboy.setTextBackground(WHITE);
arduboy.setCursor(infoX, infoY);
arduboy.print(F("X:"));
arduboy.print(xPos);
arduboy.setCursor(infoX, infoY + charHeight);
arduboy.print(F("Y:"));
arduboy.print(yPos);
arduboy.setCursor(infoX, infoY + (charHeight * 2));
arduboy.print(F("W:"));
arduboy.print(arduboy.getTextWrap() ? F("Yes") : F("No"));
arduboy.setCursor(infoX, infoY + (charHeight * 3));
arduboy.print(F("R:"));
arduboy.print(arduboy.getTextRawMode() ? F("Yes") : F("No"));
arduboy.setTextColor(WHITE);
arduboy.setTextBackground(BLACK);
arduboy.display();
}

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
Arduboy hardware test toy v1.0 September 2017 by Mr.Blinky Arduboy hardware test toy v1.1 Sep. 2017 - Nov.2021 by Mr.Blinky
*******************************************************************************/ *******************************************************************************/
#include <Arduboy2.h> #include <Arduboy2.h>
@ -14,6 +14,7 @@ Sprites sprites;
void setup() void setup()
{ {
arduboy.begin(); arduboy.begin();
arduboy.setRGBled(0,0,0);
arduboy.setFrameRate(FRAMERATE); arduboy.setFrameRate(FRAMERATE);
arduboy.audio.on; arduboy.audio.on;
} }
@ -110,6 +111,8 @@ void loop()
arduboy.setRGBled(pgm_read_byte(rgbValues + rgbLed.red), pgm_read_byte(rgbValues + rgbLed.green), pgm_read_byte(rgbValues + rgbLed.blue)); arduboy.setRGBled(pgm_read_byte(rgbValues + rgbLed.red), pgm_read_byte(rgbValues + rgbLed.green), pgm_read_byte(rgbValues + rgbLed.blue));
rxled_on ? RXLED1 : RXLED0; rxled_on ? RXLED1 : RXLED0;
txled_on ? TXLED1 : TXLED0; txled_on ? TXLED1 : TXLED0;
SPEAKER_1_PORT &= ~_BV(SPEAKER_1_BIT);
SPEAKER_2_PORT |= _BV(SPEAKER_2_BIT);
for (int i = 0; i < 50; i++) for (int i = 0; i < 50; i++)
{ {
speaker1_on ? SPEAKER_1_PORT ^= _BV(SPEAKER_1_BIT) : SPEAKER_1_PORT &= ~_BV(SPEAKER_1_BIT); speaker1_on ? SPEAKER_1_PORT ^= _BV(SPEAKER_1_BIT) : SPEAKER_1_PORT &= ~_BV(SPEAKER_1_BIT);
@ -117,7 +120,9 @@ void loop()
speaker2_on ? SPEAKER_2_PORT ^= _BV(SPEAKER_2_BIT) : SPEAKER_2_PORT |= _BV(SPEAKER_2_BIT); speaker2_on ? SPEAKER_2_PORT ^= _BV(SPEAKER_2_BIT) : SPEAKER_2_PORT |= _BV(SPEAKER_2_BIT);
#endif #endif
delayMicroseconds(300); delayMicroseconds(300);
} }
SPEAKER_1_PORT &= ~_BV(SPEAKER_1_BIT);
SPEAKER_2_PORT &= ~_BV(SPEAKER_2_BIT);
hardwareChange = false; hardwareChange = false;
} }
} }

View File

@ -23,7 +23,7 @@ void setup() {
// initiate arduboy instance // initiate arduboy instance
arduboy.begin(); arduboy.begin();
// here we set the framerate to 15, we do not need to run at // here we set the frame rate to 15, we do not need to run at
// default 60 and it saves us battery life // default 60 and it saves us battery life
arduboy.setFrameRate(15); arduboy.setFrameRate(15);
} }
@ -46,6 +46,6 @@ void loop() {
// then we print to screen what is in the Quotation marks "" // then we print to screen what is in the Quotation marks ""
arduboy.print(F("Hello, world!")); arduboy.print(F("Hello, world!"));
// then we finaly we tell the arduboy to display what we just wrote to the display // then we finally we tell the arduboy to display what we just wrote to the display
arduboy.display(); arduboy.display();
} }

View File

@ -321,7 +321,7 @@ void drawBar(int y, Color color, byte value) {
} }
} }
// Draw the informaton for one digital color // Draw the information for one digital color
void drawDigital(int y, Color color, const char* name) { void drawDigital(int y, Color color, const char* name) {
byte state = digitalState[(byte)color]; byte state = digitalState[(byte)color];

View File

@ -5,7 +5,7 @@
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8 DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Arduboy2 Library" PROJECT_NAME = "Arduboy2 Library"
PROJECT_NUMBER = 5.3.0 PROJECT_NUMBER = 6.0.0
PROJECT_BRIEF = PROJECT_BRIEF =
PROJECT_LOGO = PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen OUTPUT_DIRECTORY = doxygen

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 343 B

View File

@ -77,10 +77,13 @@ given and a non-zero exit code will be returned.
## Input file decoding ## Input file decoding
The input file should be a PNG file containing the image to be converted. The The input file should be a PNG file containing the image to be converted.
image will be translated to a raw array of 32 bit RGBA (Red, Green, Blue, Alpha) The height of the image must be a multiple of 8 pixels (8, 16, 24, 32, ...).
pixels internally before being processed to output. Ideally, pixels that are to The width can be any size.
be drawn (represented as a 1 in the image output) should be fully white.
The image will be translated to a raw array of 32 bit RGBA (Red, Green, Blue,
Alpha) pixels internally before being processed to output. Ideally, pixels that
are to be drawn (represented as a 1 in the image output) should be fully white.
Non-drawn (0) pixels should be fully black. Pixels intended to be masked out of Non-drawn (0) pixels should be fully black. Pixels intended to be masked out of
the image (represented as a 0 in both the image and mask output), should be the image (represented as a 0 in both the image and mask output), should be
fully transparent and their color doesn't matter. fully transparent and their color doesn't matter.

View File

@ -11,7 +11,7 @@ https://www.lexaloffle.com/bbs/?uid=1
https://twitter.com/lexaloffle https://twitter.com/lexaloffle
Contributed to Team A.R.G. Contributed to Team A.R.G.
Modifications by Scott Allen - July 2016 Modifications by Scott Allen - July 2020, September 2020
To the extent possible under law, the author(s) have dedicated all copyright To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain and related and neighboring rights to this software to the public domain
@ -332,6 +332,12 @@ int main(int argc, char **argv)
exit(result); exit(result);
} }
if (h % 8 != 0) {
printf("error 120: file %s: image height must be a multiple of 8 but is %u\n", argv[1], h);
free(bmp);
exit(120);
}
// generate sprite and mask // generate sprite and mask
rawlen = w * (h+7) / 8; rawlen = w * (h+7) / 8;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 199 B

View File

@ -6,7 +6,7 @@ Documentation for files contained in this repository that aren't self explanator
Provides information so that this library can be installed and updated in the Arduino IDE using the [Library Manager](https://www.arduino.cc/en/Guide/Libraries#toc3). Provides information so that this library can be installed and updated in the Arduino IDE using the [Library Manager](https://www.arduino.cc/en/Guide/Libraries#toc3).
The value of *version* must be set to the latest stable tagged release. This should be changed and commited just before tagging the new release. The value of *version* must be set to the latest stable tagged release. This should be changed and committed just before tagging the new release.
See the [Arduino IDE 1.5: Library specification](https://arduino.github.io/arduino-cli/library-specification/) for details. See the [Arduino IDE 1.5: Library specification](https://arduino.github.io/arduino-cli/library-specification/) for details.
@ -14,7 +14,7 @@ See the [Arduino IDE 1.5: Library specification](https://arduino.github.io/ardui
This JSON file is a manifest used by the [PlatformIO IDE](https://platformio.org/) to make this library available in its [Library Manager](https://docs.platformio.org/en/latest/librarymanager/index.html). This JSON file is a manifest used by the [PlatformIO IDE](https://platformio.org/) to make this library available in its [Library Manager](https://docs.platformio.org/en/latest/librarymanager/index.html).
The value of *version* must be set to the latest stable tagged release. This should be changed and commited just before tagging the new release. The value of *version* must be set to the latest stable tagged release. This should be changed and committed just before tagging the new release.
See the [PlatformIO library.json](https://docs.platformio.org/en/latest/librarymanager/config.html) documentation for details. See the [PlatformIO library.json](https://docs.platformio.org/en/latest/librarymanager/config.html) documentation for details.

View File

@ -26,6 +26,7 @@ blank KEYWORD2
boot KEYWORD2 boot KEYWORD2
bootLogo KEYWORD2 bootLogo KEYWORD2
bootLogoCompressed KEYWORD2 bootLogoCompressed KEYWORD2
bootLogoExtra KEYWORD2
bootLogoShell KEYWORD2 bootLogoShell KEYWORD2
bootLogoSpritesBOverwrite KEYWORD2 bootLogoSpritesBOverwrite KEYWORD2
bootLogoSpritesBSelfMasked KEYWORD2 bootLogoSpritesBSelfMasked KEYWORD2
@ -67,11 +68,16 @@ flipHorizontal KEYWORD2
freeRGBled KEYWORD2 freeRGBled KEYWORD2
generateRandomSeed KEYWORD2 generateRandomSeed KEYWORD2
getBuffer KEYWORD2 getBuffer KEYWORD2
getCharacterHeight KEYWORD2
getCharacterSpacing KEYWORD2
getCharacterWidth KEYWORD2
getCursorX KEYWORD2 getCursorX KEYWORD2
getCursorY KEYWORD2 getCursorY KEYWORD2
getLineSpacing KEYWORD2
getPixel KEYWORD2 getPixel KEYWORD2
getTextBackground KEYWORD2 getTextBackground KEYWORD2
getTextColor KEYWORD2 getTextColor KEYWORD2
getTextRawMode KEYWORD2
getTextSize KEYWORD2 getTextSize KEYWORD2
getTextWrap KEYWORD2 getTextWrap KEYWORD2
height KEYWORD2 height KEYWORD2
@ -104,6 +110,7 @@ setFrameRate KEYWORD2
setRGBled KEYWORD2 setRGBled KEYWORD2
setTextBackground KEYWORD2 setTextBackground KEYWORD2
setTextColor KEYWORD2 setTextColor KEYWORD2
setTextRawMode KEYWORD2
setTextSize KEYWORD2 setTextSize KEYWORD2
setTextWrap KEYWORD2 setTextWrap KEYWORD2
SPItransfer KEYWORD2 SPItransfer KEYWORD2
@ -131,6 +138,21 @@ drawOverwrite KEYWORD2
drawPlusMask KEYWORD2 drawPlusMask KEYWORD2
drawSelfMasked KEYWORD2 drawSelfMasked KEYWORD2
##### Public variables #####
audio KEYWORD2
arduboy_logo KEYWORD2
arduboy_logo_compressed KEYWORD2
arduboy_logo_sprite KEYWORD2
currentButtonState KEYWORD2
font5x7 KEYWORD2
frameCount KEYWORD2
previousButtonState KEYWORD2
sBuffer KEYWORD2
# Arduboy2Beep classes
duration KEYWORD2
####################################### #######################################
# Constants (LITERAL1) # Constants (LITERAL1)
####################################### #######################################

View File

@ -7,7 +7,7 @@
"type": "git", "type": "git",
"url": "https://github.com/MLXXXp/Arduboy2.git" "url": "https://github.com/MLXXXp/Arduboy2.git"
}, },
"version": "5.3.0", "version": "6.0.0",
"export": "export":
{ {
"exclude": "extras" "exclude": "extras"

View File

@ -1,5 +1,5 @@
name=Arduboy2 name=Arduboy2
version=5.3.0 version=6.0.0
author=Chris J. Martinez, Kevin Bates, Josh Goebel, Scott Allen, Ross O. Shoger author=Chris J. Martinez, Kevin Bates, Josh Goebel, Scott Allen, Ross O. Shoger
maintainer=Scott Allen <saydisp-git@yahoo.ca> maintainer=Scott Allen <saydisp-git@yahoo.ca>
sentence=An alternative library for use with the Arduboy game system. sentence=An alternative library for use with the Arduboy game system.

View File

@ -10,37 +10,32 @@
//========== class Arduboy2Base ========== //========== class Arduboy2Base ==========
//======================================== //========================================
uint8_t Arduboy2Base::sBuffer[]; uint8_t Arduboy2Base::sBuffer[];
uint8_t Arduboy2Base::currentButtonState = 0; uint16_t Arduboy2Base::frameCount = 0;
uint8_t Arduboy2Base::previousButtonState = 0;
// frame management uint8_t Arduboy2Base::currentButtonState = 0;
uint16_t Arduboy2Base::frameCount = 0; uint8_t Arduboy2Base::previousButtonState = 0;
uint8_t Arduboy2Base::eachFrameMillis = 16;
uint8_t Arduboy2Base::thisFrameStart; uint8_t Arduboy2Base::eachFrameMillis = 16;
uint8_t Arduboy2Base::lastFrameDurationMs; uint8_t Arduboy2Base::thisFrameStart;
bool Arduboy2Base::justRendered = false; uint8_t Arduboy2Base::lastFrameDurationMs;
bool Arduboy2Base::justRendered = false;
// functions called here should be public so users can create their // functions called here should be public so users can create their
// own init functions if they need different behavior than `begin` // own init functions if they need different behavior than `begin`
// provides by default // provides by default.
//
// This code and it's documentation should be kept in sync with
// Aruduboy2::begin()
void Arduboy2Base::begin() void Arduboy2Base::begin()
{ {
boot(); // raw hardware beginDoFirst();
//using CLEAR_BUFFER so a sketch can be optimized when using CLEAR_BUFFER exclusivly
display(CLEAR_BUFFER); //sBuffer is global, so cleared automatically.
flashlight(); // light the RGB LED and screen if UP button is being held.
// check for and handle buttons held during start up for system control
systemButtons();
audio.begin();
bootLogo(); bootLogo();
// alternative logo functions. Work the same as bootLogo() but may reduce // alternative logo functions. Work the same as bootLogo() but may reduce
// memory size if the sketch uses the same bitmap drawing function // memory size if the sketch uses the same bitmap drawing function or
// `Sprites`/`SpritesB` class
// bootLogoCompressed(); // bootLogoCompressed();
// bootLogoSpritesSelfMasked(); // bootLogoSpritesSelfMasked();
// bootLogoSpritesOverwrite(); // bootLogoSpritesOverwrite();
@ -50,6 +45,20 @@ void Arduboy2Base::begin()
waitNoButtons(); // wait for all buttons to be released waitNoButtons(); // wait for all buttons to be released
} }
void Arduboy2Base::beginDoFirst()
{
boot(); // raw hardware
display(); // blank the display (sBuffer is global, so cleared automatically)
flashlight(); // light the RGB LED and screen if UP button is being held.
// check for and handle buttons held during start up for system control
systemButtons();
audio.begin();
}
void Arduboy2Base::flashlight() void Arduboy2Base::flashlight()
{ {
if (!pressed(UP_BUTTON)) { if (!pressed(UP_BUTTON)) {
@ -60,7 +69,9 @@ void Arduboy2Base::flashlight()
#else #else
sendLCDCommand(OLED_ALL_PIXELS_ON); // smaller than allPixelsOn() sendLCDCommand(OLED_ALL_PIXELS_ON); // smaller than allPixelsOn()
#endif #endif
digitalWriteRGB(RGB_ON, RGB_ON, RGB_ON); setRGBledRedOn();
setRGBledGreenOn();
setRGBledBlueOn();
// prevent the bootloader magic number from being overwritten by timer 0 // prevent the bootloader magic number from being overwritten by timer 0
// when a timer variable overlaps the magic number location, for when // when a timer variable overlaps the magic number location, for when
@ -75,19 +86,19 @@ void Arduboy2Base::flashlight()
void Arduboy2Base::systemButtons() void Arduboy2Base::systemButtons()
{ {
while (pressed(B_BUTTON)) { while (pressed(B_BUTTON)) {
digitalWriteRGB(BLUE_LED, RGB_ON); // turn on blue LED setRGBledBlueOn();
sysCtrlSound(UP_BUTTON + B_BUTTON, GREEN_LED, 0xff); sysCtrlSound(UP_BUTTON + B_BUTTON, GREEN_LED, 0xff);
sysCtrlSound(DOWN_BUTTON + B_BUTTON, RED_LED, 0); sysCtrlSound(DOWN_BUTTON + B_BUTTON, RED_LED, 0);
delayByte(200); delayByte(200);
} }
digitalWriteRGB(BLUE_LED, RGB_OFF); // turn off blue LED setRGBledBlueOff();
} }
void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal) void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal)
{ {
if (pressed(buttons)) { if (pressed(buttons)) {
digitalWriteRGB(BLUE_LED, RGB_OFF); // turn off blue LED setRGBledBlueOff();
delayByte(200); delayByte(200);
digitalWriteRGB(led, RGB_ON); // turn on "acknowledge" LED digitalWriteRGB(led, RGB_ON); // turn on "acknowledge" LED
EEPROM.update(eepromAudioOnOff, eeVal); EEPROM.update(eepromAudioOnOff, eeVal);
@ -160,35 +171,29 @@ void Arduboy2Base::drawLogoSpritesBOverwrite(int16_t y)
// bootLogoText() should be kept in sync with bootLogoShell() // bootLogoText() should be kept in sync with bootLogoShell()
// if changes are made to one, equivalent changes should be made to the other // if changes are made to one, equivalent changes should be made to the other
void Arduboy2Base::bootLogoShell(void (*drawLogo)(int16_t)) bool Arduboy2Base::bootLogoShell(void (&drawLogo)(int16_t))
{ {
bool showLEDs = readShowBootLogoLEDsFlag(); bool showLEDs = readShowBootLogoLEDsFlag();
if (!readShowBootLogoFlag()) { if (!readShowBootLogoFlag()) {
return; return false;
} }
if (showLEDs) { if (showLEDs) {
#if defined(LCD_ST7565) setRGBledRedOn();
digitalWriteRGB(RGB_ON, RGB_OFF, RGB_OFF);
#else
digitalWriteRGB(RED_LED, RGB_ON);
#endif
} }
for (int16_t y = -15; y <= 24; y++) { for (int16_t y = -15; y <= 24; y++) {
if (pressed(RIGHT_BUTTON)) { if (pressed(RIGHT_BUTTON)) {
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_OFF); // all LEDs off setRGBledRedOff();
return; setRGBledGreenOff();
//setRGBledblueOff(); // Blue LED not turned on inside loop
return false;
} }
if (showLEDs && y == 4) { if (showLEDs && y == 4) {
#if defined(LCD_ST7565) setRGBledRedOff();
digitalWriteRGB(RGB_OFF, RGB_ON, RGB_OFF); setRGBledGreenOn();
#else
digitalWriteRGB(RED_LED, RGB_OFF); // red LED off
digitalWriteRGB(GREEN_LED, RGB_ON); // green LED on
#endif
} }
// Using display(CLEAR_BUFFER) instead of clear() may save code space. // Using display(CLEAR_BUFFER) instead of clear() may save code space.
@ -200,27 +205,17 @@ void Arduboy2Base::bootLogoShell(void (*drawLogo)(int16_t))
} }
if (showLEDs) { if (showLEDs) {
#if defined(LCD_ST7565) setRGBledGreenOff();
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_ON); setRGBledBlueOn();
#else
digitalWriteRGB(GREEN_LED, RGB_OFF); // green LED off
digitalWriteRGB(BLUE_LED, RGB_ON); // blue LED on
#endif
} }
delayShort(400); delayShort(400);
#if defined(LCD_ST7565) setRGBledBlueOff();
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_OFF); return true;
#else
digitalWriteRGB(BLUE_LED, RGB_OFF);
#endif
bootLogoExtra();
} }
// Virtual function overridden by derived class
void Arduboy2Base::bootLogoExtra() { }
// wait for all buttons to be released // wait for all buttons to be released
void Arduboy2Base::waitNoButtons() { void Arduboy2Base::waitNoButtons()
{
do { do {
delayByte(50); // simple button debounce delayByte(50); // simple button debounce
} while (buttonsState()); } while (buttonsState());
@ -319,12 +314,10 @@ void Arduboy2Base::clear()
void Arduboy2Base::drawPixel(int16_t x, int16_t y, uint8_t color) void Arduboy2Base::drawPixel(int16_t x, int16_t y, uint8_t color)
{ {
#ifdef PIXEL_SAFE_MODE
if (x < 0 || x > (WIDTH-1) || y < 0 || y > (HEIGHT-1)) if (x < 0 || x > (WIDTH-1) || y < 0 || y > (HEIGHT-1))
{ {
return; return;
} }
#endif
uint16_t row_offset; uint16_t row_offset;
uint8_t bit; uint8_t bit;
@ -644,7 +637,7 @@ void Arduboy2Base::fillScreen(uint8_t color)
// { // {
// color = 0xFF; // all pixels on // color = 0xFF; // all pixels on
// } // }
// for (int16_t i = 0; i < WIDTH * HEIGTH / 8; i++) // for (int16_t i = 0; i < WIDTH * HEIGHT / 8; i++)
// { // {
// sBuffer[i] = color; // sBuffer[i] = color;
// } // }
@ -837,8 +830,7 @@ void Arduboy2Base::drawBitmap
int8_t yOffset = y & 7; int8_t yOffset = y & 7;
int8_t sRow = y >> 3; int8_t sRow = y >> 3;
uint8_t rows = h >> 3; uint8_t rows = (h+7) >> 3;
if (h % 8 != 0) rows++;
for (int a = 0; a < rows; a++) { for (int a = 0; a < rows; a++) {
int bRow = sRow + a; int bRow = sRow + a;
if (bRow > (HEIGHT/8)-1) break; if (bRow > (HEIGHT/8)-1) break;
@ -887,17 +879,18 @@ void Arduboy2Base::drawSlowXYBitmap
} }
} }
// Helper for drawCompressed() // Helper for drawCompressed()
struct Arduboy2Base::BitStreamReader class Arduboy2Base::BitStreamReader
{ {
private:
const uint8_t *source; const uint8_t *source;
uint16_t sourceIndex; uint16_t sourceIndex;
uint8_t bitBuffer; uint8_t bitBuffer;
uint8_t byteBuffer; uint8_t byteBuffer;
BitStreamReader(const uint8_t *source) public:
: source(source), sourceIndex(), bitBuffer(), byteBuffer() BitStreamReader(const uint8_t *bitmap)
: source(bitmap), sourceIndex(), bitBuffer(), byteBuffer()
{ {
} }
@ -906,17 +899,17 @@ struct Arduboy2Base::BitStreamReader
uint16_t result = 0; uint16_t result = 0;
for (uint8_t i = 0; i < bitCount; i++) for (uint8_t i = 0; i < bitCount; i++)
{ {
if (this->bitBuffer == 0) if (bitBuffer == 0)
{ {
this->bitBuffer = 0x1; bitBuffer = 0x1;
this->byteBuffer = pgm_read_byte(&this->source[this->sourceIndex]); byteBuffer = pgm_read_byte(&source[sourceIndex]);
++this->sourceIndex; ++sourceIndex;
} }
if ((this->byteBuffer & this->bitBuffer) != 0) if ((byteBuffer & bitBuffer) != 0)
result |= (1 << i); result |= (1 << i);
this->bitBuffer += this->bitBuffer; bitBuffer += bitBuffer;
} }
return result; return result;
} }
@ -925,7 +918,7 @@ struct Arduboy2Base::BitStreamReader
void Arduboy2Base::drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color) void Arduboy2Base::drawCompressed(int16_t sx, int16_t sy, const uint8_t *bitmap, uint8_t color)
{ {
// set up decompress state // set up decompress state
BitStreamReader cs = BitStreamReader(bitmap); BitStreamReader cs(bitmap);
// read header // read header
int width = (int)cs.readBits(8) + 1; int width = (int)cs.readBits(8) + 1;
@ -1176,14 +1169,84 @@ void Arduboy2Base::swapInt16(int16_t& a, int16_t& b)
//========== class Arduboy2 ========== //========== class Arduboy2 ==========
//==================================== //====================================
int16_t Arduboy2::cursor_x = 0; int16_t Arduboy2::cursor_x = 0;
int16_t Arduboy2::cursor_y = 0; int16_t Arduboy2::cursor_y = 0;
uint8_t Arduboy2::textColor = 1; uint8_t Arduboy2::textColor = WHITE;
uint8_t Arduboy2::textBackground = 0; uint8_t Arduboy2::textBackground = BLACK;
uint8_t Arduboy2::textSize = 1; uint8_t Arduboy2::textSize = 1;
bool Arduboy2::textWrap = false; bool Arduboy2::textWrap = false;
//bool Arduboy2::textRaw = false; bool Arduboy2::textRaw = false;
// functions called here should be public so users can create their
// own init functions if they need different behavior than `begin`
// provides by default.
//
// This code and it's documentation should be kept in sync with
// Aruduboy2Base::begin()
void Arduboy2::begin()
{
beginDoFirst();
bootLogo();
// alternative logo functions. Work the same as bootLogo() but may reduce
// memory size if the sketch uses the same bitmap drawing function or
// `Sprites`/`SpritesB` class
// bootLogoCompressed();
// bootLogoSpritesSelfMasked();
// bootLogoSpritesOverwrite();
// bootLogoSpritesBSelfMasked();
// bootLogoSpritesBOverwrite();
waitNoButtons();
}
void Arduboy2::bootLogo()
{
if (bootLogoShell(drawLogoBitmap))
{
bootLogoExtra();
}
}
void Arduboy2::bootLogoCompressed()
{
if (bootLogoShell(drawLogoCompressed))
{
bootLogoExtra();
}
}
void Arduboy2::bootLogoSpritesSelfMasked()
{
if (bootLogoShell(drawLogoSpritesSelfMasked))
{
bootLogoExtra();
}
}
void Arduboy2::bootLogoSpritesOverwrite()
{
if (bootLogoShell(drawLogoSpritesOverwrite))
{
bootLogoExtra();
}
}
void Arduboy2::bootLogoSpritesBSelfMasked()
{
if (bootLogoShell(drawLogoSpritesBSelfMasked))
{
bootLogoExtra();
}
}
void Arduboy2::bootLogoSpritesBOverwrite()
{
if (bootLogoShell(drawLogoSpritesBOverwrite))
{
bootLogoExtra();
}
}
// bootLogoText() should be kept in sync with bootLogoShell() // bootLogoText() should be kept in sync with bootLogoShell()
// if changes are made to one, equivalent changes should be made to the other // if changes are made to one, equivalent changes should be made to the other
@ -1196,26 +1259,20 @@ void Arduboy2::bootLogoText()
} }
if (showLEDs) { if (showLEDs) {
#if defined(LCD_ST7565) setRGBledRedOn();
digitalWriteRGB(RGB_ON, RGB_OFF, RGB_OFF);
#else
digitalWriteRGB(RED_LED, RGB_ON);
#endif
} }
for (int8_t y = -16; y <= 24; y++) { for (int8_t y = -16; y <= 24; y++) {
if (pressed(RIGHT_BUTTON)) { if (pressed(RIGHT_BUTTON)) {
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_OFF); // all LEDs off setRGBledRedOff();
setRGBledGreenOff();
//setRGBledBlueOff(); //not turned on inside loop
return; return;
} }
if (showLEDs && y == 4) { if (showLEDs && y == 4) {
#if defined(LCD_ST7565) setRGBledRedOff();
digitalWriteRGB(RGB_OFF, RGB_ON, RGB_OFF); setRGBledGreenOn();
#else
digitalWriteRGB(RED_LED, RGB_OFF); // red LED off
digitalWriteRGB(GREEN_LED, RGB_ON); // green LED on
#endif
} }
// Using display(CLEAR_BUFFER) instead of clear() may save code space. // Using display(CLEAR_BUFFER) instead of clear() may save code space.
@ -1231,20 +1288,11 @@ void Arduboy2::bootLogoText()
} }
if (showLEDs) { if (showLEDs) {
#if defined(LCD_ST7565) setRGBledGreenOff();
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_ON); setRGBledBlueOn();
#else
digitalWriteRGB(GREEN_LED, RGB_OFF); // green LED off
digitalWriteRGB(BLUE_LED, RGB_ON); // blue LED on
#endif
} }
delayShort(400); delayShort(400);
#if defined(LCD_ST7565) setRGBledBlueOff();
digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_OFF);
#else
digitalWriteRGB(BLUE_LED, RGB_OFF);
#endif
bootLogoExtra(); bootLogoExtra();
} }
@ -1279,64 +1327,106 @@ void Arduboy2::bootLogoExtra()
size_t Arduboy2::write(uint8_t c) size_t Arduboy2::write(uint8_t c)
{ {
if (c == '\n') if ((c == '\r') && !textRaw)
{
return 1;
}
if (((c == '\n') && !textRaw) ||
(textWrap && (cursor_x > (WIDTH - (characterWidth * textSize)))))
{ {
cursor_y += textSize * 8;
cursor_x = 0; cursor_x = 0;
cursor_y += fullCharacterHeight * textSize;
} }
else if (c == '\r')
{ if ((c != '\n') || textRaw)
// skip em
}
else
{ {
drawChar(cursor_x, cursor_y, c, textColor, textBackground, textSize); drawChar(cursor_x, cursor_y, c, textColor, textBackground, textSize);
cursor_x += textSize * 6; cursor_x += fullCharacterWidth * textSize;
if (textWrap && (cursor_x > (WIDTH - textSize * 6)))
{
// calling ourselves recursively for 'newline' is
// 12 bytes smaller than doing the same math here
write('\n');
}
} }
return 1; return 1;
} }
void Arduboy2::drawChar void Arduboy2::drawChar
(int16_t x, int16_t y, unsigned char c, uint8_t color, uint8_t bg, uint8_t size) (int16_t x, int16_t y, uint8_t c, uint8_t color, uint8_t bg, uint8_t size)
{ {
uint8_t line; // It is assumed that rendering characters fully off screen will be rare,
bool draw_background = bg != color; // so let drawPixel() handle off screen checks, to reduce code size at the
const uint8_t* bitmap = font5x7 + c * 5; // expense of slower off screen character handling.
#if 0
if ((x >= WIDTH) || // Clip right if ((x >= WIDTH) || // Clip right
(y >= HEIGHT) || // Clip bottom (y >= HEIGHT) || // Clip bottom
((x + 5 * size - 1) < 0) || // Clip left ((x + characterWidth * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0) // Clip top ((y + characterHeight * size - 1) < 0) // Clip top
) )
{ {
return; return;
} }
#endif
for (uint8_t i = 0; i < 6; i++ ) bool drawBackground = bg != color;
const uint8_t* bitmap =
&font5x7[c * characterWidth * ((characterHeight + 8 - 1) / 8)];
for (uint8_t i = 0; i < fullCharacterWidth; i++)
{ {
line = pgm_read_byte(bitmap++); uint8_t column;
if (i == 5) {
line = 0x0; if (characterHeight <= 8)
{
column = (i < characterWidth) ? pgm_read_byte(bitmap++) : 0;
}
else
{
column = 0;
} }
for (uint8_t j = 0; j < 8; j++) // draw the character by columns. Top to bottom, left to right
// including character spacing on the right
for (uint8_t j = 0; j < characterHeight; j++)
{ {
uint8_t draw_color = (line & 0x1) ? color : bg; if (characterHeight > 8)
{
// at this point variable "column" will be 0, either from initialization
// or by having eight 0 bits shifted in by the >>= operation below
if ((j % 8 == 0) && (i < characterWidth))
{
column = pgm_read_byte(bitmap++);
}
}
if (draw_color || draw_background) { // pixelIsSet should be a bool but at the time of writing,
for (uint8_t a = 0; a < size; a++ ) { // the GCC AVR compiler generates less code if it's a uint8_t
for (uint8_t b = 0; b < size; b++ ) { uint8_t pixelIsSet = column & 0x01;
drawPixel(x + (i * size) + a, y + (j * size) + b, draw_color);
if (pixelIsSet || drawBackground)
{
for (uint8_t a = 0; a < size; a++)
{
for (uint8_t b = 0; b < size; b++)
{
drawPixel(x + (i * size) + a, y + (j * size) + b,
pixelIsSet ? color : bg);
}
}
}
column >>= 1;
}
// draw the inter-line spacing pixels for this column if required
if (drawBackground)
{
for (uint8_t j = characterHeight; j < fullCharacterHeight; j++)
{
for (uint8_t a = 0; a < size; a++)
{
for (uint8_t b = 0; b < size; b++)
{
drawPixel(x + (i * size) + a, y + (j * size) + b, bg);
} }
} }
} }
line >>= 1;
} }
} }
} }
@ -1408,6 +1498,16 @@ bool Arduboy2::getTextWrap()
return textWrap; return textWrap;
} }
void Arduboy2::setTextRawMode(bool raw)
{
textRaw = raw;
}
bool Arduboy2::getTextRawMode()
{
return textRaw;
}
void Arduboy2::clear() void Arduboy2::clear()
{ {
Arduboy2Base::clear(); Arduboy2Base::clear();

File diff suppressed because it is too large Load Diff

View File

@ -80,11 +80,8 @@ class Arduboy2Audio
* *
* \details * \details
* The speaker is initialized based on the current mute setting saved in * The speaker is initialized based on the current mute setting saved in
* system EEPROM. This function is called by `Arduboy2Base::begin()` so it * system EEPROM.
* isn't normally required to call it within a sketch. However, if */
* `Arduboy2Core::boot()` is used instead of `Arduboy2Base::begin()` and the
* sketch includes sound, then this function should be called after `boot()`.
*/
static void begin(); static void begin();
/** \brief /** \brief

View File

@ -45,7 +45,7 @@ void BeepPin1::noTone()
} }
// Speaker pin 2, Timer 4A, Port C bit 7, Arduino pin 13 // Speaker pin 2, Timer 4A, Port C bit 7, Arduino pin 13 or Port D bit 7, Arduino pin 6 for alternate wiring
uint8_t BeepPin2::duration = 0; uint8_t BeepPin2::duration = 0;
@ -53,6 +53,9 @@ void BeepPin2::begin()
{ {
TCCR4A = 0; // normal mode. Disable PWM TCCR4A = 0; // normal mode. Disable PWM
TCCR4B = bit(CS43); // divide by 128 clock prescale TCCR4B = bit(CS43); // divide by 128 clock prescale
#ifdef AB_ALTERNATE_WIRING
TCCR4C = 0; // normal mode
#endif
TCCR4D = 0; // normal mode TCCR4D = 0; // normal mode
TC4H = 0; // toggle pin at count = 0 TC4H = 0; // toggle pin at count = 0
OCR4A = 0; // " OCR4A = 0; // "
@ -66,22 +69,30 @@ void BeepPin2::tone(uint16_t count)
void BeepPin2::tone(uint16_t count, uint8_t dur) void BeepPin2::tone(uint16_t count, uint8_t dur)
{ {
duration = dur; duration = dur;
TCCR4A = bit(COM4A0); // set toggle on compare mode (which connects the pin) #ifdef AB_ALTERNATE_WIRING
TC4H = highByte(count); // load the count (10 bits), TCCR4C = bit(COM4D0); // set toggle on compare mode (which connects pin 6)
#else
TCCR4A = bit(COM4A0); // set toggle on compare mode (which connects pin 13)
#endif
TC4H = highByte(count); // load the count (10 bits),
OCR4C = lowByte(count); // which determines the frequency OCR4C = lowByte(count); // which determines the frequency
} }
void BeepPin2::timer() void BeepPin2::timer()
{ {
if (duration && (--duration == 0)) { if (duration && (--duration == 0)) {
TCCR4A = 0; // set normal mode (which disconnects the pin) noTone();
} }
} }
void BeepPin2::noTone() void BeepPin2::noTone()
{ {
duration = 0; duration = 0;
#ifdef AB_ALTERNATE_WIRING
TCCR4C = 0; // set normal mode (which disconnects the pin)
#else
TCCR4A = 0; // set normal mode (which disconnects the pin) TCCR4A = 0; // set normal mode (which disconnects the pin)
#endif
} }

View File

@ -8,13 +8,14 @@
#include <avr/wdt.h> #include <avr/wdt.h>
#ifndef OLED_CONTRAST
# define OLED_CONTRAST 0xCF
#endif
//======================================== //========================================
//========== class Arduboy2Core ========== //========== class Arduboy2Core ==========
//======================================== //========================================
Arduboy2Core::Arduboy2Core() { }
// Commands sent to the OLED display to initialize it // Commands sent to the OLED display to initialize it
const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = { const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = {
// boot defaults are commented out but left here in case they // boot defaults are commented out but left here in case they
@ -27,13 +28,13 @@ const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = {
0x47, // set brightness 0x47, // set brightness
0x64, 0x00, // set x position 0 0x64, 0x00, // set x position 0
0x84, // address mode set: X increment 0x84, // address mode set: X increment
#elif defined(OLED_SH1106) #elif defined(OLED_SH1106) || (OLED_SH1106_I2C)
0x8D, 0x14, // Charge Pump Setting v = enable (0x14) 0x8D, 0x14, // Charge Pump Setting v = enable (0x14)
0xA1, // Set Segment Re-map 0xA1, // Set Segment Re-map
0xC8, // Set COM Output Scan Direction 0xC8, // Set COM Output Scan Direction
0x81, 0xCF, // Set Contrast v = 0xCF 0x81, OLED_CONTRAST, // Set Contrast v = 0xCF
0xD9, 0xF1, // Set Precharge = 0xF1 0xD9, 0xF1, // Set Precharge = 0xF1
OLED_SET_COLUMN_ADDRESS_LO, //Set column address for left most pixel OLED_SET_COLUMN_ADDRESS_LO, //Set column address for left most pixel
0xAF // Display On 0xAF // Display On
#elif defined(LCD_ST7565) #elif defined(LCD_ST7565)
0xC8, //SET_COM_REVERSE 0xC8, //SET_COM_REVERSE
@ -78,7 +79,7 @@ const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = {
0xA8, 0x7F, //Set MUX ratio 128MUX 0xA8, 0x7F, //Set MUX ratio 128MUX
//0xB2, 0x23, //0xB2, 0x23,
//0xB3, 0xF0, //set devider clock | oscillator frequency //0xB3, 0xF0, //set devider clock | oscillator frequency
0x81, 0xCF, //Set contrast 0x81, OLED_CONTRAST, //Set contrast
//0xBC, 0x1F, //set precharge voltage //0xBC, 0x1F, //set precharge voltage
//0x82, 0xFE, //set second Precharge speed //0x82, 0xFE, //set second Precharge speed
0xB1, 0x21, //reset and 1st precharge phase length phase 2:2 DCLKs, Phase 1: 1 DCLKs 0xB1, 0x21, //reset and 1st precharge phase length phase 2:2 DCLKs, Phase 1: 1 DCLKs
@ -124,7 +125,7 @@ const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = {
// 0xDA, 0x12, // 0xDA, 0x12,
// Set Contrast v = 0xCF // Set Contrast v = 0xCF
0x81, 0xCF, 0x81, OLED_CONTRAST,
// Set Precharge = 0xF1 // Set Precharge = 0xF1
0xD9, 0xF1, 0xD9, 0xF1,
@ -224,11 +225,11 @@ void Arduboy2Core::bootPins()
_BV(TX_LED_BIT) | //TX LED off for Arduboy and non Micro based Arduino _BV(TX_LED_BIT) | //TX LED off for Arduboy and non Micro based Arduino
#endif #endif
_BV(CART_BIT) | _BV(CART_BIT) |
#if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX)) #if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C))
_BV(DC_BIT) | _BV(DC_BIT) |
#endif #endif
0) & ~( // Port D INPUTs or LOW outputs 0) & ~( // Port D INPUTs or LOW outputs
#if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX)) #if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C))
_BV(CS_BIT) | // oled display enabled _BV(CS_BIT) | // oled display enabled
_BV(RST_BIT) | // reset active _BV(RST_BIT) | // reset active
#endif #endif
@ -238,7 +239,7 @@ void Arduboy2Core::bootPins()
#if defined(LCD_ST7565) #if defined(LCD_ST7565)
_BV(POWER_LED_BIT) | _BV(POWER_LED_BIT) |
#endif #endif
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
_BV(I2C_SCL) | _BV(I2C_SCL) |
_BV(I2C_SDA) | _BV(I2C_SDA) |
#endif #endif
@ -246,7 +247,7 @@ void Arduboy2Core::bootPins()
// Port D outputs // Port D outputs
DDRD = ( DDRD = (
#if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX)) #if !(defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C))
_BV(DC_BIT) | _BV(DC_BIT) |
#endif #endif
#if !(defined(AB_ALTERNATE_WIRING) && (CART_CS_SDA)) #if !(defined(AB_ALTERNATE_WIRING) && (CART_CS_SDA))
@ -262,7 +263,7 @@ void Arduboy2Core::bootPins()
_BV(CART_BIT) | _BV(CART_BIT) |
_BV(TX_LED_BIT) | _BV(TX_LED_BIT) |
0) & ~(// Port D inputs 0) & ~(// Port D inputs
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
_BV(I2C_SCL) | // SDA and SCL as inputs without pullups _BV(I2C_SCL) | // SDA and SCL as inputs without pullups
_BV(I2C_SDA) | // (both externally pulled up) _BV(I2C_SDA) | // (both externally pulled up)
#endif #endif
@ -349,7 +350,7 @@ void Arduboy2Core::bootOLED()
displayWrite(pgm_read_byte(lcdBootProgram + i - 8)); displayWrite(pgm_read_byte(lcdBootProgram + i - 8));
} }
displayDisable(); displayDisable();
#elif defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #elif defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_CMD); i2c_start(SSD1306_I2C_CMD);
for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++) for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++)
i2c_sendByte(pgm_read_byte(lcdBootProgram + i)); i2c_sendByte(pgm_read_byte(lcdBootProgram + i));
@ -418,7 +419,7 @@ void Arduboy2Core::SPItransfer(uint8_t data)
while (!(SPSR & _BV(SPIF))) { } // wait while (!(SPSR & _BV(SPIF))) { } // wait
} }
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
void Arduboy2Core::i2c_start(uint8_t mode) void Arduboy2Core::i2c_start(uint8_t mode)
{ {
I2C_SDA_LOW(); // disable posible internal pullup, ensure SDA low on enabling output I2C_SDA_LOW(); // disable posible internal pullup, ensure SDA low on enabling output
@ -467,7 +468,7 @@ void Arduboy2Core::safeMode()
{ {
if (buttonsState() == UP_BUTTON) if (buttonsState() == UP_BUTTON)
{ {
digitalWriteRGB(RED_LED, RGB_ON); setRGBledRedOn();
#ifndef ARDUBOY_CORE // for Arduboy core timer 0 should remain enabled #ifndef ARDUBOY_CORE // for Arduboy core timer 0 should remain enabled
// prevent the bootloader magic number from being overwritten by timer 0 // prevent the bootloader magic number from being overwritten by timer 0
@ -529,13 +530,13 @@ void Arduboy2Core::displayOff()
displayWrite(0x20); displayWrite(0x20);
displayWrite(0x00); displayWrite(0x00);
displayDisable(); displayDisable();
#elif defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #elif defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_CMD); i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(0xAE); // display off i2c_sendByte(0xAE); // display off
i2c_sendByte(0x8D); // charge pump: i2c_sendByte(0x8D); // charge pump:
i2c_sendByte(0x10); // disable i2c_sendByte(0x10); // disable
i2c_stop(); i2c_stop();
#else #else
LCDCommandMode(); LCDCommandMode();
SPItransfer(0xAE); // display off SPItransfer(0xAE); // display off
SPItransfer(0x8D); // charge pump: SPItransfer(0x8D); // charge pump:
@ -554,7 +555,7 @@ void Arduboy2Core::displayOn()
void Arduboy2Core::paint8Pixels(uint8_t pixels) void Arduboy2Core::paint8Pixels(uint8_t pixels)
{ {
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_DATA); i2c_start(SSD1306_I2C_DATA);
i2c_sendByte(pixels); i2c_sendByte(pixels);
i2c_stop(); i2c_stop();
@ -587,6 +588,19 @@ void Arduboy2Core::paintScreen(const uint8_t *image)
for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++) for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++)
i2c_sendByte(pgm_read_byte(image+i)); i2c_sendByte(pgm_read_byte(image+i));
i2c_stop(); i2c_stop();
#elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI); // only reset hi nibble to zero
i2c_stop();
const uint8_t *line = image + page*WIDTH;
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(pgm_read_byte(line+i));
i2c_stop();
}
#elif defined(OLED_SH1106) || defined(LCD_ST7565) #elif defined(OLED_SH1106) || defined(LCD_ST7565)
for (uint8_t i = 0; i < HEIGHT / 8; i++) for (uint8_t i = 0; i < HEIGHT / 8; i++)
{ {
@ -807,7 +821,28 @@ void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
); );
#endif #endif
i2c_stop(); i2c_stop();
#elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI);
i2c_stop();
i2c_start(SSD1306_I2C_DATA);
if (clear)
{
for (int i = 0; i < WIDTH; i++)
{
i2c_sendByte(*image);
*(image++) = 0;
}
} else
{
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(*(image++));
}
i2c_stop();
}
#elif defined(OLED_SH1106) || defined(LCD_ST7565) #elif defined(OLED_SH1106) || defined(LCD_ST7565)
//Assembly optimized page mode display code with clear support. //Assembly optimized page mode display code with clear support.
//Each byte transfer takes 18 cycles //Each byte transfer takes 18 cycles
@ -1025,7 +1060,19 @@ void Arduboy2Core::blank()
for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++) for (int i = 0; i < (HEIGHT * WIDTH) / 8; i++)
i2c_sendByte(0); i2c_sendByte(0);
i2c_stop(); i2c_stop();
#else #elif defined (OLED_SH1106_I2C)
for (int page = 0; page < HEIGHT/8; page++)
{
i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(OLED_SET_PAGE_ADDRESS + page); // set page
i2c_sendByte(OLED_SET_COLUMN_ADDRESS_HI); // only reset hi nibble to zero
i2c_stop();
i2c_start(SSD1306_I2C_DATA);
for (int i = 0; i < WIDTH; i++)
i2c_sendByte(0);
i2c_stop();
}
#else
#if defined (OLED_SH1106) #if defined (OLED_SH1106)
for (int i = 0; i < (HEIGHT * 132) / 8; i++) for (int i = 0; i < (HEIGHT * 132) / 8; i++)
#elif defined(OLED_96X96) || defined(OLED_128X96) || defined(OLED_128X128)|| defined(OLED_128X64_ON_96X96) || defined(OLED_128X64_ON_128X96) || defined(OLED_128X64_ON_128X128)|| defined(OLED_128X96_ON_128X128) || defined(OLED_96X96_ON_128X128) || defined(OLED_64X128_ON_128X128) #elif defined(OLED_96X96) || defined(OLED_128X96) || defined(OLED_128X128)|| defined(OLED_128X64_ON_96X96) || defined(OLED_128X64_ON_128X96) || defined(OLED_128X64_ON_128X128)|| defined(OLED_128X96_ON_128X128) || defined(OLED_96X96_ON_128X128) || defined(OLED_64X128_ON_128X128)
@ -1039,7 +1086,7 @@ void Arduboy2Core::blank()
void Arduboy2Core::sendLCDCommand(uint8_t command) void Arduboy2Core::sendLCDCommand(uint8_t command)
{ {
#if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined(OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
i2c_start(SSD1306_I2C_CMD); i2c_start(SSD1306_I2C_CMD);
i2c_sendByte(command); i2c_sendByte(command);
i2c_stop(); i2c_stop();
@ -1109,6 +1156,60 @@ void Arduboy2Core::flipHorizontal(bool flipped)
/* RGB LED */ /* RGB LED */
void Arduboy2Core::setRGBledRedOn()
{
#ifndef LCD_ST7565
bitClear(RED_LED_PORT, RED_LED_BIT); // Red on
#else
bitSet(RED_LED_PORT, RED_LED_BIT); // Red on
#endif
}
void Arduboy2Core::setRGBledRedOff()
{
#ifndef LCD_ST7565
bitSet(RED_LED_PORT, RED_LED_BIT); // Red off
#else
bitClear(RED_LED_PORT, RED_LED_BIT); // Red off
#endif
}
void Arduboy2Core::setRGBledGreenOn()
{
#ifndef LCD_ST7565
bitClear(GREEN_LED_PORT, GREEN_LED_BIT); // Green on
#else
bitSet(GREEN_LED_PORT, GREEN_LED_BIT); // Green on
#endif
}
void Arduboy2Core::setRGBledGreenOff()
{
#ifndef LCD_ST7565
bitSet(GREEN_LED_PORT, GREEN_LED_BIT); // Green off
#else
bitClear(GREEN_LED_PORT, GREEN_LED_BIT); // Green off
#endif
}
void Arduboy2Core::setRGBledBlueOn()
{
#ifndef LCD_ST7565
bitClear(BLUE_LED_PORT, BLUE_LED_BIT); // Blue on
#else
bitSet(BLUE_LED_PORT, BLUE_LED_BIT); // Blue on
#endif
}
void Arduboy2Core::setRGBledBlueOff()
{
#ifndef LCD_ST7565
bitSet(BLUE_LED_PORT, BLUE_LED_BIT); // Blue off
#else
bitClear(BLUE_LED_PORT, BLUE_LED_BIT); // Blue off
#endif
}
void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue) void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue)
{ {
#ifdef LCD_ST7565 #ifdef LCD_ST7565
@ -1120,93 +1221,35 @@ void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue)
} }
#endif #endif
#ifdef ARDUBOY_10 // RGB, all the pretty colors #ifdef ARDUBOY_10 // RGB, all the pretty colors
uint8_t pwmstate = TCCR0A; // timer 0: Fast PWM, OC0A clear on compare / set at top
// We must stay in Fast PWM mode because timer 0 is used for system timing.
// We can't use "inverted" mode because it won't allow full shut off.
#ifndef AB_ALTERNATE_WIRING #ifndef AB_ALTERNATE_WIRING
pwmstate &= ~_BV(COM0A1); //default to digital pin for min and max values TCCR0A = _BV(COM0A1) | _BV(WGM01) | _BV(WGM00);
#else #ifndef LCD_ST7565
pwmstate &= ~_BV(COM0B1); OCR0A = 255 - green;
#else
OCR0A = green;
#endif
#else
TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
#ifndef LCD_ST7565
OCR0B = 255 - green;
#else
OCR0B = green;
#endif
#endif
// timer 1: Phase correct PWM 8 bit
// OC1A and OC1B set on up-counting / clear on down-counting (inverted). This
// allows the value to be directly loaded into the OCR with common anode LED.
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM10);
#ifndef LCD_ST7565
OCR1AL = blue;
OCR1BL = red;
#else
OCR1AL = 255 - blue;
OCR1BL = 255 - red;
#endif #endif
if (green == 0)
#if defined(LCD_ST7565)
bitClear(GREEN_LED_PORT, GREEN_LED_BIT);
#else
bitSet(GREEN_LED_PORT, GREEN_LED_BIT);
#endif
else if (green == 255)
#if defined(LCD_ST7565)
bitSet(GREEN_LED_PORT, GREEN_LED_BIT);
#else
bitClear(GREEN_LED_PORT, GREEN_LED_BIT);
#endif
else
{
#ifndef AB_ALTERNATE_WIRING
pwmstate |= _BV(COM0A1); //configure pin as pwm pin
#if defined(LCD_ST7565)
OCR0A = green; //set pwm duty
#else
OCR0A = 255 - green; //set pwm duty
#endif
#else
pwmstate |= _BV(COM0B1);
OCR0B = 255 - green;
#endif
}
TCCR0A = pwmstate;
pwmstate = TCCR1A & ~(_BV(COM1B1) | _BV(COM1A1)); //default to digital pins for min and max values
if (red == 0)
{
#if defined(LCD_ST7565)
bitClear(RED_LED_PORT, RED_LED_BIT);
#else
bitSet(RED_LED_PORT, RED_LED_BIT);
#endif
}
else if (red == 255)
{
#if defined(LCD_ST7565)
bitSet(RED_LED_PORT, RED_LED_BIT);
#else
bitClear(RED_LED_PORT, RED_LED_BIT);
#endif
}
else
{
pwmstate |= _BV(COM1B1); //configure pin as pwm pin
OCR1BH = 0;
#if defined(LCD_ST7565)
OCR1BL = red; //set pwm duty
#else
OCR1BL = 255 - red; //set pwm duty
#endif
}
if (blue == 0)
{
#if defined(LCD_ST7565)
bitClear(BLUE_LED_PORT, BLUE_LED_BIT);
#else
bitSet(BLUE_LED_PORT, BLUE_LED_BIT);
#endif
}
else if (blue == 255)
{
#if defined(LCD_ST7565)
bitSet(BLUE_LED_PORT, BLUE_LED_BIT);
#else
bitClear(BLUE_LED_PORT, BLUE_LED_BIT);
#endif
}
else
{
pwmstate |= _BV(COM1A1); //configure pin as pwm pin
OCR1AH = 0;
#if defined(LCD_ST7565)
OCR1AL = blue; //set pwm duty
#else
OCR1AL = 255 - blue; //set pwm duty
#endif
}
TCCR1A = pwmstate;
#elif defined(AB_DEVKIT) #elif defined(AB_DEVKIT)
// only blue on DevKit, which is not PWM capable // only blue on DevKit, which is not PWM capable
(void)red; // parameter unused (void)red; // parameter unused
@ -1324,7 +1367,11 @@ uint8_t Arduboy2Core::buttonsState()
// up, right, left, down // up, right, left, down
buttons = ((~PINF) & buttons = ((~PINF) &
(_BV(UP_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) | (_BV(UP_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
_BV(LEFT_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT))); _BV(LEFT_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
#ifdef SUPPORT_XY_BUTTONS
_BV(X_BUTTON_BIT) | _BV(Y_BUTTON_BIT) |
#endif
0));
// A // A
if (bitRead(A_BUTTON_PORTIN, A_BUTTON_BIT) == 0) { buttons |= A_BUTTON; } if (bitRead(A_BUTTON_PORTIN, A_BUTTON_BIT) == 0) { buttons |= A_BUTTON; }
// B // B
@ -1421,6 +1468,7 @@ void Arduboy2NoUSB::mainNoUSB()
// This would normally be done in the USB code that uses the TX and RX LEDs // This would normally be done in the USB code that uses the TX and RX LEDs
//TX_RX_LED_INIT; // configured by bootpins //TX_RX_LED_INIT; // configured by bootpins
#ifndef ARDUBOY_CORE // (Arduboy core supports UP + DOWN to enter bootloader)
// Set the DOWN button pin for INPUT_PULLUP // Set the DOWN button pin for INPUT_PULLUP
bitSet(DOWN_BUTTON_PORT, DOWN_BUTTON_BIT); bitSet(DOWN_BUTTON_PORT, DOWN_BUTTON_BIT);
bitClear(DOWN_BUTTON_DDR, DOWN_BUTTON_BIT); bitClear(DOWN_BUTTON_DDR, DOWN_BUTTON_BIT);
@ -1432,7 +1480,7 @@ void Arduboy2NoUSB::mainNoUSB()
if (bitRead(DOWN_BUTTON_PORTIN, DOWN_BUTTON_BIT) == 0) { if (bitRead(DOWN_BUTTON_PORTIN, DOWN_BUTTON_BIT) == 0) {
Arduboy2Core::exitToBootloader(); Arduboy2Core::exitToBootloader();
} }
#endif
// The remainder is a copy of the Arduino main() function with the // The remainder is a copy of the Arduino main() function with the
// USB code and other unneeded code commented out. // USB code and other unneeded code commented out.
// init() was called above. // init() was called above.

View File

@ -11,7 +11,6 @@
#include <avr/power.h> #include <avr/power.h>
#include <avr/sleep.h> #include <avr/sleep.h>
extern volatile unsigned char bootloader_timer;
// main hardware compile flags // main hardware compile flags
@ -78,7 +77,7 @@ extern volatile unsigned char bootloader_timer;
#define SPI_SCK_PORT PORTB #define SPI_SCK_PORT PORTB
#define SPI_SCK_BIT PORTB1 #define SPI_SCK_BIT PORTB1
#if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
#define I2C_PORT PORTD #define I2C_PORT PORTD
#define I2C_DDR DDRD #define I2C_DDR DDRD
#define I2C_PIN PIND #define I2C_PIN PIND
@ -147,6 +146,10 @@ extern volatile unsigned char bootloader_timer;
#define DOWN_BUTTON _BV(4) /**< The Down button value for functions requiring a bitmask */ #define DOWN_BUTTON _BV(4) /**< The Down button value for functions requiring a bitmask */
#define A_BUTTON _BV(3) /**< The A button value for functions requiring a bitmask */ #define A_BUTTON _BV(3) /**< The A button value for functions requiring a bitmask */
#define B_BUTTON _BV(2) /**< The B button value for functions requiring a bitmask */ #define B_BUTTON _BV(2) /**< The B button value for functions requiring a bitmask */
#ifdef SUPPORT_XY_BUTTONS
#define X_BUTTON _BV(1)
#define Y_BUTTON _BV(0)
#endif
#define PIN_LEFT_BUTTON A2 #define PIN_LEFT_BUTTON A2
#define LEFT_BUTTON_PORT PORTF #define LEFT_BUTTON_PORT PORTF
@ -184,6 +187,20 @@ extern volatile unsigned char bootloader_timer;
#define B_BUTTON_DDR DDRB #define B_BUTTON_DDR DDRB
#define B_BUTTON_BIT PORTB4 #define B_BUTTON_BIT PORTB4
#ifdef SUPPORT_XY_BUTTONS
#define PIN_X_BUTTON A4
#define X_BUTTON_PORT PORTF
#define X_BUTTON_PORTIN PINF
#define X_BUTTON_DDR DDRF
#define X_BUTTON_BIT PORTF1
#define PIN_Y_BUTTON A5
#define Y_BUTTON_PORT PORTF
#define Y_BUTTON_PORTIN PINF
#define Y_BUTTON_DDR DDRF
#define Y_BUTTON_BIT PORTF0
#endif
#define PIN_SPEAKER_1 5 /**< The pin number of the first lead of the speaker */ #define PIN_SPEAKER_1 5 /**< The pin number of the first lead of the speaker */
#define SPEAKER_1_PORT PORTC #define SPEAKER_1_PORT PORTC
@ -330,12 +347,13 @@ extern volatile unsigned char bootloader_timer;
#define OLED_HORIZ_NORMAL 0xA1 // normal segment re-map #define OLED_HORIZ_NORMAL 0xA1 // normal segment re-map
#define OLED_SET_PAGE_ADDRESS 0xB0 #define OLED_SET_PAGE_ADDRESS 0xB0
#ifdef OLED_SH1106 #if defined(OLED_SH1106) || defined(OLED_SH1106_I2C)
#define OLED_SET_COLUMN_ADDRESS_LO 0x02 //SH1106 only: 1st pixel starts on column 2 #define OLED_SET_COLUMN_ADDRESS_LO 0x02 //SH1106 only: 1st pixel starts on column 2
#else #else
#define OLED_SET_COLUMN_ADDRESS_LO 0x00 #define OLED_SET_COLUMN_ADDRESS_LO 0x00
#endif #endif
#define OLED_SET_COLUMN_ADDRESS_HI 0x10 #define OLED_SET_COLUMN_ADDRESS_HI 0x10
// ----- // -----
#if defined (OLED_96X96) || (OLED_96X96_ON_128X128) #if defined (OLED_96X96) || (OLED_96X96_ON_128X128)
#define WIDTH 96 #define WIDTH 96
@ -445,7 +463,6 @@ class Arduboy2Core : public Arduboy2NoUSB
friend class Arduboy2Ex; friend class Arduboy2Ex;
public: public:
Arduboy2Core();
/** \brief /** \brief
* Idle the CPU to save power. * Idle the CPU to save power.
@ -473,7 +490,7 @@ class Arduboy2Core : public Arduboy2NoUSB
* *
* \see LCDCommandMode() SPItransfer() * \see LCDCommandMode() SPItransfer()
*/ */
void static inline LCDDataMode() __attribute__((always_inline)) static void inline LCDDataMode() __attribute__((always_inline))
{ {
#if defined(GU12864_800B) #if defined(GU12864_800B)
bitClear(DC_PORT, DC_BIT); bitClear(DC_PORT, DC_BIT);
@ -503,7 +520,7 @@ class Arduboy2Core : public Arduboy2NoUSB
* *
* \see LCDDataMode() sendLCDCommand() SPItransfer() * \see LCDDataMode() sendLCDCommand() SPItransfer()
*/ */
void static inline LCDCommandMode() __attribute__((always_inline)) static void inline LCDCommandMode() __attribute__((always_inline))
{ {
#ifdef GU12864_800B #ifdef GU12864_800B
bitSet(DC_PORT, DC_BIT); bitSet(DC_PORT, DC_BIT);
@ -522,7 +539,7 @@ class Arduboy2Core : public Arduboy2NoUSB
* or as data to be placed on the screen, depending on the command/data * or as data to be placed on the screen, depending on the command/data
* mode. * mode.
* *
* \see LCDDataMode() LCDCommandMode() sendLCDCommand() * \see LCDDataMode() LCDCommandMode() sendLCDCommand() SPItransferAndRead()
*/ */
static void SPItransfer(uint8_t data); static void SPItransfer(uint8_t data);
@ -548,17 +565,17 @@ class Arduboy2Core : public Arduboy2NoUSB
*/ */
static uint8_t SPItransferAndRead(uint8_t data); static uint8_t SPItransferAndRead(uint8_t data);
#if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) #if defined (OLED_SSD1306_I2C) || (OLED_SSD1306_I2CX) || (OLED_SH1106_I2C)
void static i2c_start(uint8_t mode); static void i2c_start(uint8_t mode);
void static inline i2c_stop() __attribute__((always_inline)) static void inline i2c_stop() __attribute__((always_inline))
{ {
// SDA and SCL both are already low, from writing ACK bit no need to change state // SDA and SCL both are already low, from writing ACK bit no need to change state
I2C_SDA_AS_INPUT(); // switch to input so SDA is pulled up externally first for stop condition I2C_SDA_AS_INPUT(); // switch to input so SDA is pulled up externally first for stop condition
I2C_SCL_AS_INPUT(); // pull up SCL externally I2C_SCL_AS_INPUT(); // pull up SCL externally
} }
void static i2c_sendByte(uint8_t byte); static void i2c_sendByte(uint8_t byte);
#endif #endif
//#endif //#endif
@ -794,6 +811,13 @@ class Arduboy2Core : public Arduboy2NoUSB
*/ */
static void sendLCDCommand(uint8_t command); static void sendLCDCommand(uint8_t command);
static void setRGBledRedOn();
static void setRGBledRedOff();
static void setRGBledGreenOn();
static void setRGBledGreenOff();
static void setRGBledBlueOn();
static void setRGBledBlueOff();
/** \brief /** \brief
* Set the light output of the RGB LED. * Set the light output of the RGB LED.
* *
@ -932,14 +956,21 @@ class Arduboy2Core : public Arduboy2NoUSB
* \details * \details
* This function initializes the display, buttons, etc. * This function initializes the display, buttons, etc.
* *
* This function is called by begin() so isn't normally called within a * This function is called by `begin()` so isn't normally called within a
* sketch. However, in order to free up some code space, by eliminating * sketch. However, in order to free up some code space, by eliminating
* some of the start up features, it can be called in place of begin(). * some of the start up features, it can be called in place of begin().
* The functions that begin() would call after boot() can then be called * The functions that `begin()` would call after `boot()` can then be
* to add back in some of the start up features, if desired. * called to add back in some of the start up features as space permits.
* See the README file or documentation on the main page for more details.
* *
* \see Arduboy2Base::begin() * See the README file or main page, in section
* _Substitute or remove boot up features_, for more details.
*
* \warning
* If this function is used, it is recommended that at least `flashlight()`
* or `safeMode()` be called after it to provide a means to upload a new
* sketch if the bootloader "magic number" problem is encountered.
*
* \see Arduboy2::begin() Arduboy2Base::flashlight() safeMode()
*/ */
static void boot(); static void boot();
@ -953,8 +984,8 @@ class Arduboy2Core : public Arduboy2NoUSB
* sketch, for sketches that interfere with the bootloader "magic number". * sketch, for sketches that interfere with the bootloader "magic number".
* The problem occurs with certain sketches that use large amounts of RAM. * The problem occurs with certain sketches that use large amounts of RAM.
* *
* This function should be called after `boot()` in sketches that * This function should be called after `boot()` in sketches that don't
* potentially could cause the problem. * call `flashlight()`.
* *
* It is intended to replace the `flashlight()` function when more * It is intended to replace the `flashlight()` function when more
* program space is required. If possible, it is more desirable to use * program space is required. If possible, it is more desirable to use
@ -995,11 +1026,11 @@ class Arduboy2Core : public Arduboy2NoUSB
* of Arduino `delay()` will save a few bytes of code. * of Arduino `delay()` will save a few bytes of code.
*/ */
#ifndef ARDUBOY_CORE #ifndef ARDUBOY_CORE
void static delayShort(uint16_t ms) __attribute__ ((noinline)); static void delayShort(uint16_t ms) __attribute__ ((noinline));
#else #else
void static delayShort(uint16_t ms); static void delayShort(uint16_t ms);
#endif #endif
void static delayByte(uint8_t ms) __attribute__ ((noinline)); static void delayByte(uint8_t ms) __attribute__ ((noinline));
/** \brief /** \brief
* Exit the sketch and start the bootloader * Exit the sketch and start the bootloader
@ -1029,9 +1060,9 @@ class Arduboy2Core : public Arduboy2NoUSB
static const PROGMEM uint8_t lcdBootProgram[]; static const PROGMEM uint8_t lcdBootProgram[];
#if defined(GU12864_800B) #if defined(GU12864_800B)
void static displayWrite(uint8_t d); static void displayWrite(uint8_t d);
void static displayEnable(); static void displayEnable();
void static displayDisable(); static void displayDisable();
#endif #endif
}; };

View File

@ -9,7 +9,7 @@
// arduboy_logo.png // arduboy_logo.png
// drawBitmap() format // drawBitmap() format
// 88x16 // 88x16 px (176 bytes)
const PROGMEM uint8_t Arduboy2Base::arduboy_logo[] = { const PROGMEM uint8_t Arduboy2Base::arduboy_logo[] = {
0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8, 0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8,
0xF0, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0xF0, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03,
@ -33,7 +33,7 @@ const PROGMEM uint8_t Arduboy2Base::arduboy_logo[] = {
// arduboy_logo.png // arduboy_logo.png
// drawCompressed() format // drawCompressed() format
// 88x16 // 88x16 px (151 bytes)
const PROGMEM uint8_t Arduboy2Base::arduboy_logo_compressed[] = { const PROGMEM uint8_t Arduboy2Base::arduboy_logo_compressed[] = {
0x57, 0x0F, 0x9C, 0x53, 0x72, 0x75, 0x29, 0xE5, 0x9C, 0x92, 0x57, 0x0F, 0x9C, 0x53, 0x72, 0x75, 0x29, 0xE5, 0x9C, 0x92,
0xCE, 0x95, 0x52, 0xAD, 0x4E, 0x49, 0xE7, 0x08, 0x09, 0xED, 0xCE, 0x95, 0x52, 0xAD, 0x4E, 0x49, 0xE7, 0x08, 0x09, 0xED,
@ -55,7 +55,7 @@ const PROGMEM uint8_t Arduboy2Base::arduboy_logo_compressed[] = {
// arduboy_logo.png // arduboy_logo.png
// Sprites::drawSelfMasked() format // Sprites::drawSelfMasked() format
// 88x16 // 88x16 px (178 bytes)
const PROGMEM uint8_t Arduboy2Base::arduboy_logo_sprite[] = { const PROGMEM uint8_t Arduboy2Base::arduboy_logo_sprite[] = {
88, 16, 88, 16,
0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8, 0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8,

View File

@ -1,83 +0,0 @@
/**
* @file ab_logo.c
* \brief
* The ARDUBOY logo bitmap.
*/
#include <avr/pgmspace.h>
#ifndef ARDUBOY_LOGO_CREATED
#define ARDUBOY_LOGO_CREATED
// arduboy_logo.png
// drawBitmap() format
// 88x16
const uint8_t arduboy_logo[] PROGMEM = {
0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8,
0xF0, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03,
0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0xFE, 0xFF, 0x83, 0x83, 0x83, 0x83, 0x83, 0xC7,
0xEE, 0x7C, 0x38, 0x00, 0x00, 0xF8, 0xFC, 0x0E, 0x07, 0x03,
0x03, 0x03, 0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0x3F, 0x7F,
0xE0, 0xC0, 0x80, 0x80, 0xC0, 0xE0, 0x7F, 0x3F, 0xFF, 0xFF,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0xFF, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0x3E, 0x77,
0xE3, 0xC1, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00, 0x1F, 0x3F, 0x70,
0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00,
0x7F, 0xFF, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xE3, 0x77, 0x3E,
0x1C, 0x00, 0x00, 0x1F, 0x3F, 0x70, 0xE0, 0xC0, 0xC0, 0xC0,
0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00
};
// arduboy_logo.png
// drawCompressed() format
// 88x16
const uint8_t arduboy_logo_compressed[] PROGMEM = {
0x57, 0x0F, 0x9C, 0x53, 0x72, 0x75, 0x29, 0xE5, 0x9C, 0x92,
0xCE, 0x95, 0x52, 0xAD, 0x4E, 0x49, 0xE7, 0x08, 0x09, 0xED,
0x76, 0xBB, 0xDD, 0x2A, 0xAB, 0xAC, 0x55, 0x92, 0x90, 0xD0,
0x6E, 0xB7, 0xDB, 0xAD, 0xB2, 0xCA, 0x5A, 0x25, 0xF9, 0xF8,
0xF0, 0xC6, 0x47, 0x48, 0x28, 0x95, 0x54, 0x52, 0x49, 0x25,
0x9D, 0x3A, 0x95, 0x5A, 0x3A, 0x45, 0x2A, 0xB7, 0x29, 0xA7,
0xE4, 0x76, 0xBB, 0x55, 0x56, 0x59, 0xAB, 0x24, 0x9F, 0x5D,
0x5B, 0x65, 0xD7, 0xE9, 0xEC, 0x92, 0x29, 0x3B, 0xA1, 0x4E,
0xA7, 0xD3, 0xE9, 0x74, 0x9A, 0x8F, 0x8F, 0xEF, 0xED, 0x76,
0xBB, 0x55, 0x4E, 0xAE, 0x52, 0xAD, 0x9C, 0x9C, 0x4F, 0xE7,
0xED, 0x76, 0xBB, 0xDD, 0x2E, 0x95, 0x53, 0xD9, 0x25, 0xA5,
0x54, 0xD6, 0x2A, 0xAB, 0xEC, 0x76, 0xBB, 0x54, 0x4E, 0x65,
0x97, 0x94, 0x3A, 0x22, 0xA9, 0xA4, 0x92, 0x4A, 0x2A, 0xE9,
0x94, 0x4D, 0x2D, 0x9D, 0xA2, 0x94, 0xCA, 0x5A, 0x65, 0x95,
0xDD, 0x6E, 0x97, 0xCA, 0xA9, 0xEC, 0x12, 0x55, 0x69, 0x42,
0x7A
};
// arduboy_logo.png
// Sprites::drawSelfMasked() format
// 88x16
const uint8_t arduboy_logo_sprite[] PROGMEM = {
88, 16,
0xF0, 0xF8, 0x9C, 0x8E, 0x87, 0x83, 0x87, 0x8E, 0x9C, 0xF8,
0xF0, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03,
0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xFE, 0xFF, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0xFE, 0xFF, 0x83, 0x83, 0x83, 0x83, 0x83, 0xC7,
0xEE, 0x7C, 0x38, 0x00, 0x00, 0xF8, 0xFC, 0x0E, 0x07, 0x03,
0x03, 0x03, 0x07, 0x0E, 0xFC, 0xF8, 0x00, 0x00, 0x3F, 0x7F,
0xE0, 0xC0, 0x80, 0x80, 0xC0, 0xE0, 0x7F, 0x3F, 0xFF, 0xFF,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0xFF, 0x0C, 0x0C, 0x0C, 0x0C, 0x1C, 0x3E, 0x77,
0xE3, 0xC1, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00, 0x1F, 0x3F, 0x70,
0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00,
0x7F, 0xFF, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xE3, 0x77, 0x3E,
0x1C, 0x00, 0x00, 0x1F, 0x3F, 0x70, 0xE0, 0xC0, 0xC0, 0xC0,
0xE0, 0x70, 0x3F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00
};
#endif

View File

@ -1,274 +0,0 @@
/**
* @file glcdfont.c
* \brief
* The font definitions used to display text characters.
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#ifndef FONT5X7_H
#define FONT5X7_H
// standard ascii 5x7 font
static const unsigned char font[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08,
0x10, 0x20, 0x7E, 0x20, 0x10,
0x08, 0x08, 0x2A, 0x1C, 0x08,
0x08, 0x1C, 0x2A, 0x08, 0x08,
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12,
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x21, 0x54, 0x54, 0x78, 0x41,
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0xF0, 0x29, 0x24, 0x29, 0xF0,
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x32, 0x48, 0x48, 0x48, 0x32,
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x39, 0x44, 0x44, 0x44, 0x39,
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0x95, 0x00, 0x22, 0x00, 0x95,
0xAA, 0x00, 0x55, 0x00, 0xAA,
0xAA, 0x55, 0xAA, 0x55, 0xAA,
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44,
0x7C, 0x2A, 0x2A, 0x3E, 0x14,
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02,
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20,
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C,
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x44, 0x44, 0x5F, 0x44, 0x44,
0x40, 0x51, 0x4A, 0x44, 0x40,
0x40, 0x44, 0x4A, 0x51, 0x40,
0x00, 0x00, 0xFF, 0x01, 0x03,
0xE0, 0x80, 0xFF, 0x00, 0x00,
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36,
0x06, 0x0F, 0x09, 0x0F, 0x06,
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01,
0x00, 0x1F, 0x01, 0x01, 0x1E,
0x00, 0x19, 0x1D, 0x17, 0x12,
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif

View File

@ -669,7 +669,7 @@ void FX::readDataArray(uint24_t address, uint8_t index, uint8_t offset, uint8_t
} }
uint16_t FX::readIndexedUInt8(uint24_t address, uint8_t index) uint8_t FX::readIndexedUInt8(uint24_t address, uint8_t index)
{ {
seekDataArray(address, index, 0, sizeof(uint8_t)); seekDataArray(address, index, 0, sizeof(uint8_t));
return readEnd(); return readEnd();