Compare commits

..
Author SHA1 Message Date
Huw Duddy 3a75482e17 Merge pull request #53 from sefinek/update/gh-actions
Update GitHub actions
2026-08-20 14:23:21 +10:00
Sefinek d08b95c281 Update GitHub actions 2026-08-20 02:25:00 +02:00
taco a62825be47 update github workflow
Build / set-matrix (push) Canceled after 0s
Build / build (${{ fromJSON(needs.set-matrix.outputs.matrix) }}) (push) Canceled after 0s
Build / draft-release (push) Canceled after 0s
2026-08-19 23:05:04 +10:00
taco d2a6c95506 fix incorrect MADCTL macro for Heltec T096 2026-08-19 22:11:47 +10:00
taco 04a1315cbb update README.md 2026-08-19 21:45:26 +10:00
taco 8fc85e7ddb board support: add Heltec T1 2026-08-19 15:45:24 +10:00
taco e6c7f4600d fix T096 optional display orientation 2026-08-19 15:40:59 +10:00
taco dde7c96665 board support: add RAK3401 2026-08-19 09:34:30 +10:00
taco 038ae7e111 board support: add Heltec T096 2026-08-19 09:34:30 +10:00
taco ee88df71b8 refactored screen.c to allow other display sizes 2026-08-19 09:34:12 +10:00
taco d4a604e48d update workflow for node24 2026-04-13 22:40:44 +10:00
15 changed files with 695 additions and 134 deletions

No files matched your search

+35 -15
View File
@@ -1,12 +1,14 @@
name: Build
on:
# pull_request:
# push:
# repository_dispatch:
release:
types:
- created
push:
tags:
- '*'
pull_request:
workflow_dispatch:
permissions:
contents: write
jobs:
set-matrix:
@@ -15,7 +17,7 @@ jobs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Set matrix
id: set-matrix
@@ -34,7 +36,7 @@ jobs:
board: ${{ fromJSON(needs.set-matrix.outputs.matrix) }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: true
@@ -53,16 +55,34 @@ jobs:
make BOARD=${{ matrix.board }} all
make BOARD=${{ matrix.board }} copy-artifact
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.board }}
path: _bin/${{ matrix.board }}
if-no-files-found: error
- name: Upload Release Asset
uses: softprops/action-gh-release@v1
if: ${{ github.event_name == 'release' }}
draft-release:
needs: build
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Collect all board artifacts
uses: actions/download-artifact@v8
with:
path: _bin
merge-multiple: true
- name: List collected files
run: ls -lR _bin
- name: Create draft release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ github.ref_name }}
draft: true
generate_release_notes: true
fail_on_unmatched_files: true
files: |
_bin/${{ matrix.board }}/${{ matrix.board }}_bootloader-*.zip
_bin/${{ matrix.board }}/${{ matrix.board }}_bootloader-*.hex
_bin/${{ matrix.board }}/update-${{ matrix.board }}_bootloader-*.uf2
_bin/*_bootloader-*.zip
_bin/*_bootloader-*.hex
_bin/update-*_bootloader-*.uf2
+39 -23
View File
@@ -1,5 +1,14 @@
# Adafruit nRF52 Bootloader with Enhanced OTA DFU
## Changes in OTAFIX 2.3
- **ST7735 Display support**
Added ST7735 display driver and refactored display code to allow for configuring different display sizes at the board level.
- **New boards**
Heltec T096
Heltec T1
RAK 3401
## Changes in OTAFIX 2.2
- **Use maximum TX power for BLE**
@@ -32,32 +41,22 @@
When connected to a USB host, devices now automatically reboot into the application after a successful OTA update, instead of requiring a manual reset.
- **Unique BLE advertising names per board**
In OTA DFU mode, devices advertise using a board-specific name instead of the generic `AdaDFU`:
- **Elecrow ThinkNode M1** → `TNM1_DFU`
- **Elecrow ThinkNode M3** → `TNM3_DFU`
- **Elecrow ThinkNode M6** → `TNM6_DFU`
- **Heltec T114** → `T114_DFU`
- **LILYGO T-Echo** → `LGTE_DFU`
- **Minewsemi MX25LE01** → `MX25_DFU`
- **ProMicro NRF52840** → `PROM_DFU`
- **RAK 4631** → `4631_DFU`
- **RAK WisMesh Tag** → `RTAG_DFU`
- **Seeed SenseCAP Solar Node P1** → `SCAP_DFU`
- **Seeed T1000e** → `T1KE_DFU`
- **Seeed WioTracker L1** → `WTL1_DFU`
- **XIAO NRF52 BLE / SENSE** → `XIAO_DFU`
In OTA DFU mode, devices advertise using a board-specific name instead of the generic `AdaDFU`.
See the [BLE advertising names](#ble-advertising-names) section for the current names.
---
## Boards supported
- Elecrow ThinkNode M1
- Elecrow ThinkNode M3
- Elecrow ThinkNode M6
- Heltec Automation Mesh Node T114 / HT-nRF5262
- Heltec T096
- Heltec T1
- Heltec T114 / HT-nRF5262
- LilyGO T-Echo
- Minewsemi MX25LE01
- Nologo ProMicro NRF52840 (aka SuperMini NRF52840)
- RAK 4631 ([See note](#notes-on-RAK4631-bootloader))
- RAK 4631
- RAK 3401
- RAK WisMesh Tag
- Seeed Studio SenseCAP Card Tracker T1000-E
- Seeed SenseCAP Solar Node P1
@@ -66,6 +65,29 @@
- Seeed Studio XIAO nRF52840 BLE SENSE
If there is another nRF52840-based board you would like to see supported please raise a github issue and we can make it happen.
## BLE advertising names
When in OTA DFU mode, devices advertise using a board-specific name rather than the generic `AdaDFU`.
| Board | OTA DFU advertising name |
| ---------------------------- | ------------------------ |
| Elecrow ThinkNode M1 | `TNM1_DFU` |
| Elecrow ThinkNode M3 | `TNM3_DFU` |
| Elecrow ThinkNode M6 | `TNM6_DFU` |
| Heltec T096 | `T096_DFU` |
| Heltec T1 | `T1_DFU` |
| Heltec T114 | `T114_DFU` |
| LILYGO T-Echo | `LGTE_DFU` |
| Minewsemi MX25LE01 | `MX25_DFU` |
| ProMicro NRF52840 | `PROM_DFU` |
| RAK 4631 | `4631_DFU` |
| RAK 3401 | `3401_DFU` |
| RAK WisMesh Tag | `RTAG_DFU` |
| Seeed SenseCAP Solar Node P1 | `SCAP_DFU` |
| Seeed T1000e | `T1KE_DFU` |
| Seeed WioTracker L1 | `WTL1_DFU` |
| XIAO NRF52 BLE / SENSE | `XIAO_DFU` |
---
@@ -183,9 +205,3 @@ To check:
2. Open the `INFO_UF2.TXT` file on the mounted drive
If the file shows: "Board-ID: nRF52840-SeeedXiaoSense-v1" then you must install the ***SENSE*** variant if updating via UF2 file.
## Notes on RAK4631 bootloader
This version of the RAK4631 bootloader is based on a much newer version (0.9.2) of the Adafruit nRF52 bootloader than what RAK Wireless uses on their official bootloader (0.6.2-11).
I haven't looked to see what changes (if any) that RAK made to the Adafruit bootloader, so I'm not sure if there's any difference but I have tested this bootloader and I haven't found any problems thus far. If you would rather use the original RAK bootloader but with these patches included you can find that [here](https://github.com/oltaco/WisCore_RAK4631_Bootloader/releases).
+144
View File
@@ -777,3 +777,147 @@ static void tft_controller_init(void) {
}
#endif
#ifdef DISPLAY_CONTROLLER_ST7735
#define ST_CMD_DELAY 0x80 // special signifier for command lists
// ST77XX common commands (shared with ST7789)
#define ST77XX_NOP 0x00
#define ST77XX_SWRESET 0x01
#define ST77XX_RDDID 0x04
#define ST77XX_RDDST 0x09
#define ST77XX_SLPIN 0x10
#define ST77XX_SLPOUT 0x11
#define ST77XX_PTLON 0x12
#define ST77XX_NORON 0x13
#define ST77XX_INVOFF 0x20
#define ST77XX_INVON 0x21
#define ST77XX_DISPOFF 0x28
#define ST77XX_DISPON 0x29
#define ST77XX_CASET 0x2A
#define ST77XX_RASET 0x2B
#define ST77XX_RAMWR 0x2C
#define ST77XX_RAMRD 0x2E
#define ST77XX_PTLAR 0x30
#define ST77XX_TEOFF 0x34
#define ST77XX_TEON 0x35
#define ST77XX_MADCTL 0x36
#define ST77XX_VSCSAD 0x37
#define ST77XX_COLMOD 0x3A
#define ST77XX_MADCTL_MY 0x80
#define ST77XX_MADCTL_MX 0x40
#define ST77XX_MADCTL_MV 0x20
#define ST77XX_MADCTL_ML 0x10
#define ST77XX_MADCTL_RGB 0x00
#define ST77XX_RDID1 0xDA
#define ST77XX_RDID2 0xDB
#define ST77XX_RDID3 0xDC
#define ST77XX_RDID4 0xDD
// ST7735-specific commands
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST7735_MADCTL_BGR 0x08
// Some ready-made 16-bit ('565') color settings:
#define ST77XX_BLACK 0x0000
#define ST77XX_WHITE 0xFFFF
#define ST77XX_RED 0xF800
#define ST77XX_GREEN 0x07E0
#define ST77XX_BLUE 0x001F
#define ST77XX_CYAN 0x07FF
#define ST77XX_MAGENTA 0xF81F
#define ST77XX_YELLOW 0xFFE0
#define ST77XX_ORANGE 0xFC00
static void tft_controller_init(void) {
// Init commands for ST7735 mini 160x80 screens
// Based on Adafruit INITR_MINI160x80 sequence
uint8_t cmdinit_st7735[] = {
#if !defined(DISPLAY_PIN_RST) || (DISPLAY_PIN_RST < 0)
// Software reset if rst pin not available
ST77XX_SWRESET, ST_CMD_DELAY, 150,
#endif
// Out of sleep mode, w/delay 255 = 500ms
ST77XX_SLPOUT, ST_CMD_DELAY, 255,
// Frame rate control - normal mode (3 args)
ST7735_FRMCTR1, 3, 0x01, 0x2C, 0x2D,
// Frame rate control - idle mode (3 args)
ST7735_FRMCTR2, 3, 0x01, 0x2C, 0x2D,
// Frame rate control - partial mode (6 args)
ST7735_FRMCTR3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
// Display inversion control (1 arg)
ST7735_INVCTR, 1, 0x07,
// Power control 1 (3 args)
ST7735_PWCTR1, 3, 0xA2, 0x02, 0x84,
// Power control 2 (1 arg)
ST7735_PWCTR2, 1, 0xC5,
// Power control 3 - normal mode (2 args)
ST7735_PWCTR3, 2, 0x0A, 0x00,
// Power control 4 - idle mode (2 args)
ST7735_PWCTR4, 2, 0x8A, 0x2A,
// Power control 5 - partial mode (2 args)
ST7735_PWCTR5, 2, 0x8A, 0xEE,
// VCOM control (1 arg)
ST7735_VMCTR1, 1, 0x0E,
// Inversion off (required for Heltec T096)
ST77XX_INVOFF, 0,
// Set color mode, 1 arg: 16-bit color (0x05 for ST7735)
ST77XX_COLMOD, 1 + ST_CMD_DELAY, 0x05, 10,
// Mem access ctrl, 1 arg: row/col addr, color order
ST77XX_MADCTL, 1, DISPLAY_MADCTL,
// Column addr set, 4 args: XSTART/XEND (132 wide framebuffer)
ST77XX_CASET, 4, 0x00, 0x00, 0x00, 0x83,
// Row addr set, 4 args: YSTART/YEND (162 tall framebuffer)
ST77XX_RASET, 4, 0x00, 0x00, 0x00, 0xA1,
// Positive gamma correction (16 args)
ST7735_GMCTRP1, 16,
0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D,
0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10,
// Negative gamma correction (16 args)
ST7735_GMCTRN1, 16,
0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D,
0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10,
// Normal display on, w/delay 10ms
ST77XX_NORON, ST_CMD_DELAY, 10,
// Main screen turn on, w/delay 100ms
ST77XX_DISPON, ST_CMD_DELAY, 100
};
size_t count = 0;
while (count < sizeof(cmdinit_st7735)) {
uint8_t const cmd = cmdinit_st7735[count++];
uint8_t const cmd_arg = cmdinit_st7735[count++];
uint8_t const has_delay = cmd_arg & ST_CMD_DELAY;
uint8_t const narg = cmd_arg & ~ST_CMD_DELAY;
tft_cmd(cmd, cmdinit_st7735 + count, narg);
count += narg;
if (has_delay) {
uint16_t delay = (uint16_t) cmdinit_st7735[count++];
if (delay == 255) {
delay = 500; // If 255, delay for 500 ms
}
NRFX_DELAY_MS(delay);
}
}
}
#endif
+1
View File
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
+123
View File
@@ -0,0 +1,123 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _HELTEC_T096_H
#define _HELTEC_T096_H
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 28) // White
#define LED_STATE_ON 0
// #define LED_NEOPIXEL _PINNUM(0, 14)
// #define NEOPIXEL_POWER_PIN _PINNUM(0, 21)
// #define NEOPIXELS_NUMBER 2
#define BOARD_RGB_BRIGHTNESS 0x040404
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(1, 10)
#define BUTTON_2 _PINNUM(1, 2) // stock bootloader has this set to 34
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
// VSensor required to power the display
#define DISPLAY_VSENSOR_PIN _PINNUM(0, 26)
#define DISPLAY_VSENSOR_ON 1
// #define DISPLAY_CONTROLLER_ST7789
#define DISPLAY_CONTROLLER_ST7735
#define DISPLAY_PIN_SCK _PINNUM(0, 20)
#define DISPLAY_PIN_MOSI _PINNUM(0, 17)
#define DISPLAY_PIN_CS _PINNUM(0, 22)
#define DISPLAY_PIN_DC _PINNUM(0, 15)
#define DISPLAY_PIN_RST _PINNUM(0, 13)
#define DISPLAY_PIN_BL _PINNUM(1, 12)
#define DISPLAY_BL_ON 0 // GPIO state to enable back light
#define DISPLAY_WIDTH 160
#define DISPLAY_HEIGHT 80
// USB FACING LEFT
#define DISPLAY_COL_OFFSET 24
#define DISPLAY_ROW_OFFSET 0
#define DISPLAY_MADCTL (ST77XX_MADCTL_MY | ST7735_MADCTL_BGR)
// USB FACING RIGHT
//#define DISPLAY_COL_OFFSET 52
//#define DISPLAY_ROW_OFFSET 40
//#define DISPLAY_MADCTL (ST77XX_MADCTL_MX | ST7735_MADCTL_BGR)
#define DISPLAY_VSCSAD 0
#define DISPLAY_TITLE "T096"
#define BANNER_TEXT "https://github.com/oltaco"
#define FONT_SIZE_LARGE 3
#define NOLABELS
#define SCREEN_BAR1_Y 0
#define SCREEN_BAR1_H 32
#define SCREEN_BAR2_Y 32
#define SCREEN_BAR2_H 36
#define SCREEN_BAR3_Y 68
#define SCREEN_BAR3_H 12
#define BANNER_TEXT_X 0
#define BANNER_TEXT_Y 70
#define DISPLAY_TITLE_Y 1
#define UF2_VERSION_BASE_Y 24
#define BLE_OTA_Y 38
#define DRAG 34
#define DRAGX 4
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Heltec AutoMation"
#define BLEDIS_MODEL "Tracker"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x239A
#define USB_DESC_UF2_PID 0x0071
#define USB_DESC_CDC_ONLY_PID 0x0071
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "Heltec-T096"
#define UF2_VOLUME_LABEL "HeltecT096"
#define UF2_BOARD_ID "Heltec-T096-v1"
#define UF2_INDEX_URL "http://heltec.org/"
#endif
+3
View File
@@ -0,0 +1,3 @@
MCU_SUB_VARIANT = nrf52840
CFLAGS += -DDEVICE_NAME='"T096_DFU"'
+19
View File
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+1
View File
@@ -0,0 +1 @@
set(MCU_VARIANT nrf52840)
+122
View File
@@ -0,0 +1,122 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _HELTEC_T1_H
#define _HELTEC_T1_H
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 1
#define LED_PRIMARY_PIN _PINNUM(0, 16)
#define LED_STATE_ON 0
// #define LED_NEOPIXEL _PINNUM(0, 14)
// #define NEOPIXEL_POWER_PIN _PINNUM(0, 21)
// #define NEOPIXELS_NUMBER 2
// #define BOARD_RGB_BRIGHTNESS 0x040404
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(1, 10)
#define BUTTON_2 _PINNUM(1, 2) // stock bootloader has this set to 34
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// Display
//--------------------------------------------------------------------+
// VSensor required to power the display
#define DISPLAY_VSENSOR_PIN _PINNUM(0, 13)
#define DISPLAY_VSENSOR_ON 0
#define DISPLAY_CONTROLLER_ST7735
#define DISPLAY_PIN_SCK _PINNUM(1, 0)
#define DISPLAY_PIN_MOSI _PINNUM(0, 24)
#define DISPLAY_PIN_CS _PINNUM(0, 12)
#define DISPLAY_PIN_DC _PINNUM(0, 22)
#define DISPLAY_PIN_RST _PINNUM(0, 20)
#define DISPLAY_PIN_BL _PINNUM(0, 15)
#define DISPLAY_BL_ON 0 // GPIO state to enable back light
#define DISPLAY_WIDTH 160
#define DISPLAY_HEIGHT 80
// // USB FACING DOWN
// #define DISPLAY_COL_OFFSET 24
// #define DISPLAY_ROW_OFFSET 0
// #define DISPLAY_MADCTL (ST77XX_MADCTL_MY | ST7735_MADCTL_BGR)
// USB FACING UP
#define DISPLAY_COL_OFFSET 24
#define DISPLAY_ROW_OFFSET 0
#define DISPLAY_MADCTL (ST77XX_MADCTL_MX | ST7735_MADCTL_BGR)
#define DISPLAY_VSCSAD 0
#define DISPLAY_TITLE "T1"
#define BANNER_TEXT "https://github.com/oltaco"
#define FONT_SIZE_LARGE 3
#define NOLABELS
#define SCREEN_BAR1_Y 0
#define SCREEN_BAR1_H 32
#define SCREEN_BAR2_Y 32
#define SCREEN_BAR2_H 36
#define SCREEN_BAR3_Y 68
#define SCREEN_BAR3_H 12
#define BANNER_TEXT_X 0
#define BANNER_TEXT_Y 70
#define DISPLAY_TITLE_Y 1
#define UF2_VERSION_BASE_Y 24
#define BLE_OTA_Y 38
#define DRAG 34
#define DRAGX 4
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "Heltec AutoMation"
#define BLEDIS_MODEL "T1"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x239A
#define USB_DESC_UF2_PID 0x0071
#define USB_DESC_CDC_ONLY_PID 0x0071
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "Heltec-T1"
#define UF2_VOLUME_LABEL "HeltecT1"
#define UF2_BOARD_ID "Heltec-T1"
#define UF2_INDEX_URL "http://heltec.org/"
#endif
+3
View File
@@ -0,0 +1,3 @@
MCU_SUB_VARIANT = nrf52840
CFLAGS += -DDEVICE_NAME='"T1_DFU"'
+19
View File
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+68
View File
@@ -0,0 +1,68 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _WISCORE_RAK3401_BOARD_H
#define _WISCORE_RAK3401_BOARD_H
// change default 1.8v to 3.3v, add by taylor
#define UICR_REGOUT0_VALUE UICR_REGOUT0_VOUT_3V3
#define _PINNUM(port, pin) ((port)*32 + (pin))
/*------------------------------------------------------------------*/
/* LED
*------------------------------------------------------------------*/
#define LEDS_NUMBER 2
#define LED_PRIMARY_PIN _PINNUM(1, 3)
#define LED_SECONDARY_PIN _PINNUM(1, 4)
#define LED_STATE_ON 1
/*------------------------------------------------------------------*/
/* BUTTON
*------------------------------------------------------------------*/
#define BUTTONS_NUMBER 2
#define BUTTON_1 _PINNUM(0, 8) // change default 0.0 to 0.8, add by Michael. This pin is not connected on 4631.
#define BUTTON_2 _PINNUM(0, 8) // change default 0.0 to 0.8, add by Michael. This pin is not connected on 4631.
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
//--------------------------------------------------------------------+
// BLE OTA
//--------------------------------------------------------------------+
#define BLEDIS_MANUFACTURER "RAKWireless"
#define BLEDIS_MODEL "WisBlock RAK3401"
//--------------------------------------------------------------------+
// USB
//--------------------------------------------------------------------+
#define USB_DESC_VID 0x239A
#define USB_DESC_UF2_PID 0x0029
#define USB_DESC_CDC_ONLY_PID 0x002A
//------------- UF2 -------------//
#define UF2_PRODUCT_NAME "WisBlock RAK3401 Board"
#define UF2_VOLUME_LABEL "RAK3401"
#define UF2_BOARD_ID "WisBlock-RAK3401-Board"
#define UF2_INDEX_URL "https://store.rakwireless.com/collections/wisblock-core"
#endif // _WISCORE_RAK3401_BOARD_H
+2
View File
@@ -0,0 +1,2 @@
MCU_SUB_VARIANT = nrf52840
CFLAGS += -DDEVICE_NAME='"3401_DFU"'
+19
View File
@@ -0,0 +1,19 @@
#include "boards.h"
#include "uf2/configkeys.h"
__attribute__((used, section(".bootloaderConfig")))
const uint32_t bootloaderConfig[] =
{
/* CF2 START */
CFG_MAGIC0, CFG_MAGIC1, // magic
5, 100, // used entries, total entries
204, 0x100000, // FLASH_BYTES = 0x100000
205, 0x40000, // RAM_BYTES = 0x40000
208, (USB_DESC_VID << 16) | USB_DESC_UF2_PID, // BOOTLOADER_BOARD_ID = USB VID+PID, used for verification when updating bootloader via uf2
209, 0xada52840, // UF2_FAMILY = 0xada52840
210, 0x20, // PINS_PORT_SIZE = PA_32
0, 0, 0, 0, 0, 0, 0, 0
/* CF2 END */
};
+97 -96
View File
@@ -33,11 +33,10 @@
#include <string.h>
#include <stdlib.h>
// Overlap 4x chars by this much.
#define CHAR4_KERNING 3
// Width of a single 4x char, adjusted by kerning
#define CHAR4_KERNED_WIDTH (6 * 4 - CHAR4_KERNING)
// Size independent kerning
#define CHAR_ADV(n) (5 * (n) + 1) // cursor step between chars
#define CHAR_INK(n) (6 * (n)) // columns printch actually writes
#define TEXT_WIDTH(n, len) ((len) ? CHAR_ADV(n) * ((len) - 1) + CHAR_INK(n) : 0)
#define COL0(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define COL(c) COL0((c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff)
@@ -77,6 +76,56 @@ const uint16_t palette[] = {
COL(0x000000), // 15
};
// inital display-size agnostic hack
#ifndef SCREEN_BAR1_Y
#define SCREEN_BAR1_Y 0
#endif
#ifndef SCREEN_BAR1_H
#define SCREEN_BAR1_H 52
#endif
#ifndef SCREEN_BAR2_Y
#define SCREEN_BAR2_Y 52
#endif
#ifndef SCREEN_BAR2_H
#define SCREEN_BAR2_H 55
#endif
#ifndef SCREEN_BAR3_Y
#define SCREEN_BAR3_Y 107
#endif
#ifndef SCREEN_BAR3_H
#define SCREEN_BAR3_H 14
#endif
#ifndef fileLogo_X
#define fileLogo_X 0
#endif
#ifndef arrowLogo_X
#define arrowLogo_X 65
#endif
#ifndef pendriveLogo_X
#define pendriveLogo_X 129
#endif
#ifndef DISPLAY_TITLE_Y
#define DISPLAY_TITLE_Y 5
#endif
#ifndef UF2_VERSION_BASE_Y
#define UF2_VERSION_BASE_Y 40
#endif
#ifndef BANNER_TEXT_X
#define BANNER_TEXT_X 23
#endif
#ifndef BANNER_TEXT_Y
#define BANNER_TEXT_Y 110
#endif
#ifndef BLE_OTA_Y
#define BLE_OTA_Y 65
#endif
#ifndef FONT_SIZE_LARGE
#define FONT_SIZE_LARGE 4
#endif
// TODO only buffer partial screen to save SRAM
// ESP32s2 can only statically allocated DRAM up to 160KB.
// the remaining 160KB can only be allocated at runtime as heap.
@@ -92,38 +141,16 @@ extern const uint8_t arrowLogo[];
//
//--------------------------------------------------------------------+
// print character with font size = 1
static void printch(int x, int y, int color, const uint8_t* fnt) {
for (int i = 0; i < 6; ++i) {
// print character
static void printch(int x, int y, int color, const uint8_t* fnt, int size) {
for (int i = 0; i < 6 * size; ++i) {
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
uint8_t mask = 0x01;
uint8_t b = fnt[i / size];
for (int j = 0; j < 8; ++j) {
if (*fnt & mask) {
*p = color;
if (b & (1u << j)) {
for (int k = 0; k < size; ++k) p[k] = color;
}
p++;
mask <<= 1;
}
fnt++;
}
}
// print character with font size = 4
static void printch4(int x, int y, int color, const uint8_t* fnt) {
for (int i = 0; i < 6 * 4; ++i) {
uint8_t* p = frame_buf + (x + i) * DISPLAY_HEIGHT + y;
uint8_t mask = 0x01;
for (int j = 0; j < 8; ++j) {
for (int k = 0; k < 4; ++k) {
if (*fnt & mask) {
*p = color;
}
p++;
}
mask <<= 1;
}
if ((i & 3) == 3) {
fnt++;
p += size;
}
}
}
@@ -175,45 +202,25 @@ static void printicon(int x, int y, int color, const uint8_t* icon) {
}
}
// print text with font size = 1
static void print(int x, int y, int col, const char* text) {
int x0 = x;
while (*text) {
char c = *text++;
if (c == '\r') continue;
if (c == '\n') {
x = x0;
y += 10;
continue;
}
/*
if (x + 8 > DISPLAY_WIDTH) {
x = x0;
y += 10;
}
*/
if (c < ' ') c = '?';
if (c >= 0x7f) c = '?';
c -= ' ';
printch(x, y, col, &font8[c * 6]);
x += 6;
}
}
// Print text with font size = 4
static void print4(int x, int y, int color, const char* text) {
static void print(int x, int y, int color, const char* text, int size) {
while (*text) {
char c = *text++;
c -= ' ';
printch4(x, y, color, &font8[c * 6]);
x += CHAR4_KERNED_WIDTH;
if (x + CHAR4_KERNED_WIDTH > DISPLAY_WIDTH) {
printch(x, y, color, &font8[c * 6], size);
x += CHAR_ADV(size);
if (x + CHAR_INK(size) > DISPLAY_WIDTH) {
// Next char won't fit.
return;
}
}
}
static inline void print_centered(int y, int color, const char* text, int size) {
int len = (int) strlen(text);
int text_x = (DISPLAY_WIDTH - TEXT_WIDTH(size, len)) / 2;
print(text_x >= 0 ? text_x : 0, y, color, text, size);
}
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
@@ -242,48 +249,42 @@ static void drawBar(int y, int h, int color) {
// draw drag & drop screen
void screen_draw_drag(void) {
drawBar(0, 52, COLOR_GREEN);
drawBar(52, 55, COLOR_BLUE);
drawBar(107, 14, COLOR_ORANGE);
drawBar(SCREEN_BAR1_Y, SCREEN_BAR1_H, COLOR_GREEN);
drawBar(SCREEN_BAR2_Y, SCREEN_BAR2_H, COLOR_BLUE);
drawBar(SCREEN_BAR3_Y, SCREEN_BAR3_H, COLOR_ORANGE);
// Center UF2_PRODUCT_NAME and UF2_VERSION_BASE.
int name_x = (DISPLAY_WIDTH - CHAR4_KERNED_WIDTH * (int) strlen(DISPLAY_TITLE)) / 2;
print4(name_x >= 0 ? name_x : 0, 5, COLOR_WHITE, DISPLAY_TITLE);
int version_x = (DISPLAY_WIDTH - 6 * (int) strlen(UF2_VERSION_BASE)) / 2;
print(version_x >= 0 ? version_x : 0, 40, COLOR_PURPLE, UF2_VERSION_BASE);
// TODO the reset should be center as well
print(23, 110, 1, BANNER_TEXT);
// Print title, version, banner.
print_centered(DISPLAY_TITLE_Y, COLOR_WHITE, DISPLAY_TITLE, FONT_SIZE_LARGE);
print_centered(UF2_VERSION_BASE_Y, COLOR_PURPLE, UF2_VERSION_BASE, 1);
print_centered(BANNER_TEXT_Y, COLOR_WHITE, BANNER_TEXT, 1);
#ifndef DRAG
#define DRAG 70
#endif
#ifndef DRAGX
#define DRAGX 47
printicon(DRAGX + 0, DRAG + 5, COLOR_WHITE, fileLogo);
printicon(DRAGX + 65, DRAG, COLOR_WHITE, arrowLogo);
printicon(DRAGX + 129, DRAG, COLOR_WHITE, pendriveLogo);
print(22, DRAG - 12, COLOR_WHITE, "firmware.uf2");
print(160, DRAG - 12, COLOR_WHITE, UF2_VOLUME_LABEL);
#endif
printicon(DRAGX + fileLogo_X, DRAG + 5, COLOR_WHITE, fileLogo);
printicon(DRAGX + arrowLogo_X, DRAG, COLOR_WHITE, arrowLogo);
printicon(DRAGX + pendriveLogo_X, DRAG, COLOR_WHITE, pendriveLogo);
#ifndef NOLABELS
print(22, DRAG - 12, COLOR_WHITE, "firmware.uf2", 1);
print(160, DRAG - 12, COLOR_WHITE, UF2_VOLUME_LABEL, 1);
#endif // NOLABELS
draw_screen(frame_buf);
}
void screen_draw_ble(void) {
drawBar(0, 52, COLOR_GREEN);
drawBar(52, 55, COLOR_BLUE);
drawBar(107, 14, COLOR_ORANGE);
drawBar(SCREEN_BAR1_Y, SCREEN_BAR1_H, COLOR_GREEN);
drawBar(SCREEN_BAR2_Y, SCREEN_BAR2_H, COLOR_BLUE);
drawBar(SCREEN_BAR3_Y, SCREEN_BAR3_H, COLOR_ORANGE);
// Center UF2_PRODUCT_NAME and UF2_VERSION_BASE.
int name_x = (DISPLAY_WIDTH - CHAR4_KERNED_WIDTH * (int) strlen(DISPLAY_TITLE)) / 2;
print4(name_x >= 0 ? name_x : 0, 5, COLOR_WHITE, DISPLAY_TITLE);
int version_x = (DISPLAY_WIDTH - 6 * (int) strlen(UF2_VERSION_BASE)) / 2;
print(version_x >= 0 ? version_x : 0, 40, COLOR_PURPLE, UF2_VERSION_BASE);
// TODO the reset should be center as well
print(23, 110, 1, BANNER_TEXT);
int ble_x = (DISPLAY_WIDTH - CHAR4_KERNED_WIDTH * (int) strlen("BLE OTA")) / 2;
print4(ble_x >= 0 ? ble_x : 0, 65, COLOR_WHITE, "BLE OTA");
// Print title, version, OTA, banner
print_centered(DISPLAY_TITLE_Y, COLOR_WHITE, DISPLAY_TITLE, FONT_SIZE_LARGE);
print_centered(UF2_VERSION_BASE_Y, COLOR_PURPLE, UF2_VERSION_BASE, 1);
print_centered(BLE_OTA_Y, COLOR_WHITE, "BLE OTA", FONT_SIZE_LARGE);
print_centered(BANNER_TEXT_Y, COLOR_WHITE, BANNER_TEXT, 1);
draw_screen(frame_buf);
}