├── .gitattributes ├── .github └── workflows │ ├── main.yaml │ └── release.yaml ├── .gitignore ├── .gitmodules ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── app ├── action.c ├── action.h ├── aircopy.c ├── aircopy.h ├── app.c ├── app.h ├── dtmf.c ├── dtmf.h ├── fm.c ├── fm.h ├── generic.c ├── generic.h ├── main.c ├── main.h ├── menu.c ├── menu.h ├── scanner.c ├── scanner.h ├── uart.c └── uart.h ├── audio.c ├── audio.h ├── bitmaps.c ├── bitmaps.h ├── board.c ├── board.h ├── bsp └── dp32g030 │ ├── aes.h │ ├── crc.h │ ├── dma.h │ ├── flash.h │ ├── gpio.h │ ├── irq.h │ ├── pmu.h │ ├── portcon.h │ ├── saradc.h │ ├── spi.h │ ├── syscon.h │ └── uart.h ├── compile-with-docker.bat ├── compile-with-docker.sh ├── dcs.c ├── dcs.h ├── dp32g030.cfg ├── driver ├── adc.c ├── adc.h ├── aes.c ├── aes.h ├── backlight.c ├── backlight.h ├── bk1080-regs.h ├── bk1080.c ├── bk1080.h ├── bk4819-regs.h ├── bk4819.c ├── bk4819.h ├── crc.c ├── crc.h ├── eeprom.c ├── eeprom.h ├── flash.c ├── flash.h ├── gpio.c ├── gpio.h ├── i2c.c ├── i2c.h ├── keyboard.c ├── keyboard.h ├── spi.c ├── spi.h ├── st7565.c ├── st7565.h ├── system.c ├── system.h ├── systick.c ├── systick.h ├── uart.c └── uart.h ├── firmware.ld ├── font.c ├── font.h ├── frequencies.c ├── frequencies.h ├── functions.c ├── functions.h ├── fw-pack.py ├── hardware └── dp32g030 │ ├── aes.def │ ├── crc.def │ ├── dma.def │ ├── flash.def │ ├── gpio.def │ ├── pmu.def │ ├── portcon.def │ ├── saradc.def │ ├── spi.def │ ├── syscon.def │ └── uart.def ├── helper ├── battery.c ├── battery.h ├── boot.c └── boot.h ├── init.c ├── main.c ├── misc.c ├── misc.h ├── printf_config.h ├── radio.c ├── radio.h ├── scheduler.c ├── settings.c ├── settings.h ├── sram-overlay.c ├── sram-overlay.h ├── start.S ├── ui ├── aircopy.c ├── aircopy.h ├── battery.c ├── battery.h ├── fmradio.c ├── fmradio.h ├── helper.c ├── helper.h ├── inputbox.c ├── inputbox.h ├── lock.c ├── lock.h ├── main.c ├── main.h ├── menu.c ├── menu.h ├── rssi.c ├── rssi.h ├── scanner.c ├── scanner.h ├── status.c ├── status.h ├── ui.c ├── ui.h ├── welcome.c └── welcome.h ├── version.c └── version.h /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-22.04 7 | 8 | steps: 9 | - name: arm-none-eabi-gcc 10 | uses: carlosperate/arm-none-eabi-gcc-action@v1 11 | with: 12 | release: '10.3-2021.10' 13 | 14 | - name: Install Python dependencies 15 | run: python -m pip install --upgrade pip crcmod 16 | 17 | - name: Checkout 18 | uses: actions/checkout@v3 19 | 20 | - name: Submodules 21 | run: git submodule update --init --recursive --depth 1 22 | 23 | - name: Make 24 | run: make 25 | 26 | - name: size 27 | run: arm-none-eabi-size firmware 28 | 29 | - name: 'Upload Artifact' 30 | uses: actions/upload-artifact@v3 31 | with: 32 | name: firmware 33 | path: firmware*.bin 34 | 35 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - '*' 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-22.04 9 | 10 | steps: 11 | - name: arm-none-eabi-gcc 12 | uses: carlosperate/arm-none-eabi-gcc-action@v1 13 | with: 14 | release: '10.3-2021.10' 15 | 16 | - name: Install Python dependencies 17 | run: python3 -m pip install --upgrade pip crcmod 18 | 19 | - name: Checkout 20 | uses: actions/checkout@v3 21 | 22 | - name: Submodules 23 | run: git submodule update --init --recursive --depth 1 24 | 25 | - name: Make 26 | run: make 27 | 28 | - name: size 29 | run: arm-none-eabi-size firmware 30 | 31 | - name: 'Upload Artifact' 32 | uses: actions/upload-artifact@v3 33 | with: 34 | name: firmware 35 | path: firmware*.bin 36 | 37 | - name: 'Create Release' 38 | uses: ncipollo/release-action@v1 39 | with: 40 | artifacts: "firmware*.bin" 41 | 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | /compiled-firmware 4 | link-overlay.S 5 | sram-overlay 6 | sram-overlay.bin 7 | 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/CMSIS_5"] 2 | path = external/CMSIS_5 3 | url = https://github.com/ARM-software/CMSIS_5 4 | ignore = dirty 5 | 6 | [submodule "external/printf"] 7 | path = external/printf 8 | url = https://github.com/mpaland/printf 9 | ignore = dirty 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM archlinux:latest 2 | RUN pacman -Syyu base-devel --noconfirm 3 | RUN pacman -Syyu arm-none-eabi-gcc --noconfirm 4 | RUN pacman -Syyu arm-none-eabi-newlib --noconfirm 5 | RUN pacman -Syyu git --noconfirm 6 | RUN pacman -Syyu python-pip --noconfirm 7 | RUN pacman -Syyu python-crcmod --noconfirm 8 | WORKDIR /app 9 | COPY . . 10 | 11 | RUN git submodule update --init --recursive 12 | #RUN make && cp firmware* compiled-firmware/ 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = firmware 2 | 3 | ENABLE_AIRCOPY := 1 4 | ENABLE_ALARM := 1 5 | ENABLE_FMRADIO := 1 6 | ENABLE_NOAA := 1 7 | ENABLE_OVERLAY := 1 8 | ENABLE_SWD := 0 9 | ENABLE_TX1750 := 1 10 | ENABLE_UART := 1 11 | 12 | BSP_DEFINITIONS := $(wildcard hardware/*/*.def) 13 | BSP_HEADERS := $(patsubst hardware/%,bsp/%,$(BSP_DEFINITIONS)) 14 | BSP_HEADERS := $(patsubst %.def,%.h,$(BSP_HEADERS)) 15 | 16 | OBJS = 17 | # Startup files 18 | OBJS += start.o 19 | OBJS += init.o 20 | ifeq ($(ENABLE_OVERLAY),1) 21 | OBJS += sram-overlay.o 22 | endif 23 | OBJS += external/printf/printf.o 24 | 25 | # Drivers 26 | OBJS += driver/adc.o 27 | ifeq ($(ENABLE_UART),1) 28 | OBJS += driver/aes.o 29 | endif 30 | OBJS += driver/backlight.o 31 | ifeq ($(ENABLE_FMRADIO),1) 32 | OBJS += driver/bk1080.o 33 | endif 34 | OBJS += driver/bk4819.o 35 | ifeq ($(filter $(ENABLE_AIRCOPY) $(ENABLE_UART),1),1) 36 | OBJS += driver/crc.o 37 | endif 38 | OBJS += driver/eeprom.o 39 | ifeq ($(ENABLE_OVERLAY),1) 40 | OBJS += driver/flash.o 41 | endif 42 | OBJS += driver/gpio.o 43 | OBJS += driver/i2c.o 44 | OBJS += driver/keyboard.o 45 | OBJS += driver/spi.o 46 | OBJS += driver/st7565.o 47 | OBJS += driver/system.o 48 | OBJS += driver/systick.o 49 | ifeq ($(ENABLE_UART),1) 50 | OBJS += driver/uart.o 51 | endif 52 | 53 | # Main 54 | OBJS += app/action.o 55 | ifeq ($(ENABLE_AIRCOPY),1) 56 | OBJS += app/aircopy.o 57 | endif 58 | OBJS += app/app.o 59 | OBJS += app/dtmf.o 60 | ifeq ($(ENABLE_FMRADIO),1) 61 | OBJS += app/fm.o 62 | endif 63 | OBJS += app/generic.o 64 | OBJS += app/main.o 65 | OBJS += app/menu.o 66 | OBJS += app/scanner.o 67 | ifeq ($(ENABLE_UART),1) 68 | OBJS += app/uart.o 69 | endif 70 | OBJS += audio.o 71 | OBJS += bitmaps.o 72 | OBJS += board.o 73 | OBJS += dcs.o 74 | OBJS += font.o 75 | OBJS += frequencies.o 76 | OBJS += functions.o 77 | OBJS += helper/battery.o 78 | OBJS += helper/boot.o 79 | OBJS += misc.o 80 | OBJS += radio.o 81 | OBJS += scheduler.o 82 | OBJS += settings.o 83 | ifeq ($(ENABLE_AIRCOPY),1) 84 | OBJS += ui/aircopy.o 85 | endif 86 | OBJS += ui/battery.o 87 | ifeq ($(ENABLE_FMRADIO),1) 88 | OBJS += ui/fmradio.o 89 | endif 90 | OBJS += ui/helper.o 91 | OBJS += ui/inputbox.o 92 | OBJS += ui/lock.o 93 | OBJS += ui/main.o 94 | OBJS += ui/menu.o 95 | OBJS += ui/rssi.o 96 | OBJS += ui/scanner.o 97 | OBJS += ui/status.o 98 | OBJS += ui/ui.o 99 | OBJS += ui/welcome.o 100 | OBJS += version.o 101 | 102 | OBJS += main.o 103 | 104 | ifeq ($(OS),Windows_NT) 105 | TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) 106 | else 107 | TOP := $(shell pwd) 108 | endif 109 | 110 | AS = arm-none-eabi-gcc 111 | CC = arm-none-eabi-gcc 112 | LD = arm-none-eabi-gcc 113 | OBJCOPY = arm-none-eabi-objcopy 114 | SIZE = arm-none-eabi-size 115 | 116 | GIT_HASH := $(shell git rev-parse --short HEAD) 117 | 118 | ASFLAGS = -c -mcpu=cortex-m0 119 | ifeq ($(ENABLE_OVERLAY),1) 120 | ASFLAGS += -DENABLE_OVERLAY 121 | endif 122 | CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD 123 | CFLAGS += -DPRINTF_INCLUDE_CONFIG_H 124 | CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" 125 | ifeq ($(ENABLE_AIRCOPY),1) 126 | CFLAGS += -DENABLE_AIRCOPY 127 | endif 128 | ifeq ($(ENABLE_ALARM),1) 129 | CFLAGS += -DENABLE_ALARM 130 | endif 131 | ifeq ($(ENABLE_FMRADIO),1) 132 | CFLAGS += -DENABLE_FMRADIO 133 | endif 134 | ifeq ($(ENABLE_NOAA),1) 135 | CFLAGS += -DENABLE_NOAA 136 | endif 137 | ifeq ($(ENABLE_OVERLAY),1) 138 | CFLAGS += -DENABLE_OVERLAY 139 | endif 140 | ifeq ($(ENABLE_SWD),1) 141 | CFLAGS += -DENABLE_SWD 142 | endif 143 | ifeq ($(ENABLE_TX1750),1) 144 | CFLAGS += -DENABLE_TX1750 145 | endif 146 | ifeq ($(ENABLE_UART),1) 147 | CFLAGS += -DENABLE_UART 148 | endif 149 | LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld 150 | 151 | ifeq ($(DEBUG),1) 152 | ASFLAGS += -g 153 | CFLAGS += -g 154 | LDFLAGS += -g 155 | endif 156 | 157 | INC = 158 | INC += -I $(TOP) 159 | INC += -I $(TOP)/external/CMSIS_5/CMSIS/Core/Include/ 160 | INC += -I $(TOP)/external/CMSIS_5/Device/ARM/ARMCM0/Include 161 | 162 | LIBS = 163 | 164 | DEPS = $(OBJS:.o=.d) 165 | 166 | all: $(TARGET) 167 | $(OBJCOPY) -O binary $< $<.bin 168 | -python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin 169 | -python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin 170 | $(SIZE) $< 171 | 172 | debug: 173 | /opt/openocd/bin/openocd -c "bindto 0.0.0.0" -f interface/jlink.cfg -f dp32g030.cfg 174 | 175 | flash: 176 | /opt/openocd/bin/openocd -c "bindto 0.0.0.0" -f interface/jlink.cfg -f dp32g030.cfg -c "write_image firmware.bin 0; shutdown;" 177 | 178 | version.o: .FORCE 179 | 180 | $(TARGET): $(OBJS) 181 | $(LD) $(LDFLAGS) $^ -o $@ $(LIBS) 182 | 183 | bsp/dp32g030/%.h: hardware/dp32g030/%.def 184 | 185 | %.o: %.c | $(BSP_HEADERS) 186 | $(CC) $(CFLAGS) $(INC) -c $< -o $@ 187 | 188 | %.o: %.S 189 | $(AS) $(ASFLAGS) $< -o $@ 190 | 191 | .FORCE: 192 | 193 | -include $(DEPS) 194 | 195 | clean: 196 | rm -f $(TARGET).bin $(TARGET).packed.bin $(TARGET) $(OBJS) $(DEPS) 197 | 198 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open reimplementation of the Quan Sheng UV K5 v2.1.27 firmware 2 | 3 | This repository is a preservation project of the UV K5 v2.1.27 firmware. 4 | It is dedicated to understanding how the radio works and help developers making their own customisations/fixes/etc. 5 | It is by no means fully understood or has all variables/functions properly named, as this is best effort only. 6 | As a result, this repository will not include any customisations or improvements over the original firmware. 7 | 8 | You can find an alternate branch called "fixes" that contains fixes for real bugs present in the original firmware. 9 | This branch will also accumulate fixes/improvements from newer releases by QS (for example v2.01.31). 10 | 11 | For improved/better firmware and new features, you can find the following repositories by other collaborators: 12 | 13 | * https://github.com/fagci/uv-k5-firmware-fagci-mod 14 | * https://github.com/OneOfEleven/uv-k5-firmware-custom 15 | * https://github.com/Tunas1337/uv-k5-firmware (Check the branches) 16 | * https://github.com/rebezhir/openquack for Russian users 17 | 18 | # Compiler 19 | 20 | arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on Ubuntu 22.04.03 LTS. 21 | Other versions may generate a flash file that is too big. 22 | You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm 23 | 24 | # Building 25 | 26 | To build the firmware, you need to fetch the submodules and then run make: 27 | ``` 28 | git submodule update --init --recursive --depth=1 29 | make 30 | ``` 31 | 32 | # Flashing with the official updater 33 | 34 | * Use the firmware.packed.bin file 35 | 36 | # Flashing with [k5prog](https://github.com/piotr022/k5prog) 37 | 38 | * ./k5prog -F -YYY -b firmware.bin 39 | 40 | # Flashing with SWD 41 | 42 | * If you own a JLink or compatible device and want to use the Segger software, you can find a flash loader [here](https://github.com/DualTachyon/dp32g030-flash-loader) 43 | * If you want to use OpenOCD instead, you can use run "make flash" off this repo. 44 | * The DP32G030 has flash masking to move the bootloader out of the way. Do not try to flash your own way outside of the above methods or risk losing your bootloader. 45 | 46 | # Support 47 | 48 | * If you like my work, you can support me through https://ko-fi.com/DualTachyon 49 | 50 | # Credits 51 | 52 | Many thanks to various people on Telegram for putting up with me during this effort and helping: 53 | 54 | * [Mikhail](https://github.com/fagci/) 55 | * [Andrej](https://github.com/Tunas1337) 56 | * [Manuel](https://github.com/manujedi) 57 | * @wagner 58 | * @Lohtse Shar 59 | * [@Matoz](https://github.com/spm81) 60 | * @Davide 61 | * @Ismo OH2FTG 62 | * [OneOfEleven](https://github.com/OneOfEleven) 63 | * and others I forget 64 | 65 | # License 66 | 67 | Copyright 2023 Dual Tachyon 68 | https://github.com/DualTachyon 69 | 70 | Licensed under the Apache License, Version 2.0 (the "License"); 71 | you may not use this file except in compliance with the License. 72 | You may obtain a copy of the License at 73 | 74 | http://www.apache.org/licenses/LICENSE-2.0 75 | 76 | Unless required by applicable law or agreed to in writing, software 77 | distributed under the License is distributed on an "AS IS" BASIS, 78 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 79 | See the License for the specific language governing permissions and 80 | limitations under the License. 81 | 82 | -------------------------------------------------------------------------------- /app/action.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_ACTION_H 18 | #define APP_ACTION_H 19 | 20 | #include "driver/keyboard.h" 21 | 22 | void ACTION_Power(void); 23 | void ACTION_Scan(bool bFlag); 24 | void ACTION_Vox(void); 25 | void ACTION_FM(void); 26 | 27 | void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /app/aircopy.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_AIRCOPY_H 18 | #define APP_AIRCOPY_H 19 | 20 | #include "driver/keyboard.h" 21 | 22 | enum AIRCOPY_State_t { 23 | AIRCOPY_READY = 0U, 24 | AIRCOPY_TRANSFER = 1U, 25 | AIRCOPY_COMPLETE = 2U, 26 | }; 27 | 28 | typedef enum AIRCOPY_State_t AIRCOPY_State_t; 29 | 30 | extern AIRCOPY_State_t gAircopyState; 31 | extern uint16_t gAirCopyBlockNumber; 32 | extern uint16_t gErrorsDuringAirCopy; 33 | extern uint8_t gAirCopyIsSendMode; 34 | 35 | extern uint16_t g_FSK_Buffer[36]; 36 | 37 | void AIRCOPY_SendMessage(void); 38 | void AIRCOPY_StorePacket(void); 39 | 40 | void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /app/app.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_APP_H 18 | #define APP_APP_H 19 | 20 | #include 21 | #include "functions.h" 22 | #include "radio.h" 23 | 24 | void APP_EndTransmission(void); 25 | void CHANNEL_Next(bool bFlag, int8_t Direction); 26 | void APP_StartListening(FUNCTION_Type_t Function); 27 | void APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step); 28 | 29 | void APP_Update(void); 30 | void APP_TimeSlice10ms(void); 31 | void APP_TimeSlice500ms(void); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /app/dtmf.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DTMF_H 18 | #define DTMF_H 19 | 20 | #include 21 | #include 22 | 23 | enum DTMF_State_t { 24 | DTMF_STATE_0 = 0U, 25 | DTMF_STATE_TX_SUCC = 1U, 26 | DTMF_STATE_CALL_OUT_RSP = 2U, 27 | }; 28 | 29 | typedef enum DTMF_State_t DTMF_State_t; 30 | 31 | enum DTMF_CallState_t { 32 | DTMF_CALL_STATE_NONE = 0U, 33 | DTMF_CALL_STATE_CALL_OUT = 1U, 34 | DTMF_CALL_STATE_RECEIVED = 2U, 35 | }; 36 | 37 | typedef enum DTMF_CallState_t DTMF_CallState_t; 38 | 39 | enum DTMF_ReplyState_t { 40 | DTMF_REPLY_NONE = 0U, 41 | DTMF_REPLY_ANI = 1U, 42 | DTMF_REPLY_AB = 2U, 43 | DTMF_REPLY_AAAAA = 3U, 44 | }; 45 | 46 | typedef enum DTMF_ReplyState_t DTMF_ReplyState_t; 47 | 48 | enum DTMF_CallMode_t { 49 | DTMF_CALL_MODE_NOT_GROUP = 0U, 50 | DTMF_CALL_MODE_GROUP = 1U, 51 | DTMF_CALL_MODE_DTMF = 2U, 52 | }; 53 | 54 | typedef enum DTMF_CallMode_t DTMF_CallMode_t; 55 | 56 | extern char gDTMF_String[15]; 57 | extern char gDTMF_InputBox[15]; 58 | extern char gDTMF_Received[16]; 59 | extern bool gIsDtmfContactValid; 60 | extern char gDTMF_ID[4]; 61 | extern char gDTMF_Caller[4]; 62 | extern char gDTMF_Callee[4]; 63 | extern DTMF_State_t gDTMF_State; 64 | extern bool gDTMF_DecodeRing; 65 | extern uint8_t gDTMF_DecodeRingCountdown; 66 | extern uint8_t gDTMFChosenContact; 67 | extern uint8_t gDTMF_WriteIndex; 68 | extern uint8_t gDTMF_PreviousIndex; 69 | extern uint8_t gDTMF_AUTO_RESET_TIME; 70 | extern uint8_t gDTMF_InputIndex; 71 | extern bool gDTMF_InputMode; 72 | extern uint8_t gDTMF_RecvTimeout; 73 | extern DTMF_CallState_t gDTMF_CallState; 74 | extern DTMF_ReplyState_t gDTMF_ReplyState; 75 | extern DTMF_CallMode_t gDTMF_CallMode; 76 | extern bool gDTMF_IsTx; 77 | extern uint8_t gDTMF_TxStopCountdown; 78 | 79 | bool DTMF_ValidateCodes(char *pCode, uint8_t Size); 80 | bool DTMF_GetContact(uint8_t Index, char *pContact); 81 | bool DTMF_FindContact(const char *pContact, char *pResult); 82 | char DTMF_GetCharacter(uint8_t Code); 83 | bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, uint8_t Size, bool bFlag); 84 | DTMF_CallMode_t DTMF_CheckGroupCall(const char *pDTMF, uint32_t Size); 85 | void DTMF_Append(char Code); 86 | void DTMF_HandleRequest(void); 87 | void DTMF_Reply(void); 88 | 89 | #endif 90 | 91 | -------------------------------------------------------------------------------- /app/fm.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_FM_H 18 | #define APP_FM_H 19 | 20 | #include "driver/keyboard.h" 21 | 22 | #define FM_CHANNEL_UP 0x01 23 | #define FM_CHANNEL_DOWN 0xFF 24 | 25 | enum { 26 | FM_SCAN_OFF = 0U, 27 | }; 28 | 29 | extern uint16_t gFM_Channels[20]; 30 | extern bool gFmRadioMode; 31 | extern uint8_t gFmRadioCountdown; 32 | extern volatile uint16_t gFmPlayCountdown; 33 | extern volatile int8_t gFM_ScanState; 34 | extern bool gFM_AutoScan; 35 | extern uint8_t gFM_ChannelPosition; 36 | // Doubts about whether this should be signed or not. 37 | extern uint16_t gFM_FrequencyDeviation; 38 | extern bool gFM_FoundFrequency; 39 | extern bool gFM_AutoScan; 40 | extern uint8_t gFM_ResumeCountdown; 41 | extern uint16_t gFM_RestoreCountdown; 42 | 43 | bool FM_CheckValidChannel(uint8_t Channel); 44 | uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction); 45 | int FM_ConfigureChannelState(void); 46 | void FM_TurnOff(void); 47 | void FM_EraseChannels(void); 48 | 49 | void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag); 50 | void FM_PlayAndUpdate(void); 51 | int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit); 52 | 53 | void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 54 | 55 | void FM_Play(void); 56 | void FM_Start(void); 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /app/generic.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_GENERIC_H 18 | #define APP_GENERIC_H 19 | 20 | #include 21 | 22 | void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld); 23 | void GENERIC_Key_PTT(bool bKeyPressed); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /app/main.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_MAIN_H 18 | #define APP_MAIN_H 19 | 20 | #include "driver/keyboard.h" 21 | 22 | void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /app/menu.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_MENU_H 18 | #define APP_MENU_H 19 | 20 | #include "driver/keyboard.h" 21 | 22 | int MENU_GetLimits(uint8_t Cursor, uint8_t *pMin, uint8_t *pMax); 23 | void MENU_AcceptSetting(void); 24 | void MENU_SelectNextCode(void); 25 | void MENU_ShowCurrentSetting(void); 26 | void MENU_StartCssScan(int8_t Direction); 27 | void MENU_StopCssScan(void); 28 | 29 | void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /app/scanner.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_SCANNER_H 18 | #define APP_SCANNER_H 19 | 20 | #include "dcs.h" 21 | #include "driver/keyboard.h" 22 | 23 | enum SCAN_CssState_t { 24 | SCAN_CSS_STATE_OFF = 0U, 25 | SCAN_CSS_STATE_SCANNING = 1U, 26 | SCAN_CSS_STATE_FOUND = 2U, 27 | SCAN_CSS_STATE_FAILED = 3U, 28 | }; 29 | 30 | typedef enum SCAN_CssState_t SCAN_CssState_t; 31 | 32 | enum { 33 | SCAN_OFF = 0U, 34 | }; 35 | 36 | extern DCS_CodeType_t gScanCssResultType; 37 | extern uint8_t gScanCssResultCode; 38 | extern bool gFlagStartScan; 39 | extern bool gFlagStopScan; 40 | extern bool gScanSingleFrequency; 41 | extern uint8_t gScannerEditState; 42 | extern uint8_t gScanChannel; 43 | extern uint32_t gScanFrequency; 44 | extern bool gScanPauseMode; 45 | extern SCAN_CssState_t gScanCssState; 46 | extern volatile bool gScheduleScanListen; 47 | extern volatile uint16_t ScanPauseDelayIn10msec; 48 | extern uint8_t gScanProgressIndicator; 49 | extern uint8_t gScanHitCount; 50 | extern bool gScanUseCssResult; 51 | extern int8_t gScanState; 52 | extern bool bScanKeepFrequency; 53 | 54 | void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); 55 | void SCANNER_Start(void); 56 | void SCANNER_Stop(void); 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /app/uart.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef APP_UART_H 18 | #define APP_UART_H 19 | 20 | #include 21 | 22 | bool UART_IsCommandAvailable(void); 23 | void UART_HandleCommand(void); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /audio.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef AUDIO_H 18 | #define AUDIO_H 19 | 20 | #include 21 | #include 22 | 23 | enum BEEP_Type_t { 24 | BEEP_NONE = 0U, 25 | BEEP_1KHZ_60MS_OPTIONAL = 1U, 26 | BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL = 2U, 27 | BEEP_440HZ_500MS = 3U, 28 | BEEP_500HZ_60MS_DOUBLE_BEEP = 4U, 29 | }; 30 | 31 | typedef enum BEEP_Type_t BEEP_Type_t; 32 | 33 | enum { 34 | VOICE_ID_CHI_BASE = 0x10U, 35 | VOICE_ID_ENG_BASE = 0x60U, 36 | }; 37 | 38 | enum VOICE_ID_t { 39 | VOICE_ID_0 = 0x00U, 40 | VOICE_ID_1 = 0x01U, 41 | VOICE_ID_2 = 0x02U, 42 | VOICE_ID_3 = 0x03U, 43 | VOICE_ID_4 = 0x04U, 44 | VOICE_ID_5 = 0x05U, 45 | VOICE_ID_6 = 0x06U, 46 | VOICE_ID_7 = 0x07U, 47 | VOICE_ID_8 = 0x08U, 48 | VOICE_ID_9 = 0x09U, 49 | VOICE_ID_10 = 0x0AU, 50 | VOICE_ID_100 = 0x0BU, 51 | VOICE_ID_WELCOME = 0x0CU, 52 | VOICE_ID_LOCK = 0x0DU, 53 | VOICE_ID_UNLOCK = 0x0EU, 54 | VOICE_ID_SCANNING_BEGIN = 0x0FU, 55 | VOICE_ID_SCANNING_STOP = 0x10U, 56 | VOICE_ID_SCRAMBLER_ON = 0x11U, 57 | VOICE_ID_SCRAMBLER_OFF = 0x12U, 58 | VOICE_ID_FUNCTION = 0x13U, 59 | VOICE_ID_CTCSS = 0x14U, 60 | VOICE_ID_DCS = 0x15U, 61 | VOICE_ID_POWER = 0x16U, 62 | VOICE_ID_SAVE_MODE = 0x17U, 63 | VOICE_ID_MEMORY_CHANNEL = 0x18U, 64 | VOICE_ID_DELETE_CHANNEL = 0x19U, 65 | VOICE_ID_FREQUENCY_STEP = 0x1AU, 66 | VOICE_ID_SQUELCH = 0x1BU, 67 | VOICE_ID_TRANSMIT_OVER_TIME = 0x1CU, 68 | VOICE_ID_BACKLIGHT_SELECTION = 0x1DU, 69 | VOICE_ID_VOX = 0x1EU, 70 | VOICE_ID_FREQUENCY_DIRECTION = 0x1FU, 71 | VOICE_ID_OFFSET_FREQUENCY = 0x20U, 72 | VOICE_ID_TRANSMITING_MEMORY = 0x21U, 73 | VOICE_ID_RECEIVING_MEMORY = 0x22U, 74 | VOICE_ID_EMERGENCY_CALL = 0x23U, 75 | VOICE_ID_LOW_VOLTAGE = 0x24U, 76 | VOICE_ID_CHANNEL_MODE = 0x25U, 77 | VOICE_ID_FREQUENCY_MODE = 0x26U, 78 | VOICE_ID_VOICE_PROMPT = 0x27U, 79 | VOICE_ID_BAND_SELECTION = 0x28U, 80 | VOICE_ID_DUAL_STANDBY = 0x29U, 81 | VOICE_ID_CHANNEL_BANDWIDTH = 0x2AU, 82 | VOICE_ID_OPTIONAL_SIGNAL = 0x2BU, 83 | VOICE_ID_MUTE_MODE = 0x2CU, 84 | VOICE_ID_BUSY_LOCKOUT = 0x2DU, 85 | VOICE_ID_BEEP_PROMPT = 0x2EU, 86 | VOICE_ID_ANI_CODE = 0x2FU, 87 | VOICE_ID_INITIALISATION = 0x30U, 88 | VOICE_ID_CONFIRM = 0x31U, 89 | VOICE_ID_CANCEL = 0x32U, 90 | VOICE_ID_ON = 0x33U, 91 | VOICE_ID_OFF = 0x34U, 92 | VOICE_ID_2_TONE = 0x35U, 93 | VOICE_ID_5_TONE = 0x36U, 94 | VOICE_ID_DIGITAL_SIGNAL = 0x37U, 95 | VOICE_ID_REPEATER = 0x38U, 96 | VOICE_ID_MENU = 0x39U, 97 | VOICE_ID_11 = 0x3AU, 98 | VOICE_ID_12 = 0x3BU, 99 | VOICE_ID_13 = 0x3CU, 100 | VOICE_ID_14 = 0x3DU, 101 | VOICE_ID_15 = 0x3EU, 102 | VOICE_ID_16 = 0x3FU, 103 | VOICE_ID_17 = 0x40U, 104 | VOICE_ID_18 = 0x41U, 105 | VOICE_ID_19 = 0x42U, 106 | VOICE_ID_20 = 0x43U, 107 | VOICE_ID_30 = 0x44U, 108 | VOICE_ID_40 = 0x45U, 109 | VOICE_ID_50 = 0x46U, 110 | VOICE_ID_60 = 0x47U, 111 | VOICE_ID_70 = 0x48U, 112 | VOICE_ID_80 = 0x49U, 113 | VOICE_ID_90 = 0x4AU, 114 | VOICE_ID_END = 0x4BU, 115 | 116 | VOICE_ID_INVALID = 0xFFU, 117 | }; 118 | 119 | typedef enum VOICE_ID_t VOICE_ID_t; 120 | 121 | extern VOICE_ID_t gVoiceID[8]; 122 | extern uint8_t gVoiceReadIndex; 123 | extern uint8_t gVoiceWriteIndex; 124 | extern volatile uint16_t gCountdownToPlayNextVoice; 125 | extern volatile bool gFlagPlayQueuedVoice; 126 | extern VOICE_ID_t gAnotherVoiceID; 127 | extern BEEP_Type_t gBeepToPlay; 128 | 129 | void AUDIO_PlayBeep(BEEP_Type_t Beep); 130 | void AUDIO_PlayVoice(uint8_t VoiceID); 131 | void AUDIO_PlaySingleVoice(bool bFlag); 132 | void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID); 133 | uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value); 134 | void AUDIO_PlayQueuedVoice(void); 135 | 136 | #endif 137 | 138 | -------------------------------------------------------------------------------- /bitmaps.c: -------------------------------------------------------------------------------- 1 | #include "bitmaps.h" 2 | 3 | const uint8_t BITMAP_PowerSave[8] = { 0x00, 0x26, 0x49, 0x49, 0x49, 0x49, 0x49, 0x32 }; 4 | 5 | const uint8_t BITMAP_BatteryLevel1[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 }; 6 | const uint8_t BITMAP_BatteryLevel2[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 }; 7 | const uint8_t BITMAP_BatteryLevel3[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 }; 8 | const uint8_t BITMAP_BatteryLevel4[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x63 }; 9 | const uint8_t BITMAP_BatteryLevel5[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x63 }; 10 | 11 | const uint8_t BITMAP_USB_C[9] = { 0x00, 0x1C, 0x27, 0x44, 0x44, 0x44, 0x44, 0x27, 0x1C }; 12 | const uint8_t BITMAP_KeyLock[9] = { 0x00, 0x7C, 0x46, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7C }; 13 | 14 | const uint8_t BITMAP_F_Key[10] = { 0xFF, 0x81, 0xBD, 0x95, 0x95, 0x95, 0x95, 0x85, 0x81, 0xFF }; 15 | 16 | const uint8_t BITMAP_VOX[18] = { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x0, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }; 17 | 18 | const uint8_t BITMAP_WX[12] = { 0x00, 0x7F, 0x20, 0x18, 0x20, 0x7F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }; 19 | const uint8_t BITMAP_TDR[12] = { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x20, 0x18, 0x20, 0x7F }; 20 | const uint8_t BITMAP_VoicePrompt[9] = { 0x00, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0xFF, 0x18 }; 21 | 22 | #if defined(ENABLE_FMRADIO) 23 | const uint8_t BITMAP_FM[12] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }; 24 | #endif 25 | #if defined(ENABLE_NOAA) 26 | const uint8_t BITMAP_NOAA[12] = { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }; 27 | #endif 28 | 29 | const uint8_t BITMAP_Antenna[5] = { 0x03, 0x05, 0x7F, 0x05, 0x03 }; 30 | const uint8_t BITMAP_AntennaLevel1[3] = { 0x60, 0x60, 0x00 }; 31 | const uint8_t BITMAP_AntennaLevel2[3] = { 0x70, 0x70, 0x00 }; 32 | const uint8_t BITMAP_AntennaLevel3[3] = { 0x78, 0x78, 0x00 }; 33 | const uint8_t BITMAP_AntennaLevel4[3] = { 0x7C, 0x7C, 0x00 }; 34 | const uint8_t BITMAP_AntennaLevel5[3] = { 0x7E, 0x7E, 0x00 }; 35 | const uint8_t BITMAP_AntennaLevel6[3] = { 0x7F, 0x7F, 0x00 }; 36 | 37 | const uint8_t BITMAP_CurrentIndicator[8] = { 0xFF, 0xFF, 0x7E, 0x7E, 0x3C, 0x3C, 0x18, 0x18 }; 38 | 39 | const uint8_t BITMAP_VFO_Default[8] = { 0x00, 0x7F, 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08 }; 40 | const uint8_t BITMAP_VFO_NotDefault[8] = { 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08 }; 41 | 42 | const uint8_t BITMAP_TX[16] = { 0x00, 0x01, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x01, 0x00, 0x63, 0x22, 0x14, 0x08, 0x14, 0x22, 0x63 }; 43 | const uint8_t BITMAP_RX[16] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x19, 0x29, 0x46, 0x00, 0x63, 0x22, 0x14, 0x08, 0x14, 0x22, 0x63 }; 44 | 45 | const uint8_t BITMAP_M[8] = { 0x00, 0x7F, 0x02, 0x04, 0x18, 0x04, 0x02, 0x7F }; 46 | const uint8_t BITMAP_F[8] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01 }; 47 | 48 | const uint8_t BITMAP_ReverseMode[8] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x19, 0x29, 0x46 }; 49 | 50 | const uint8_t BITMAP_NarrowBand[8] = { 0x00, 0x7F, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7F }; 51 | 52 | const uint8_t BITMAP_DTMF[24] = { 53 | 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x01, 54 | 0x01, 0x7F, 0x01, 0x01, 0x00, 0x7F, 0x02, 0x0C, 55 | 0x02, 0x7F, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 56 | }; 57 | 58 | const uint8_t BITMAP_Scramble[18] = { 59 | 0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x3E, 60 | 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x09, 0x19, 61 | 0x29, 0x46, 62 | }; 63 | 64 | const uint8_t BITMAP_Add[8] = { 0x00, 0x18, 0x18, 0x7E, 0x7E, 0x7E, 0x18, 0x18 }; 65 | const uint8_t BITMAP_Sub[8] = { 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }; 66 | 67 | const uint8_t BITMAP_PowerHigh[8] = { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x7F }; 68 | const uint8_t BITMAP_PowerMid[8] = { 0x00, 0x7F, 0x02, 0x04, 0x18, 0x04, 0x02, 0x7F }; 69 | const uint8_t BITMAP_PowerLow[8] = { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; 70 | 71 | const uint8_t BITMAP_AM[12] = { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }; 72 | 73 | const uint8_t BITMAP_CT[12] = { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }; 74 | const uint8_t BITMAP_DCS[18] = { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32 }; 75 | 76 | const uint8_t BITMAP_ScanList[6] = { 0x08, 0x1C, 0x3E, 0x3E, 0x1C, 0x08 }; 77 | -------------------------------------------------------------------------------- /bitmaps.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMAP_H 2 | #define BITMAP_H 3 | 4 | #include 5 | 6 | extern const uint8_t BITMAP_PowerSave[8]; 7 | 8 | extern const uint8_t BITMAP_BatteryLevel1[18]; 9 | extern const uint8_t BITMAP_BatteryLevel2[18]; 10 | extern const uint8_t BITMAP_BatteryLevel3[18]; 11 | extern const uint8_t BITMAP_BatteryLevel4[18]; 12 | extern const uint8_t BITMAP_BatteryLevel5[18]; 13 | 14 | extern const uint8_t BITMAP_USB_C[9]; 15 | extern const uint8_t BITMAP_KeyLock[9]; 16 | 17 | extern const uint8_t BITMAP_F_Key[10]; 18 | 19 | extern const uint8_t BITMAP_VOX[18]; 20 | 21 | extern const uint8_t BITMAP_WX[12]; 22 | extern const uint8_t BITMAP_TDR[12]; 23 | extern const uint8_t BITMAP_VoicePrompt[9]; 24 | 25 | #if defined(ENABLE_FMRADIO) 26 | extern const uint8_t BITMAP_FM[12]; 27 | #endif 28 | extern const uint8_t BITMAP_NOAA[12]; 29 | 30 | extern const uint8_t BITMAP_Antenna[5]; 31 | extern const uint8_t BITMAP_AntennaLevel1[3]; 32 | extern const uint8_t BITMAP_AntennaLevel2[3]; 33 | extern const uint8_t BITMAP_AntennaLevel3[3]; 34 | extern const uint8_t BITMAP_AntennaLevel4[3]; 35 | extern const uint8_t BITMAP_AntennaLevel5[3]; 36 | extern const uint8_t BITMAP_AntennaLevel6[3]; 37 | 38 | extern const uint8_t BITMAP_CurrentIndicator[8]; 39 | 40 | extern const uint8_t BITMAP_VFO_Default[8]; 41 | extern const uint8_t BITMAP_VFO_NotDefault[8]; 42 | 43 | extern const uint8_t BITMAP_TX[16]; 44 | extern const uint8_t BITMAP_RX[16]; 45 | 46 | extern const uint8_t BITMAP_M[8]; 47 | extern const uint8_t BITMAP_F[8]; 48 | 49 | extern const uint8_t BITMAP_ReverseMode[8]; 50 | 51 | extern const uint8_t BITMAP_NarrowBand[8]; 52 | 53 | extern const uint8_t BITMAP_DTMF[24]; 54 | extern const uint8_t BITMAP_Scramble[18]; 55 | 56 | extern const uint8_t BITMAP_Add[8]; 57 | extern const uint8_t BITMAP_Sub[8]; 58 | 59 | extern const uint8_t BITMAP_PowerHigh[8]; 60 | extern const uint8_t BITMAP_PowerMid[8]; 61 | extern const uint8_t BITMAP_PowerLow[8]; 62 | 63 | extern const uint8_t BITMAP_AM[12]; 64 | 65 | extern const uint8_t BITMAP_CT[12]; 66 | extern const uint8_t BITMAP_DCS[18]; 67 | 68 | extern const uint8_t BITMAP_ScanList[6]; 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /board.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BOARD_H 18 | #define BOARD_H 19 | 20 | #include 21 | #include 22 | 23 | void BOARD_FLASH_Init(void); 24 | void BOARD_GPIO_Init(void); 25 | void BOARD_PORTCON_Init(void); 26 | void BOARD_ADC_Init(void); 27 | void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent); 28 | void BOARD_Init(void); 29 | void BOARD_EEPROM_Init(void); 30 | void BOARD_EEPROM_LoadCalibration(void); 31 | void BOARD_FactoryReset(bool bIsAll); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /bsp/dp32g030/aes.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef HARDWARE_DP32G030_AES_H 18 | #define HARDWARE_DP32G030_AES_H 19 | 20 | #if !defined(__ASSEMBLY__) 21 | #include 22 | #endif 23 | 24 | /* -------- AES -------- */ 25 | #define AES_BASE_ADDR 0x400BD000U 26 | #define AES_BASE_SIZE 0x00000800U 27 | 28 | #define AES_CR_ADDR (AES_BASE_ADDR + 0x0000U) 29 | #define AES_CR (*(volatile uint32_t *)AES_CR_ADDR) 30 | #define AES_CR_EN_SHIFT 0 31 | #define AES_CR_EN_WIDTH 1 32 | #define AES_CR_EN_MASK (((1U << AES_CR_EN_WIDTH) - 1U) << AES_CR_EN_SHIFT) 33 | #define AES_CR_EN_VALUE_DISABLE 0U 34 | #define AES_CR_EN_BITS_DISABLE (AES_CR_EN_VALUE_DISABLE << AES_CR_EN_SHIFT) 35 | #define AES_CR_EN_VALUE_ENABLE 1U 36 | #define AES_CR_EN_BITS_ENABLE (AES_CR_EN_VALUE_ENABLE << AES_CR_EN_SHIFT) 37 | 38 | #define AES_CR_CHMOD_SHIFT 5 39 | #define AES_CR_CHMOD_WIDTH 2 40 | #define AES_CR_CHMOD_MASK (((1U << AES_CR_CHMOD_WIDTH) - 1U) << AES_CR_CHMOD_SHIFT) 41 | #define AES_CR_CHMOD_VALUE_ECB 0U 42 | #define AES_CR_CHMOD_BITS_ECB (AES_CR_CHMOD_VALUE_ECB << AES_CR_CHMOD_SHIFT) 43 | #define AES_CR_CHMOD_VALUE_CBC 1U 44 | #define AES_CR_CHMOD_BITS_CBC (AES_CR_CHMOD_VALUE_CBC << AES_CR_CHMOD_SHIFT) 45 | #define AES_CR_CHMOD_VALUE_CTR 2U 46 | #define AES_CR_CHMOD_BITS_CTR (AES_CR_CHMOD_VALUE_CTR << AES_CR_CHMOD_SHIFT) 47 | 48 | #define AES_CR_CCFC_SHIFT 7 49 | #define AES_CR_CCFC_WIDTH 1 50 | #define AES_CR_CCFC_MASK (((1U << AES_CR_CCFC_WIDTH) - 1U) << AES_CR_CCFC_SHIFT) 51 | #define AES_CR_CCFC_VALUE_SET 1U 52 | #define AES_CR_CCFC_BITS_SET (AES_CR_CCFC_VALUE_SET << AES_CR_CCFC_SHIFT) 53 | 54 | #define AES_SR_ADDR (AES_BASE_ADDR + 0x0004U) 55 | #define AES_SR (*(volatile uint32_t *)AES_SR_ADDR) 56 | #define AES_SR_CCF_SHIFT 0 57 | #define AES_SR_CCF_WIDTH 1 58 | #define AES_SR_CCF_MASK (((1U << AES_SR_CCF_WIDTH) - 1U) << AES_SR_CCF_SHIFT) 59 | #define AES_SR_CCF_VALUE_NOT_COMPLETE 0U 60 | #define AES_SR_CCF_BITS_NOT_COMPLETE (AES_SR_CCF_VALUE_NOT_COMPLETE << AES_SR_CCF_SHIFT) 61 | #define AES_SR_CCF_VALUE_COMPLETE 1U 62 | #define AES_SR_CCF_BITS_COMPLETE (AES_SR_CCF_VALUE_COMPLETE << AES_SR_CCF_SHIFT) 63 | 64 | #define AES_DINR_ADDR (AES_BASE_ADDR + 0x0008U) 65 | #define AES_DINR (*(volatile uint32_t *)AES_DINR_ADDR) 66 | #define AES_DOUTR_ADDR (AES_BASE_ADDR + 0x000CU) 67 | #define AES_DOUTR (*(volatile uint32_t *)AES_DOUTR_ADDR) 68 | #define AES_KEYR0_ADDR (AES_BASE_ADDR + 0x0010U) 69 | #define AES_KEYR0 (*(volatile uint32_t *)AES_KEYR0_ADDR) 70 | #define AES_KEYR1_ADDR (AES_BASE_ADDR + 0x0014U) 71 | #define AES_KEYR1 (*(volatile uint32_t *)AES_KEYR1_ADDR) 72 | #define AES_KEYR2_ADDR (AES_BASE_ADDR + 0x0018U) 73 | #define AES_KEYR2 (*(volatile uint32_t *)AES_KEYR2_ADDR) 74 | #define AES_KEYR3_ADDR (AES_BASE_ADDR + 0x001CU) 75 | #define AES_KEYR3 (*(volatile uint32_t *)AES_KEYR3_ADDR) 76 | #define AES_IVR0_ADDR (AES_BASE_ADDR + 0x0020U) 77 | #define AES_IVR0 (*(volatile uint32_t *)AES_IVR0_ADDR) 78 | #define AES_IVR1_ADDR (AES_BASE_ADDR + 0x0024U) 79 | #define AES_IVR1 (*(volatile uint32_t *)AES_IVR1_ADDR) 80 | #define AES_IVR2_ADDR (AES_BASE_ADDR + 0x0028U) 81 | #define AES_IVR2 (*(volatile uint32_t *)AES_IVR2_ADDR) 82 | #define AES_IVR3_ADDR (AES_BASE_ADDR + 0x002CU) 83 | #define AES_IVR3 (*(volatile uint32_t *)AES_IVR3_ADDR) 84 | 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /bsp/dp32g030/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef DP32G030_IRQ_H 2 | #define DP32G030_IRQ_H 3 | 4 | enum { 5 | DP32_WWDT_IRQn = 0, 6 | DP32_IWDT_IRQn, 7 | DP32_RTC_IRQn, 8 | DP32_DMA_IRQn, 9 | DP32_SARADC_IRQn, 10 | DP32_TIMER_BASE0_IRQn, 11 | DP32_TIMER_BASE1_IRQn, 12 | DP32_TIMER_PLUS0_IRQn, 13 | DP32_TIMER_PLUS1_IRQn, 14 | DP32_PWM_BASE0_IRQn, 15 | DP32_PWM_BASE1_IRQn, 16 | DP32_PWM_PLUS0_IRQn, 17 | DP32_PWM_PLUS1_IRQn, 18 | DP32_UART0_IRQn, 19 | DP32_UART1_IRQn, 20 | DP32_UART2_IRQn, 21 | DP32_SPI0_IRQn, 22 | DP32_SPI1_IRQn, 23 | DP32_IIC0_IRQn, 24 | DP32_IIC1_IRQn, 25 | DP32_CMP_IRQn, 26 | DP32_TIMER_BASE2_IRQn, 27 | DP32_GPIOA5_IRQn, 28 | DP32_GPIOA6_IRQn, 29 | DP32_GPIOA7_IRQn, 30 | DP32_GPIOB0_IRQn, 31 | DP32_GPIOB1_IRQn, 32 | DP32_GPIOC0_IRQn, 33 | DP32_GPIOC1_IRQn, 34 | DP32_GPIOA_IRQn, 35 | DP32_GPIOB_IRQn, 36 | DP32_GPIOC_IRQn, 37 | }; 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /bsp/dp32g030/pmu.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef HARDWARE_DP32G030_PMU_H 18 | #define HARDWARE_DP32G030_PMU_H 19 | 20 | #if !defined(__ASSEMBLY__) 21 | #include 22 | #endif 23 | 24 | /* -------- PMU -------- */ 25 | #define PMU_BASE_ADDR 0x40000800U 26 | #define PMU_BASE_SIZE 0x00000800U 27 | 28 | #define PMU_SRC_CFG_ADDR (PMU_BASE_ADDR + 0x0010U) 29 | #define PMU_SRC_CFG (*(volatile uint32_t *)PMU_SRC_CFG_ADDR) 30 | #define PMU_SRC_CFG_RCHF_EN_SHIFT 0 31 | #define PMU_SRC_CFG_RCHF_EN_WIDTH 1 32 | #define PMU_SRC_CFG_RCHF_EN_MASK (((1U << PMU_SRC_CFG_RCHF_EN_WIDTH) - 1U) << PMU_SRC_CFG_RCHF_EN_SHIFT) 33 | #define PMU_SRC_CFG_RCHF_EN_VALUE_DISABLE 0U 34 | #define PMU_SRC_CFG_RCHF_EN_BITS_DISABLE (PMU_SRC_CFG_RCHF_EN_VALUE_DISABLE << PMU_SRC_CFG_RCHF_EN_SHIFT) 35 | #define PMU_SRC_CFG_RCHF_EN_VALUE_ENABLE 1U 36 | #define PMU_SRC_CFG_RCHF_EN_BITS_ENABLE (PMU_SRC_CFG_RCHF_EN_VALUE_ENABLE << PMU_SRC_CFG_RCHF_EN_SHIFT) 37 | 38 | #define PMU_SRC_CFG_RCHF_SEL_SHIFT 1 39 | #define PMU_SRC_CFG_RCHF_SEL_WIDTH 1 40 | #define PMU_SRC_CFG_RCHF_SEL_MASK (((1U << PMU_SRC_CFG_RCHF_SEL_WIDTH) - 1U) << PMU_SRC_CFG_RCHF_SEL_SHIFT) 41 | #define PMU_SRC_CFG_RCHF_SEL_VALUE_48MHZ 0U 42 | #define PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ (PMU_SRC_CFG_RCHF_SEL_VALUE_48MHZ << PMU_SRC_CFG_RCHF_SEL_SHIFT) 43 | #define PMU_SRC_CFG_RCHF_SEL_VALUE_24MHZ 1U 44 | #define PMU_SRC_CFG_RCHF_SEL_BITS_24MHZ (PMU_SRC_CFG_RCHF_SEL_VALUE_24MHZ << PMU_SRC_CFG_RCHF_SEL_SHIFT) 45 | 46 | #define PMU_TRIM_POW0_ADDR (PMU_BASE_ADDR + 0x0020U) 47 | #define PMU_TRIM_POW0 (*(volatile uint32_t *)PMU_TRIM_POW0_ADDR) 48 | #define PMU_TRIM_POW1_ADDR (PMU_BASE_ADDR + 0x0024U) 49 | #define PMU_TRIM_POW1 (*(volatile uint32_t *)PMU_TRIM_POW1_ADDR) 50 | #define PMU_TRIM_POW2_ADDR (PMU_BASE_ADDR + 0x0028U) 51 | #define PMU_TRIM_POW2 (*(volatile uint32_t *)PMU_TRIM_POW2_ADDR) 52 | #define PMU_TRIM_POW3_ADDR (PMU_BASE_ADDR + 0x002CU) 53 | #define PMU_TRIM_POW3 (*(volatile uint32_t *)PMU_TRIM_POW3_ADDR) 54 | #define PMU_TRIM_RCHF_ADDR (PMU_BASE_ADDR + 0x0030U) 55 | #define PMU_TRIM_RCHF (*(volatile uint32_t *)PMU_TRIM_RCHF_ADDR) 56 | #define PMU_TRIM_RCLF_ADDR (PMU_BASE_ADDR + 0x0034U) 57 | #define PMU_TRIM_RCLF (*(volatile uint32_t *)PMU_TRIM_RCLF_ADDR) 58 | #define PMU_TRIM_OPA_ADDR (PMU_BASE_ADDR + 0x0038U) 59 | #define PMU_TRIM_OPA (*(volatile uint32_t *)PMU_TRIM_OPA_ADDR) 60 | #define PMU_TRIM_PLL_ADDR (PMU_BASE_ADDR + 0x003CU) 61 | #define PMU_TRIM_PLL (*(volatile uint32_t *)PMU_TRIM_PLL_ADDR) 62 | 63 | 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /compile-with-docker.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | docker build -t uvk5 . 3 | docker run -v %CD%\compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/" -------------------------------------------------------------------------------- /compile-with-docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | docker build -t uvk5 . 3 | docker run -v $(PWD)/compiled-firmware:/app/compiled-firmware uvk5 /bin/bash -c "cd /app && make && cp firmware* compiled-firmware/" -------------------------------------------------------------------------------- /dcs.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "dcs.h" 18 | 19 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 20 | 21 | const uint16_t CTCSS_Options[50] = { 22 | 0x029E, 0x02B5, 0x02CF, 0x02E8, 23 | 0x0302, 0x031D, 0x0339, 0x0356, 24 | 0x0375, 0x0393, 0x03B4, 0x03CE, 25 | 0x03E8, 0x040B, 0x0430, 0x0455, 26 | 0x047C, 0x04A4, 0x04CE, 0x04F9, 27 | 0x0526, 0x0555, 0x0585, 0x05B6, 28 | 0x05EA, 0x061F, 0x063E, 0x0656, 29 | 0x0677, 0x068F, 0x06B1, 0x06CA, 30 | 0x06ED, 0x0707, 0x072B, 0x0746, 31 | 0x076B, 0x0788, 0x07AE, 0x07CB, 32 | 0x07F3, 0x0811, 0x083B, 0x0885, 33 | 0x08D1, 0x08F3, 0x0920, 0x0972, 34 | 0x09C7, 0x09ED, 35 | }; 36 | 37 | const uint16_t DCS_Options[104] = { 38 | 0x0013, 0x0015, 0x0016, 0x0019, 39 | 0x001A, 0x001E, 0x0023, 0x0027, 40 | 0x0029, 0x002B, 0x002C, 0x0035, 41 | 0x0039, 0x003A, 0x003B, 0x003C, 42 | 0x004C, 0x004D, 0x004E, 0x0052, 43 | 0x0055, 0x0059, 0x005A, 0x005C, 44 | 0x0063, 0x0065, 0x006A, 0x006D, 45 | 0x006E, 0x0072, 0x0075, 0x007A, 46 | 0x007C, 0x0085, 0x008A, 0x0093, 47 | 0x0095, 0x0096, 0x00A3, 0x00A4, 48 | 0x00A5, 0x00A6, 0x00A9, 0x00AA, 49 | 0x00AD, 0x00B1, 0x00B3, 0x00B5, 50 | 0x00B6, 0x00B9, 0x00BC, 0x00C6, 51 | 0x00C9, 0x00CD, 0x00D5, 0x00D9, 52 | 0x00DA, 0x00E3, 0x00E6, 0x00E9, 53 | 0x00EE, 0x00F4, 0x00F5, 0x00F9, 54 | 0x0109, 0x010A, 0x010B, 0x0113, 55 | 0x0119, 0x011A, 0x0125, 0x0126, 56 | 0x012A, 0x012C, 0x012D, 0x0132, 57 | 0x0134, 0x0135, 0x0136, 0x0143, 58 | 0x0146, 0x014E, 0x0153, 0x0156, 59 | 0x015A, 0x0166, 0x0175, 0x0186, 60 | 0x018A, 0x0194, 0x0197, 0x0199, 61 | 0x019A, 0x01AC, 0x01B2, 0x01B4, 62 | 0x01C3, 0x01CA, 0x01D3, 0x01D9, 63 | 0x01DA, 0x01DC, 0x01E3, 0x01EC, 64 | }; 65 | 66 | static uint32_t DCS_CalculateGolay(uint32_t CodeWord) 67 | { 68 | uint32_t Word; 69 | uint8_t i; 70 | 71 | Word = CodeWord; 72 | for (i = 0; i < 12; i++) { 73 | Word <<= 1; 74 | if (Word & 0x1000) { 75 | Word ^= 0x08EA; 76 | } 77 | } 78 | return CodeWord | ((Word & 0x0FFE) << 11); 79 | } 80 | 81 | uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option) 82 | { 83 | uint32_t Code; 84 | 85 | Code = DCS_CalculateGolay(DCS_Options[Option] + 0x800U); 86 | if (CodeType == CODE_TYPE_REVERSE_DIGITAL) { 87 | Code ^= 0x7FFFFF; 88 | } 89 | 90 | return Code; 91 | } 92 | 93 | uint8_t DCS_GetCdcssCode(uint32_t Code) 94 | { 95 | uint8_t i; 96 | 97 | for (i = 0; i < 23; i++) { 98 | uint32_t Shift; 99 | 100 | if (((Code >> 9) & 0x7U) == 4) { 101 | uint8_t j; 102 | 103 | for (j = 0; j < ARRAY_SIZE(DCS_Options); j++) { 104 | if (DCS_Options[j] == (Code & 0x1FF)) { 105 | if (DCS_GetGolayCodeWord(2, j) == Code) { 106 | return j; 107 | } 108 | } 109 | } 110 | } 111 | Shift = Code >> 1; 112 | if (Code & 1U) { 113 | Shift |= 0x400000U; 114 | } 115 | Code = Shift; 116 | } 117 | 118 | return 0xFF; 119 | } 120 | 121 | uint8_t DCS_GetCtcssCode(uint16_t Code) 122 | { 123 | uint8_t i; 124 | int Smallest; 125 | uint8_t Result = 0xFF; 126 | 127 | Smallest = ARRAY_SIZE(CTCSS_Options); 128 | for (i = 0; i < ARRAY_SIZE(CTCSS_Options); i++) { 129 | int Delta; 130 | 131 | Delta = Code - CTCSS_Options[i]; 132 | if (Delta < 0) { 133 | Delta = -(Code - CTCSS_Options[i]); 134 | } 135 | if (Delta < Smallest) { 136 | Smallest = Delta; 137 | Result = i; 138 | } 139 | } 140 | 141 | return Result; 142 | } 143 | 144 | -------------------------------------------------------------------------------- /dcs.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DCS_H 18 | #define DCS_H 19 | 20 | #include 21 | 22 | enum DCS_CodeType_t { 23 | CODE_TYPE_OFF = 0x00U, 24 | CODE_TYPE_CONTINUOUS_TONE = 0x01U, 25 | CODE_TYPE_DIGITAL = 0x02U, 26 | CODE_TYPE_REVERSE_DIGITAL = 0x03U, 27 | }; 28 | 29 | typedef enum DCS_CodeType_t DCS_CodeType_t; 30 | 31 | enum { 32 | CDCSS_POSITIVE_CODE = 1U, 33 | CDCSS_NEGATIVE_CODE = 2U, 34 | }; 35 | 36 | extern const uint16_t CTCSS_Options[50]; 37 | extern const uint16_t DCS_Options[104]; 38 | 39 | uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option); 40 | uint8_t DCS_GetCdcssCode(uint32_t Code); 41 | uint8_t DCS_GetCtcssCode(uint16_t Code); 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /dp32g030.cfg: -------------------------------------------------------------------------------- 1 | transport select swd 2 | adapter speed 32000 3 | reset_config srst_only srst_nogate connect_assert_srst 4 | gdb_breakpoint_override hard 5 | 6 | set _CHIP_NAME DP32G0xx 7 | # Create a new dap, with name chip and role CPU, -enable let's OpenOCD to know to add it to the scan 8 | swd newdap $_CHIP_NAME cpu -enable 9 | 10 | # Create the DAP instance, this must be explicitly created according to the OpenOCD docs 11 | dap create $_CHIP_NAME.dap -chain-position $_CHIP_NAME.cpu 12 | 13 | # Set up the GDB target for the CPU, cortex_m is the CPU type, 14 | target create $_CHIP_NAME.cpu cortex_m -dap $_CHIP_NAME.dap 15 | 16 | set _SECTOR_SIZE 512 17 | proc uv_clear_flash_sector {sector_number} { 18 | echo [format "Erasing sector 0x%02x = offset 0x%04x" [expr {$sector_number}] [expr {$sector_number*256}] ] 19 | write_memory 0x4006F000 32 {0x09} ;#set erasing mode 20 | write_memory 0x4006F004 32 [expr {$sector_number << 6}] 21 | write_memory 0x4006F01c 32 {0xAA} ;#unlock flash 22 | write_memory 0x4006F010 32 {0x01} ;#set OPSTART=1 23 | read_memory 0x4006F014 32 1 ;#check status for 0x02 24 | uv_wait_busy 25 | write_memory 0x4006F018 32 {0x55} ;#lock flash 26 | } 27 | 28 | proc uv_clear_whole_flash {} { 29 | for {set i 0} {$i < 0x100} {incr i} { 30 | uv_clear_flash_sector $i 31 | } 32 | } 33 | 34 | proc uv_clear_sectors {sectors_count} { 35 | for {set i 0} {$i < $sectors_count} {incr i} { 36 | uv_clear_flash_sector $i 37 | } 38 | } 39 | 40 | proc uv_flash_unlock {} { 41 | write_memory 0x4006F01c 32 {0xAA} ;#unlock flash 42 | uv_wait_busy 43 | } 44 | 45 | proc uv_flash_lock {} { 46 | write_memory 0x4006F018 32 {0x55} ;#lock flash 47 | uv_wait_busy 48 | } 49 | 50 | proc uv_flash_write {address value} { 51 | write_memory 0x4006F000 32 {0x05} ;#set writing mode 52 | write_memory 0x4006F004 32 [expr {($address>>2)+0xC000}] ;#set address in flash 53 | write_memory 0x4006F008 32 $value ;#set data 54 | write_memory 0x4006F010 32 {0x01} ;#set OPSTART=1 55 | while {1} { 56 | set status [read_memory 0x4006F014 32 1] 57 | if {($status & 0x4) != 0} { 58 | break 59 | } 60 | } 61 | uv_wait_busy 62 | } 63 | 64 | proc uv_wait_busy {} { 65 | while {1} { 66 | set status [read_memory 0x4006F014 32 1] 67 | if {($status & 0x2) == 0} { 68 | break 69 | } 70 | } 71 | } 72 | 73 | proc write_image {filename address} { 74 | global _SECTOR_SIZE 75 | 76 | set fs [file size $filename] 77 | set fd [open $filename "rb"] 78 | 79 | echo "Checking mask" 80 | set status [read_memory 0x4006F020 32 1] 81 | if {$status != 6} { 82 | echo "Changing mask" 83 | write_memory 0x4006F020 32 0 84 | uv_wait_busy 85 | write_memory 0x4006F020 32 6 86 | uv_wait_busy 87 | set status [read_memory 0x4006F020 32 1] 88 | if {$status != 6} { 89 | echo [format "Cannot set flash mask %d!" $status] 90 | close $fd 91 | return 92 | } 93 | } 94 | uv_clear_sectors [expr {(($fs+$_SECTOR_SIZE-1)&(0x10000000-$_SECTOR_SIZE))/($_SECTOR_SIZE/2)}] 95 | uv_flash_unlock 96 | 97 | set addr $address 98 | while {![eof $fd]} { 99 | set data [read $fd 4] 100 | if {[string length $data] == 4} { 101 | set b0 [scan [string index $data 0] %c] 102 | set b1 [scan [string index $data 1] %c] 103 | set b2 [scan [string index $data 2] %c] 104 | set b3 [scan [string index $data 3] %c] 105 | set i_data [expr {$b0 | $b1 << 8 | $b2 << 16 | $b3 << 24}] 106 | 107 | echo [format "Writing 0x%04x to address 0x%04x (%02d %%)" $i_data $addr [expr {(100*($addr+4)/$fs)}]] 108 | uv_flash_write $addr $i_data 109 | incr addr 4 110 | } 111 | } 112 | uv_flash_lock 113 | 114 | close $fd 115 | } 116 | 117 | # dap init 118 | init 119 | halt 120 | # reset halt 121 | -------------------------------------------------------------------------------- /driver/adc.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_ADC_H 18 | #define DRIVER_ADC_H 19 | 20 | #include 21 | #include 22 | 23 | enum ADC_CH_MASK { 24 | ADC_CH0 = 0x0001U, 25 | ADC_CH1 = 0x0002U, 26 | ADC_CH2 = 0x0004U, 27 | ADC_CH3 = 0x0008U, 28 | ADC_CH4 = 0x0010U, 29 | ADC_CH5 = 0x0020U, 30 | ADC_CH6 = 0x0040U, 31 | ADC_CH7 = 0x0080U, 32 | ADC_CH8 = 0x0100U, 33 | ADC_CH9 = 0x0200U, 34 | ADC_CH10 = 0x0400U, 35 | ADC_CH11 = 0x0800U, 36 | ADC_CH12 = 0x1000U, 37 | ADC_CH13 = 0x2000U, 38 | ADC_CH14 = 0x4000U, 39 | ADC_CH15 = 0x8000U, 40 | }; 41 | 42 | typedef enum ADC_CH_MASK ADC_CH_MASK; 43 | 44 | typedef struct { 45 | uint8_t CLK_SEL; 46 | ADC_CH_MASK CH_SEL; 47 | uint8_t AVG; 48 | uint8_t CONT; 49 | uint8_t MEM_MODE; 50 | uint8_t SMPL_CLK; 51 | uint8_t SMPL_SETUP; 52 | uint8_t SMPL_WIN; 53 | uint8_t ADC_TRIG; 54 | uint16_t EXTTRIG_SEL; 55 | bool CALIB_OFFSET_VALID; 56 | bool CALIB_KD_VALID; 57 | uint8_t DMA_EN; 58 | uint16_t IE_CHx_EOC; 59 | uint8_t IE_FIFO_HFULL; 60 | uint8_t IE_FIFO_FULL; 61 | } ADC_Config_t; 62 | 63 | uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask); 64 | void ADC_Disable(void); 65 | void ADC_Enable(void); 66 | void ADC_SoftReset(void); 67 | uint32_t ADC_GetClockConfig(void); 68 | void ADC_Configure(ADC_Config_t *pAdc); 69 | void ADC_Start(void); 70 | bool ADC_CheckEndOfConversion(ADC_CH_MASK Mask); 71 | uint16_t ADC_GetValue(ADC_CH_MASK Mask); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /driver/aes.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include "bsp/dp32g030/aes.h" 20 | #include "driver/aes.h" 21 | 22 | static void AES_Setup_ENC_CBC(bool IsDecrypt, const void *pKey, const void *pIv) 23 | { 24 | const uint32_t *pK = (const uint32_t *)pKey; 25 | const uint32_t *pI = (const uint32_t *)pIv; 26 | 27 | AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE; 28 | AES_CR = AES_CR_CHMOD_BITS_CBC; 29 | AES_KEYR3 = pK[0]; 30 | AES_KEYR2 = pK[1]; 31 | AES_KEYR1 = pK[2]; 32 | AES_KEYR0 = pK[3]; 33 | AES_IVR3 = pI[0]; 34 | AES_IVR2 = pI[1]; 35 | AES_IVR1 = pI[2]; 36 | AES_IVR0 = pI[3]; 37 | AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_ENABLE; 38 | } 39 | 40 | static void AES_Transform(const void *pIn, void *pOut) 41 | { 42 | const uint32_t *pI = (const uint32_t *)pIn; 43 | uint32_t *pO = (uint32_t *)pOut; 44 | 45 | AES_DINR = pI[0]; 46 | AES_DINR = pI[1]; 47 | AES_DINR = pI[2]; 48 | AES_DINR = pI[3]; 49 | 50 | while ((AES_SR & AES_SR_CCF_MASK) == AES_SR_CCF_BITS_NOT_COMPLETE) { 51 | } 52 | 53 | pO[0] = AES_DOUTR; 54 | pO[1] = AES_DOUTR; 55 | pO[2] = AES_DOUTR; 56 | pO[3] = AES_DOUTR; 57 | 58 | AES_CR |= AES_CR_CCFC_BITS_SET; 59 | } 60 | 61 | void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks) 62 | { 63 | const uint8_t *pI = (const uint8_t *)pIn; 64 | uint8_t *pO = (uint8_t *)pOut; 65 | uint8_t i; 66 | 67 | AES_Setup_ENC_CBC(0, pKey, pIv); 68 | for (i = 0; i < NumBlocks; i++) { 69 | AES_Transform(pI + (i * 16), pO + (i * 16)); 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /driver/aes.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_AES_H 18 | #define DRIVER_AES_H 19 | 20 | #include 21 | 22 | void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /driver/backlight.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsp/dp32g030/gpio.h" 18 | #include "driver/backlight.h" 19 | #include "driver/gpio.h" 20 | #include "settings.h" 21 | 22 | uint8_t gBacklightCountdown; 23 | 24 | void BACKLIGHT_TurnOn(void) 25 | { 26 | if (gEeprom.BACKLIGHT) { 27 | GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); 28 | gBacklightCountdown = 1 + (gEeprom.BACKLIGHT * 2); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /driver/backlight.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_BACKLIGHT_H 18 | #define DRIVER_BACKLIGHT_H 19 | 20 | #include 21 | 22 | extern uint8_t gBacklightCountdown; 23 | 24 | void BACKLIGHT_TurnOn(void); 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /driver/bk1080-regs.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BK1080_REGS_H 18 | #define BK1080_REGS_H 19 | 20 | enum BK1080_Register_t { 21 | BK1080_REG_00 = 0x00U, 22 | BK1080_REG_02_POWER_CONFIGURATION = 0x02U, 23 | BK1080_REG_03_CHANNEL = 0x03U, 24 | BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U, 25 | BK1080_REG_07 = 0x07U, 26 | BK1080_REG_10 = 0x0AU, 27 | BK1080_REG_25_INTERNAL = 0x19U, 28 | }; 29 | 30 | typedef enum BK1080_Register_t BK1080_Register_t; 31 | 32 | // REG 07 33 | 34 | #define BK1080_REG_07_SHIFT_FREQD 4 35 | #define BK1080_REG_07_SHIFT_SNR 0 36 | 37 | #define BK1080_REG_07_MASK_FREQD (0xFFFU << BK1080_REG_07_SHIFT_FREQD) 38 | #define BK1080_REG_07_MASK_SNR (0x00FU << BK1080_REG_07_SHIFT_SNR) 39 | 40 | #define BK1080_REG_07_GET_FREQD(x) (((x) & BK1080_REG_07_MASK_FREQD) >> BK1080_REG_07_SHIFT_FREQD) 41 | #define BK1080_REG_07_GET_SNR(x) (((x) & BK1080_REG_07_MASK_SNR) >> BK1080_REG_07_SHIFT_SNR) 42 | 43 | // REG 10 44 | 45 | #define BK1080_REG_10_SHIFT_AFCRL 12 46 | #define BK1080_REG_10_SHIFT_RSSI 0 47 | 48 | #define BK1080_REG_10_MASK_AFCRL (0x01U << BK1080_REG_10_SHIFT_AFCRL) 49 | #define BK1080_REG_10_MASK_RSSI (0xFFU << BK1080_REG_10_SHIFT_RSSI) 50 | 51 | #define BK1080_REG_10_AFCRL_NOT_RAILED (0U << BK1080_REG_10_SHIFT_AFCRL) 52 | #define BK1080_REG_10_AFCRL_RAILED (1U << BK1080_REG_10_SHIFT_AFCRL) 53 | 54 | #define BK1080_REG_10_GET_RSSI(x) (((x) & BK1080_REG_10_MASK_RSSI) >> BK1080_REG_10_SHIFT_RSSI) 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /driver/bk1080.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsp/dp32g030/gpio.h" 18 | #include "driver/bk1080.h" 19 | #include "driver/gpio.h" 20 | #include "driver/i2c.h" 21 | #include "driver/system.h" 22 | #include "misc.h" 23 | 24 | static const uint16_t BK1080_RegisterTable[] = { 25 | 0x0008, 0x1080, 0x0201, 0x0000, 26 | 0x40C0, 0x0A1F, 0x002E, 0x02FF, 27 | 0x5B11, 0x0000, 0x411E, 0x0000, 28 | 0xCE00, 0x0000, 0x0000, 0x1000, 29 | 0x3197, 0x0000, 0x13FF, 0x9852, 30 | 0x0000, 0x0000, 0x0008, 0x0000, 31 | 0x51E1, 0xA8BC, 0x2645, 0x00E4, 32 | 0x1CD8, 0x3A50, 0xEAE0, 0x3000, 33 | 0x0200, 0x0000, 34 | }; 35 | 36 | static bool gIsInitBK1080; 37 | 38 | uint16_t BK1080_BaseFrequency; 39 | uint16_t BK1080_FrequencyDeviation; 40 | 41 | void BK1080_Init(uint16_t Frequency, bool bEnable) 42 | { 43 | uint8_t i; 44 | 45 | if (bEnable) { 46 | GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080); 47 | 48 | if (!gIsInitBK1080) { 49 | for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++) { 50 | BK1080_WriteRegister(i, BK1080_RegisterTable[i]); 51 | } 52 | SYSTEM_DelayMs(250); 53 | BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA83C); 54 | BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA8BC); 55 | SYSTEM_DelayMs(60); 56 | gIsInitBK1080 = true; 57 | } else { 58 | BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201); 59 | } 60 | BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A5F); 61 | BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760); 62 | SYSTEM_DelayMs(10); 63 | BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000); 64 | } else { 65 | BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0241); 66 | GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080); 67 | } 68 | } 69 | 70 | uint16_t BK1080_ReadRegister(BK1080_Register_t Register) 71 | { 72 | uint8_t Value[2]; 73 | 74 | I2C_Start(); 75 | I2C_Write(0x80); 76 | I2C_Write((Register << 1) | I2C_READ); 77 | I2C_ReadBuffer(Value, sizeof(Value)); 78 | I2C_Stop(); 79 | return (Value[0] << 8) | Value[1]; 80 | } 81 | 82 | void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value) 83 | { 84 | I2C_Start(); 85 | I2C_Write(0x80); 86 | I2C_Write((Register << 1) | I2C_WRITE); 87 | Value = ((Value >> 8) & 0xFF) | ((Value & 0xFF) << 8); 88 | I2C_WriteBuffer(&Value, sizeof(Value)); 89 | I2C_Stop(); 90 | } 91 | 92 | void BK1080_Mute(bool Mute) 93 | { 94 | if (Mute) { 95 | BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x4201); 96 | } else { 97 | BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201); 98 | } 99 | } 100 | 101 | void BK1080_SetFrequency(uint16_t Frequency) 102 | { 103 | BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760); 104 | SYSTEM_DelayMs(10); 105 | BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000); 106 | } 107 | 108 | void BK1080_GetFrequencyDeviation(uint16_t Frequency) 109 | { 110 | BK1080_BaseFrequency = Frequency; 111 | BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /driver/bk1080.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_BK1080_H 18 | #define DRIVER_BK1080_H 19 | 20 | #include 21 | #include 22 | #include "driver/bk1080-regs.h" 23 | 24 | extern uint16_t BK1080_BaseFrequency; 25 | extern uint16_t BK1080_FrequencyDeviation; 26 | 27 | void BK1080_Init(uint16_t Frequency, bool bEnable); 28 | uint16_t BK1080_ReadRegister(BK1080_Register_t Register); 29 | void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value); 30 | void BK1080_Mute(bool Mute); 31 | void BK1080_SetFrequency(uint16_t Frequency); 32 | void BK1080_GetFrequencyDeviation(uint16_t Frequency); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /driver/bk4819.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_BK4819_h 18 | #define DRIVER_BK4819_h 19 | 20 | #include 21 | #include 22 | #include "driver/bk4819-regs.h" 23 | 24 | enum BK4819_AF_Type_t { 25 | BK4819_AF_MUTE = 0U, 26 | BK4819_AF_OPEN = 1U, 27 | BK4819_AF_ALAM = 2U, 28 | BK4819_AF_BEEP = 3U, 29 | BK4819_AF_CTCO = 6U, 30 | BK4819_AF_AM = 7U, 31 | BK4819_AF_FSKO = 8U, 32 | }; 33 | 34 | typedef enum BK4819_AF_Type_t BK4819_AF_Type_t; 35 | 36 | enum BK4819_FilterBandwidth_t { 37 | BK4819_FILTER_BW_WIDE = 0U, 38 | BK4819_FILTER_BW_NARROW = 1U, 39 | }; 40 | 41 | typedef enum BK4819_FilterBandwidth_t BK4819_FilterBandwidth_t; 42 | 43 | enum BK4819_CssScanResult_t { 44 | BK4819_CSS_RESULT_NOT_FOUND = 0U, 45 | BK4819_CSS_RESULT_CTCSS = 1U, 46 | BK4819_CSS_RESULT_CDCSS = 2U, 47 | }; 48 | 49 | typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t; 50 | 51 | extern bool gRxIdleMode; 52 | 53 | void BK4819_Init(void); 54 | uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register); 55 | void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data); 56 | void BK4819_WriteU8(uint8_t Data); 57 | void BK4819_WriteU16(uint16_t Data); 58 | 59 | void BK4819_SetAGC(uint8_t Value); 60 | 61 | void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet); 62 | 63 | void BK4819_SetCDCSSCodeWord(uint32_t CodeWord); 64 | void BK4819_SetCTCSSFrequency(uint32_t BaudRate); 65 | void BK4819_Set55HzTailDetection(void); 66 | void BK4819_EnableVox(uint16_t Vox1Threshold, uint16_t Vox0Threshold); 67 | void BK4819_SetFilterBandwidth(BK4819_FilterBandwidth_t Bandwidth); 68 | void BK4819_SetupPowerAmplifier(uint16_t Bias, uint32_t Frequency); 69 | void BK4819_SetFrequency(uint32_t Frequency); 70 | void BK4819_SetupSquelch( 71 | uint8_t SquelchOpenRSSIThresh, uint8_t SquelchCloseRSSIThresh, 72 | uint8_t SquelchOpenNoiseThresh, uint8_t SquelchCloseNoiseThresh, 73 | uint8_t SquelchCloseGlitchThresh, uint8_t SquelchOpenGlitchThresh); 74 | 75 | void BK4819_SetAF(BK4819_AF_Type_t AF); 76 | void BK4819_RX_TurnOn(void); 77 | void BK4819_SelectFilter(uint32_t Frequency); 78 | void BK4819_DisableScramble(void); 79 | void BK4819_EnableScramble(uint8_t Type); 80 | void BK4819_DisableVox(void); 81 | void BK4819_DisableDTMF(void); 82 | void BK4819_EnableDTMF(void); 83 | void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch); 84 | void BK4819_EnterTxMute(void); 85 | void BK4819_ExitTxMute(void); 86 | void BK4819_Sleep(void); 87 | void BK4819_TurnsOffTones_TurnsOnRX(void); 88 | void BK4819_SetupAircopy(void); 89 | void BK4819_ResetFSK(void); 90 | void BK4819_Idle(void); 91 | void BK4819_ExitBypass(void); 92 | void BK4819_PrepareTransmit(void); 93 | void BK4819_TxOn_Beep(void); 94 | void BK4819_ExitSubAu(void); 95 | 96 | void BK4819_EnableRX(void); 97 | 98 | void BK4819_EnterDTMF_TX(bool bLocalLoopback); 99 | void BK4819_ExitDTMF_TX(bool bKeep); 100 | void BK4819_EnableTXLink(void); 101 | 102 | void BK4819_PlayDTMF(char Code); 103 | void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime); 104 | 105 | void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency); 106 | 107 | void BK4819_GenTail(uint8_t Tail); 108 | void BK4819_EnableCDCSS(void); 109 | void BK4819_EnableCTCSS(void); 110 | 111 | uint16_t BK4819_GetRSSI(void); 112 | 113 | bool BK4819_GetFrequencyScanResult(uint32_t *pFrequency); 114 | BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t *pCtcssFreq); 115 | void BK4819_DisableFrequencyScan(void); 116 | void BK4819_EnableFrequencyScan(void); 117 | void BK4819_SetScanFrequency(uint32_t Frequency); 118 | 119 | void BK4819_Disable(void); 120 | 121 | void BK4819_StopScan(void); 122 | 123 | uint8_t BK4819_GetDTMF_5TONE_Code(void); 124 | 125 | uint8_t BK4819_GetCDCSSCodeType(void); 126 | uint8_t BK4819_GetCTCType(void); 127 | 128 | void BK4819_SendFSKData(uint16_t *pData); 129 | void BK4819_PrepareFSKReceive(void); 130 | 131 | void BK4819_PlayRoger(void); 132 | void BK4819_PlayRogerMDC(void); 133 | 134 | void BK4819_Enable_AfDac_DiscMode_TxDsp(void); 135 | 136 | void BK4819_GetVoxAmp(uint16_t *pResult); 137 | void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency); 138 | void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code); 139 | 140 | #endif 141 | 142 | -------------------------------------------------------------------------------- /driver/crc.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsp/dp32g030/crc.h" 18 | #include "driver/crc.h" 19 | 20 | void CRC_Init(void) 21 | { 22 | CRC_CR = 0 23 | | CRC_CR_CRC_EN_BITS_DISABLE 24 | | CRC_CR_INPUT_REV_BITS_NORMAL 25 | | CRC_CR_INPUT_INV_BITS_NORMAL 26 | | CRC_CR_OUTPUT_REV_BITS_NORMAL 27 | | CRC_CR_OUTPUT_INV_BITS_NORMAL 28 | | CRC_CR_DATA_WIDTH_BITS_8 29 | | CRC_CR_CRC_SEL_BITS_CRC_16_CCITT 30 | ; 31 | CRC_IV = 0; 32 | } 33 | 34 | uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size) 35 | { 36 | const uint8_t *pData = (const uint8_t *)pBuffer; 37 | uint16_t i, Crc; 38 | 39 | CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE; 40 | 41 | for (i = 0; i < Size; i++) { 42 | CRC_DATAIN = pData[i]; 43 | } 44 | Crc = (uint16_t)CRC_DATAOUT; 45 | 46 | CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE; 47 | 48 | return Crc; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /driver/crc.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_CRC_H 18 | #define DRIVER_CRC_H 19 | 20 | #include 21 | 22 | void CRC_Init(void); 23 | uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /driver/eeprom.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "driver/eeprom.h" 18 | #include "driver/i2c.h" 19 | #include "driver/system.h" 20 | 21 | void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size) 22 | { 23 | I2C_Start(); 24 | 25 | I2C_Write(0xA0); 26 | 27 | I2C_Write((Address >> 8) & 0xFF); 28 | I2C_Write((Address >> 0) & 0xFF); 29 | 30 | I2C_Start(); 31 | 32 | I2C_Write(0xA1); 33 | 34 | I2C_ReadBuffer(pBuffer, Size); 35 | 36 | I2C_Stop(); 37 | } 38 | 39 | void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer) 40 | 41 | { 42 | I2C_Start(); 43 | 44 | I2C_Write(0xA0); 45 | 46 | I2C_Write((Address >> 8) & 0xFF); 47 | I2C_Write((Address >> 0) & 0xFF); 48 | 49 | I2C_WriteBuffer(pBuffer, 8); 50 | 51 | I2C_Stop(); 52 | 53 | SYSTEM_DelayMs(10); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /driver/eeprom.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_EEPROM_H 18 | #define DRIVER_EEPROM_H 19 | 20 | #include 21 | 22 | void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size); 23 | void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /driver/flash.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "driver/flash.h" 18 | #include "sram-overlay.h" 19 | 20 | void FLASH_Init(FLASH_READ_MODE ReadMode) 21 | { 22 | overlay_FLASH_Init(ReadMode); 23 | } 24 | 25 | void FLASH_ConfigureTrimValues(void) 26 | { 27 | overlay_FLASH_ConfigureTrimValues(); 28 | } 29 | 30 | uint32_t FLASH_ReadNvrWord(uint32_t Address) 31 | { 32 | return overlay_FLASH_ReadNvrWord(Address); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /driver/flash.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_FLASH_H 18 | #define DRIVER_FLASH_H 19 | 20 | #include "bsp/dp32g030/flash.h" 21 | 22 | enum FLASH_READ_MODE { 23 | FLASH_READ_MODE_1_CYCLE = FLASH_CFG_READ_MD_VALUE_1_CYCLE, 24 | FLASH_READ_MODE_2_CYCLE = FLASH_CFG_READ_MD_VALUE_2_CYCLE, 25 | }; 26 | 27 | typedef enum FLASH_READ_MODE FLASH_READ_MODE; 28 | 29 | enum FLASH_MASK_SELECTION { 30 | FLASH_MASK_SELECTION_NONE = FLASH_MASK_SEL_VALUE_NONE, 31 | FLASH_MASK_SELECTION_2KB = FLASH_MASK_SEL_VALUE_2KB, 32 | FLASH_MASK_SELECTION_4KB = FLASH_MASK_SEL_VALUE_4KB, 33 | FLASH_MASK_SELECTION_8KB = FLASH_MASK_SEL_VALUE_8KB, 34 | }; 35 | 36 | typedef enum FLASH_MASK_SELECTION FLASH_MASK_SELECTION; 37 | 38 | enum FLASH_MODE { 39 | FLASH_MODE_READ_AHB = FLASH_CFG_MODE_VALUE_READ_AHB, 40 | FLASH_MODE_PROGRAM = FLASH_CFG_MODE_VALUE_PROGRAM, 41 | FLASH_MODE_ERASE = FLASH_CFG_MODE_VALUE_ERASE, 42 | FLASH_MODE_READ_APB = FLASH_CFG_MODE_VALUE_READ_APB, 43 | }; 44 | 45 | typedef enum FLASH_MODE FLASH_MODE; 46 | 47 | enum FLASH_AREA { 48 | FLASH_AREA_MAIN = FLASH_CFG_NVR_SEL_VALUE_MAIN, 49 | FLASH_AREA_NVR = FLASH_CFG_NVR_SEL_VALUE_NVR, 50 | }; 51 | 52 | typedef enum FLASH_AREA FLASH_AREA; 53 | 54 | void FLASH_Init(FLASH_READ_MODE ReadMode); 55 | void FLASH_ConfigureTrimValues(void); 56 | uint32_t FLASH_ReadNvrWord(uint32_t Address); 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /driver/gpio.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "driver/gpio.h" 18 | 19 | void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit) 20 | { 21 | *pReg &= ~(1U << Bit); 22 | } 23 | 24 | uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit) 25 | { 26 | return (*pReg >> Bit) & 1U; 27 | } 28 | 29 | void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit) 30 | { 31 | *pReg ^= 1U << Bit; 32 | } 33 | 34 | void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit) 35 | { 36 | *pReg |= 1U << Bit; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /driver/gpio.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_GPIO_H 18 | #define DRIVER_GPIO_H 19 | 20 | #include 21 | 22 | enum GPIOA_PINS { 23 | GPIOA_PIN_KEYBOARD_0 = 3, 24 | GPIOA_PIN_KEYBOARD_1 = 4, 25 | GPIOA_PIN_KEYBOARD_2 = 5, 26 | GPIOA_PIN_KEYBOARD_3 = 6, 27 | GPIOA_PIN_KEYBOARD_4 = 10, // Shared with I2C! 28 | GPIOA_PIN_KEYBOARD_5 = 11, // Shared with I2C! 29 | GPIOA_PIN_KEYBOARD_6 = 12, // Shared with voice chip! 30 | GPIOA_PIN_KEYBOARD_7 = 13, // Shared with voice chip! 31 | 32 | GPIOA_PIN_I2C_SCL = 10, // Shared with keyboard! 33 | GPIOA_PIN_I2C_SDA = 11, // Shared with keyboard! 34 | 35 | GPIOA_PIN_VOICE_0 = 12, // Shared with keyboard! 36 | GPIOA_PIN_VOICE_1 = 13, // Shared with keyboard! 37 | }; 38 | 39 | enum GPIOB_PINS { 40 | GPIOB_PIN_BACKLIGHT = 6, 41 | 42 | GPIOB_PIN_ST7565_A0 = 9, 43 | GPIOB_PIN_ST7565_RES = 11, // Shared with SWD! 44 | 45 | GPIOB_PIN_SWD_IO = 11, // Shared with ST7565! 46 | GPIOB_PIN_SWD_CLK = 14, 47 | 48 | GPIOB_PIN_BK1080 = 15, 49 | }; 50 | 51 | enum GPIOC_PINS { 52 | GPIOC_PIN_BK4819_SCN = 0, 53 | GPIOC_PIN_BK4819_SCL = 1, 54 | GPIOC_PIN_BK4819_SDA = 2, 55 | 56 | GPIOC_PIN_FLASHLIGHT = 3, 57 | 58 | GPIOC_PIN_AUDIO_PATH = 4, 59 | 60 | GPIOC_PIN_PTT = 5, 61 | }; 62 | 63 | void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit); 64 | uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit); 65 | void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit); 66 | void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /driver/i2c.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsp/dp32g030/gpio.h" 18 | #include "bsp/dp32g030/portcon.h" 19 | #include "driver/gpio.h" 20 | #include "driver/i2c.h" 21 | #include "driver/systick.h" 22 | 23 | void I2C_Start(void) 24 | { 25 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 26 | SYSTICK_DelayUs(1); 27 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 28 | SYSTICK_DelayUs(1); 29 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 30 | SYSTICK_DelayUs(1); 31 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 32 | SYSTICK_DelayUs(1); 33 | } 34 | 35 | void I2C_Stop(void) 36 | { 37 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 38 | SYSTICK_DelayUs(1); 39 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 40 | SYSTICK_DelayUs(1); 41 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 42 | SYSTICK_DelayUs(1); 43 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 44 | SYSTICK_DelayUs(1); 45 | } 46 | 47 | uint8_t I2C_Read(bool bFinal) 48 | { 49 | uint8_t i, Data; 50 | 51 | PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; 52 | PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; 53 | GPIOA->DIR &= ~GPIO_DIR_11_MASK; 54 | 55 | Data = 0; 56 | for (i = 0; i < 8; i++) { 57 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 58 | SYSTICK_DelayUs(1); 59 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 60 | SYSTICK_DelayUs(1); 61 | Data <<= 1; 62 | SYSTICK_DelayUs(1); 63 | if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA)) { 64 | Data |= 1U; 65 | } 66 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 67 | SYSTICK_DelayUs(1); 68 | } 69 | 70 | PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; 71 | PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; 72 | GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; 73 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 74 | SYSTICK_DelayUs(1); 75 | if (bFinal) { 76 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 77 | } else { 78 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 79 | } 80 | SYSTICK_DelayUs(1); 81 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 82 | SYSTICK_DelayUs(1); 83 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 84 | SYSTICK_DelayUs(1); 85 | 86 | return Data; 87 | } 88 | 89 | int I2C_Write(uint8_t Data) 90 | { 91 | uint8_t i; 92 | int ret = -1; 93 | 94 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 95 | SYSTICK_DelayUs(1); 96 | for (i = 0; i < 8; i++) { 97 | if ((Data & 0x80) == 0) { 98 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 99 | } else { 100 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 101 | } 102 | Data <<= 1; 103 | SYSTICK_DelayUs(1); 104 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 105 | SYSTICK_DelayUs(1); 106 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 107 | SYSTICK_DelayUs(1); 108 | } 109 | 110 | PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE; 111 | PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK; 112 | GPIOA->DIR &= ~GPIO_DIR_11_MASK; 113 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 114 | SYSTICK_DelayUs(1); 115 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 116 | SYSTICK_DelayUs(1); 117 | 118 | for (i = 0; i < 255; i++) { 119 | if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA) == 0) { 120 | ret = 0; 121 | break; 122 | } 123 | } 124 | 125 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL); 126 | SYSTICK_DelayUs(1); 127 | PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK; 128 | PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE; 129 | GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT; 130 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA); 131 | 132 | return ret; 133 | } 134 | 135 | int I2C_ReadBuffer(void *pBuffer, uint8_t Size) 136 | { 137 | uint8_t *pData = (uint8_t *)pBuffer; 138 | uint8_t i; 139 | 140 | if (Size == 1) { 141 | *pData = I2C_Read(true); 142 | return 1; 143 | } 144 | 145 | for (i = 0; i < Size - 1; i++) { 146 | SYSTICK_DelayUs(1); 147 | pData[i] = I2C_Read(false); 148 | } 149 | 150 | SYSTICK_DelayUs(1); 151 | pData[i++] = I2C_Read(true); 152 | 153 | return Size; 154 | } 155 | 156 | int I2C_WriteBuffer(const void *pBuffer, uint8_t Size) 157 | { 158 | const uint8_t *pData = (const uint8_t *)pBuffer; 159 | uint8_t i; 160 | 161 | for (i = 0; i < Size; i++) { 162 | if (I2C_Write(*pData++) < 0) { 163 | return -1; 164 | } 165 | } 166 | 167 | return 0; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /driver/i2c.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_I2C_H 18 | #define DRIVER_I2C_H 19 | 20 | #include 21 | #include 22 | 23 | enum { 24 | I2C_WRITE = 0U, 25 | I2C_READ = 1U, 26 | }; 27 | 28 | void I2C_Start(void); 29 | void I2C_Stop(void); 30 | 31 | uint8_t I2C_Read(bool bFinal); 32 | int I2C_Write(uint8_t Data); 33 | 34 | int I2C_ReadBuffer(void *pBuffer, uint8_t Size); 35 | int I2C_WriteBuffer(const void *pBuffer, uint8_t Size); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /driver/keyboard.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Manuel Jinger 2 | * Copyright 2023 Dual Tachyon 3 | * https://github.com/DualTachyon 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #include "bsp/dp32g030/gpio.h" 19 | #include "driver/gpio.h" 20 | #include "driver/keyboard.h" 21 | #include "driver/systick.h" 22 | 23 | KEY_Code_t gKeyReading0 = KEY_INVALID; 24 | KEY_Code_t gKeyReading1 = KEY_INVALID; 25 | uint16_t gDebounceCounter; 26 | bool gWasFKeyPressed; 27 | 28 | KEY_Code_t KEYBOARD_Poll(void) 29 | { 30 | KEY_Code_t Key = KEY_INVALID; 31 | 32 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 33 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5); 34 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); 35 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7); 36 | 37 | SYSTICK_DelayUs(1); 38 | 39 | // Keys connected to gnd 40 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { 41 | Key = KEY_SIDE1; 42 | goto Bye; 43 | } 44 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { 45 | Key = KEY_SIDE2; 46 | goto Bye; 47 | } 48 | // Original doesn't do PTT 49 | 50 | // First row 51 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 52 | SYSTICK_DelayUs(1); 53 | 54 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { 55 | Key = KEY_MENU; 56 | goto Bye; 57 | } 58 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { 59 | Key = KEY_1; 60 | goto Bye; 61 | } 62 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { 63 | Key = KEY_4; 64 | goto Bye; 65 | } 66 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { 67 | Key = KEY_7; 68 | goto Bye; 69 | } 70 | 71 | // Second row 72 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5); 73 | SYSTICK_DelayUs(1); 74 | 75 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 76 | SYSTICK_DelayUs(1); 77 | 78 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { 79 | Key = KEY_UP; 80 | goto Bye; 81 | } 82 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { 83 | Key = KEY_2; 84 | goto Bye; 85 | } 86 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { 87 | Key = KEY_5; 88 | goto Bye; 89 | } 90 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { 91 | Key = KEY_8; 92 | goto Bye; 93 | } 94 | 95 | // Third row 96 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 97 | SYSTICK_DelayUs(1); 98 | 99 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5); 100 | SYSTICK_DelayUs(1); 101 | 102 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 103 | SYSTICK_DelayUs(1); 104 | 105 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); 106 | SYSTICK_DelayUs(1); 107 | 108 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { 109 | Key = KEY_DOWN; 110 | goto Bye; 111 | } 112 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { 113 | Key = KEY_3; 114 | goto Bye; 115 | } 116 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { 117 | Key = KEY_6; 118 | goto Bye; 119 | } 120 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { 121 | Key = KEY_9; 122 | goto Bye; 123 | } 124 | 125 | // Fourth row 126 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7); 127 | SYSTICK_DelayUs(1); 128 | 129 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); 130 | SYSTICK_DelayUs(1); 131 | 132 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) { 133 | Key = KEY_EXIT; 134 | goto Bye; 135 | } 136 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) { 137 | Key = KEY_STAR; 138 | goto Bye; 139 | } 140 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) { 141 | Key = KEY_0; 142 | goto Bye; 143 | } 144 | if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) { 145 | Key = KEY_F; 146 | goto Bye; 147 | } 148 | 149 | Bye: 150 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4); 151 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5); 152 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6); 153 | GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7); 154 | 155 | return Key; 156 | } 157 | 158 | -------------------------------------------------------------------------------- /driver/keyboard.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Manuel Jinger 2 | * Copyright 2023 Dual Tachyon 3 | * https://github.com/DualTachyon 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #ifndef DRIVER_KEYBOARD_H 19 | #define DRIVER_KEYBOARD_H 20 | 21 | #include 22 | #include 23 | 24 | enum KEY_Code_t { 25 | KEY_0 = 0, 26 | KEY_1 = 1, 27 | KEY_2 = 2, 28 | KEY_3 = 3, 29 | KEY_4 = 4, 30 | KEY_5 = 5, 31 | KEY_6 = 6, 32 | KEY_7 = 7, 33 | KEY_8 = 8, 34 | KEY_9 = 9, 35 | KEY_MENU = 10, 36 | KEY_UP = 11, 37 | KEY_DOWN = 12, 38 | KEY_EXIT = 13, 39 | KEY_STAR = 14, 40 | KEY_F = 15, 41 | KEY_PTT = 21, 42 | KEY_SIDE2 = 22, 43 | KEY_SIDE1 = 23, 44 | KEY_INVALID = 255, 45 | }; 46 | 47 | typedef enum KEY_Code_t KEY_Code_t; 48 | 49 | extern KEY_Code_t gKeyReading0; 50 | extern KEY_Code_t gKeyReading1; 51 | extern uint16_t gDebounceCounter; 52 | extern bool gWasFKeyPressed; 53 | 54 | KEY_Code_t KEYBOARD_Poll(void); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /driver/spi.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ARMCM0.h" 18 | #include "bsp/dp32g030/spi.h" 19 | #include "bsp/dp32g030/syscon.h" 20 | #include "bsp/dp32g030/irq.h" 21 | #include "driver/spi.h" 22 | 23 | void SPI0_Init(void) 24 | { 25 | SPI_Config_t Config; 26 | 27 | SPI_Disable(&SPI0->CR); 28 | 29 | Config.TXFIFO_EMPTY = 0; 30 | Config.RXFIFO_HFULL = 0; 31 | Config.RXFIFO_FULL = 0; 32 | Config.RXFIFO_OVF = 0; 33 | Config.MSTR = 1; 34 | Config.SPR = 2; 35 | Config.CPHA = 1; 36 | Config.CPOL = 1; 37 | Config.LSB = 0; 38 | Config.TF_CLR = 0; 39 | Config.RF_CLR = 0; 40 | Config.TXFIFO_HFULL = 0; 41 | SPI_Configure(SPI0, &Config); 42 | 43 | SPI_Enable(&SPI0->CR); 44 | } 45 | 46 | void SPI_WaitForUndocumentedTxFifoStatusBit(void) 47 | { 48 | uint32_t Timeout; 49 | 50 | Timeout = 0; 51 | do { 52 | // Undocumented bit! 53 | if ((SPI0->IF & 0x20) == 0) { 54 | break; 55 | } 56 | Timeout++; 57 | } while (Timeout <= 100000); 58 | } 59 | 60 | void SPI_Disable(volatile uint32_t *pCR) 61 | { 62 | *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_DISABLE; 63 | } 64 | 65 | void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig) 66 | { 67 | if (pPort == SPI0) { 68 | SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI0_MASK) | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE; 69 | } else if (pPort == SPI1) { 70 | SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI1_MASK) | SYSCON_DEV_CLK_GATE_SPI1_BITS_ENABLE; 71 | } 72 | 73 | SPI_Disable(&pPort->CR); 74 | 75 | pPort->CR = 0 76 | | (pPort->CR & ~(SPI_CR_SPR_MASK | SPI_CR_CPHA_MASK | SPI_CR_CPOL_MASK | SPI_CR_MSTR_MASK | SPI_CR_LSB_MASK | SPI_CR_RF_CLR_MASK)) 77 | | ((pConfig->SPR << SPI_CR_SPR_SHIFT) & SPI_CR_SPR_MASK) 78 | | ((pConfig->CPHA << SPI_CR_CPHA_SHIFT) & SPI_CR_CPHA_MASK) 79 | | ((pConfig->CPOL << SPI_CR_CPOL_SHIFT) & SPI_CR_CPOL_MASK) 80 | | ((pConfig->MSTR << SPI_CR_MSTR_SHIFT) & SPI_CR_MSTR_MASK) 81 | | ((pConfig->LSB << SPI_CR_LSB_SHIFT) & SPI_CR_LSB_MASK) 82 | | ((pConfig->RF_CLR << SPI_CR_RF_CLR_SHIFT) & SPI_CR_RF_CLR_MASK) 83 | | ((pConfig->TF_CLR << SPI_CR_TF_CLR_SHIFT) & SPI_CR_TF_CLR_MASK) 84 | ; 85 | 86 | pPort->IE = 0 87 | | ((pConfig->RXFIFO_OVF << SPI_IE_RXFIFO_OVF_SHIFT) & SPI_IE_RXFIFO_OVF_MASK) 88 | | ((pConfig->RXFIFO_FULL << SPI_IE_RXFIFO_FULL_SHIFT) & SPI_IE_RXFIFO_FULL_MASK) 89 | | ((pConfig->RXFIFO_HFULL << SPI_IE_RXFIFO_HFULL_SHIFT) & SPI_IE_RXFIFO_HFULL_MASK) 90 | | ((pConfig->TXFIFO_EMPTY << SPI_IE_TXFIFO_EMPTY_SHIFT) & SPI_IE_TXFIFO_EMPTY_MASK) 91 | | ((pConfig->TXFIFO_HFULL << SPI_IE_TXFIFO_HFULL_SHIFT) & SPI_IE_TXFIFO_HFULL_MASK) 92 | ; 93 | 94 | if (pPort->IE) { 95 | if (pPort == SPI0) { 96 | NVIC_EnableIRQ(DP32_SPI0_IRQn); 97 | } else if (pPort == SPI1) { 98 | NVIC_EnableIRQ(DP32_SPI1_IRQn); 99 | } 100 | } 101 | } 102 | 103 | void SPI_ToggleMasterMode(volatile uint32_t *pCR, bool bIsMaster) 104 | { 105 | if (bIsMaster) { 106 | *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_ENABLE; 107 | } else { 108 | *pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_DISABLE; 109 | } 110 | } 111 | 112 | void SPI_Enable(volatile uint32_t *pCR) 113 | { 114 | *pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_ENABLE; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /driver/spi.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_SPI_H 18 | #define DRIVER_SPI_H 19 | 20 | #include 21 | #include 22 | 23 | typedef struct { 24 | uint8_t MSTR; 25 | uint8_t SPR; 26 | uint8_t CPHA; 27 | uint8_t CPOL; 28 | uint8_t LSB; 29 | uint8_t TF_CLR; 30 | uint8_t RF_CLR; 31 | uint8_t TXFIFO_HFULL; 32 | uint8_t TXFIFO_EMPTY; 33 | uint8_t RXFIFO_HFULL; 34 | uint8_t RXFIFO_FULL; 35 | uint8_t RXFIFO_OVF; 36 | } SPI_Config_t; 37 | 38 | void SPI0_Init(void); 39 | void SPI_WaitForUndocumentedTxFifoStatusBit(void); 40 | 41 | void SPI_Disable(volatile uint32_t *pCR); 42 | void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig); 43 | void SPI_ToggleMasterMode(volatile uint32_t *pCr, bool bIsMaster); 44 | void SPI_Enable(volatile uint32_t *pCR); 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /driver/st7565.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_ST7565_H 18 | #define DRIVER_ST7565_H 19 | 20 | #include 21 | #include 22 | 23 | extern uint8_t gStatusLine[128]; 24 | extern uint8_t gFrameBuffer[7][128]; 25 | 26 | void ST7565_DrawLine(uint8_t Column, uint8_t Line, uint16_t Size, const uint8_t *pBitmap, bool bIsClearMode); 27 | void ST7565_BlitFullScreen(void); 28 | void ST7565_BlitStatusLine(void); 29 | void ST7565_FillScreen(uint8_t Value); 30 | void ST7565_Init(void); 31 | void ST7565_HardwareReset(void); 32 | void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line); 33 | void ST7565_WriteByte(uint8_t Value); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /driver/system.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "bsp/dp32g030/pmu.h" 18 | #include "bsp/dp32g030/syscon.h" 19 | #include "driver/system.h" 20 | #include "driver/systick.h" 21 | 22 | void SYSTEM_DelayMs(uint32_t Delay) 23 | { 24 | SYSTICK_DelayUs(Delay * 1000); 25 | } 26 | 27 | void SYSTEM_ConfigureClocks(void) 28 | { 29 | // Set source clock from external crystal 30 | PMU_SRC_CFG = (PMU_SRC_CFG & ~(PMU_SRC_CFG_RCHF_SEL_MASK | PMU_SRC_CFG_RCHF_EN_MASK)) 31 | | PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ 32 | | PMU_SRC_CFG_RCHF_EN_BITS_ENABLE; 33 | 34 | // Divide by 2 35 | SYSCON_CLK_SEL = SYSCON_CLK_SEL_DIV_BITS_2; 36 | 37 | // Disable division clock gate 38 | SYSCON_DIV_CLK_GATE = (SYSCON_DIV_CLK_GATE & ~SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_MASK) | SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_DISABLE; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /driver/system.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_SYSTEM_H 18 | #define DRIVER_SYSTEM_H 19 | 20 | #include 21 | 22 | void SYSTEM_DelayMs(uint32_t Delay); 23 | void SYSTEM_ConfigureClocks(void); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /driver/systick.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ARMCM0.h" 18 | #include "driver/systick.h" 19 | #include "misc.h" 20 | 21 | // 0x20000324 22 | static uint32_t gTickMultiplier; 23 | 24 | void SYSTICK_Init(void) 25 | { 26 | SysTick_Config(480000); 27 | gTickMultiplier = 48; 28 | } 29 | 30 | void SYSTICK_DelayUs(uint32_t Delay) 31 | { 32 | uint32_t i; 33 | uint32_t Start; 34 | uint32_t Previous; 35 | uint32_t Current; 36 | uint32_t Delta; 37 | 38 | i = 0; 39 | Start = SysTick->LOAD; 40 | Previous = SysTick->VAL; 41 | do { 42 | do { 43 | Current = SysTick->VAL; 44 | } while (Current == Previous); 45 | if (Current < Previous) { 46 | Delta = -Current; 47 | } else { 48 | Delta = Start - Current; 49 | } 50 | i += Delta + Previous; 51 | Previous = Current; 52 | } while (i < Delay * gTickMultiplier); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /driver/systick.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef DRIVER_SYSTICK_H 18 | #define DRIVER_SYSTICK_H 19 | 20 | #include 21 | 22 | void SYSTICK_Init(void); 23 | void SYSTICK_DelayUs(uint32_t Delay); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /driver/uart.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "bsp/dp32g030/dma.h" 19 | #include "bsp/dp32g030/syscon.h" 20 | #include "bsp/dp32g030/uart.h" 21 | #include "driver/uart.h" 22 | 23 | static bool UART_IsLogEnabled; 24 | uint8_t UART_DMA_Buffer[256]; 25 | 26 | void UART_Init(void) 27 | { 28 | uint32_t Delta; 29 | uint32_t Positive; 30 | uint32_t Frequency; 31 | 32 | UART1->CTRL = (UART1->CTRL & ~UART_CTRL_UARTEN_MASK) | UART_CTRL_UARTEN_BITS_DISABLE; 33 | Delta = SYSCON_RC_FREQ_DELTA; 34 | Positive = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT; 35 | Frequency = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT; 36 | if (Positive) { 37 | Frequency += 48000000U; 38 | } else { 39 | Frequency = 48000000U - Frequency; 40 | } 41 | 42 | UART1->BAUD = Frequency / 39053U; 43 | UART1->CTRL = UART_CTRL_RXEN_BITS_ENABLE | UART_CTRL_TXEN_BITS_ENABLE | UART_CTRL_RXDMAEN_BITS_ENABLE; 44 | UART1->RXTO = 4; 45 | UART1->FC = 0; 46 | UART1->FIFO = UART_FIFO_RF_LEVEL_BITS_8_BYTE | UART_FIFO_RF_CLR_BITS_ENABLE | UART_FIFO_TF_CLR_BITS_ENABLE; 47 | UART1->IE = 0; 48 | 49 | DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE; 50 | 51 | DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR; 52 | DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer; 53 | DMA_CH0->MOD = 0 54 | // Source 55 | | DMA_CH_MOD_MS_ADDMOD_BITS_NONE 56 | | DMA_CH_MOD_MS_SIZE_BITS_8BIT 57 | | DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1 58 | // Destination 59 | | DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT 60 | | DMA_CH_MOD_MD_SIZE_BITS_8BIT 61 | | DMA_CH_MOD_MD_SEL_BITS_SRAM 62 | ; 63 | DMA_INTEN = 0; 64 | DMA_INTST = 0 65 | | DMA_INTST_CH0_TC_INTST_BITS_SET 66 | | DMA_INTST_CH1_TC_INTST_BITS_SET 67 | | DMA_INTST_CH2_TC_INTST_BITS_SET 68 | | DMA_INTST_CH3_TC_INTST_BITS_SET 69 | | DMA_INTST_CH0_THC_INTST_BITS_SET 70 | | DMA_INTST_CH1_THC_INTST_BITS_SET 71 | | DMA_INTST_CH2_THC_INTST_BITS_SET 72 | | DMA_INTST_CH3_THC_INTST_BITS_SET 73 | ; 74 | DMA_CH0->CTR = 0 75 | | DMA_CH_CTR_CH_EN_BITS_ENABLE 76 | | ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK) 77 | | DMA_CH_CTR_LOOP_BITS_ENABLE 78 | | DMA_CH_CTR_PRI_BITS_MEDIUM 79 | ; 80 | UART1->IF = UART_IF_RXTO_BITS_SET; 81 | 82 | DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE; 83 | 84 | UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE; 85 | } 86 | 87 | void UART_Send(const void *pBuffer, uint32_t Size) 88 | { 89 | const uint8_t *pData = (const uint8_t *)pBuffer; 90 | uint32_t i; 91 | 92 | for (i = 0; i < Size; i++) { 93 | UART1->TDR = pData[i]; 94 | while ((UART1->IF & UART_IF_TXFIFO_FULL_MASK) != UART_IF_TXFIFO_FULL_BITS_NOT_SET) { 95 | } 96 | } 97 | } 98 | 99 | void UART_LogSend(const void *pBuffer, uint32_t Size) 100 | { 101 | if (UART_IsLogEnabled) { 102 | UART_Send(pBuffer, Size); 103 | } 104 | } 105 | 106 | -------------------------------------------------------------------------------- /driver/uart.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | #ifndef DRIVER_UART_H 19 | #define DRIVER_UART_H 20 | 21 | #include 22 | 23 | extern uint8_t UART_DMA_Buffer[256]; 24 | 25 | void UART_Init(void); 26 | void UART_Send(const void *pBuffer, uint32_t Size); 27 | void UART_LogSend(const void *pBuffer, uint32_t Size); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /firmware.ld: -------------------------------------------------------------------------------- 1 | ENTRY(HandlerReset) 2 | 3 | _estack = 0x20004000; /* end of 16K RAM */ 4 | 5 | _Min_Heap_Size = 0; /* required amount of heap */ 6 | _Min_Stack_Size = 0x80; /* required amount of stack */ 7 | 8 | MEMORY 9 | { 10 | FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 60K 11 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K 12 | } 13 | 14 | SECTIONS 15 | { 16 | /* Program code */ 17 | .text : 18 | { 19 | . = ALIGN(4); 20 | *(.text.isr) /* .text sections of code */ 21 | *(.text) /* .text sections of code */ 22 | *(.text*) /* .text* sections of code */ 23 | *(.rodata) /* .rodata sections */ 24 | *(.rodata*) /* .rodata* sections */ 25 | *(.glue_7) /* Glue arm to thumb code */ 26 | *(.glue_7t) /* Glue thumb to arm code */ 27 | *(.eh_frame) 28 | 29 | KEEP(*(.fini)) 30 | . = ALIGN(4); 31 | _etext = .; /* global symbols at end */ 32 | } >FLASH 33 | 34 | /* Used by startup code */ 35 | 36 | . = ALIGN(4); 37 | 38 | flash_data_start = .; 39 | 40 | .data : 41 | { 42 | . = ALIGN(4); 43 | sram_data_start = .; 44 | *(.sramtext) 45 | *(.srambss) 46 | *(.data) /* .data sections */ 47 | *(.data*) /* .data* sections */ 48 | 49 | . = ALIGN(4); 50 | _edata = .; /* Global symbol at data end */ 51 | } >RAM AT> FLASH 52 | 53 | sram_data_end = .; 54 | 55 | /* Uninitialized data */ 56 | . = ALIGN(4); 57 | .bss : 58 | { 59 | _sbss = .; /* Global symbol at bss start */ 60 | __bss_start__ = _sbss; 61 | *(.bss) 62 | *(.bss*) 63 | *(COMMON) 64 | 65 | . = ALIGN(4); 66 | _ebss = .; /* Global symbol at bss end */ 67 | __bss_end__ = _ebss; 68 | } >RAM 69 | 70 | /* Check that there is enough RAM */ 71 | ._user_heap_stack : 72 | { 73 | . = ALIGN(4); 74 | . = . + _Min_Heap_Size; 75 | . = . + _Min_Stack_Size; 76 | . = ALIGN(4); 77 | } >RAM 78 | } 79 | 80 | -------------------------------------------------------------------------------- /font.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FONT_H 18 | #define FONT_H 19 | 20 | #include 21 | 22 | extern const uint8_t gFontBig[95][16]; 23 | extern const uint8_t gFontBigDigits[11][26]; 24 | extern const uint8_t gFontSmallDigits[11][7]; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /frequencies.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FREQUENCIES_H 18 | #define FREQUENCIES_H 19 | 20 | #include 21 | #include "radio.h" 22 | 23 | enum FREQUENCY_Band_t { 24 | BAND1_50MHz = 0, 25 | BAND2_108MHz, 26 | BAND3_136MHz, 27 | BAND4_174MHz, 28 | BAND5_350MHz, 29 | BAND6_400MHz, 30 | BAND7_470MHz, 31 | }; 32 | 33 | typedef enum FREQUENCY_Band_t FREQUENCY_Band_t; 34 | 35 | extern const uint32_t LowerLimitFrequencyBandTable[7]; 36 | extern const uint32_t MiddleFrequencyBandTable[7]; 37 | extern const uint32_t UpperLimitFrequencyBandTable[7]; 38 | #if defined(ENABLE_NOAA) 39 | extern const uint32_t NoaaFrequencyTable[10]; 40 | #endif 41 | extern const uint16_t StepFrequencyTable[7]; 42 | 43 | FREQUENCY_Band_t FREQUENCY_GetBand(uint32_t Frequency); 44 | uint8_t FREQUENCY_CalculateOutputPower(uint8_t TxpLow, uint8_t TxpMid, uint8_t TxpHigh, int32_t LowerLimit, int32_t Middle, int32_t UpperLimit, int32_t Frequency); 45 | uint32_t FREQUENCY_FloorToStep(uint32_t Upper, uint32_t Step, uint32_t Lower); 46 | int FREQUENCY_Check(VFO_Info_t *pInfo); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /functions.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef FUNCTIONS_H 18 | #define FUNCTIONS_H 19 | 20 | #include 21 | 22 | enum FUNCTION_Type_t { 23 | FUNCTION_FOREGROUND = 0U, 24 | FUNCTION_TRANSMIT = 1U, 25 | FUNCTION_MONITOR = 2U, 26 | FUNCTION_INCOMING = 3U, 27 | FUNCTION_RECEIVE = 4U, 28 | FUNCTION_POWER_SAVE = 5U, 29 | }; 30 | 31 | typedef enum FUNCTION_Type_t FUNCTION_Type_t; 32 | 33 | extern FUNCTION_Type_t gCurrentFunction; 34 | 35 | void FUNCTION_Init(void); 36 | void FUNCTION_Select(FUNCTION_Type_t Function); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /fw-pack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import crcmod 4 | import sys 5 | 6 | from itertools import cycle 7 | from binascii import hexlify 8 | 9 | OBFUSCATION = [ 10 | 0x47, 0x22, 0xC0, 0x52, 0x5D, 0x57, 0x48, 0x94, 0xB1, 0x60, 0x60, 0xDB, 0x6F, 0xE3, 0x4C, 0x7C, 11 | 0xD8, 0x4A, 0xD6, 0x8B, 0x30, 0xEC, 0x25, 0xE0, 0x4C, 0xD9, 0x00, 0x7F, 0xBF, 0xE3, 0x54, 0x05, 12 | 0xE9, 0x3A, 0x97, 0x6B, 0xB0, 0x6E, 0x0C, 0xFB, 0xB1, 0x1A, 0xE2, 0xC9, 0xC1, 0x56, 0x47, 0xE9, 13 | 0xBA, 0xF1, 0x42, 0xB6, 0x67, 0x5F, 0x0F, 0x96, 0xF7, 0xC9, 0x3C, 0x84, 0x1B, 0x26, 0xE1, 0x4E, 14 | 0x3B, 0x6F, 0x66, 0xE6, 0xA0, 0x6A, 0xB0, 0xBF, 0xC6, 0xA5, 0x70, 0x3A, 0xBA, 0x18, 0x9E, 0x27, 15 | 0x1A, 0x53, 0x5B, 0x71, 0xB1, 0x94, 0x1E, 0x18, 0xF2, 0xD6, 0x81, 0x02, 0x22, 0xFD, 0x5A, 0x28, 16 | 0x91, 0xDB, 0xBA, 0x5D, 0x64, 0xC6, 0xFE, 0x86, 0x83, 0x9C, 0x50, 0x1C, 0x73, 0x03, 0x11, 0xD6, 17 | 0xAF, 0x30, 0xF4, 0x2C, 0x77, 0xB2, 0x7D, 0xBB, 0x3F, 0x29, 0x28, 0x57, 0x22, 0xD6, 0x92, 0x8B, 18 | ] 19 | 20 | def obfuscate(fw): 21 | return bytes([a^b for a, b in zip(fw, cycle(OBFUSCATION))]) 22 | 23 | plain = open(sys.argv[1], 'rb').read() 24 | if len(sys.argv[2]) > 10: 25 | print('Version suffix is too big!') 26 | sys.exit(1) 27 | 28 | version = b'*OEFW-' + bytes(sys.argv[2], 'ascii') 29 | if len(version) < 16: 30 | version += b'\x00' * (16 - len(version)) 31 | 32 | packed = obfuscate(plain[:0x2000] + version + plain[0x2000:]) 33 | 34 | crc = crcmod.predefined.Crc('xmodem') 35 | crc.update(packed) 36 | digest = crc.digest() 37 | digest = bytes([digest[1], digest[0]]) 38 | 39 | open(sys.argv[3], 'wb').write(packed + digest) 40 | 41 | -------------------------------------------------------------------------------- /hardware/dp32g030/aes.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [AES] 17 | @ = 0x400BD000, 0x800 18 | 19 | CR = 0x0000 20 | > CCFC, 7, 1 21 | = SET, 1 22 | 23 | > CHMOD, 5, 2 24 | = ECB, 0 25 | = CBC, 1 26 | = CTR, 2 27 | 28 | > EN, 0, 1 29 | = DISABLE, 0 30 | = ENABLE, 1 31 | 32 | SR = 0x0004 33 | > CCF, 0, 1 34 | = NOT_COMPLETE, 0 35 | = COMPLETE, 1 36 | 37 | DINR = 0x0008 38 | DOUTR = 0x000C 39 | 40 | KEYR0 = 0x0010 41 | KEYR1 = 0x0014 42 | KEYR2 = 0x0018 43 | KEYR3 = 0x001C 44 | 45 | IVR0 = 0x0020 46 | IVR1 = 0x0024 47 | IVR2 = 0x0028 48 | IVR3 = 0x002C 49 | 50 | -------------------------------------------------------------------------------- /hardware/dp32g030/crc.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [CRC] 17 | @ = 0x40003000, 0x800 18 | 19 | CR = 0x0000 20 | > CRC_EN, 0, 1 21 | = DISABLE, 0 22 | = ENABLE, 1 23 | 24 | > INPUT_REV, 1, 1 25 | = NORMAL, 0 26 | = REVERSED, 1 27 | 28 | > INPUT_INV, 2, 2 29 | = NORMAL, 0 30 | = BIT_INVERTED, 1 31 | = BYTE_INVERTED, 2 32 | = BIT_BYTE_INVERTED, 3 33 | 34 | > OUTPUT_REV, 4, 1 35 | = NORMAL, 0 36 | = REVERSED, 1 37 | 38 | > OUTPUT_INV, 5, 2 39 | = NORMAL, 0 40 | = BIT_INVERTED, 1 41 | = BYTE_INVERTED, 2 42 | = BIT_BYTE_INVERTED, 3 43 | 44 | > DATA_WIDTH, 7, 2 45 | = 32, 0 46 | = 16, 1 47 | = 8, 2 48 | 49 | > CRC_SEL, 9, 2 50 | = CRC_16_CCITT, 0 51 | = CRC_8_ATM, 1 52 | = CRC_16, 2 53 | = CRC_32_IEEE802_3, 3 54 | 55 | IV = 0x0004 56 | DATAIN = 0x0008 57 | DATAOUT = 0x000C 58 | 59 | -------------------------------------------------------------------------------- /hardware/dp32g030/dma.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [DMA] 17 | @ = 0x40001000, 0x100 18 | 19 | CTR = 0x0000 20 | > DMAEN, 0, 1 21 | = DISABLE, 0 22 | = ENABLE, 1 23 | 24 | INTEN = 0x0004 25 | > CH0_TC_INTEN, 0, 1 26 | = DISABLE, 0 27 | = ENABLE, 1 28 | 29 | > CH1_TC_INTEN, 1, 1 30 | = DISABLE, 0 31 | = ENABLE, 1 32 | 33 | > CH2_TC_INTEN, 2, 1 34 | = DISABLE, 0 35 | = ENABLE, 1 36 | 37 | > CH3_TC_INTEN, 3, 1 38 | = DISABLE, 0 39 | = ENABLE, 1 40 | 41 | > CH0_THC_INTEN, 8, 1 42 | = DISABLE, 0 43 | = ENABLE, 1 44 | 45 | > CH1_THC_INTEN, 9, 1 46 | = DISABLE, 0 47 | = ENABLE, 1 48 | 49 | > CH2_THC_INTEN, 10, 1 50 | = DISABLE, 0 51 | = ENABLE, 1 52 | 53 | > CH3_THC_INTEN, 11, 1 54 | = DISABLE, 0 55 | = ENABLE, 1 56 | 57 | INTST = 0x0008 58 | > CH0_TC_INTST, 0, 1 59 | = NOT_SET, 0 60 | = SET, 1 61 | 62 | > CH1_TC_INTST, 1, 1 63 | = NOT_SET, 0 64 | = SET, 1 65 | 66 | > CH2_TC_INTST, 2, 1 67 | = NOT_SET, 0 68 | = SET, 1 69 | 70 | > CH3_TC_INTST, 3, 1 71 | = NOT_SET, 0 72 | = SET, 1 73 | 74 | > CH0_THC_INTST, 8, 1 75 | = NOT_SET, 0 76 | = SET, 1 77 | 78 | > CH1_THC_INTST, 9, 1 79 | = NOT_SET, 0 80 | = SET, 1 81 | 82 | > CH2_THC_INTST, 10, 1 83 | = NOT_SET, 0 84 | = SET, 1 85 | 86 | > CH3_THC_INTST, 11, 1 87 | = NOT_SET, 0 88 | = SET, 1 89 | 90 | [DMA_CH] 91 | $ = DMA_Channel_t 92 | 93 | CTR = 0x0000 94 | > CH_EN, 0, 1 95 | = DISABLE, 0 96 | = ENABLE, 1 97 | 98 | > LENGTH, 1, 12 99 | 100 | > LOOP, 13, 1 101 | = DISABLE, 0 102 | = ENABLE, 1 103 | 104 | > PRI, 14, 2 105 | = LOW, 0 106 | = MEDIUM, 1 107 | = HIGH, 2 108 | = HIGHEST, 3 109 | 110 | > SWREQ, 16, 1 111 | = SET, 1 112 | 113 | MOD = 0x0004 114 | > MS_ADDMOD, 0, 1 115 | = NONE, 0 116 | = INCREMENT, 1 117 | 118 | > MS_SIZE, 1, 2 119 | = 8BIT, 0 120 | = 16BIT, 1 121 | = 32BIT, 2 122 | = KEEP, 3 123 | 124 | > MS_SEL, 3, 3 125 | = SRAM, 0 126 | = HSREQ_MS0, 1 127 | = HSREQ_MS1, 2 128 | = HSREQ_MS2, 3 129 | = HSREQ_MS3, 4 130 | = HSREQ_MS4, 5 131 | = HSREQ_MS5, 6 132 | = HSREQ_MS6, 7 133 | 134 | > MD_ADDMOD, 8, 1 135 | = NONE, 0 136 | = INCREMENT, 1 137 | 138 | > MD_SIZE, 9, 2 139 | = 8BIT, 0 140 | = 16BIT, 1 141 | = 32BIT, 2 142 | = KEEP, 3 143 | 144 | > MD_SEL, 11, 3 145 | = SRAM, 0 146 | = HSREQ_MS0, 1 147 | = HSREQ_MS1, 2 148 | = HSREQ_MS2, 3 149 | = HSREQ_MS3, 4 150 | = HSREQ_MS4, 5 151 | = HSREQ_MS5, 6 152 | = HSREQ_MS6, 7 153 | 154 | MSADDR = 0x0008 155 | MDADDR = 0x000C 156 | ST = 0x0010 157 | 158 | [DMA_CH0] 159 | @ = 0x40001100, 0x20, $DMA_CH 160 | 161 | [DMA_CH1] 162 | @ = 0x40001120, 0x20, $DMA_CH 163 | 164 | [DMA_CH2] 165 | @ = 0x40001140, 0x20, $DMA_CH 166 | 167 | [DMA_CH3] 168 | @ = 0x40001160, 0x20, $DMA_CH 169 | 170 | -------------------------------------------------------------------------------- /hardware/dp32g030/flash.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [FLASH] 17 | @ = 0x4006F000, 0x800 18 | 19 | CFG = 0x0000 20 | > READ_MD, 0, 1 21 | = 1_CYCLE, 0 22 | = 2_CYCLE, 1 23 | 24 | > NVR_SEL, 1, 1 25 | = MAIN, 0 26 | = NVR, 1 27 | 28 | > MODE, 2, 3 29 | = READ_AHB, 0 30 | = PROGRAM, 1 31 | = ERASE, 2 32 | = READ_APB, 5 33 | 34 | > DEEP_PD, 31, 1 35 | = NORMAL, 0 36 | = LOW_POWER, 1 37 | 38 | ADDR = 0x0004 39 | WDATA = 0x0008 40 | RDATA = 0x000C 41 | 42 | START = 0x0010 43 | > START, 0, 1 44 | = START, 1 45 | 46 | ST = 0x0014 47 | > INIT_BUSY, 0, 1 48 | = COMPLETE, 0 49 | = BUSY, 1 50 | 51 | > BUSY, 1, 1 52 | = READY, 0 53 | = BUSY, 1 54 | 55 | > PROG_BUF_EMPTY, 2, 1 56 | = NOT_EMPTY, 0 57 | = EMPTY, 1 58 | 59 | LOCK = 0x0018 60 | > LOCK, 0, 8 61 | = LOCK, 0x55 62 | 63 | UNLOCK = 0x001C 64 | > UNLOCK, 0, 8 65 | = UNLOCK, 0xAA 66 | 67 | MASK = 0x0020 68 | > SEL, 0, 2 69 | = NONE, 0 70 | = 2KB, 1 71 | = 4KB, 2 72 | = 8KB, 3 73 | 74 | > LOCK, 2, 1 75 | = NOT_SET, 0 76 | = SET, 1 77 | 78 | ERASETIME = 0x0024 79 | > TERASE, 0, 19 80 | > TRCV, 19, 12 81 | 82 | PROGTIME = 0x0028 83 | > TPROG, 0, 11 84 | > TPGS, 11, 11 85 | 86 | -------------------------------------------------------------------------------- /hardware/dp32g030/gpio.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [GPIO] 17 | $ = GPIO_Bank_t 18 | 19 | DATA = 0x0000 20 | DIR = 0x0004 21 | > 0, 0, 1 22 | = INPUT, 0 23 | = OUTPUT, 1 24 | 25 | > 1, 1, 1 26 | = INPUT, 0 27 | = OUTPUT, 1 28 | 29 | > 2, 2, 1 30 | = INPUT, 0 31 | = OUTPUT, 1 32 | 33 | > 3, 3, 1 34 | = INPUT, 0 35 | = OUTPUT, 1 36 | 37 | > 4, 4, 1 38 | = INPUT, 0 39 | = OUTPUT, 1 40 | 41 | > 5, 5, 1 42 | = INPUT, 0 43 | = OUTPUT, 1 44 | 45 | > 6, 6, 1 46 | = INPUT, 0 47 | = OUTPUT, 1 48 | 49 | > 7, 7, 1 50 | = INPUT, 0 51 | = OUTPUT, 1 52 | 53 | > 8, 8, 1 54 | = INPUT, 0 55 | = OUTPUT, 1 56 | 57 | > 9, 9, 1 58 | = INPUT, 0 59 | = OUTPUT, 1 60 | 61 | > 10, 10, 1 62 | = INPUT, 0 63 | = OUTPUT, 1 64 | 65 | > 11, 11, 1 66 | = INPUT, 0 67 | = OUTPUT, 1 68 | 69 | > 12, 12, 1 70 | = INPUT, 0 71 | = OUTPUT, 1 72 | 73 | > 13, 13, 1 74 | = INPUT, 0 75 | = OUTPUT, 1 76 | 77 | > 14, 14, 1 78 | = INPUT, 0 79 | = OUTPUT, 1 80 | 81 | > 15, 15, 1 82 | = INPUT, 0 83 | = OUTPUT, 1 84 | 85 | [GPIOA] 86 | @ = 0x40060000, 0x800, $GPIO 87 | 88 | [GPIOB] 89 | @ = 0x40060800, 0x800, $GPIO 90 | 91 | [GPIOC] 92 | @ = 0x40061000, 0x800, $GPIO 93 | 94 | -------------------------------------------------------------------------------- /hardware/dp32g030/pmu.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [PMU] 17 | @ = 0x40000800, 0x800 18 | 19 | SRC_CFG = 0x0010 20 | > RCHF_SEL, 1, 1 21 | = 48MHZ, 0 22 | = 24MHZ, 1 23 | 24 | > RCHF_EN, 0, 1 25 | = DISABLE, 0 26 | = ENABLE, 1 27 | 28 | TRIM_POW0 = 0x0020 29 | TRIM_POW1 = 0x0024 30 | TRIM_POW2 = 0x0028 31 | TRIM_POW3 = 0x002C 32 | 33 | TRIM_RCHF = 0x0030 34 | TRIM_RCLF = 0x0034 35 | TRIM_OPA = 0x0038 36 | TRIM_PLL = 0x003C 37 | 38 | -------------------------------------------------------------------------------- /hardware/dp32g030/saradc.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [SARADC] 17 | @ = 0x400BA000, 0x800 18 | 19 | CFG = 0x0000 20 | > CH_SEL, 0, 15 21 | 22 | > AVG, 16, 2 23 | = 1_SAMPLE, 0 24 | = 2_SAMPLE, 1 25 | = 4_SAMPLE, 2 26 | = 8_SAMPLE, 3 27 | 28 | > CONT, 18, 1 29 | = SINGLE, 0 30 | = CONTINUOUS, 1 31 | 32 | > SMPL_SETUP, 19, 3 33 | = 1_CYCLE, 0 34 | = 2_CYCLE, 1 35 | = 4_CYCLE, 2 36 | = 8_CYCLE, 3 37 | = 16_CYCLE, 4 38 | = 32_CYCLE, 5 39 | = 64_CYCLE, 6 40 | = 128_CYCLE, 7 41 | 42 | > MEM_MODE, 22, 1 43 | = FIFO, 0 44 | = CHANNEL, 1 45 | 46 | > SMPL_CLK, 23, 1 47 | = EXTERNAL, 0 48 | = INTERNAL, 1 49 | 50 | > SMPL_WIN, 24, 3 51 | = 1_CYCLE, 0 52 | = 3_CYCLE, 1 53 | = 5_CYCLE, 2 54 | = 7_CYCLE, 3 55 | = 9_CYCLE, 4 56 | = 11_CYCLE, 5 57 | = 13_CYCLE, 6 58 | = 15_CYCLE, 7 59 | 60 | > ADC_EN, 27, 1 61 | = DISABLE, 0 62 | = ENABLE, 1 63 | 64 | > ADC_TRIG, 28, 1 65 | = CPU, 0 66 | = EXTERNAL, 1 67 | 68 | > DMA_EN, 29, 1 69 | = DISABLE, 0 70 | = ENABLE, 1 71 | 72 | START = 0x0004 73 | > START, 0, 1 74 | = DISABLE, 0 75 | = ENABLE, 1 76 | 77 | > SOFT_RESET, 2, 1 78 | = ASSERT, 0 79 | = DEASSERT, 1 80 | 81 | IE = 0x0008 82 | > CHx_EOC, 0, 16 83 | = NONE, 0x0000 84 | = ALL, 0xFFFF 85 | 86 | > FIFO_FULL, 16, 1 87 | = DISABLE, 0 88 | = ENABLE, 1 89 | 90 | > FIFO_HFULL, 17, 1 91 | = DISABLE, 0 92 | = ENABLE, 1 93 | 94 | IF = 0x000C 95 | > CHx_EOC, 0, 16 96 | 97 | > FIFO_FULL, 16, 1 98 | = NOT_SET, 0 99 | = SET, 1 100 | 101 | > FIFO_HFULL, 17, 1 102 | = NOT_SET, 0 103 | = SET, 1 104 | 105 | CH0 = 0x0010 106 | 107 | EXTTRIG_SEL = 0x00B0 108 | 109 | CALIB_OFFSET = 0x00F0 110 | > OFFSET, 0, 8 111 | > VALID, 16, 1 112 | = NO, 0 113 | = YES, 1 114 | 115 | CALIB_KD = 0x00F4 116 | > KD, 0, 8 117 | > VALID, 16, 1 118 | = NO, 0 119 | = YES, 1 120 | 121 | [ADC_CHx] 122 | $ = ADC_Channel_t 123 | 124 | STAT = 0x0000 125 | > EOC, 0, 1 126 | = NOT_COMPLETE, 0 127 | = COMPLETE, 1 128 | 129 | DATA = 0x0004 130 | > DATA, 0, 12 131 | > NUM, 12, 4 132 | 133 | -------------------------------------------------------------------------------- /hardware/dp32g030/spi.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [SPI] 17 | $ = SPI_Port_t 18 | 19 | CR = 0x0000 20 | > TF_CLR, 16, 1 21 | > RF_CLR, 15, 1 22 | > TXDMAEN, 14, 1 23 | > RXDMAEN, 13, 1 24 | 25 | > MSR_SSN, 12, 1 26 | = DISABLE, 0 27 | = ENABLE, 1 28 | 29 | > CPHA_DATA_HOLD_S, 8, 4 30 | > LSB, 7, 1 31 | > MSTR, 6, 1 32 | > CPOL, 5, 1 33 | > CPHA, 4, 1 34 | 35 | > SPE, 3, 1 36 | = DISABLE, 0 37 | = ENABLE, 1 38 | 39 | > SPR, 0, 3 40 | = FPCLK_DIV_4, 0 41 | = FPCLK_DIV_8, 1 42 | = FPCLK_DIV_16, 2 43 | = FPCLK_DIV_32, 3 44 | = FPCLK_DIV_64, 4 45 | = FPCLK_DIV_128, 5 46 | = FPCLK_DIV_256, 6 47 | = FPCLK_DIV_512, 7 48 | 49 | WDR = 0x0004 50 | RDR = 0x0008 51 | 52 | IE = 0x0010 53 | > RXFIFO_OVF, 0, 1 54 | = DISABLE, 0 55 | = ENABLE, 1 56 | 57 | > RXFIFO_FULL, 1, 1 58 | = DISABLE, 0 59 | = ENABLE, 1 60 | 61 | > RXFIFO_HFULL, 2, 1 62 | = DISABLE, 0 63 | = ENABLE, 1 64 | 65 | > TXFIFO_EMPTY, 3, 1 66 | = DISABLE, 0 67 | = ENABLE, 1 68 | 69 | > TXFIFO_HFULL, 4, 1 70 | = DISABLE, 0 71 | = ENABLE, 1 72 | 73 | IF = 0x0014 74 | FIFOST = 0x0018 75 | > RFE, 0, 1 76 | = NOT_EMPTY, 0 77 | = EMPTY, 1 78 | 79 | > RFF, 1, 1 80 | = NOT_FULL, 0 81 | = FULL, 1 82 | 83 | > RFHF, 2, 1 84 | = NOT_HALF_FULL, 0 85 | = HALF_FULL, 1 86 | 87 | > TFE, 3, 1 88 | = NOT_EMPTY, 0 89 | = EMPTY, 1 90 | 91 | > TFF, 4, 1 92 | = NOT_FULL, 0 93 | = FULL, 1 94 | 95 | > TFHF, 5, 1 96 | = NOT_HALF_FULL, 0 97 | = HALF_FULL, 1 98 | 99 | > RF_LEVEL, 6, 3 100 | = 0_BYTE, 0 101 | = 1_BYTE, 1 102 | = 2_BYTE, 2 103 | = 3_BYTE, 3 104 | = 4_BYTE, 4 105 | = 5_BYTE, 5 106 | = 6_BYTE, 6 107 | = 7_BYTE, 7 108 | 109 | > TF_LEVEL, 9, 3 110 | = 0_BYTE, 0 111 | = 1_BYTE, 1 112 | = 2_BYTE, 2 113 | = 3_BYTE, 3 114 | = 4_BYTE, 4 115 | = 5_BYTE, 5 116 | = 6_BYTE, 6 117 | = 7_BYTE, 7 118 | 119 | [SPI0] 120 | @ = 0x400B8000, 0x800, $SPI 121 | 122 | [SPI1] 123 | @ = 0x400B8800, 0x800, $SPI 124 | 125 | -------------------------------------------------------------------------------- /hardware/dp32g030/syscon.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [SYSCON] 17 | @ = 0x40000000, 0x800 18 | 19 | CLK_SEL = 0x0000 20 | > SYS, 0, 1 21 | = RCHF, 0 22 | = DIV_CLK, 1 23 | 24 | > DIV, 1, 3 25 | = 1, 0 26 | = 2, 1 27 | = 4, 2 28 | = 8, 3 29 | = 16, 4 30 | = 32, 5 31 | 32 | > SRC, 4, 3 33 | = RCHF, 0 34 | = RCLF, 1 35 | = XTAH, 2 36 | = XTAL, 3 37 | = PLL, 4 38 | 39 | > W_PLL, 7, 1 40 | = RCHF, 0 41 | = XTAH, 1 42 | 43 | # The documentation doesn't match the firmware! 44 | > R_SARADC_SMPL, 9, 2 45 | = DIV1, 0 46 | = DIV2, 1 47 | = DIV4, 2 48 | = DIV8, 3 49 | 50 | > W_SARADC_SMPL, 10, 2 51 | = DIV1, 0 52 | = DIV2, 1 53 | = DIV4, 2 54 | = DIV8, 3 55 | 56 | > R_PLL, 11, 1 57 | = RCHF, 0 58 | = XTAH, 1 59 | 60 | DIV_CLK_GATE = 0x0004 61 | > DIV_CLK_GATE, 0, 1 62 | = DISABLE, 0 63 | = ENABLE, 1 64 | 65 | DEV_CLK_GATE = 0x0008 66 | > GPIOA, 0, 1 67 | = DISABLE, 0 68 | = ENABLE, 1 69 | 70 | > GPIOB, 1, 1 71 | = DISABLE, 0 72 | = ENABLE, 1 73 | 74 | > GPIOC, 2, 1 75 | = DISABLE, 0 76 | = ENABLE, 1 77 | 78 | > IIC0, 4, 1 79 | = DISABLE, 0 80 | = ENABLE, 1 81 | 82 | > IIC1, 5, 1 83 | = DISABLE, 0 84 | = ENABLE, 1 85 | 86 | > UART0, 6, 1 87 | = DISABLE, 0 88 | = ENABLE, 1 89 | 90 | > UART1, 7, 1 91 | = DISABLE, 0 92 | = ENABLE, 1 93 | 94 | > UART2, 8, 1 95 | = DISABLE, 0 96 | = ENABLE, 1 97 | 98 | > SPI0, 10, 1 99 | = DISABLE, 0 100 | = ENABLE, 1 101 | 102 | > SPI1, 11, 1 103 | = DISABLE, 0 104 | = ENABLE, 1 105 | 106 | > TIMER_BASE0, 12, 1 107 | = DISABLE, 0 108 | = ENABLE, 1 109 | 110 | > TIMER_BASE1, 13, 1 111 | = DISABLE, 0 112 | = ENABLE, 1 113 | 114 | > TIMER_BASE2, 14, 1 115 | = DISABLE, 0 116 | = ENABLE, 1 117 | 118 | > TIMER_PLUS0, 15, 1 119 | = DISABLE, 0 120 | = ENABLE, 1 121 | 122 | > TIMER_PLUS1, 16, 1 123 | = DISABLE, 0 124 | = ENABLE, 1 125 | 126 | > PWM_BASE0, 17, 1 127 | = DISABLE, 0 128 | = ENABLE, 1 129 | 130 | > PWM_BASE1, 18, 1 131 | = DISABLE, 0 132 | = ENABLE, 1 133 | 134 | > PWM_PLUS0, 20, 1 135 | = DISABLE, 0 136 | = ENABLE, 1 137 | 138 | > PWM_PLUS1, 21, 1 139 | = DISABLE, 0 140 | = ENABLE, 1 141 | 142 | > RTC, 22, 1 143 | = DISABLE, 0 144 | = ENABLE, 1 145 | 146 | > IWDT, 23, 1 147 | = DISABLE, 0 148 | = ENABLE, 1 149 | 150 | > WWDT, 24, 1 151 | = DISABLE, 0 152 | = ENABLE, 1 153 | 154 | > SARADC, 25, 1 155 | = DISABLE, 0 156 | = ENABLE, 1 157 | 158 | > CRC, 27, 1 159 | = DISABLE, 0 160 | = ENABLE, 1 161 | 162 | > AES, 28, 1 163 | = DISABLE, 0 164 | = ENABLE, 1 165 | 166 | RC_FREQ_DELTA = 0x0078 167 | > RCLF_DELTA, 0, 10 168 | > RCLF_SIG, 10, 1 169 | > RCHF_DELTA, 11, 20 170 | > RCHF_SIG, 31, 1 171 | 172 | VREF_VOLT_DELTA = 0x007C 173 | 174 | CHIP_ID0 = 0x0080 175 | CHIP_ID1 = 0x0084 176 | CHIP_ID2 = 0x0088 177 | CHIP_ID3 = 0x008C 178 | 179 | -------------------------------------------------------------------------------- /hardware/dp32g030/uart.def: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | [UART] 17 | $ = UART_Port_t 18 | 19 | CTRL = 0x0000 20 | > UARTEN, 0, 1 21 | = DISABLE, 0 22 | = ENABLE, 1 23 | 24 | > RXEN, 1, 1 25 | = DISABLE, 0 26 | = ENABLE, 1 27 | 28 | > TXEN, 2, 1 29 | = DISABLE, 0 30 | = ENABLE, 1 31 | 32 | > RXDMAEN, 3, 1 33 | = DISABLE, 0 34 | = ENABLE, 1 35 | 36 | > TXDMAEN, 4, 1 37 | = DISABLE, 0 38 | = ENABLE, 1 39 | 40 | > NINEBIT, 5, 1 41 | = DISABLE, 0 42 | = ENABLE, 1 43 | 44 | > PAREN, 6, 1 45 | = DISABLE, 0 46 | = ENABLE, 1 47 | 48 | BAUD = 0x0004 49 | TDR = 0x0008 50 | RDR = 0x000C 51 | 52 | IE = 0x0010 53 | > TXDONE, 2, 1 54 | = DISABLE, 0 55 | = ENABLE, 1 56 | 57 | > PARITYE, 3, 1 58 | = DISABLE, 0 59 | = ENABLE, 1 60 | 61 | > STOPE, 4, 1 62 | = DISABLE, 0 63 | = ENABLE, 1 64 | 65 | > RXTO, 5, 1 66 | = DISABLE, 0 67 | = ENABLE, 1 68 | 69 | > RXFIFO, 6, 1 70 | = DISABLE, 0 71 | = ENABLE, 1 72 | 73 | > TXFIFO, 7, 1 74 | = DISABLE, 0 75 | = ENABLE, 1 76 | 77 | > RXFIFO_OVF, 8, 1 78 | = DISABLE, 0 79 | = ENABLE, 1 80 | 81 | > ABRD_OVF, 9, 1 82 | = DISABLE, 0 83 | = ENABLE, 1 84 | 85 | IF = 0x0014 86 | > TXDONE, 2, 1 87 | = NOT_SET, 0 88 | = SET, 1 89 | 90 | > PARITYE, 3, 1 91 | = NOT_SET, 0 92 | = SET, 1 93 | 94 | > STOPE, 4, 1 95 | = NOT_SET, 0 96 | = SET, 1 97 | 98 | > RXTO, 5, 1 99 | = NOT_SET, 0 100 | = SET, 1 101 | 102 | > RXFIFO, 6, 1 103 | = NOT_SET, 0 104 | = SET, 1 105 | 106 | > TXFIFO, 7, 1 107 | = NOT_SET, 0 108 | = SET, 1 109 | 110 | > RXFIFO_OVF, 8, 1 111 | = NOT_SET, 0 112 | = SET, 1 113 | 114 | > ABRD_OVF, 9, 1 115 | = NOT_SET, 0 116 | = SET, 1 117 | 118 | > RXFIFO_EMPTY, 10, 1 119 | = NOT_SET, 0 120 | = SET, 1 121 | 122 | > RXFIFO_FULL, 11, 1 123 | = NOT_SET, 0 124 | = SET, 1 125 | 126 | > RXFIFO_HFULL, 12, 1 127 | = NOT_SET, 0 128 | = SET, 1 129 | 130 | > TXFIFO_EMPTY, 13, 1 131 | = NOT_SET, 0 132 | = SET, 1 133 | 134 | > TXFIFO_FULL, 14, 1 135 | = NOT_SET, 0 136 | = SET, 1 137 | 138 | > TXFIFO_HFULL, 15, 1 139 | = NOT_SET, 0 140 | = SET, 1 141 | 142 | > TXBUSY, 16, 1 143 | = NOT_SET, 0 144 | = SET, 1 145 | 146 | > RF_LEVEL, 17, 3 147 | = 0_8_BYTE, 0 148 | = 1_BYTE, 1 149 | = 2_BYTE, 2 150 | = 3_BYTE, 3 151 | = 4_BYTE, 4 152 | = 5_BYTE, 5 153 | = 6_BYTE, 6 154 | = 7_BYTE, 7 155 | 156 | > TF_LEVEL, 20, 3 157 | = 0_8_BYTE, 0 158 | = 1_BYTE, 1 159 | = 2_BYTE, 2 160 | = 3_BYTE, 3 161 | = 4_BYTE, 4 162 | = 5_BYTE, 5 163 | = 6_BYTE, 6 164 | = 7_BYTE, 7 165 | 166 | FIFO = 0x0018 167 | > RF_LEVEL, 0, 3 168 | = 1_BYTE, 0 169 | = 2_BYTE, 1 170 | = 3_BYTE, 2 171 | = 4_BYTE, 3 172 | = 5_BYTE, 4 173 | = 6_BYTE, 5 174 | = 7_BYTE, 6 175 | = 8_BYTE, 7 176 | 177 | > TF_LEVEL, 3, 3 178 | = 0_BYTE, 0 179 | = 1_BYTE, 1 180 | = 2_BYTE, 2 181 | = 3_BYTE, 3 182 | = 4_BYTE, 4 183 | = 5_BYTE, 5 184 | = 6_BYTE, 6 185 | = 7_BYTE, 7 186 | 187 | > RF_CLR, 6, 1 188 | = DISABLE, 0 189 | = ENABLE, 1 190 | 191 | > TF_CLR, 7, 1 192 | = DISABLE, 0 193 | = ENABLE, 1 194 | 195 | FC = 0x001C 196 | > CTSEN, 0, 1 197 | = DISABLE, 0 198 | = ENABLE, 1 199 | 200 | > RTSEN, 1, 1 201 | = DISABLE, 0 202 | = ENABLE, 1 203 | 204 | > CTSPOL, 2, 1 205 | = LOW, 0 206 | = HIGH, 1 207 | 208 | > RTSPOL, 3, 1 209 | = LOW, 0 210 | = HIGH, 1 211 | 212 | > CTS_SIGNAL, 4, 1 213 | = LOW, 0 214 | = HIGH, 1 215 | 216 | > RTS_SIGNAL, 5, 1 217 | = LOW, 0 218 | = HIGH, 1 219 | 220 | RXTO = 0x0020 221 | 222 | [UART0] 223 | @ = 0x4006B000, 0x800, $UART 224 | 225 | [UART1] 226 | @ = 0x4006B800, 0x800, $UART 227 | 228 | [UART2] 229 | @ = 0x4006C000, 0x800, $UART 230 | 231 | -------------------------------------------------------------------------------- /helper/battery.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "battery.h" 18 | #include "driver/backlight.h" 19 | #include "misc.h" 20 | #include "ui/battery.h" 21 | #include "ui/menu.h" 22 | #include "ui/ui.h" 23 | 24 | uint16_t gBatteryCalibration[6]; 25 | uint16_t gBatteryCurrentVoltage; 26 | uint16_t gBatteryCurrent; 27 | uint16_t gBatteryVoltages[4]; 28 | uint16_t gBatteryVoltageAverage; 29 | 30 | uint8_t gBatteryDisplayLevel; 31 | 32 | bool gChargingWithTypeC; 33 | bool gLowBattery; 34 | bool gLowBatteryBlink; 35 | 36 | volatile uint16_t gBatterySave; 37 | 38 | uint16_t gBatteryCheckCounter; 39 | 40 | void BATTERY_GetReadings(bool bDisplayBatteryLevel) 41 | { 42 | uint16_t Voltage; 43 | uint8_t PreviousBatteryLevel; 44 | 45 | PreviousBatteryLevel = gBatteryDisplayLevel; 46 | 47 | Voltage = (gBatteryVoltages[0] + gBatteryVoltages[1] + gBatteryVoltages[2] + gBatteryVoltages[3]) / 4; 48 | 49 | if (gBatteryCalibration[5] < Voltage) { 50 | gBatteryDisplayLevel = 6; 51 | } else if (gBatteryCalibration[4] < Voltage) { 52 | gBatteryDisplayLevel = 5; 53 | } else if (gBatteryCalibration[3] < Voltage) { 54 | gBatteryDisplayLevel = 4; 55 | } else if (gBatteryCalibration[2] < Voltage) { 56 | gBatteryDisplayLevel = 3; 57 | } else if (gBatteryCalibration[1] < Voltage) { 58 | gBatteryDisplayLevel = 2; 59 | } else if (gBatteryCalibration[0] < Voltage) { 60 | gBatteryDisplayLevel = 1; 61 | } else { 62 | gBatteryDisplayLevel = 0; 63 | } 64 | 65 | gBatteryVoltageAverage = (Voltage * 760) / gBatteryCalibration[3]; 66 | 67 | if ((gScreenToDisplay == DISPLAY_MENU) && gMenuCursor == MENU_VOL) { 68 | gUpdateDisplay = true; 69 | } 70 | if (gBatteryCurrent < 501) { 71 | if (gChargingWithTypeC) { 72 | gUpdateStatus = true; 73 | } 74 | gChargingWithTypeC = 0; 75 | } else { 76 | if (!gChargingWithTypeC) { 77 | gUpdateStatus = true; 78 | BACKLIGHT_TurnOn(); 79 | } 80 | gChargingWithTypeC = 1; 81 | } 82 | 83 | if (PreviousBatteryLevel != gBatteryDisplayLevel) { 84 | if (gBatteryDisplayLevel < 2) { 85 | gLowBattery = true; 86 | } else { 87 | gLowBattery = false; 88 | if (bDisplayBatteryLevel) { 89 | UI_DisplayBattery(gBatteryDisplayLevel); 90 | } 91 | } 92 | gLowBatteryCountdown = 0; 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /helper/battery.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BATTERY_H 18 | #define BATTERY_H 19 | 20 | #include 21 | #include 22 | 23 | extern uint16_t gBatteryCalibration[6]; 24 | extern uint16_t gBatteryCurrentVoltage; 25 | extern uint16_t gBatteryCurrent; 26 | extern uint16_t gBatteryVoltages[4]; 27 | extern uint16_t gBatteryVoltageAverage; 28 | 29 | extern uint8_t gBatteryDisplayLevel; 30 | 31 | extern bool gChargingWithTypeC; 32 | extern bool gLowBattery; 33 | extern bool gLowBatteryBlink; 34 | 35 | extern volatile uint16_t gBatterySave; 36 | 37 | extern uint16_t gBatteryCheckCounter; 38 | 39 | void BATTERY_GetReadings(bool bDisplayBatteryLevel); 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /helper/boot.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "app/aircopy.h" 18 | #include "bsp/dp32g030/gpio.h" 19 | #include "driver/bk4819.h" 20 | #include "driver/keyboard.h" 21 | #include "driver/gpio.h" 22 | #include "driver/system.h" 23 | #include "helper/boot.h" 24 | #include "misc.h" 25 | #include "radio.h" 26 | #include "settings.h" 27 | #include "ui/menu.h" 28 | #include "ui/ui.h" 29 | 30 | BOOT_Mode_t BOOT_GetMode(void) 31 | { 32 | KEY_Code_t Keys[2]; 33 | uint8_t i; 34 | 35 | for (i = 0; i < 2; i++) { 36 | if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT)) { 37 | return BOOT_MODE_NORMAL; 38 | } 39 | Keys[i] = KEYBOARD_Poll(); 40 | SYSTEM_DelayMs(20); 41 | } 42 | if (Keys[0] == Keys[1]) { 43 | gKeyReading0 = Keys[0]; 44 | gKeyReading1 = Keys[0]; 45 | gDebounceCounter = 2; 46 | if (Keys[0] == KEY_SIDE1) { 47 | return BOOT_MODE_F_LOCK; 48 | } 49 | #if defined(ENABLE_AIRCOPY) 50 | if (Keys[0] == KEY_SIDE2) { 51 | return BOOT_MODE_AIRCOPY; 52 | } 53 | #endif 54 | } 55 | 56 | return BOOT_MODE_NORMAL; 57 | } 58 | 59 | void BOOT_ProcessMode(BOOT_Mode_t Mode) 60 | { 61 | if (Mode == BOOT_MODE_F_LOCK) { 62 | gMenuCursor = MENU_350TX; 63 | gSubMenuSelection = gSetting_350TX; 64 | GUI_SelectNextDisplay(DISPLAY_MENU); 65 | gMenuListCount = 55; 66 | #if defined(ENABLE_ALARM) 67 | gMenuListCount++; 68 | #endif 69 | #if defined(ENABLE_NOAA) 70 | gMenuListCount++; 71 | #endif 72 | gF_LOCK = true; 73 | #if defined(ENABLE_AIRCOPY) 74 | } else if (Mode == BOOT_MODE_AIRCOPY) { 75 | gEeprom.DUAL_WATCH = DUAL_WATCH_OFF; 76 | gEeprom.BATTERY_SAVE = 0; 77 | gEeprom.VOX_SWITCH = false; 78 | gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF; 79 | gEeprom.AUTO_KEYPAD_LOCK = false; 80 | gEeprom.KEY_1_SHORT_PRESS_ACTION = 0; 81 | gEeprom.KEY_1_LONG_PRESS_ACTION = 0; 82 | gEeprom.KEY_2_SHORT_PRESS_ACTION = 0; 83 | gEeprom.KEY_2_LONG_PRESS_ACTION = 0; 84 | 85 | RADIO_InitInfo(gRxVfo, 205, 5, 41002500); 86 | gRxVfo->CHANNEL_BANDWIDTH = BANDWIDTH_NARROW; 87 | gRxVfo->OUTPUT_POWER = 0; 88 | RADIO_ConfigureSquelchAndOutputPower(gRxVfo); 89 | gCurrentVfo = gRxVfo; 90 | RADIO_SetupRegisters(true); 91 | BK4819_SetupAircopy(); 92 | BK4819_ResetFSK(); 93 | gAircopyState = AIRCOPY_READY; 94 | GUI_SelectNextDisplay(DISPLAY_AIRCOPY); 95 | #endif 96 | } else { 97 | GUI_SelectNextDisplay(DISPLAY_MAIN); 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /helper/boot.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef HELPER_BOOT_H 18 | #define HELPER_BOOT_H 19 | 20 | #include 21 | #include "driver/keyboard.h" 22 | 23 | enum BOOT_Mode_t { 24 | BOOT_MODE_NORMAL = 0U, 25 | BOOT_MODE_F_LOCK = 1U, 26 | BOOT_MODE_AIRCOPY = 2U, 27 | }; 28 | 29 | typedef enum BOOT_Mode_t BOOT_Mode_t; 30 | 31 | BOOT_Mode_t BOOT_GetMode(void); 32 | void BOOT_ProcessMode(BOOT_Mode_t Mode); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /init.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * Copyright 2023 Manuel Jedinger 4 | * https://github.com/manujedi 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | 21 | extern uint32_t __bss_start__[]; 22 | extern uint32_t __bss_end__[]; 23 | extern uint8_t flash_data_start[]; 24 | extern uint8_t sram_data_start[]; 25 | extern uint8_t sram_data_end[]; 26 | 27 | void BSS_Init(void); 28 | void DATA_Init(void); 29 | 30 | void BSS_Init(void) 31 | { 32 | uint32_t *pBss; 33 | 34 | for (pBss = __bss_start__; pBss < __bss_end__; pBss++) { 35 | *pBss = 0; 36 | } 37 | } 38 | 39 | void DATA_Init(void) 40 | { 41 | volatile uint32_t *pDataRam = (volatile uint32_t *)sram_data_start; 42 | volatile uint32_t *pDataFlash = (volatile uint32_t *)flash_data_start; 43 | uint32_t Size = (uint32_t)sram_data_end - (uint32_t)sram_data_start; 44 | uint32_t i; 45 | 46 | for (i = 0; i < Size / 4; i++) { 47 | *pDataRam++ = *pDataFlash++; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "app/app.h" 19 | #include "app/dtmf.h" 20 | #include "audio.h" 21 | #include "bsp/dp32g030/gpio.h" 22 | #include "bsp/dp32g030/syscon.h" 23 | #include "board.h" 24 | #include "driver/backlight.h" 25 | #include "driver/bk4819.h" 26 | #include "driver/gpio.h" 27 | #include "driver/system.h" 28 | #include "driver/systick.h" 29 | #if defined(ENABLE_UART) 30 | #include "driver/uart.h" 31 | #endif 32 | #include "helper/battery.h" 33 | #include "helper/boot.h" 34 | #include "misc.h" 35 | #include "radio.h" 36 | #include "settings.h" 37 | #include "ui/lock.h" 38 | #include "ui/welcome.h" 39 | 40 | #if defined(ENABLE_UART) 41 | static const char Version[] = "UV-K5 Firmware, Open Edition, OEFW-"GIT_HASH"\r\n"; 42 | #endif 43 | 44 | void _putchar(char c) 45 | { 46 | #if defined(ENABLE_UART) 47 | UART_Send((uint8_t *)&c, 1); 48 | #endif 49 | } 50 | 51 | void Main(void) 52 | { 53 | uint8_t i; 54 | 55 | // Enable clock gating of blocks we need. 56 | SYSCON_DEV_CLK_GATE = 0 57 | | SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE 58 | | SYSCON_DEV_CLK_GATE_GPIOB_BITS_ENABLE 59 | | SYSCON_DEV_CLK_GATE_GPIOC_BITS_ENABLE 60 | | SYSCON_DEV_CLK_GATE_UART1_BITS_ENABLE 61 | | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE 62 | | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE 63 | | SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE 64 | | SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE 65 | ; 66 | 67 | SYSTICK_Init(); 68 | BOARD_Init(); 69 | 70 | #if defined(ENABLE_UART) 71 | UART_Init(); 72 | UART_Send(Version, sizeof(Version)); 73 | #endif 74 | 75 | // Not implementing authentic device checks 76 | 77 | memset(&gEeprom, 0, sizeof(gEeprom)); 78 | memset(gDTMF_String, '-', sizeof(gDTMF_String)); 79 | gDTMF_String[14] = 0; 80 | 81 | BK4819_Init(); 82 | BOARD_ADC_GetBatteryInfo(&gBatteryCurrentVoltage, &gBatteryCurrent); 83 | BOARD_EEPROM_Init(); 84 | BOARD_EEPROM_LoadCalibration(); 85 | 86 | RADIO_ConfigureChannel(0, 2); 87 | RADIO_ConfigureChannel(1, 2); 88 | RADIO_SelectVfos(); 89 | RADIO_SetupRegisters(true); 90 | 91 | for (i = 0; i < 4; i++) { 92 | BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[i], &gBatteryCurrent); 93 | } 94 | 95 | BATTERY_GetReadings(false); 96 | if (!gChargingWithTypeC && !gBatteryDisplayLevel) { 97 | FUNCTION_Select(FUNCTION_POWER_SAVE); 98 | GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); 99 | gReducedService = true; 100 | } else { 101 | BOOT_Mode_t BootMode; 102 | uint8_t Channel; 103 | 104 | UI_DisplayWelcome(); 105 | BACKLIGHT_TurnOn(); 106 | SYSTEM_DelayMs(1000); 107 | gMenuListCount = 49; 108 | #if defined(ENABLE_ALARM) 109 | gMenuListCount++; 110 | #endif 111 | #if defined(ENABLE_NOAA) 112 | gMenuListCount++; 113 | #endif 114 | 115 | BootMode = BOOT_GetMode(); 116 | if (gEeprom.POWER_ON_PASSWORD < 1000000) { 117 | bIsInLockScreen = true; 118 | UI_DisplayLock(); 119 | bIsInLockScreen = false; 120 | } 121 | 122 | BOOT_ProcessMode(BootMode); 123 | 124 | GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); 125 | gUpdateStatus = true; 126 | AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); 127 | Channel = gEeprom.ScreenChannel[gEeprom.TX_VFO]; 128 | if (IS_MR_CHANNEL(Channel)) { 129 | AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); 130 | AUDIO_SetDigitVoice(2, Channel + 1); 131 | } else if (IS_FREQ_CHANNEL(Channel)) { 132 | AUDIO_SetVoiceID(1, VOICE_ID_FREQUENCY_MODE); 133 | } 134 | AUDIO_PlaySingleVoice(0); 135 | #if defined(ENABLE_NOAA) 136 | RADIO_ConfigureNOAA(); 137 | #endif 138 | } 139 | 140 | while (1) { 141 | APP_Update(); 142 | if (gNextTimeslice) { 143 | APP_TimeSlice10ms(); 144 | gNextTimeslice = false; 145 | } 146 | if (gNextTimeslice500ms) { 147 | APP_TimeSlice500ms(); 148 | gNextTimeslice500ms = false; 149 | } 150 | } 151 | } 152 | 153 | -------------------------------------------------------------------------------- /printf_config.h: -------------------------------------------------------------------------------- 1 | #define PRINTF_DISABLE_SUPPORT_LONG_LONG 2 | #define PRINTF_DISABLE_SUPPORT_EXPONENTIAL 3 | #define PRINTF_DISABLE_SUPPORT_PTRDIFF_T 4 | -------------------------------------------------------------------------------- /radio.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef RADIO_H 18 | #define RADIO_H 19 | 20 | #include 21 | #include 22 | #include "dcs.h" 23 | 24 | enum { 25 | MR_CH_SCANLIST1 = (1U << 7), 26 | MR_CH_SCANLIST2 = (1U << 6), 27 | MR_CH_BAND_MASK = 0x0FU, 28 | }; 29 | 30 | enum { 31 | RADIO_CHANNEL_UP = 0x01U, 32 | RADIO_CHANNEL_DOWN = 0xFFU, 33 | }; 34 | 35 | enum { 36 | BANDWIDTH_WIDE = 0U, 37 | BANDWIDTH_NARROW = 1U, 38 | }; 39 | 40 | enum PTT_ID_t { 41 | PTT_ID_OFF = 0U, 42 | PTT_ID_BOT = 1U, 43 | PTT_ID_EOT = 2U, 44 | PTT_ID_BOTH = 3U, 45 | }; 46 | 47 | typedef enum PTT_ID_t PTT_ID_t; 48 | 49 | enum STEP_Setting_t { 50 | STEP_2_5kHz, 51 | STEP_5_0kHz, 52 | STEP_6_25kHz, 53 | STEP_10_0kHz, 54 | STEP_12_5kHz, 55 | STEP_25_0kHz, 56 | STEP_8_33kHz, 57 | }; 58 | 59 | typedef enum STEP_Setting_t STEP_Setting_t; 60 | 61 | enum VfoState_t { 62 | VFO_STATE_NORMAL = 0U, 63 | VFO_STATE_BUSY = 1U, 64 | VFO_STATE_BAT_LOW = 2U, 65 | VFO_STATE_TX_DISABLE = 3U, 66 | VFO_STATE_TIMEOUT = 4U, 67 | VFO_STATE_ALARM = 5U, 68 | VFO_STATE_VOL_HIGH = 6U, 69 | }; 70 | 71 | typedef enum VfoState_t VfoState_t; 72 | 73 | typedef struct { 74 | uint32_t Frequency; 75 | DCS_CodeType_t CodeType; 76 | uint8_t Code; 77 | uint8_t Padding[2]; 78 | } FREQ_Config_t; 79 | 80 | typedef struct VFO_Info_t { 81 | FREQ_Config_t ConfigRX; 82 | FREQ_Config_t ConfigTX; 83 | FREQ_Config_t *pRX; 84 | FREQ_Config_t *pTX; 85 | uint32_t FREQUENCY_OF_DEVIATION; 86 | uint16_t StepFrequency; 87 | uint8_t CHANNEL_SAVE; 88 | uint8_t FREQUENCY_DEVIATION_SETTING; 89 | uint8_t SquelchOpenRSSI; 90 | uint8_t SquelchOpenNoise; 91 | uint8_t SquelchCloseGlitch; 92 | uint8_t SquelchCloseRSSI; 93 | uint8_t SquelchCloseNoise; 94 | uint8_t SquelchOpenGlitch; 95 | STEP_Setting_t STEP_SETTING; 96 | uint8_t OUTPUT_POWER; 97 | uint8_t TXP_CalculatedSetting; 98 | bool FrequencyReverse; 99 | uint8_t SCRAMBLING_TYPE; 100 | uint8_t CHANNEL_BANDWIDTH; 101 | uint8_t SCANLIST1_PARTICIPATION; 102 | uint8_t SCANLIST2_PARTICIPATION; 103 | uint8_t Band; 104 | uint8_t DTMF_DECODING_ENABLE; 105 | PTT_ID_t DTMF_PTT_ID_TX_MODE; 106 | uint8_t BUSY_CHANNEL_LOCK; 107 | uint8_t AM_CHANNEL_MODE; 108 | bool IsAM; 109 | char Name[16]; 110 | } VFO_Info_t; 111 | 112 | extern VFO_Info_t *gTxVfo; 113 | extern VFO_Info_t *gRxVfo; 114 | extern VFO_Info_t *gCurrentVfo; 115 | 116 | extern DCS_CodeType_t gCurrentCodeType; 117 | extern DCS_CodeType_t gSelectedCodeType; 118 | extern uint8_t gSelectedCode; 119 | 120 | extern STEP_Setting_t gStepSetting; 121 | 122 | extern VfoState_t VfoState[2]; 123 | 124 | bool RADIO_CheckValidChannel(uint16_t ChNum, bool bCheckScanList, uint8_t RadioNum); 125 | uint8_t RADIO_FindNextChannel(uint8_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum); 126 | void RADIO_InitInfo(VFO_Info_t *pInfo, uint8_t ChannelSave, uint8_t ChIndex, uint32_t Frequency); 127 | void RADIO_ConfigureChannel(uint8_t RadioNum, uint32_t Arg); 128 | void RADIO_ConfigureSquelchAndOutputPower(VFO_Info_t *pInfo); 129 | void RADIO_ApplyOffset(VFO_Info_t *pInfo); 130 | void RADIO_SelectVfos(void); 131 | void RADIO_SetupRegisters(bool bSwitchToFunction0); 132 | void RADIO_ConfigureNOAA(void); 133 | void RADIO_SetTxParameters(void); 134 | 135 | void RADIO_SetVfoState(VfoState_t State); 136 | void RADIO_PrepareTX(void); 137 | void RADIO_EnableCxCSS(void); 138 | void RADIO_PrepareCssTX(void); 139 | void RADIO_SendEndOfTransmission(void); 140 | 141 | #endif 142 | 143 | -------------------------------------------------------------------------------- /scheduler.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #if defined(ENABLE_FMRADIO) 18 | #include "app/fm.h" 19 | #endif 20 | #include "app/scanner.h" 21 | #include "audio.h" 22 | #include "functions.h" 23 | #include "helper/battery.h" 24 | #include "misc.h" 25 | #include "settings.h" 26 | 27 | #define DECREMENT_AND_TRIGGER(cnt, flag) \ 28 | do { \ 29 | if (cnt) { \ 30 | if (--cnt == 0) { \ 31 | flag = true; \ 32 | } \ 33 | } \ 34 | } while(0) 35 | 36 | static volatile uint32_t gGlobalSysTickCounter; 37 | 38 | void SystickHandler(void); 39 | 40 | void SystickHandler(void) 41 | { 42 | gGlobalSysTickCounter++; 43 | gNextTimeslice = true; 44 | if ((gGlobalSysTickCounter % 50) == 0) { 45 | gNextTimeslice500ms = true; 46 | DECREMENT_AND_TRIGGER(gTxTimerCountdown, gTxTimeoutReached); 47 | } 48 | if ((gGlobalSysTickCounter & 3) == 0) { 49 | gNextTimeslice40ms = true; 50 | } 51 | if (gSystickCountdown2) { 52 | gSystickCountdown2--; 53 | } 54 | if (gFoundCDCSSCountdown) { 55 | gFoundCDCSSCountdown--; 56 | } 57 | if (gFoundCTCSSCountdown) { 58 | gFoundCTCSSCountdown--; 59 | } 60 | if (gCurrentFunction == FUNCTION_FOREGROUND) { 61 | DECREMENT_AND_TRIGGER(gBatterySaveCountdown, gSchedulePowerSave); 62 | } 63 | if (gCurrentFunction == FUNCTION_POWER_SAVE) { 64 | DECREMENT_AND_TRIGGER(gBatterySave, gBatterySaveCountdownExpired); 65 | } 66 | 67 | if (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) { 68 | if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) { 69 | if (gCurrentFunction != FUNCTION_RECEIVE) { 70 | DECREMENT_AND_TRIGGER(gDualWatchCountdown, gScheduleDualWatch); 71 | } 72 | } 73 | } 74 | 75 | #if defined(ENABLE_NOAA) 76 | if (gScanState == SCAN_OFF && gCssScanMode == CSS_SCAN_MODE_OFF && gEeprom.DUAL_WATCH == DUAL_WATCH_OFF) { 77 | if (gIsNoaaMode && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) { 78 | if (gCurrentFunction != FUNCTION_RECEIVE) { 79 | DECREMENT_AND_TRIGGER(gNOAA_Countdown, gScheduleNOAA); 80 | } 81 | } 82 | } 83 | #endif 84 | 85 | if (gScanState != SCAN_OFF || gCssScanMode == CSS_SCAN_MODE_SCANNING) { 86 | if (gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT) { 87 | DECREMENT_AND_TRIGGER(ScanPauseDelayIn10msec, gScheduleScanListen); 88 | } 89 | } 90 | 91 | DECREMENT_AND_TRIGGER(gTailNoteEliminationCountdown, gFlagTteComplete); 92 | 93 | DECREMENT_AND_TRIGGER(gCountdownToPlayNextVoice, gFlagPlayQueuedVoice); 94 | 95 | #if defined(ENABLE_FMRADIO) 96 | if (gFM_ScanState != FM_SCAN_OFF && gCurrentFunction != FUNCTION_MONITOR) { 97 | if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_RECEIVE) { 98 | DECREMENT_AND_TRIGGER(gFmPlayCountdown, gScheduleFM); 99 | } 100 | } 101 | #endif 102 | if (gVoxStopCountdown) { 103 | gVoxStopCountdown--; 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /sram-overlay.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SRAM_OVERLAY_H 18 | #define SRAM_OVERLAY_H 19 | 20 | #include 21 | #include 22 | #include "driver/flash.h" 23 | 24 | extern uint32_t overlay_FLASH_MainClock __attribute__((section(".srambss"))); 25 | extern uint32_t overlay_FLASH_ClockMultiplier __attribute__((section(".srambss"))); 26 | extern uint32_t overlay_0x20000478 __attribute__((section(".srambss"))); 27 | 28 | void overlay_FLASH_RebootToBootloader(void) __attribute__((noreturn)) __attribute__((section(".sramtext"))); 29 | bool overlay_FLASH_IsBusy(void) __attribute__((section(".sramtext"))); 30 | bool overlay_FLASH_IsInitComplete(void) __attribute__((section(".sramtext"))); 31 | void overlay_FLASH_Start(void) __attribute__((section(".sramtext"))); 32 | void overlay_FLASH_Init(FLASH_READ_MODE ReadMode) __attribute__((section(".sramtext"))); 33 | void overlay_FLASH_MaskLock(void) __attribute__((section(".sramtext"))); 34 | void overlay_FLASH_SetMaskSel(FLASH_MASK_SELECTION Mask) __attribute__((section(".sramtext"))); 35 | void overlay_FLASH_MaskUnlock(void) __attribute__((section(".sramtext"))); 36 | void overlay_FLASH_Lock(void) __attribute__((section(".sramtext"))); 37 | void overlay_FLASH_Unlock(void) __attribute__((section(".sramtext"))); 38 | uint32_t overlay_FLASH_ReadByAHB(uint32_t Offset) __attribute__((section(".sramtext"))); 39 | uint32_t overlay_FLASH_ReadByAPB(uint32_t Offset) __attribute__((section(".sramtext"))); 40 | void overlay_FLASH_SetArea(FLASH_AREA Area) __attribute__((section(".sramtext"))); 41 | void overlay_FLASH_SetReadMode(FLASH_READ_MODE Mode) __attribute__((section(".sramtext"))); 42 | void overlay_FLASH_SetEraseTime(void) __attribute__((section(".sramtext"))); 43 | void overlay_FLASH_WakeFromDeepSleep(void) __attribute__((section(".sramtext"))); 44 | void overlay_FLASH_SetMode(FLASH_MODE Mode) __attribute__((section(".sramtext"))); 45 | void overlay_FLASH_SetProgramTime(void) __attribute__((section(".sramtext"))); 46 | void overlay_SystemReset(void) __attribute__((noreturn)) __attribute__((section(".sramtext"))); 47 | uint32_t overlay_FLASH_ReadNvrWord(uint32_t Offset) __attribute__((section(".sramtext"))); 48 | void overlay_FLASH_ConfigureTrimValues(void) __attribute__((section(".sramtext"))); 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /start.S: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Dual Tachyon 2 | # https://github.com/DualTachyon 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | .cpu cortex-m0 17 | .fpu softvfp 18 | .thumb 19 | 20 | .global Stack 21 | .global HandlerReset 22 | .global Main 23 | 24 | .global OVERLAY_Install 25 | .global BOARD_FLASH_Init 26 | .global BSS_Init 27 | 28 | .global SystickHandler 29 | .weak SystickHandler 30 | 31 | .section .text.isr 32 | 33 | Stack: 34 | .long 0x20003FF0 35 | Reset: 36 | .long HandlerReset + 1 37 | NMI: 38 | .long HandlerNMI + 1 39 | HardFault: 40 | .long HandlerHardFault + 1 41 | Reserved_10: 42 | .long 0 43 | Reserved_14: 44 | .long 0 45 | Reserved_18: 46 | .long 0 47 | Reserved_1C: 48 | .long 0 49 | Reserved_20: 50 | .long 0 51 | Reserved_24: 52 | .long 0 53 | Reserved_28: 54 | .long 0 55 | SVCall: 56 | .long HandlerSVCall + 1 57 | Reserved_30: 58 | .long 0 59 | Reserved_34: 60 | .long 0 61 | PendSV: 62 | .long HandlerPendSV + 1 63 | SysTick: 64 | .long SystickHandler + 1 65 | WWDT: 66 | .long HandlerWWDT + 1 67 | IWDT: 68 | .long HandlerIWDT + 1 69 | RTC: 70 | .long HandlerRTC + 1 71 | DMA: 72 | .long HandlerDMA + 1 73 | SARADC: 74 | .long HandlerSARADC + 1 75 | TIMER_BASE0: 76 | .long HandlerTIMER_BASE0 + 1 77 | TIMER_BASE1: 78 | .long HandlerTIMER_BASE1 + 1 79 | TIMER_PLUS0: 80 | .long HandlerTIMER_PLUS0 + 1 81 | TIMER_PLUS1: 82 | .long HandlerTIMER_PLUS1 + 1 83 | PWM_BASE0: 84 | .long HandlerPWM_BASE0 + 1 85 | PWM_BASE1: 86 | .long HandlerPWM_BASE1 + 1 87 | PWM_PLUS0: 88 | .long HandlerPWM_PLUS0 + 1 89 | PWM_PLUS1: 90 | .long HandlerPWM_PLUS1 + 1 91 | UART0: 92 | .long HandlerUART0 + 1 93 | UART1: 94 | .long HandlerUART1 + 1 95 | UART2: 96 | .long HandlerUART2 + 1 97 | SPI0: 98 | .long HandlerSPI0 + 1 99 | SPI1: 100 | .long HandlerSPI1 + 1 101 | IIC0: 102 | .long HandlerIIC0 + 1 103 | IIC1: 104 | .long HandlerIIC1 + 1 105 | CMP: 106 | .long HandlerCMP + 1 107 | TIMER_BASE2: 108 | .long HandlerTIMER_BASE2 + 1 109 | GPIOA5: 110 | .long HandlerGPIOA5 + 1 111 | GPIOA6: 112 | .long HandlerGPIOA6 + 1 113 | GPIOA7: 114 | .long HandlerGPIOA7 + 1 115 | GPIOB0: 116 | .long HandlerGPIOB0 + 1 117 | GPIOB1: 118 | .long HandlerGPIOB1 + 1 119 | GPIOC0: 120 | .long HandlerGPIOC0 + 1 121 | GPIOC1: 122 | .long HandlerGPIOC1 + 1 123 | GPIOA: 124 | .long HandlerGPIOA + 1 125 | GPIOB: 126 | .long HandlerGPIOB + 1 127 | GPIOC: 128 | .long HandlerGPIOC + 1 129 | 130 | .section .text 131 | 132 | HandlerNMI: 133 | b . 134 | 135 | HandlerHardFault: 136 | b . 137 | 138 | HandlerSVCall: 139 | b . 140 | 141 | HandlerPendSV: 142 | b . 143 | 144 | SystickHandler: 145 | bx lr 146 | 147 | HandlerWWDT: 148 | b . 149 | 150 | HandlerIWDT: 151 | b . 152 | 153 | HandlerRTC: 154 | b . 155 | 156 | HandlerDMA: 157 | b . 158 | 159 | HandlerSARADC: 160 | b . 161 | 162 | HandlerTIMER_BASE0: 163 | b . 164 | 165 | HandlerTIMER_BASE1: 166 | b . 167 | 168 | HandlerTIMER_PLUS0: 169 | b . 170 | 171 | HandlerTIMER_PLUS1: 172 | b . 173 | 174 | HandlerPWM_BASE0: 175 | b . 176 | 177 | HandlerPWM_BASE1: 178 | b . 179 | 180 | HandlerPWM_PLUS0: 181 | b . 182 | 183 | HandlerPWM_PLUS1: 184 | b . 185 | 186 | HandlerUART0: 187 | b . 188 | 189 | HandlerUART1: 190 | b . 191 | 192 | HandlerUART2: 193 | b . 194 | 195 | HandlerSPI0: 196 | b . 197 | 198 | HandlerSPI1: 199 | b . 200 | 201 | HandlerIIC0: 202 | b . 203 | 204 | HandlerIIC1: 205 | b . 206 | 207 | HandlerCMP: 208 | b . 209 | 210 | HandlerTIMER_BASE2: 211 | b . 212 | 213 | HandlerGPIOA5: 214 | b . 215 | 216 | HandlerGPIOA6: 217 | b . 218 | 219 | HandlerGPIOA7: 220 | b . 221 | 222 | HandlerGPIOB0: 223 | b . 224 | 225 | HandlerGPIOB1: 226 | b . 227 | 228 | HandlerGPIOC0: 229 | b . 230 | 231 | HandlerGPIOC1: 232 | b . 233 | 234 | HandlerGPIOA: 235 | b . 236 | 237 | HandlerGPIOB: 238 | b . 239 | 240 | HandlerGPIOC: 241 | b . 242 | 243 | HandlerReset: 244 | ldr r0, =0x20003FF0 245 | mov sp, r0 246 | bl DATA_Init 247 | bl BSS_Init 248 | #if defined(ENABLE_OVERLAY) 249 | bl BOARD_FLASH_Init 250 | #endif 251 | bl Main 252 | b . 253 | 254 | -------------------------------------------------------------------------------- /ui/aircopy.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "app/aircopy.h" 19 | #include "driver/st7565.h" 20 | #include "external/printf/printf.h" 21 | #include "misc.h" 22 | #include "radio.h" 23 | #include "ui/aircopy.h" 24 | #include "ui/helper.h" 25 | #include "ui/inputbox.h" 26 | 27 | void UI_DisplayAircopy(void) 28 | { 29 | char String[16]; 30 | 31 | memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); 32 | 33 | if (gAircopyState == AIRCOPY_READY) { 34 | strcpy(String, "AIR COPY(RDY)"); 35 | } else if (gAircopyState == AIRCOPY_TRANSFER) { 36 | strcpy(String, "AIR COPY"); 37 | } else { 38 | strcpy(String, "AIR COPY(CMP)"); 39 | } 40 | UI_PrintString(String, 2, 127, 0, 8, true); 41 | 42 | if (gInputBoxIndex == 0) { 43 | NUMBER_ToDigits(gRxVfo->ConfigRX.Frequency, String); 44 | UI_DisplayFrequency(String, 16, 2, 0, 0); 45 | UI_DisplaySmallDigits(2, String + 6, 97, 3); 46 | } else { 47 | UI_DisplayFrequency(gInputBox, 16, 2, 1, 0); 48 | } 49 | 50 | memset(String, 0, sizeof(String)); 51 | 52 | if (gAirCopyIsSendMode == 0) { 53 | sprintf(String, "RCV:%d E:%d", gAirCopyBlockNumber, gErrorsDuringAirCopy); 54 | } else if (gAirCopyIsSendMode == 1) { 55 | sprintf(String, "SND:%d", gAirCopyBlockNumber); 56 | } 57 | UI_PrintString(String, 2, 127, 4, 8, true); 58 | ST7565_BlitFullScreen(); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /ui/aircopy.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_AIRCOPY_H 18 | #define UI_AIRCOPY_H 19 | 20 | void UI_DisplayAircopy(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/battery.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "bitmaps.h" 19 | #include "driver/st7565.h" 20 | #include "functions.h" 21 | #include "ui/battery.h" 22 | 23 | void UI_DisplayBattery(uint8_t Level) 24 | { 25 | const uint8_t *pBitmap; 26 | bool bClearMode = false; 27 | 28 | if (gCurrentFunction != 1) { 29 | switch (Level) { 30 | case 0: 31 | pBitmap = NULL; 32 | bClearMode = true; 33 | break; 34 | case 1: 35 | pBitmap = BITMAP_BatteryLevel1; 36 | break; 37 | case 2: 38 | pBitmap = BITMAP_BatteryLevel2; 39 | break; 40 | case 3: 41 | pBitmap = BITMAP_BatteryLevel3; 42 | break; 43 | case 4: 44 | pBitmap = BITMAP_BatteryLevel4; 45 | break; 46 | default: 47 | pBitmap = BITMAP_BatteryLevel5; 48 | break; 49 | } 50 | ST7565_DrawLine(110, 0, 18, pBitmap, bClearMode); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /ui/battery.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_BATTERY_H 18 | #define UI_BATTERY_H 19 | 20 | #include 21 | 22 | void UI_DisplayBattery(uint8_t Level); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /ui/fmradio.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "app/fm.h" 19 | #include "driver/st7565.h" 20 | #include "external/printf/printf.h" 21 | #include "misc.h" 22 | #include "settings.h" 23 | #include "ui/fmradio.h" 24 | #include "ui/helper.h" 25 | #include "ui/inputbox.h" 26 | #include "ui/ui.h" 27 | 28 | void UI_DisplayFM(void) 29 | { 30 | uint8_t i; 31 | char String[16]; 32 | 33 | memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); 34 | 35 | memset(String, 0, sizeof(String)); 36 | strcpy(String, "FM"); 37 | 38 | UI_PrintString(String, 0, 127, 0, 12, true); 39 | memset(String, 0, sizeof(String)); 40 | 41 | if (gAskToSave) { 42 | strcpy(String, "SAVE?"); 43 | } else if (gAskToDelete) { 44 | strcpy(String, "DEL?"); 45 | } else { 46 | if (gFM_ScanState == FM_SCAN_OFF) { 47 | if (!gEeprom.FM_IsMrMode) { 48 | for (i = 0; i < 20; i++) { 49 | if (gEeprom.FM_FrequencyPlaying == gFM_Channels[i]) { 50 | sprintf(String, "VFO(CH%02d)", i + 1); 51 | break; 52 | } 53 | } 54 | if (i == 20) { 55 | strcpy(String, "VFO"); 56 | } 57 | } else { 58 | sprintf(String, "MR(CH%02d)", gEeprom.FM_SelectedChannel + 1); 59 | } 60 | } else { 61 | if (!gFM_AutoScan) { 62 | strcpy(String, "M-SCAN"); 63 | } else { 64 | sprintf(String, "A-SCAN(%d)", gFM_ChannelPosition + 1); 65 | } 66 | } 67 | } 68 | 69 | UI_PrintString(String, 0, 127, 2, 10, true); 70 | memset(String, 0, sizeof(String)); 71 | 72 | if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex)) { 73 | UI_GenerateChannelString(String, gFM_ChannelPosition); 74 | } else if (!gAskToDelete) { 75 | if (gInputBoxIndex == 0) { 76 | NUMBER_ToDigits(gEeprom.FM_FrequencyPlaying * 10000, String); 77 | UI_DisplayFrequency(String, 23, 4, false, true); 78 | } else { 79 | UI_DisplayFrequency(gInputBox, 23, 4, true, false); 80 | } 81 | ST7565_BlitFullScreen(); 82 | return; 83 | } else { 84 | sprintf(String, "CH-%02d", gEeprom.FM_SelectedChannel + 1); 85 | } 86 | 87 | UI_PrintString(String, 0, 127, 4, 10, true); 88 | ST7565_BlitFullScreen(); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /ui/fmradio.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_FM_H 18 | #define UI_FM_H 19 | 20 | void UI_DisplayFM(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/helper.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "driver/st7565.h" 19 | #include "external/printf/printf.h" 20 | #include "font.h" 21 | #include "ui/helper.h" 22 | #include "ui/inputbox.h" 23 | 24 | void UI_GenerateChannelString(char *pString, uint8_t Channel) 25 | { 26 | uint8_t i; 27 | 28 | if (gInputBoxIndex == 0) { 29 | sprintf(pString, "CH-%02d", Channel + 1); 30 | return; 31 | } 32 | 33 | pString[0] = 'C'; 34 | pString[1] = 'H'; 35 | pString[2] = '-'; 36 | 37 | for (i = 0; i < 2; i++) { 38 | if (gInputBox[i] == 10) { 39 | pString[i + 3] = '-'; 40 | } else { 41 | pString[i + 3] = gInputBox[i] + '0'; 42 | } 43 | } 44 | 45 | } 46 | 47 | void UI_GenerateChannelStringEx(char *pString, bool bShowPrefix, uint8_t ChannelNumber) 48 | { 49 | if (gInputBoxIndex) { 50 | uint8_t i; 51 | 52 | for (i = 0; i < 3; i++) { 53 | if (gInputBox[i] == 10) { 54 | pString[i] = '-'; 55 | } else { 56 | pString[i] = gInputBox[i] + '0'; 57 | } 58 | } 59 | return; 60 | } 61 | 62 | if (bShowPrefix) { 63 | sprintf(pString, "CH-%03d", ChannelNumber + 1); 64 | } else { 65 | if (ChannelNumber == 0xFF) { 66 | strcpy(pString, "NULL"); 67 | } else { 68 | sprintf(pString, "%03d", ChannelNumber + 1); 69 | } 70 | } 71 | } 72 | 73 | void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width, bool bCentered) 74 | { 75 | uint32_t i, Length; 76 | 77 | Length = strlen(pString); 78 | if (bCentered) { 79 | Start += (((End - Start) - (Length * Width)) + 1) / 2; 80 | } 81 | for (i = 0; i < Length; i++) { 82 | if (pString[i] >= ' ' && pString[i] < 0x7F) { 83 | uint8_t Index = pString[i] - ' '; 84 | memcpy(gFrameBuffer[Line + 0] + (i * Width) + Start, &gFontBig[Index][0], 8); 85 | memcpy(gFrameBuffer[Line + 1] + (i * Width) + Start, &gFontBig[Index][8], 8); 86 | } 87 | } 88 | } 89 | 90 | void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag) 91 | { 92 | uint8_t *pFb0, *pFb1; 93 | bool bCanDisplay; 94 | uint8_t i; 95 | 96 | pFb0 = gFrameBuffer[Y] + X; 97 | pFb1 = pFb0 + 128; 98 | 99 | bCanDisplay = false; 100 | for (i = 0; i < 3; i++) { 101 | const uint8_t Digit = pDigits[i]; 102 | 103 | if (bDisplayLeadingZero || bCanDisplay || Digit) { 104 | bCanDisplay = true; 105 | memcpy(pFb0 + (i * 13), gFontBigDigits[Digit] + 0, 13); 106 | memcpy(pFb1 + (i * 13), gFontBigDigits[Digit] + 13, 13); 107 | } else if (bFlag) { 108 | pFb1 -= 6; 109 | pFb0 -= 6; 110 | } 111 | } 112 | 113 | pFb1[0x27] = 0x60; 114 | pFb1[0x28] = 0x60; 115 | pFb1[0x29] = 0x60; 116 | 117 | for (i = 0; i < 3; i++) { 118 | const uint8_t Digit = pDigits[i + 3]; 119 | 120 | memcpy(pFb0 + (i * 13) + 42, gFontBigDigits[Digit] + 0, 13); 121 | memcpy(pFb1 + (i * 13) + 42, gFontBigDigits[Digit] + 13, 13); 122 | } 123 | } 124 | 125 | void UI_DisplaySmallDigits(uint8_t Size, const char *pString, uint8_t X, uint8_t Y) 126 | { 127 | uint8_t i; 128 | 129 | for (i = 0; i < Size; i++) { 130 | memcpy(gFrameBuffer[Y] + (i * 7) + X, gFontSmallDigits[(uint8_t)pString[i]], 7); 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /ui/helper.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_UI_H 18 | #define UI_UI_H 19 | 20 | #include 21 | #include 22 | 23 | void UI_GenerateChannelString(char *pString, uint8_t Channel); 24 | void UI_GenerateChannelStringEx(char *pString, bool bShowPrefix, uint8_t ChannelNumber); 25 | void UI_PrintString(const char *pString, uint8_t Start, uint8_t End, uint8_t Line, uint8_t Width, bool bCentered); 26 | void UI_DisplayFrequency(const char *pDigits, uint8_t X, uint8_t Y, bool bDisplayLeadingZero, bool bFlag); 27 | void UI_DisplaySmallDigits(uint8_t Size, const char *pString, uint8_t X, uint8_t Y); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /ui/inputbox.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "ui/inputbox.h" 19 | 20 | char gInputBox[8]; 21 | uint8_t gInputBoxIndex; 22 | 23 | void INPUTBOX_Append(char Digit) 24 | { 25 | if (gInputBoxIndex == 0) { 26 | memset(gInputBox, 10, sizeof(gInputBox)); 27 | } else if (gInputBoxIndex >= sizeof(gInputBox)) { 28 | return; 29 | } 30 | gInputBox[gInputBoxIndex++] = Digit; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ui/inputbox.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_INPUTBOX_H 18 | #define UI_INPUTBOX_H 19 | 20 | #include 21 | 22 | extern char gInputBox[8]; 23 | extern uint8_t gInputBoxIndex; 24 | 25 | void INPUTBOX_Append(char Digit); 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /ui/lock.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "ARMCM0.h" 19 | #if defined(ENABLE_UART) 20 | #include "app/uart.h" 21 | #endif 22 | #include "audio.h" 23 | #include "driver/keyboard.h" 24 | #include "driver/st7565.h" 25 | #include "misc.h" 26 | #include "settings.h" 27 | #include "ui/helper.h" 28 | #include "ui/inputbox.h" 29 | #include "ui/lock.h" 30 | 31 | static void Render(void) 32 | { 33 | char String[7]; 34 | uint8_t i; 35 | 36 | memset(gStatusLine, 0, sizeof(gStatusLine)); 37 | memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); 38 | strcpy(String, "LOCK"); 39 | UI_PrintString(String, 0, 127, 1, 10, true); 40 | for (i = 0; i < 6; i++) { 41 | if (gInputBox[i] == 10) { 42 | String[i] = '-'; 43 | } else { 44 | String[i] = '*'; 45 | } 46 | } 47 | String[6] = 0; 48 | UI_PrintString(String, 0, 127, 3, 12, true); 49 | ST7565_BlitStatusLine(); 50 | ST7565_BlitFullScreen(); 51 | } 52 | 53 | void UI_DisplayLock(void) 54 | { 55 | KEY_Code_t Key; 56 | BEEP_Type_t Beep; 57 | 58 | gUpdateDisplay = true; 59 | memset(gInputBox, 10, sizeof(gInputBox)); 60 | 61 | while (1) { 62 | while (!gNextTimeslice) { 63 | } 64 | // TODO: Original code doesn't do the below, but is needed for proper key debounce. 65 | gNextTimeslice = false; 66 | Key = KEYBOARD_Poll(); 67 | if (gKeyReading0 == Key) { 68 | gDebounceCounter++; 69 | if (gDebounceCounter == 2) { 70 | if (Key == KEY_INVALID) { 71 | gKeyReading1 = KEY_INVALID; 72 | } else { 73 | gKeyReading1 = Key; 74 | switch (Key) { 75 | case KEY_0: case KEY_1: case KEY_2: case KEY_3: 76 | case KEY_4: case KEY_5: case KEY_6: case KEY_7: 77 | case KEY_8: case KEY_9: 78 | INPUTBOX_Append(Key - KEY_0); 79 | if (gInputBoxIndex < 6) { 80 | Beep = BEEP_1KHZ_60MS_OPTIONAL; 81 | } else { 82 | uint32_t Password; 83 | 84 | gInputBoxIndex = 0; 85 | NUMBER_Get(gInputBox, &Password); 86 | if ((gEeprom.POWER_ON_PASSWORD * 100) == Password) { 87 | AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); 88 | return; 89 | } 90 | memset(gInputBox, 10, sizeof(gInputBox)); 91 | Beep = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; 92 | } 93 | AUDIO_PlayBeep(Beep); 94 | gUpdateDisplay = true; 95 | break; 96 | case KEY_EXIT: 97 | if (gInputBoxIndex) { 98 | gInputBoxIndex--; 99 | gInputBox[gInputBoxIndex] = 10; 100 | gUpdateDisplay = true; 101 | } 102 | AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL); 103 | default: 104 | break; 105 | } 106 | } 107 | gKeyBeingHeld = false; 108 | } 109 | } else { 110 | gDebounceCounter = 0; 111 | gKeyReading0 = Key; 112 | } 113 | 114 | #if defined(ENABLE_UART) 115 | if (UART_IsCommandAvailable()) { 116 | __disable_irq(); 117 | UART_HandleCommand(); 118 | __enable_irq(); 119 | } 120 | #endif 121 | 122 | if (gUpdateDisplay) { 123 | Render(); 124 | gUpdateDisplay = false; 125 | } 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /ui/lock.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_LOCK_H 18 | #define UI_LOCK_H 19 | 20 | void UI_DisplayLock(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/main.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_MAIN_H 18 | #define UI_MAIN_H 19 | 20 | void UI_DisplayMain(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/menu.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_MENU_H 18 | #define UI_MENU_H 19 | 20 | #include 21 | #include 22 | 23 | enum { 24 | MENU_SQL = 0, 25 | MENU_STEP, 26 | MENU_TXP, 27 | MENU_R_DCS, 28 | MENU_R_CTCS, 29 | MENU_T_DCS, 30 | MENU_T_CTCS, 31 | MENU_SFT_D, 32 | MENU_OFFSET, 33 | MENU_W_N, 34 | MENU_SCR, 35 | MENU_BCL, 36 | MENU_MEM_CH, 37 | MENU_SAVE, 38 | MENU_VOX, 39 | MENU_ABR, 40 | MENU_TDR, 41 | MENU_WX, 42 | MENU_BEEP, 43 | MENU_TOT, 44 | MENU_VOICE, 45 | MENU_SC_REV, 46 | MENU_MDF, 47 | MENU_AUTOLK, 48 | MENU_S_ADD1, 49 | MENU_S_ADD2, 50 | MENU_STE, 51 | MENU_RP_STE, 52 | MENU_MIC, 53 | MENU_1_CALL, 54 | MENU_S_LIST, 55 | MENU_SLIST1, 56 | MENU_SLIST2, 57 | #if defined(ENABLE_ALARM) 58 | MENU_AL_MOD, 59 | #endif 60 | MENU_ANI_ID, 61 | MENU_UPCODE, 62 | MENU_DWCODE, 63 | MENU_D_ST, 64 | MENU_D_RSP, 65 | MENU_D_HOLD, 66 | MENU_D_PRE, 67 | MENU_PTT_ID, 68 | MENU_D_DCD, 69 | MENU_D_LIST, 70 | MENU_PONMSG, 71 | MENU_ROGER, 72 | MENU_VOL, 73 | MENU_AM, 74 | #if defined(ENABLE_NOAA) 75 | MENU_NOAA_S, 76 | #endif 77 | MENU_DEL_CH, 78 | MENU_RESET, 79 | MENU_350TX, 80 | MENU_F_LOCK, 81 | MENU_200TX, 82 | MENU_500TX, 83 | MENU_350EN, 84 | MENU_SCREN, 85 | }; 86 | 87 | extern bool gIsInSubMenu; 88 | 89 | extern uint8_t gMenuCursor; 90 | extern int8_t gMenuScrollDirection; 91 | extern uint32_t gSubMenuSelection; 92 | 93 | void UI_DisplayMenu(void); 94 | 95 | #endif 96 | 97 | -------------------------------------------------------------------------------- /ui/rssi.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "bitmaps.h" 19 | #include "driver/st7565.h" 20 | #include "functions.h" 21 | #include "misc.h" 22 | #include "settings.h" 23 | #include "ui/rssi.h" 24 | #include "ui/ui.h" 25 | 26 | static void Render(uint8_t RssiLevel, uint8_t VFO) 27 | { 28 | uint8_t *pLine; 29 | uint8_t Line; 30 | bool bIsClearMode; 31 | 32 | if (gCurrentFunction == FUNCTION_TRANSMIT || gScreenToDisplay != DISPLAY_MAIN) { 33 | return; 34 | } 35 | 36 | if (VFO == 0) { 37 | pLine = gFrameBuffer[2]; 38 | Line = 3; 39 | } else { 40 | pLine = gFrameBuffer[6]; 41 | Line = 7; 42 | } 43 | 44 | memset(pLine, 0, 23); 45 | if (RssiLevel == 0) { 46 | pLine = NULL; 47 | bIsClearMode = true; 48 | } else { 49 | memcpy(pLine, BITMAP_Antenna, 5); 50 | memcpy(pLine + 5, BITMAP_AntennaLevel1, sizeof(BITMAP_AntennaLevel1)); 51 | if (RssiLevel >= 2) { 52 | memcpy(pLine + 8, BITMAP_AntennaLevel2, sizeof(BITMAP_AntennaLevel2)); 53 | } 54 | if (RssiLevel >= 3) { 55 | memcpy(pLine + 11, BITMAP_AntennaLevel3, sizeof(BITMAP_AntennaLevel3)); 56 | } 57 | if (RssiLevel >= 4) { 58 | memcpy(pLine + 14, BITMAP_AntennaLevel4, sizeof(BITMAP_AntennaLevel4)); 59 | } 60 | if (RssiLevel >= 5) { 61 | memcpy(pLine + 17, BITMAP_AntennaLevel5, sizeof(BITMAP_AntennaLevel5)); 62 | } 63 | if (RssiLevel >= 6) { 64 | memcpy(pLine + 20, BITMAP_AntennaLevel6, sizeof(BITMAP_AntennaLevel6)); 65 | } 66 | bIsClearMode = false; 67 | } 68 | 69 | ST7565_DrawLine(0, Line, 23 , pLine, bIsClearMode); 70 | } 71 | 72 | void UI_UpdateRSSI(uint16_t RSSI) 73 | { 74 | uint8_t Level; 75 | 76 | if (RSSI >= gEEPROM_RSSI_CALIB[gRxVfo->Band][3]) { 77 | Level = 6; 78 | } else if (RSSI >= gEEPROM_RSSI_CALIB[gRxVfo->Band][2]) { 79 | Level = 4; 80 | } else if (RSSI >= gEEPROM_RSSI_CALIB[gRxVfo->Band][1]) { 81 | Level = 2; 82 | } else if (RSSI >= gEEPROM_RSSI_CALIB[gRxVfo->Band][0]) { 83 | Level = 1; 84 | } else { 85 | Level = 0; 86 | } 87 | 88 | if (gVFO_RSSI_Level[gEeprom.RX_VFO] != Level) { 89 | gVFO_RSSI_Level[gEeprom.RX_VFO] = Level; 90 | Render(Level, gEeprom.RX_VFO); 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /ui/rssi.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_RSSI_H 18 | #define UI_RSSI_H 19 | 20 | void UI_UpdateRSSI(uint16_t RSSI); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/scanner.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include "app/scanner.h" 20 | #include "dcs.h" 21 | #include "driver/st7565.h" 22 | #include "external/printf/printf.h" 23 | #include "misc.h" 24 | #include "ui/helper.h" 25 | #include "ui/scanner.h" 26 | 27 | void UI_DisplayScanner(void) 28 | { 29 | char String[16]; 30 | bool bCentered; 31 | uint8_t Start; 32 | 33 | memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); 34 | memset(String, 0, sizeof(String)); 35 | 36 | if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) { 37 | sprintf(String, "FREQ:%.5f", gScanFrequency * 1e-05); 38 | } else { 39 | sprintf(String, "FREQ:**.*****"); 40 | } 41 | UI_PrintString(String, 2, 127, 1, 8, false); 42 | memset(String, 0, sizeof(String)); 43 | 44 | if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { 45 | sprintf(String, "CTC:******"); 46 | } else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { 47 | sprintf(String, "CTC:%.1fHz", CTCSS_Options[gScanCssResultCode] * 0.1); 48 | } else { 49 | sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]); 50 | } 51 | UI_PrintString(String, 2, 127, 3, 8, false); 52 | memset(String, 0, sizeof(String)); 53 | 54 | if (gScannerEditState == 2) { 55 | strcpy(String, "SAVE?"); 56 | Start = 0; 57 | bCentered = 1; 58 | } else { 59 | if (gScannerEditState == 1) { 60 | strcpy(String, "SAVE:"); 61 | UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel); 62 | } else if (gScanCssState < SCAN_CSS_STATE_FOUND) { 63 | strcpy(String, "SCAN"); 64 | memset(String + 4, '.', (gScanProgressIndicator & 7) + 1); 65 | } else { 66 | if (gScanCssState == SCAN_CSS_STATE_FOUND) { 67 | strcpy(String, "SCAN CMP."); 68 | } else { 69 | strcpy(String, "SCAN FAIL."); 70 | } 71 | } 72 | Start = 2; 73 | bCentered = 0; 74 | } 75 | 76 | UI_PrintString(String, Start, 127, 5, 8, bCentered); 77 | ST7565_BlitFullScreen(); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /ui/scanner.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_SCANNER_H 18 | #define UI_SCANNER_H 19 | 20 | void UI_DisplayScanner(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/status.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #if defined(ENABLE_FMRADIO) 19 | #include "app/fm.h" 20 | #endif 21 | #include "bitmaps.h" 22 | #include "driver/keyboard.h" 23 | #include "driver/st7565.h" 24 | #include "functions.h" 25 | #include "helper/battery.h" 26 | #include "misc.h" 27 | #include "settings.h" 28 | #include "ui/status.h" 29 | 30 | void UI_DisplayStatus(void) 31 | { 32 | memset(gStatusLine, 0, sizeof(gStatusLine)); 33 | if (gCurrentFunction == FUNCTION_POWER_SAVE) { 34 | memcpy(gStatusLine, BITMAP_PowerSave, sizeof(BITMAP_PowerSave)); 35 | } 36 | if (gBatteryDisplayLevel < 2) { 37 | if (gLowBatteryBlink == 1) { 38 | memcpy(gStatusLine + 110, BITMAP_BatteryLevel1, sizeof(BITMAP_BatteryLevel1)); 39 | } 40 | } else { 41 | if (gBatteryDisplayLevel == 2) { 42 | memcpy(gStatusLine + 110, BITMAP_BatteryLevel2, sizeof(BITMAP_BatteryLevel2)); 43 | } else if (gBatteryDisplayLevel == 3) { 44 | memcpy(gStatusLine + 110, BITMAP_BatteryLevel3, sizeof(BITMAP_BatteryLevel3)); 45 | } else if (gBatteryDisplayLevel == 4) { 46 | memcpy(gStatusLine + 110, BITMAP_BatteryLevel4, sizeof(BITMAP_BatteryLevel4)); 47 | } else { 48 | memcpy(gStatusLine + 110, BITMAP_BatteryLevel5, sizeof(BITMAP_BatteryLevel5)); 49 | } 50 | } 51 | if (gChargingWithTypeC) { 52 | memcpy(gStatusLine + 100, BITMAP_USB_C, sizeof(BITMAP_USB_C)); 53 | } 54 | if (gEeprom.KEY_LOCK) { 55 | memcpy(gStatusLine + 90, BITMAP_KeyLock, sizeof(BITMAP_KeyLock)); 56 | } else if (gWasFKeyPressed) { 57 | memcpy(gStatusLine + 90, BITMAP_F_Key, sizeof(BITMAP_F_Key)); 58 | } 59 | 60 | if (gEeprom.VOX_SWITCH) { 61 | memcpy(gStatusLine + 71, BITMAP_VOX, sizeof(BITMAP_VOX)); 62 | } 63 | if (gEeprom.CROSS_BAND_RX_TX != CROSS_BAND_OFF) { 64 | memcpy(gStatusLine + 58, BITMAP_WX, sizeof(BITMAP_WX)); 65 | } 66 | if (gEeprom.DUAL_WATCH != DUAL_WATCH_OFF) { 67 | memcpy(gStatusLine + 45, BITMAP_TDR, sizeof(BITMAP_TDR)); 68 | } 69 | if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF) { 70 | memcpy(gStatusLine + 34, BITMAP_VoicePrompt, sizeof(BITMAP_VoicePrompt)); 71 | } 72 | if (gSetting_KILLED) { 73 | memset(gStatusLine + 21, 0xFF, 10); 74 | } 75 | #if defined(ENABLE_FMRADIO) 76 | else if (gFmRadioMode) { 77 | memcpy(gStatusLine + 21, BITMAP_FM, sizeof(BITMAP_FM)); 78 | } 79 | #endif 80 | #if defined(ENABLE_NOAA) 81 | if (gIsNoaaMode) { 82 | memcpy(gStatusLine + 7, BITMAP_NOAA, sizeof(BITMAP_NOAA)); 83 | } 84 | #endif 85 | ST7565_BlitStatusLine(); 86 | } 87 | 88 | -------------------------------------------------------------------------------- /ui/status.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_STATUS_H 18 | #define UI_STATUS_H 19 | 20 | void UI_DisplayStatus(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /ui/ui.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "app/dtmf.h" 19 | #if defined(ENABLE_FMRADIO) 20 | #include "app/fm.h" 21 | #endif 22 | #include "app/scanner.h" 23 | #include "driver/keyboard.h" 24 | #include "misc.h" 25 | #if defined(ENABLE_AIRCOPY) 26 | #include "ui/aircopy.h" 27 | #endif 28 | #include "ui/fmradio.h" 29 | #include "ui/inputbox.h" 30 | #include "ui/main.h" 31 | #include "ui/menu.h" 32 | #include "ui/scanner.h" 33 | #include "ui/ui.h" 34 | 35 | GUI_DisplayType_t gScreenToDisplay; 36 | GUI_DisplayType_t gRequestDisplayScreen = DISPLAY_INVALID; 37 | 38 | uint8_t gAskForConfirmation; 39 | bool gAskToSave; 40 | bool gAskToDelete; 41 | 42 | void GUI_DisplayScreen(void) 43 | { 44 | switch (gScreenToDisplay) { 45 | case DISPLAY_MAIN: 46 | UI_DisplayMain(); 47 | break; 48 | #if defined(ENABLE_FMRADIO) 49 | case DISPLAY_FM: 50 | UI_DisplayFM(); 51 | break; 52 | #endif 53 | case DISPLAY_MENU: 54 | UI_DisplayMenu(); 55 | break; 56 | case DISPLAY_SCANNER: 57 | UI_DisplayScanner(); 58 | break; 59 | #if defined(ENABLE_AIRCOPY) 60 | case DISPLAY_AIRCOPY: 61 | UI_DisplayAircopy(); 62 | break; 63 | #endif 64 | default: 65 | break; 66 | } 67 | } 68 | 69 | void GUI_SelectNextDisplay(GUI_DisplayType_t Display) 70 | { 71 | if (Display != DISPLAY_INVALID) { 72 | if (gScreenToDisplay != Display) { 73 | gInputBoxIndex = 0; 74 | gIsInSubMenu = false; 75 | gCssScanMode = CSS_SCAN_MODE_OFF; 76 | gScanState = SCAN_OFF; 77 | #if defined(ENABLE_FMRADIO) 78 | gFM_ScanState = FM_SCAN_OFF; 79 | #endif 80 | gAskForConfirmation = 0; 81 | gDTMF_InputMode = false; 82 | gDTMF_InputIndex = 0; 83 | gF_LOCK = false; 84 | gAskToSave = false; 85 | gAskToDelete = false; 86 | if (gWasFKeyPressed) { 87 | gWasFKeyPressed = false; 88 | gUpdateStatus = true; 89 | } 90 | } 91 | gUpdateDisplay = true; 92 | gScreenToDisplay = Display; 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /ui/ui.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef GUI_H 18 | #define GUI_H 19 | 20 | #include 21 | #include 22 | 23 | enum GUI_DisplayType_t { 24 | DISPLAY_MAIN = 0x00U, 25 | #if defined(ENABLE_FMRADIO) 26 | DISPLAY_FM = 0x01U, 27 | #endif 28 | DISPLAY_MENU = 0x02U, 29 | DISPLAY_SCANNER = 0x03U, 30 | #if defined(ENABLE_AIRCOPY) 31 | DISPLAY_AIRCOPY = 0x04U, 32 | #endif 33 | DISPLAY_INVALID = 0xFFU, 34 | }; 35 | 36 | typedef enum GUI_DisplayType_t GUI_DisplayType_t; 37 | 38 | extern GUI_DisplayType_t gScreenToDisplay; 39 | extern GUI_DisplayType_t gRequestDisplayScreen; 40 | 41 | extern uint8_t gAskForConfirmation; 42 | extern bool gAskToSave; 43 | extern bool gAskToDelete; 44 | 45 | void GUI_DisplayScreen(void); 46 | void GUI_SelectNextDisplay(GUI_DisplayType_t Display); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /ui/welcome.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include "driver/eeprom.h" 19 | #include "driver/st7565.h" 20 | #include "external/printf/printf.h" 21 | #include "helper/battery.h" 22 | #include "settings.h" 23 | #include "ui/helper.h" 24 | #include "ui/welcome.h" 25 | #include "version.h" 26 | 27 | void UI_DisplayWelcome(void) 28 | { 29 | char WelcomeString0[16]; 30 | char WelcomeString1[16]; 31 | 32 | memset(gStatusLine, 0, sizeof(gStatusLine)); 33 | memset(gFrameBuffer, 0, sizeof(gFrameBuffer)); 34 | 35 | if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) { 36 | ST7565_FillScreen(0xFF); 37 | } else { 38 | memset(WelcomeString0, 0, sizeof(WelcomeString0)); 39 | memset(WelcomeString1, 0, sizeof(WelcomeString1)); 40 | if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_VOLTAGE) { 41 | sprintf(WelcomeString0, "VOLTAGE"); 42 | sprintf(WelcomeString1, "%.2fV", gBatteryVoltageAverage * 0.01); 43 | } else { 44 | EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16); 45 | EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16); 46 | } 47 | UI_PrintString(WelcomeString0, 0, 127, 1, 10, true); 48 | UI_PrintString(WelcomeString1, 0, 127, 3, 10, true); 49 | UI_PrintString(Version, 0, 127, 5, 10, true); 50 | ST7565_BlitStatusLine(); 51 | ST7565_BlitFullScreen(); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /ui/welcome.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef UI_WELCOME_H 18 | #define UI_WELCOME_H 19 | 20 | void UI_DisplayWelcome(void); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | const char Version[] = "OEFW-" GIT_HASH; 2 | 3 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Dual Tachyon 2 | * https://github.com/DualTachyon 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef VERSION_H 18 | #define VERSION_H 19 | 20 | extern const char Version[]; 21 | 22 | #endif 23 | 24 | --------------------------------------------------------------------------------