0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-27 13:51:25 +03:00

Initial commit

This commit is contained in:
OneOfEleven 2023-09-09 08:03:56 +01:00
parent 92305117f1
commit 54441e27d9
3388 changed files with 582553 additions and 0 deletions

147
Makefile Normal file
View File

@ -0,0 +1,147 @@
TARGET = firmware
BSP_DEFINITIONS := $(wildcard hardware/*/*.def)
BSP_HEADERS := $(patsubst hardware/%,bsp/%,$(BSP_DEFINITIONS))
BSP_HEADERS := $(patsubst %.def,%.h,$(BSP_HEADERS))
OBJS =
# Startup files
OBJS += start.o
OBJS += init.o
OBJS += sram-overlay.o
OBJS += external/printf/printf.o
# Drivers
OBJS += driver/adc.o
OBJS += driver/aes.o
OBJS += driver/backlight.o
OBJS += driver/bk1080.o
OBJS += driver/bk4819.o
OBJS += driver/crc.o
OBJS += driver/eeprom.o
OBJS += driver/flash.o
OBJS += driver/gpio.o
OBJS += driver/i2c.o
OBJS += driver/keyboard.o
OBJS += driver/spi.o
OBJS += driver/st7565.o
OBJS += driver/system.o
OBJS += driver/systick.o
OBJS += driver/uart.o
# Main
OBJS += app/action.o
OBJS += app/aircopy.o
OBJS += app/app.o
OBJS += app/dtmf.o
OBJS += app/fm.o
OBJS += app/generic.o
OBJS += app/main.o
OBJS += app/menu.o
OBJS += app/scanner.o
OBJS += app/uart.o
OBJS += audio.o
OBJS += bitmaps.o
OBJS += board.o
OBJS += dcs.o
OBJS += font.o
OBJS += frequencies.o
OBJS += functions.o
OBJS += helper/battery.o
OBJS += helper/boot.o
OBJS += misc.o
OBJS += radio.o
OBJS += scheduler.o
OBJS += settings.o
OBJS += ui/aircopy.o
OBJS += ui/battery.o
OBJS += ui/fmradio.o
OBJS += ui/helper.o
OBJS += ui/inputbox.o
OBJS += ui/lock.o
OBJS += ui/main.o
OBJS += ui/menu.o
OBJS += ui/rssi.o
OBJS += ui/scanner.o
OBJS += ui/status.o
OBJS += ui/ui.o
OBJS += ui/welcome.o
OBJS += version.o
OBJS += main.o
ifeq ($(OS),Windows_NT)
TOP := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
else
TOP := $(shell pwd)
endif
AS = arm-none-eabi-as
CC = arm-none-eabi-gcc
LD = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
#GIT_HASH := $(shell git rev-parse --short HEAD)
ASFLAGS = -mcpu=cortex-m0
CFLAGS = -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
#CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
LDFLAGS = -mcpu=cortex-m0 -nostartfiles -Wl,-T,firmware.ld
# compilation options
CFLAGS += -DDISABLE_NOAA
CFLAGS += -DDISABLE_VOICE
CFLAGS += -DDISABLE_AIRCOPY
CFLAGS += -DKEEP_MEM_NAME
#CFLAGS += -DDISABLE_ALARM
#CFLAGS += -DBAND_SCOPE
ifeq ($(DEBUG),1)
ASFLAGS += -g
CFLAGS += -g
LDFLAGS += -g
endif
INC =
INC += -I $(TOP)
INC += -I $(TOP)/external/CMSIS_5/CMSIS/Core/Include/
INC += -I $(TOP)/external/CMSIS_5/Device/ARM/ARMCM0/Include
LIBS =
DEPS = $(OBJS:.o=.d)
all: $(TARGET)
$(OBJCOPY) -O binary $< $<.bin
# -python fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
# -python3 fw-pack.py $<.bin $(GIT_HASH) $<.packed.bin
$(SIZE) $<
debug:
/opt/openocd/bin/openocd -c "bindto 0.0.0.0" -f interface/jlink.cfg -f dp32g030.cfg
flash:
/opt/openocd/bin/openocd -c "bindto 0.0.0.0" -f interface/jlink.cfg -f dp32g030.cfg -c "write_image firmware.bin 0; shutdown;"
version.o: .FORCE
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@ $(LIBS)
bsp/dp32g030/%.h: hardware/dp32g030/%.def
%.o: %.c | $(BSP_HEADERS)
$(CC) $(CFLAGS) $(INC) -c $< -o $@
%.o: %.S
$(AS) $(ASFLAGS) $< -o $@
.FORCE:
-include $(DEPS)
clean:
rm -f $(TARGET).bin $(TARGET) $(OBJS) $(DEPS)

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# Open reimplementation of the Quan Sheng UV K5 v2.1.27 firmware
This repository is a cloned and customized version of DualTachyon's firmware found here ..
https://github.com/DualTachyon/uv-k5-firmware
# User customization
This version you can customize at compile time by making various changes to the makefile.
You can edit those changes by (currently) editing the MakeFile, look for these lines ..
"# compilation options"
"CFLAGS += -DDISABLE_NOAA" .. remove NOAA channels option from the firmware
"CFLAGS += -DDISABLE_VOICE" .. remove spoken VOICES option from the firmware
"CFLAGS += -DDISABLE_AIRCOPY" .. remove AIRCOPY option
"CFLAGS += -DKEEP_MEM_NAME" .. don't wipe out the memory channel's name when saving a memory channel
"#CFLAGS += -DDISABLE_ALARM" .. not yet implemented
"#CFLAGS += -DBAND_SCOPE" .. not yet implemented
To enable the custom option just uncomment the line by removing the starting '#'.
# Other changes made
# Compiler
arm-none-eabi GCC version 10.3.1 is recommended, which is the current version on Ubuntu 22.04.03 LTS.
Other versions may generate a flash file that is too big.
You can get an appropriate version from: https://developer.arm.com/downloads/-/gnu-rm
# Building
To build the firmware, you need to fetch the submodules and then run make:
```
git submodule update --init --recursive --depth=1
make
```
You can also easily compile this in windows (will an an example shortly) meaning you no longer have to install a linux VM on Windows.
# Credits
Many thanks to various people on Telegram for putting up with me during this effort and helping:
* [Mikhail](https://github.com/fagci/)
* [Andrej](https://github.com/Tunas1337)
* @wagner
* @Lohtse Shar
* [@Matoz](https://github.com/spm81)
* @Davide
* @Ismo OH2FTG
* and others I forget
# License
Copyright 2023 Dual Tachyon
https://github.com/DualTachyon
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

302
app/action.c Normal file
View File

@ -0,0 +1,302 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/action.h"
#include "app/app.h"
#include "app/dtmf.h"
#include "app/fm.h"
#include "app/scanner.h"
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/bk1080.h"
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
static void ACTION_FlashLight(void)
{
switch (gFlashLightState)
{
case 0:
gFlashLightState++;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
break;
case 1:
gFlashLightState++;
break;
default:
gFlashLightState = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
}
}
void ACTION_Power(void)
{
if (++gTxVfo->OUTPUT_POWER > OUTPUT_POWER_HIGH)
gTxVfo->OUTPUT_POWER = OUTPUT_POWER_LOW;
gRequestSaveChannel = 1;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_POWER;
#endif
gRequestDisplayScreen = gScreenToDisplay;
}
static void ACTION_Monitor(void)
{
if (gCurrentFunction != FUNCTION_MONITOR)
{
RADIO_SelectVfos();
#ifndef DISABLE_NOAA
if (gRxVfo->CHANNEL_SAVE >= NOAA_CHANNEL_FIRST && gIsNoaaMode)
gNoaaChannel = gRxVfo->CHANNEL_SAVE - NOAA_CHANNEL_FIRST;
#endif
RADIO_SetupRegisters(true);
APP_StartListening(FUNCTION_MONITOR);
return;
}
if (gScanState != SCAN_OFF)
{
ScanPauseDelayIn10msec = 500;
gScheduleScanListen = false;
gScanPauseMode = true;
}
#ifndef DISABLE_NOAA
if (gEeprom.DUAL_WATCH == DUAL_WATCH_OFF && gIsNoaaMode)
{
gNOAA_Countdown = 500;
gScheduleNOAA = false;
}
#endif
RADIO_SetupRegisters(true);
if (gFmRadioMode)
{
FM_Start();
gRequestDisplayScreen = DISPLAY_FM;
}
else
gRequestDisplayScreen = gScreenToDisplay;
}
void ACTION_Scan(bool bRestart)
{
if (gFmRadioMode)
{
if (gCurrentFunction != FUNCTION_RECEIVE && gCurrentFunction != FUNCTION_MONITOR && gCurrentFunction != FUNCTION_TRANSMIT)
{
uint16_t Frequency;
GUI_SelectNextDisplay(DISPLAY_FM);
if (gFM_ScanState != FM_SCAN_OFF)
{
FM_PlayAndUpdate();
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
if (bRestart)
{
gFM_AutoScan = true;
gFM_ChannelPosition = 0;
FM_EraseChannels();
Frequency = gEeprom.FM_LowerLimit;
}
else
{
gFM_AutoScan = false;
gFM_ChannelPosition = 0;
Frequency = gEeprom.FM_FrequencyPlaying;
}
BK1080_GetFrequencyDeviation(Frequency);
FM_Tune(Frequency, 1, bRestart);
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_BEGIN;
#endif
}
}
}
else
if (gScreenToDisplay != DISPLAY_SCANNER)
{
RADIO_SelectVfos();
#ifndef DISABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
#endif
{
GUI_SelectNextDisplay(DISPLAY_MAIN);
if (gScanState != SCAN_OFF)
{
SCANNER_Stop();
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
else
{
CHANNEL_Next(true, 1);
#ifndef DISABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(true);
#endif
}
}
}
}
void ACTION_Vox(void)
{
gEeprom.VOX_SWITCH = !gEeprom.VOX_SWITCH;
gRequestSaveSettings = true;
gFlagReconfigureVfos = true;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_VOX;
#endif
gUpdateStatus = true;
}
static void ACTION_AlarmOr1750(bool b1750)
{
gInputBoxIndex = 0;
gAlarmState = b1750 ? ALARM_STATE_TX1750 : ALARM_STATE_TXALARM;
gAlarmRunningCounter = 0;
gFlagPrepareTX = true;
gRequestDisplayScreen = DISPLAY_MAIN;
}
void ACTION_FM(void)
{
if (gCurrentFunction != FUNCTION_TRANSMIT && gCurrentFunction != FUNCTION_MONITOR)
{
if (gFmRadioMode)
{
FM_TurnOff();
gInputBoxIndex = 0;
gVoxResumeCountdown = 80;
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
RADIO_SelectVfos();
RADIO_SetupRegisters(true);
FM_Start();
gInputBoxIndex = 0;
gRequestDisplayScreen = DISPLAY_FM;
}
}
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t Short;
uint8_t Long;
if (gScreenToDisplay == DISPLAY_MAIN && gDTMF_InputMode)
{
if (Key == KEY_SIDE1 && !bKeyHeld && bKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gDTMF_InputIndex)
{
gDTMF_InputBox[--gDTMF_InputIndex] = '-';
if (gDTMF_InputIndex)
{
gPttWasReleased = true;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
}
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
}
gPttWasReleased = true;
return;
}
if (Key == KEY_SIDE1)
{
Short = gEeprom.KEY_1_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_1_LONG_PRESS_ACTION;
}
else
{
Short = gEeprom.KEY_2_SHORT_PRESS_ACTION;
Long = gEeprom.KEY_2_LONG_PRESS_ACTION;
}
if (!bKeyHeld && bKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (bKeyHeld || bKeyPressed)
{
if (!bKeyHeld)
return;
Short = Long;
if (!bKeyPressed)
return;
}
switch (Short)
{
case 1:
ACTION_FlashLight();
break;
case 2:
ACTION_Power();
break;
case 3:
ACTION_Monitor();
break;
case 4:
ACTION_Scan(true);
break;
case 5:
ACTION_Vox();
break;
case 6:
ACTION_AlarmOr1750(false);
break;
case 7:
ACTION_FM();
break;
case 8:
ACTION_AlarmOr1750(true);
break;
}
}

33
app/action.h Normal file
View File

@ -0,0 +1,33 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_ACTION_H
#define APP_ACTION_H
#include "driver/keyboard.h"
//static void ACTION_FlashLight(void)
void ACTION_Power(void);
//static void ACTION_Monitor(void)
void ACTION_Scan(bool bFlag);
void ACTION_Vox(void);
//static void ACTION_AlarmOr1750(bool b1750)
void ACTION_FM(void);
void ACTION_Handle(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
#endif

231
app/aircopy.c Normal file
View File

@ -0,0 +1,231 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DISABLE_AIRCOPY
#include "app/aircopy.h"
#include "audio.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
#include "frequencies.h"
#include "misc.h"
#include "radio.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
static const uint16_t Obfuscation[8] = {0x6C16, 0xE614, 0x912E, 0x400D, 0x3521, 0x40D5, 0x0313, 0x80E9};
AIRCOPY_State_t gAircopyState;
uint16_t gAirCopyBlockNumber;
uint16_t gErrorsDuringAirCopy;
uint8_t gAirCopyIsSendMode;
uint16_t g_FSK_Buffer[36];
void AIRCOPY_SendMessage(void)
{
unsigned int i;
g_FSK_Buffer[1] = (gAirCopyBlockNumber & 0x3FF) << 6;
EEPROM_ReadBuffer(g_FSK_Buffer[1], &g_FSK_Buffer[2], 64);
g_FSK_Buffer[34] = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
for (i = 0; i < 34; i++)
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
if (++gAirCopyBlockNumber >= 0x78)
gAircopyState = AIRCOPY_COMPLETE;
RADIO_SetTxParameters();
BK4819_SendFSKData(g_FSK_Buffer);
BK4819_SetupPowerAmplifier(0, 0);
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1, false);
gAircopySendCountdown = 30;
}
void AIRCOPY_StorePacket(void)
{
uint16_t Status;
if (gFSKWriteIndex < 36)
return;
gFSKWriteIndex = 0;
gUpdateDisplay = true;
Status = BK4819_ReadRegister(BK4819_REG_0B);
BK4819_PrepareFSKReceive();
// Doc says bit 4 should be 1 = CRC OK, 0 = CRC FAIL, but original firmware checks for FAIL.
if ((Status & 0x0010U) == 0 && g_FSK_Buffer[0] == 0xABCD && g_FSK_Buffer[35] == 0xDCBA)
{
uint16_t CRC;
unsigned int i;
for (i = 0; i < 34; i++)
g_FSK_Buffer[i + 1] ^= Obfuscation[i % 8];
CRC = CRC_Calculate(&g_FSK_Buffer[1], 2 + 64);
if (g_FSK_Buffer[34] == CRC)
{
const uint16_t *pData;
uint16_t Offset;
Offset = g_FSK_Buffer[1];
if (Offset < 0x1E00)
{
pData = &g_FSK_Buffer[2];
for (i = 0; i < 8; i++)
{
EEPROM_WriteBuffer(Offset, pData);
pData += 4;
Offset += 8;
}
if (Offset == 0x1E00)
gAircopyState = AIRCOPY_COMPLETE;
gAirCopyBlockNumber++;
return;
}
}
}
gErrorsDuringAirCopy++;
}
static void AIRCOPY_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
uint32_t Frequency;
unsigned int i;
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_AIRCOPY;
if (gInputBoxIndex < 6)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
for (i = 0; i < 7; i++)
{
if (Frequency >= gLowerLimitFrequencyBandTable[i] && Frequency <= gUpperLimitFrequencyBandTable[i])
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRxVfo->Band = i;
Frequency += 75;
Frequency = FREQUENCY_FloorToStep(Frequency, gRxVfo->StepFrequency, 0);
gRxVfo->ConfigRX.Frequency = Frequency;
gRxVfo->ConfigTX.Frequency = Frequency;
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
gCurrentVfo = gRxVfo;
RADIO_SetupRegisters(true);
BK4819_SetupAircopy();
BK4819_ResetFSK();
return;
}
}
gRequestDisplayScreen = DISPLAY_AIRCOPY;
}
}
static void AIRCOPY_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (gInputBoxIndex == 0)
{
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gErrorsDuringAirCopy = 0;
gInputBoxIndex = 0;
gAirCopyIsSendMode = 0;
BK4819_PrepareFSKReceive();
gAircopyState = AIRCOPY_TRANSFER;
}
else
gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_AIRCOPY;
}
}
static void AIRCOPY_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
gFSKWriteIndex = 0;
gAirCopyBlockNumber = 0;
gInputBoxIndex = 0;
gAirCopyIsSendMode = 1;
g_FSK_Buffer[0] = 0xABCD;
g_FSK_Buffer[1] = 0;
g_FSK_Buffer[35] = 0xDCBA;
AIRCOPY_SendMessage();
GUI_DisplayScreen();
gAircopyState = AIRCOPY_TRANSFER;
}
}
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
AIRCOPY_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
AIRCOPY_Key_MENU(bKeyPressed, bKeyHeld);
break;
case KEY_EXIT:
AIRCOPY_Key_EXIT(bKeyPressed, bKeyHeld);
break;
default:
break;
}
}
#endif

47
app/aircopy.h Normal file
View File

@ -0,0 +1,47 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_AIRCOPY_H
#define APP_AIRCOPY_H
#ifndef DISABLE_AIRCOPY
#include "driver/keyboard.h"
enum AIRCOPY_State_t
{
AIRCOPY_READY = 0,
AIRCOPY_TRANSFER,
AIRCOPY_COMPLETE
};
typedef enum AIRCOPY_State_t AIRCOPY_State_t;
extern AIRCOPY_State_t gAircopyState;
extern uint16_t gAirCopyBlockNumber;
extern uint16_t gErrorsDuringAirCopy;
extern uint8_t gAirCopyIsSendMode;
extern uint16_t g_FSK_Buffer[36];
void AIRCOPY_SendMessage(void);
void AIRCOPY_StorePacket(void);
void AIRCOPY_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
#endif
#endif

1922
app/app.c Normal file

File diff suppressed because it is too large Load Diff

34
app/app.h Normal file
View File

@ -0,0 +1,34 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_APP_H
#define APP_APP_H
#include <stdbool.h>
#include "functions.h"
#include "radio.h"
void APP_EndTransmission(void);
void CHANNEL_Next(bool bFlag, int8_t Direction);
void APP_StartListening(FUNCTION_Type_t Function);
void APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t Step);
void APP_Update(void);
void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void);
#endif

371
app/dtmf.c Normal file
View File

@ -0,0 +1,371 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "app/fm.h"
#include "app/scanner.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/bk4819.h"
#include "driver/eeprom.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "dtmf.h"
#include "external/printf/printf.h"
#include "misc.h"
#include "settings.h"
#include "ui/ui.h"
char gDTMF_String[15];
char gDTMF_InputBox[15];
char gDTMF_Received[16];
bool gIsDtmfContactValid;
char gDTMF_ID[4];
char gDTMF_Caller[4];
char gDTMF_Callee[4];
DTMF_State_t gDTMF_State;
bool gDTMF_DecodeRing;
uint8_t gDTMF_DecodeRingCountdown;
uint8_t gDTMFChosenContact;
uint8_t gDTMF_WriteIndex;
uint8_t gDTMF_PreviousIndex;
uint8_t gDTMF_AUTO_RESET_TIME;
uint8_t gDTMF_InputIndex;
bool gDTMF_InputMode;
uint8_t gDTMF_RecvTimeout;
DTMF_CallState_t gDTMF_CallState;
DTMF_ReplyState_t gDTMF_ReplyState;
DTMF_CallMode_t gDTMF_CallMode;
bool gDTMF_IsTx;
uint8_t gDTMF_TxStopCountdown;
bool gDTMF_IsGroupCall;
bool DTMF_ValidateCodes(char *pCode, uint8_t Size)
{
uint8_t i;
if (pCode[0] == 0xFF || pCode[0] == 0)
return false;
for (i = 0; i < Size; i++)
{
if (pCode[i] == 0xFF || pCode[i] == 0)
{
pCode[i] = 0;
break;
}
if ((pCode[i] < '0' || pCode[i] > '9') && (pCode[i] < 'A' || pCode[i] > 'D') && pCode[i] != '*' && pCode[i] != '#')
return false;
}
return true;
}
bool DTMF_GetContact(uint8_t Index, char *pContact)
{
EEPROM_ReadBuffer(0x1C00 + (Index * 16), pContact, 16);
return ((pContact[0] - ' ') >= 0x5F) ? false : true;
}
bool DTMF_FindContact(const char *pContact, char *pResult)
{
char Contact [16];
uint8_t i, j;
for (i = 0; i < 16; i++)
{
if (!DTMF_GetContact(i, Contact))
return false;
for (j = 0; j < 3; j++)
if (pContact[j] != Contact[j + 8])
break;
if (j == 3)
{
memcpy(pResult, Contact, 8);
pResult[8] = 0;
return true;
}
}
return false;
}
char DTMF_GetCharacter(uint8_t Code)
{
switch (Code)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
return '0' + (char)Code;
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return '*';
case 15:
return '#';
}
return 0xFF;
}
bool DTMF_CompareMessage(const char *pMsg, const char *pTemplate, uint8_t Size, bool bCheckGroup)
{
uint8_t i;
for (i = 0; i < Size; i++)
{
if (pMsg[i] != pTemplate[i])
{
if (!bCheckGroup || pMsg[i] != gEeprom.DTMF_GROUP_CALL_CODE)
return false;
gDTMF_IsGroupCall = true;
}
}
return true;
}
bool DTMF_CheckGroupCall(const char *pMsg, uint32_t Size)
{
uint32_t i;
for (i = 0; i < Size; i++)
if (pMsg[i] == gEeprom.DTMF_GROUP_CALL_CODE)
break;
return (i != Size) ? true : false;
}
void DTMF_Append(char Code)
{
if (gDTMF_InputIndex == 0)
{
memset(gDTMF_InputBox, '-', sizeof(gDTMF_InputBox));
gDTMF_InputBox[14] = 0;
}
else
if (gDTMF_InputIndex >= sizeof(gDTMF_InputBox))
return;
gDTMF_InputBox[gDTMF_InputIndex++] = Code;
}
void DTMF_HandleRequest(void)
{
char String[20];
uint8_t Offset;
if (!gDTMF_RequestPending)
return;
gDTMF_RequestPending = false;
if (gScanState != SCAN_OFF || gCssScanMode != CSS_SCAN_MODE_OFF)
return;
if (!gRxVfo->DTMF_DECODING_ENABLE && !gSetting_KILLED)
return;
if (gDTMF_WriteIndex >= 9)
{
Offset = gDTMF_WriteIndex - 9;
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.KILL_CODE);
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true))
{
if (gEeprom.PERMIT_REMOTE_KILL)
{
gSetting_KILLED = true;
SETTINGS_SaveSettings();
gDTMF_ReplyState = DTMF_REPLY_AB;
if (gFmRadioMode)
{
FM_TurnOff();
GUI_SelectNextDisplay(DISPLAY_MAIN);
}
}
else
{
gDTMF_ReplyState = DTMF_REPLY_NONE;
}
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gUpdateDisplay = true;
gUpdateStatus = true;
return;
}
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, gEeprom.REVIVE_CODE);
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, true))
{
gSetting_KILLED = false;
SETTINGS_SaveSettings();
gDTMF_ReplyState = DTMF_REPLY_AB;
gDTMF_CallState = DTMF_CALL_STATE_NONE;
gUpdateDisplay = true;
gUpdateStatus = true;
return;
}
}
if (gDTMF_WriteIndex >= 2)
{
if (DTMF_CompareMessage(gDTMF_Received + (gDTMF_WriteIndex - 2), "AB", 2, true))
{
gDTMF_State = DTMF_STATE_TX_SUCC;
gUpdateDisplay = true;
return;
}
}
if (gDTMF_CallState == DTMF_CALL_STATE_CALL_OUT && gDTMF_CallMode == DTMF_CALL_MODE_NOT_GROUP && gDTMF_WriteIndex >= 9)
{
Offset = gDTMF_WriteIndex - 9;
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 9, false))
{
gDTMF_State = DTMF_STATE_CALL_OUT_RSP;
gUpdateDisplay = true;
}
}
if (gSetting_KILLED || gDTMF_CallState != DTMF_CALL_STATE_NONE)
return;
if (gDTMF_WriteIndex >= 7)
{
Offset = gDTMF_WriteIndex - 7;
sprintf(String, "%s%c", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE);
gDTMF_IsGroupCall = false;
if (DTMF_CompareMessage(gDTMF_Received + Offset, String, 4, true))
{
gDTMF_CallState = DTMF_CALL_STATE_RECEIVED;
memcpy(gDTMF_Callee, gDTMF_Received + Offset, 3);
memcpy(gDTMF_Caller, gDTMF_Received + Offset + 4, 3);
gUpdateDisplay = true;
switch (gEeprom.DTMF_DECODE_RESPONSE)
{
case 3:
gDTMF_DecodeRing = true;
gDTMF_DecodeRingCountdown = 20;
// Fallthrough
case 2:
gDTMF_ReplyState = DTMF_REPLY_AAAAA;
break;
case 1:
gDTMF_DecodeRing = true;
gDTMF_DecodeRingCountdown = 20;
break;
default:
gDTMF_DecodeRing = false;
gDTMF_ReplyState = DTMF_REPLY_NONE;
break;
}
if (gDTMF_IsGroupCall)
gDTMF_ReplyState = DTMF_REPLY_NONE;
}
}
}
void DTMF_Reply(void)
{
char String[20];
const char *pString;
uint16_t Delay;
switch (gDTMF_ReplyState)
{
case DTMF_REPLY_ANI:
if (gDTMF_CallMode == DTMF_CALL_MODE_DTMF)
{
pString = gDTMF_String;
}
else
{
sprintf(String, "%s%c%s", gDTMF_String, gEeprom.DTMF_SEPARATE_CODE, gEeprom.ANI_DTMF_ID);
pString = String;
}
break;
case DTMF_REPLY_AB:
pString = "AB";
break;
case DTMF_REPLY_AAAAA:
sprintf(String, "%s%c%s", gEeprom.ANI_DTMF_ID, gEeprom.DTMF_SEPARATE_CODE, "AAAAA");
pString = String;
break;
default:
if (gDTMF_CallState != DTMF_CALL_STATE_NONE || (gCurrentVfo->DTMF_PTT_ID_TX_MODE != PTT_ID_BOT && gCurrentVfo->DTMF_PTT_ID_TX_MODE != PTT_ID_BOTH))
{
gDTMF_ReplyState = DTMF_REPLY_NONE;
return;
}
pString = gEeprom.DTMF_UP_CODE;
break;
}
gDTMF_ReplyState = DTMF_REPLY_NONE;
Delay = gEeprom.DTMF_PRELOAD_TIME;
if (gEeprom.DTMF_SIDE_TONE)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = true;
Delay = gEeprom.DTMF_PRELOAD_TIME;
if (gEeprom.DTMF_PRELOAD_TIME < 60)
Delay = 60;
}
SYSTEM_DelayMs(Delay);
BK4819_EnterDTMF_TX(gEeprom.DTMF_SIDE_TONE);
BK4819_PlayDTMFString(
pString,
1,
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME,
gEeprom.DTMF_HASH_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_PERSIST_TIME,
gEeprom.DTMF_CODE_INTERVAL_TIME);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
BK4819_ExitDTMF_TX(false);
}

90
app/dtmf.h Normal file
View File

@ -0,0 +1,90 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DTMF_H
#define DTMF_H
#include <stdbool.h>
#include <stdint.h>
enum DTMF_State_t {
DTMF_STATE_0 = 0U,
DTMF_STATE_TX_SUCC = 1U,
DTMF_STATE_CALL_OUT_RSP = 2U,
};
typedef enum DTMF_State_t DTMF_State_t;
enum DTMF_CallState_t {
DTMF_CALL_STATE_NONE = 0U,
DTMF_CALL_STATE_CALL_OUT = 1U,
DTMF_CALL_STATE_RECEIVED = 2U,
};
typedef enum DTMF_CallState_t DTMF_CallState_t;
enum DTMF_ReplyState_t {
DTMF_REPLY_NONE = 0U,
DTMF_REPLY_ANI = 1U,
DTMF_REPLY_AB = 2U,
DTMF_REPLY_AAAAA = 3U,
};
typedef enum DTMF_ReplyState_t DTMF_ReplyState_t;
enum DTMF_CallMode_t {
DTMF_CALL_MODE_NOT_GROUP = 0U,
DTMF_CALL_MODE_GROUP = 1U,
DTMF_CALL_MODE_DTMF = 2U,
};
typedef enum DTMF_CallMode_t DTMF_CallMode_t;
extern char gDTMF_String[15];
extern char gDTMF_InputBox[15];
extern char gDTMF_Received[16];
extern bool gIsDtmfContactValid;
extern char gDTMF_ID[4];
extern char gDTMF_Caller[4];
extern char gDTMF_Callee[4];
extern DTMF_State_t gDTMF_State;
extern bool gDTMF_DecodeRing;
extern uint8_t gDTMF_DecodeRingCountdown;
extern uint8_t gDTMFChosenContact;
extern uint8_t gDTMF_WriteIndex;
extern uint8_t gDTMF_PreviousIndex;
extern uint8_t gDTMF_AUTO_RESET_TIME;
extern uint8_t gDTMF_InputIndex;
extern bool gDTMF_InputMode;
extern uint8_t gDTMF_RecvTimeout;
extern DTMF_CallState_t gDTMF_CallState;
extern DTMF_ReplyState_t gDTMF_ReplyState;
extern DTMF_CallMode_t gDTMF_CallMode;
extern bool gDTMF_IsTx;
extern uint8_t gDTMF_TxStopCountdown;
bool DTMF_ValidateCodes(char *pCode, uint8_t Size);
bool DTMF_GetContact(uint8_t Index, char *pContact);
bool DTMF_FindContact(const char *pContact, char *pResult);
char DTMF_GetCharacter(uint8_t Code);
bool DTMF_CompareMessage(const char *pDTMF, const char *pTemplate, uint8_t Size, bool bFlag);
bool DTMF_CheckGroupCall(const char *pDTMF, uint32_t Size);
void DTMF_Append(char Code);
void DTMF_HandleRequest(void);
void DTMF_Reply(void);
#endif

563
app/fm.c Normal file
View File

@ -0,0 +1,563 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "app/action.h"
#include "app/fm.h"
#include "app/generic.h"
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/bk1080.h"
#include "driver/eeprom.h"
#include "driver/gpio.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
uint16_t gFM_Channels[20];
bool gFmRadioMode;
uint8_t gFmRadioCountdown;
volatile uint16_t gFmPlayCountdown;
volatile int8_t gFM_ScanState;
bool gFM_AutoScan;
uint8_t gFM_ChannelPosition;
bool gFM_FoundFrequency;
bool gFM_AutoScan;
uint8_t gFM_ResumeCountdown;
uint16_t gFM_RestoreCountdown;
bool FM_CheckValidChannel(uint8_t Channel)
{
if (Channel < 20 && (gFM_Channels[Channel] >= 760 && gFM_Channels[Channel] < 1080)) {
return true;
}
return false;
}
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction)
{
uint8_t i;
for (i = 0; i < 20; i++) {
Channel %= 20;
if (FM_CheckValidChannel(Channel)) {
return Channel;
}
Channel += Direction;
}
return 0xFF;
}
int FM_ConfigureChannelState(void)
{
uint8_t Channel;
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
if (gEeprom.FM_IsMrMode) {
Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel, FM_CHANNEL_UP);
if (Channel == 0xFF) {
gEeprom.FM_IsMrMode = false;
return -1;
}
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
}
return 0;
}
void FM_TurnOff(void)
{
gFmRadioMode = false;
gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown = 0;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
BK1080_Init(0, false);
gUpdateStatus = true;
}
void FM_EraseChannels(void)
{
uint8_t i;
uint8_t Template[8];
memset(Template, 0xFF, sizeof(Template));
for (i = 0; i < 5; i++) {
EEPROM_WriteBuffer(0x0E40 + (i * 8), Template);
}
memset(gFM_Channels, 0xFF, sizeof(gFM_Channels));
}
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag)
{
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = false;
if (gFM_ScanState == FM_SCAN_OFF) {
gFmPlayCountdown = 120;
} else {
gFmPlayCountdown = 10;
}
gScheduleFM = false;
gFM_FoundFrequency = false;
gAskToSave = false;
gAskToDelete = false;
gEeprom.FM_FrequencyPlaying = Frequency;
if (!bFlag) {
Frequency += Step;
if (Frequency < gEeprom.FM_LowerLimit) {
Frequency = gEeprom.FM_UpperLimit;
} else if (Frequency > gEeprom.FM_UpperLimit) {
Frequency = gEeprom.FM_LowerLimit;
}
gEeprom.FM_FrequencyPlaying = Frequency;
}
gFM_ScanState = Step;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
}
void FM_PlayAndUpdate(void)
{
gFM_ScanState = FM_SCAN_OFF;
if (gFM_AutoScan) {
gEeprom.FM_IsMrMode = true;
gEeprom.FM_SelectedChannel = 0;
}
FM_ConfigureChannelState();
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
SETTINGS_SaveFM();
gFmPlayCountdown = 0;
gScheduleFM = false;
gAskToSave = false;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = true;
}
int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit)
{
uint16_t Test2;
uint16_t Deviation;
int ret = -1;
Test2 = BK1080_ReadRegister(BK1080_REG_07);
// This is supposed to be a signed value, but above function is unsigned
Deviation = BK1080_REG_07_GET_FREQD(Test2);
if (BK1080_REG_07_GET_SNR(Test2) >= 2) {
uint16_t Status;
Status = BK1080_ReadRegister(BK1080_REG_10);
if ((Status & BK1080_REG_10_MASK_AFCRL) == BK1080_REG_10_AFCRL_NOT_RAILED && BK1080_REG_10_GET_RSSI(Status) >= 10) {
// if (Deviation > -281 && Deviation < 280)
if (Deviation < 280 || Deviation > 3815) {
// not BLE(less than or equal)
if (Frequency > LowerLimit && (Frequency - BK1080_BaseFrequency) == 1) {
if (BK1080_FrequencyDeviation & 0x800) {
goto Bail;
}
if (BK1080_FrequencyDeviation < 20) {
goto Bail;
}
}
// not BLT(less than)
if (Frequency >= LowerLimit && (BK1080_BaseFrequency - Frequency) == 1) {
if ((BK1080_FrequencyDeviation & 0x800) == 0) {
goto Bail;
}
// if (BK1080_FrequencyDeviation > -21) {
if (BK1080_FrequencyDeviation > 4075) {
goto Bail;
}
}
ret = 0;
}
}
}
Bail:
BK1080_FrequencyDeviation = Deviation;
BK1080_BaseFrequency = Frequency;
return ret;
}
static void FM_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
#define STATE_FREQ_MODE 0
#define STATE_MR_MODE 1
#define STATE_SAVE 2
if (!bKeyHeld && bKeyPressed) {
if (!gWasFKeyPressed) {
uint8_t State;
if (gAskToDelete) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gAskToSave) {
State = STATE_SAVE;
} else {
if (gFM_ScanState != FM_SCAN_OFF) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gEeprom.FM_IsMrMode) {
State = STATE_MR_MODE;
} else {
State = STATE_FREQ_MODE;
}
}
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_FM;
if (State == STATE_FREQ_MODE) {
if (gInputBoxIndex == 1) {
if (gInputBox[0] > 1) {
gInputBox[1] = gInputBox[0];
gInputBox[0] = 0;
gInputBoxIndex = 2;
}
} else if (gInputBoxIndex > 3) {
uint32_t Frequency;
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
Frequency = Frequency / 10000;
if (Frequency < gEeprom.FM_LowerLimit || gEeprom.FM_UpperLimit < Frequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gRequestDisplayScreen = DISPLAY_FM;
return;
}
gEeprom.FM_SelectedFrequency = (uint16_t)Frequency;
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_FrequencyPlaying = gEeprom.FM_SelectedFrequency;
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
return;
}
} else if (gInputBoxIndex == 2) {
uint8_t Channel;
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 10) + gInputBox[1]) - 1;
if (State == STATE_MR_MODE) {
if (FM_CheckValidChannel(Channel))
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
return;
}
}
else
if (Channel < 20)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_FM;
gInputBoxIndex = 0;
gFM_ChannelPosition = Channel;
return;
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gWasFKeyPressed = false;
gUpdateStatus = true;
gRequestDisplayScreen = DISPLAY_FM;
switch (Key) {
case KEY_0:
ACTION_FM();
break;
case KEY_1:
gEeprom.FM_IsMrMode = !gEeprom.FM_IsMrMode;
if (!FM_ConfigureChannelState()) {
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
} else {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
break;
case KEY_2:
ACTION_Scan(true);
break;
case KEY_3:
ACTION_Scan(false);
break;
default:
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
}
}
}
static void FM_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (bKeyHeld) {
return;
}
if (!bKeyPressed) {
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF) {
if (gInputBoxIndex == 0) {
if (!gAskToSave && !gAskToDelete) {
ACTION_FM();
return;
}
gAskToSave = false;
gAskToDelete = false;
} else {
gInputBoxIndex--;
gInputBox[gInputBoxIndex] = 10;
if (gInputBoxIndex) {
if (gInputBoxIndex != 1) {
gRequestDisplayScreen = DISPLAY_FM;
return;
}
if (gInputBox[0] != 0) {
gRequestDisplayScreen = DISPLAY_FM;
return;
}
}
gInputBoxIndex = 0;
}
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
}
else
{
FM_PlayAndUpdate();
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
gRequestDisplayScreen = DISPLAY_FM;
}
static void FM_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
if (bKeyHeld) {
return;
}
if (!bKeyPressed) {
return;
}
gRequestDisplayScreen = DISPLAY_FM;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gFM_ScanState == FM_SCAN_OFF) {
if (!gEeprom.FM_IsMrMode) {
if (gAskToSave) {
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gAskToSave = false;
gRequestSaveFM = true;
} else {
gAskToSave = true;
}
} else {
if (gAskToDelete) {
gFM_Channels[gEeprom.FM_SelectedChannel] = 0xFFFF;
FM_ConfigureChannelState();
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestSaveFM = true;
gAskToDelete = false;
} else {
gAskToDelete = true;
}
}
} else {
if (gFM_AutoScan || !gFM_FoundFrequency) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
gInputBoxIndex = 0;
return;
} else if (gAskToSave) {
gFM_Channels[gFM_ChannelPosition] = gEeprom.FM_FrequencyPlaying;
gAskToSave = false;
gRequestSaveFM = true;
} else {
gAskToSave = true;
}
}
}
static void FM_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Step)
{
if (bKeyHeld || !bKeyPressed) {
if (gInputBoxIndex) {
return;
}
if (!bKeyPressed) {
return;
}
} else {
if (gInputBoxIndex) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gAskToSave) {
gRequestDisplayScreen = DISPLAY_FM;
gFM_ChannelPosition = NUMBER_AddWithWraparound(gFM_ChannelPosition, Step, 0, 19);
return;
}
if (gFM_ScanState != FM_SCAN_OFF) {
if (gFM_AutoScan) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
FM_Tune(gEeprom.FM_FrequencyPlaying, Step, false);
gRequestDisplayScreen = DISPLAY_FM;
return;
}
if (gEeprom.FM_IsMrMode) {
uint8_t Channel;
Channel = FM_FindNextChannel(gEeprom.FM_SelectedChannel + Step, Step);
if (Channel == 0xFF || gEeprom.FM_SelectedChannel == Channel) {
goto Bail;
}
gEeprom.FM_SelectedChannel = Channel;
gEeprom.FM_FrequencyPlaying = gFM_Channels[Channel];
} else {
uint16_t Frequency;
Frequency = gEeprom.FM_SelectedFrequency + Step;
if (Frequency < gEeprom.FM_LowerLimit) {
Frequency = gEeprom.FM_UpperLimit;
} else if (Frequency > gEeprom.FM_UpperLimit) {
Frequency = gEeprom.FM_LowerLimit;
}
gEeprom.FM_FrequencyPlaying = Frequency;
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
}
gRequestSaveFM = true;
Bail:
BK1080_SetFrequency(gEeprom.FM_FrequencyPlaying);
gRequestDisplayScreen = DISPLAY_FM;
}
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key) {
case KEY_0: case KEY_1: case KEY_2: case KEY_3:
case KEY_4: case KEY_5: case KEY_6: case KEY_7:
case KEY_8: case KEY_9:
FM_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
FM_Key_MENU(bKeyPressed, bKeyHeld);
return;
case KEY_UP:
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
break;
case KEY_DOWN:
FM_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
break;;
case KEY_EXIT:
FM_Key_EXIT(bKeyPressed, bKeyHeld);
break;
case KEY_F:
GENERIC_Key_F(bKeyPressed, bKeyHeld);
break;
case KEY_PTT:
GENERIC_Key_PTT(bKeyPressed);
break;
default:
if (!bKeyHeld && bKeyPressed) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
break;
}
}
void FM_Play(void)
{
if (!FM_CheckFrequencyLock(gEeprom.FM_FrequencyPlaying, gEeprom.FM_LowerLimit)) {
if (!gFM_AutoScan) {
gFmPlayCountdown = 0;
gFM_FoundFrequency = true;
if (!gEeprom.FM_IsMrMode) {
gEeprom.FM_SelectedFrequency = gEeprom.FM_FrequencyPlaying;
}
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = true;
GUI_SelectNextDisplay(DISPLAY_FM);
return;
}
if (gFM_ChannelPosition < 20) {
gFM_Channels[gFM_ChannelPosition++] = gEeprom.FM_FrequencyPlaying;
}
if (gFM_ChannelPosition >= 20) {
FM_PlayAndUpdate();
GUI_SelectNextDisplay(DISPLAY_FM);
return;
}
}
if (gFM_AutoScan && gEeprom.FM_FrequencyPlaying >= gEeprom.FM_UpperLimit) {
FM_PlayAndUpdate();
} else {
FM_Tune(gEeprom.FM_FrequencyPlaying, gFM_ScanState, false);
}
GUI_SelectNextDisplay(DISPLAY_FM);
}
void FM_Start(void)
{
gFmRadioMode = true;
gFM_ScanState = FM_SCAN_OFF;
gFM_RestoreCountdown = 0;
BK1080_Init(gEeprom.FM_FrequencyPlaying, true);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gEnableSpeaker = true;
gUpdateStatus = true;
}

59
app/fm.h Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_FM_H
#define APP_FM_H
#include "driver/keyboard.h"
#define FM_CHANNEL_UP 0x01
#define FM_CHANNEL_DOWN 0xFF
enum {
FM_SCAN_OFF = 0U,
};
extern uint16_t gFM_Channels[20];
extern bool gFmRadioMode;
extern uint8_t gFmRadioCountdown;
extern volatile uint16_t gFmPlayCountdown;
extern volatile int8_t gFM_ScanState;
extern bool gFM_AutoScan;
extern uint8_t gFM_ChannelPosition;
// Doubts about whether this should be signed or not.
extern uint16_t gFM_FrequencyDeviation;
extern bool gFM_FoundFrequency;
extern bool gFM_AutoScan;
extern uint8_t gFM_ResumeCountdown;
extern uint16_t gFM_RestoreCountdown;
bool FM_CheckValidChannel(uint8_t Channel);
uint8_t FM_FindNextChannel(uint8_t Channel, uint8_t Direction);
int FM_ConfigureChannelState(void);
void FM_TurnOff(void);
void FM_EraseChannels(void);
void FM_Tune(uint16_t Frequency, int8_t Step, bool bFlag);
void FM_PlayAndUpdate(void);
int FM_CheckFrequencyLock(uint16_t Frequency, uint16_t LowerLimit);
void FM_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void FM_Play(void);
void FM_Start(void);
#endif

223
app/generic.c Normal file
View File

@ -0,0 +1,223 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/app.h"
#include "app/fm.h"
#include "app/generic.h"
#include "app/menu.h"
#include "app/scanner.h"
#include "audio.h"
#include "driver/keyboard.h"
#include "dtmf.h"
#include "external/printf/printf.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld)
{
if (gInputBoxIndex)
{
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (bKeyHeld || !bKeyPressed)
{
if (bKeyHeld || bKeyPressed)
{
if (!bKeyHeld)
return;
if (!bKeyPressed)
return;
#ifndef DISABLE_VOICE
gAnotherVoiceID = gEeprom.KEY_LOCK ? VOICE_ID_UNLOCK : VOICE_ID_LOCK;
#endif
gEeprom.KEY_LOCK = !gEeprom.KEY_LOCK;
gRequestSaveSettings = true;
}
else
{
if ((gFmRadioMode || gScreenToDisplay != DISPLAY_MAIN) && gScreenToDisplay != DISPLAY_FM)
return;
gWasFKeyPressed = !gWasFKeyPressed;
#ifndef DISABLE_VOICE
if (!gWasFKeyPressed)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gUpdateStatus = true;
}
}
else
{
if (gScreenToDisplay != DISPLAY_FM)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
if (gFM_ScanState == FM_SCAN_OFF)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
gBeepToPlay = BEEP_440HZ_500MS;
gPttWasReleased = true;
}
}
void GENERIC_Key_PTT(bool bKeyPressed)
{
gInputBoxIndex = 0;
if (!bKeyPressed)
{
if (gScreenToDisplay == DISPLAY_MAIN)
{
if (gCurrentFunction == FUNCTION_TRANSMIT)
{
if (gFlagEndTransmission)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
}
else
{
APP_EndTransmission();
if (gEeprom.REPEATER_TAIL_TONE_ELIMINATION == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
else
gRTTECountdown = gEeprom.REPEATER_TAIL_TONE_ELIMINATION * 10;
}
gFlagEndTransmission = false;
gVOX_NoiseDetected = false;
}
RADIO_SetVfoState(VFO_STATE_NORMAL);
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
gInputBoxIndex = 0;
return;
}
if (gScanState != SCAN_OFF)
{
SCANNER_Stop();
gPttDebounceCounter = 0;
gPttIsPressed = false;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
if (gFM_ScanState == FM_SCAN_OFF)
{
if (gCssScanMode == CSS_SCAN_MODE_OFF)
{
if (gScreenToDisplay == DISPLAY_MENU || gScreenToDisplay == DISPLAY_FM)
{
gRequestDisplayScreen = DISPLAY_MAIN;
gInputBoxIndex = 0;
gPttIsPressed = false;
gPttDebounceCounter = 0;
return;
}
if (gScreenToDisplay != DISPLAY_SCANNER)
{
if (gCurrentFunction == FUNCTION_TRANSMIT && gRTTECountdown == 0)
{
gInputBoxIndex = 0;
return;
}
gFlagPrepareTX = true;
if (gDTMF_InputMode)
{
if (gDTMF_InputIndex || gDTMF_PreviousIndex)
{
if (gDTMF_InputIndex == 0)
gDTMF_InputIndex = gDTMF_PreviousIndex;
gDTMF_InputBox[gDTMF_InputIndex] = 0;
if (gDTMF_InputIndex == 3)
gDTMF_CallMode = DTMF_CheckGroupCall(gDTMF_InputBox, 3);
else
gDTMF_CallMode = DTMF_CALL_MODE_DTMF;
sprintf(gDTMF_String, "%s", gDTMF_InputBox);
gDTMF_PreviousIndex = gDTMF_InputIndex;
gDTMF_ReplyState = DTMF_REPLY_ANI;
gDTMF_State = DTMF_STATE_0;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gDTMF_InputMode = false;
gDTMF_InputIndex = 0;
return;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gFlagPrepareTX = true;
gInputBoxIndex = 0;
return;
}
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
}
else
{
MENU_StopCssScan();
gRequestDisplayScreen = DISPLAY_MENU;
}
}
else
{
FM_PlayAndUpdate();
gRequestDisplayScreen = DISPLAY_FM;
}
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
gPttWasPressed = true;
}

26
app/generic.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_GENERIC_H
#define APP_GENERIC_H
#include <stdbool.h>
void GENERIC_Key_F(bool bKeyPressed, bool bKeyHeld);
void GENERIC_Key_PTT(bool bKeyPressed);
#endif

621
app/main.c Normal file
View File

@ -0,0 +1,621 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "app/action.h"
#include "app/app.h"
#include "app/fm.h"
#include "app/generic.h"
#include "app/main.h"
#include "app/scanner.h"
#include "audio.h"
#include "dtmf.h"
#include "frequencies.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
uint8_t Band;
uint8_t Vfo = gEeprom.TX_CHANNEL;
if (bKeyHeld)
return;
if (!bKeyPressed)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (!gWasFKeyPressed)
{
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_MAIN;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
uint16_t Channel;
if (gInputBoxIndex != 3)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (!RADIO_CheckValidChannel(Channel, false, 0))
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.MrChannel[Vfo] = (uint8_t)Channel;
gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel;
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
#ifndef DISABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#endif
{
uint32_t Frequency;
if (gInputBoxIndex < 6)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gInputBoxIndex = 0;
NUMBER_Get(gInputBox, &Frequency);
if (gSetting_350EN || (4999990 < (Frequency - 35000000)))
{
unsigned int i;
for (i = 0; i < 7; i++)
{
if (Frequency <= gUpperLimitFrequencyBandTable[i] && (gLowerLimitFrequencyBandTable[i] <= Frequency))
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
if (gTxVfo->Band != i)
{
gTxVfo->Band = i;
gEeprom.ScreenChannel[Vfo] = i + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[Vfo] = i + FREQ_CHANNEL_FIRST;
SETTINGS_SaveVfoIndices();
RADIO_ConfigureChannel(Vfo, 2);
}
Frequency += 75;
gTxVfo->ConfigRX.Frequency = FREQUENCY_FloorToStep(
Frequency,
gTxVfo->StepFrequency,
gLowerLimitFrequencyBandTable[gTxVfo->Band]);
gRequestSaveChannel = 1;
return;
}
}
}
}
#ifndef DISABLE_NOAA
else
{
uint8_t Channel;
if (gInputBoxIndex != 2)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
gInputBoxIndex = 0;
Channel = (gInputBox[0] * 10) + gInputBox[1];
if (Channel >= 1 && Channel <= 10)
{
Channel += NOAA_CHANNEL_FIRST;
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gEeprom.NoaaChannel[Vfo] = Channel;
gEeprom.ScreenChannel[Vfo] = Channel;
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
}
#endif
gRequestDisplayScreen = DISPLAY_MAIN;
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
switch (Key)
{
case KEY_0:
ACTION_FM();
break;
case KEY_1:
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gWasFKeyPressed = false;
gUpdateStatus = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
Band = gTxVfo->Band + 1;
if (gSetting_350EN || Band != BAND5_350MHz)
{
if (BAND7_470MHz < Band)
Band = BAND1_50MHz;
}
else
Band = BAND6_400MHz;
gTxVfo->Band = Band;
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_MAIN;
break;
case KEY_2:
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_B;
else
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_A;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_B;
else
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
else
gEeprom.TX_CHANNEL = (Vfo == 0);
gRequestSaveSettings = 1;
gFlagReconfigureVfos = true;
gRequestDisplayScreen = DISPLAY_MAIN;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break;
case KEY_3:
#ifndef DISABLE_NOAA
if (gEeprom.VFO_OPEN && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gEeprom.VFO_OPEN)
#endif
{
uint8_t Channel;
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 0);
if (Channel != 0xFF)
{
gEeprom.ScreenChannel[Vfo] = Channel;
#ifndef DISABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, Channel + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
case KEY_4:
gWasFKeyPressed = false;
gUpdateStatus = true;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true;
gScanSingleFrequency = false;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
break;
case KEY_5:
// TODO: something wrong here !!
#ifndef DISABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL];
else
{
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
}
#else
//gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL];
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
#endif
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
case KEY_6:
ACTION_Power();
break;
case KEY_7:
ACTION_Vox();
break;
case KEY_8:
gTxVfo->FrequencyReverse = gTxVfo->FrequencyReverse == false;
gRequestSaveChannel = 1;
break;
case KEY_9:
if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0))
{
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
#ifndef DISABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
break;
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
default:
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gUpdateStatus = true;
gWasFKeyPressed = false;
break;
}
}
static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (!gFmRadioMode)
{
if (gScanState == SCAN_OFF)
{
if (gInputBoxIndex == 0)
return;
gInputBox[--gInputBoxIndex] = 10;
#ifndef DISABLE_VOICE
if (gInputBoxIndex == 0)
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
}
else
{
SCANNER_Stop();
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
#endif
}
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
ACTION_FM();
}
}
static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
bool bFlag;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
bFlag = (gInputBoxIndex == 0);
gInputBoxIndex = 0;
if (bFlag)
{
gFlagRefreshSetting = true;
gRequestDisplayScreen = DISPLAY_MENU;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_MENU;
#endif
}
else
{
gRequestDisplayScreen = DISPLAY_MAIN;
}
}
}
static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{
if (gInputBoxIndex)
{
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (bKeyHeld || !bKeyPressed)
{
if (bKeyHeld || bKeyPressed)
{
if (!bKeyHeld)
return;
if (!bKeyPressed)
return;
ACTION_Scan(false);
return;
}
#ifndef DISABLE_NOAA
if (gScanState == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
#else
if (gScanState == SCAN_OFF)
#endif
{
gDTMF_InputMode = true;
memcpy(gDTMF_InputBox, gDTMF_String, 15);
gDTMF_InputIndex = 0;
gRequestDisplayScreen = DISPLAY_MAIN;
return;
}
}
else
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (!gWasFKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
return;
}
gWasFKeyPressed = false;
gUpdateStatus = true;
#ifndef DISABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
}
else
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
#else
gFlagStartScan = true;
gScanSingleFrequency = true;
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
#endif
gPttWasReleased = true;
}
}
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
{
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
if (bKeyHeld || !bKeyPressed)
{
if (gInputBoxIndex)
return;
if (!bKeyPressed)
{
if (!bKeyHeld)
return;
if (IS_FREQ_CHANNEL(Channel))
return;
#ifndef DISABLE_VOICE
AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
return;
}
}
else
{
if (gInputBoxIndex)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScanState == SCAN_OFF)
{
#ifndef DISABLE_NOAA
if (IS_NOT_NOAA_CHANNEL(Channel))
#endif
{
uint8_t Next;
if (IS_FREQ_CHANNEL(Channel))
{
APP_SetFrequencyByStep(gTxVfo, Direction);
gRequestSaveChannel = 1;
return;
}
Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0);
if (Next == 0xFF)
return;
if (Channel == Next)
return;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Next;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Next;
if (!bKeyHeld)
{
#ifndef DISABLE_VOICE
AUDIO_SetDigitVoice(0, Next + 1);
gAnotherVoiceID = (VOICE_ID_t)0xFE;
#endif
}
}
#ifndef DISABLE_NOAA
else
{
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
gEeprom.NoaaChannel[gEeprom.TX_CHANNEL] = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
}
#endif
gRequestSaveVFO = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
return;
}
CHANNEL_Next(false, Direction);
gPttWasReleased = true;
}
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT)
{
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gDTMF_InputMode && !bKeyHeld && bKeyPressed)
{
const char Character = DTMF_GetCharacter(Key);
if (Character != 0xFF)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
DTMF_Append(Character);
gRequestDisplayScreen = DISPLAY_MAIN;
gPttWasReleased = true;
return;
}
}
// TODO: ???
if (KEY_PTT < Key)
{
Key = KEY_SIDE2;
}
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
MAIN_Key_MENU(bKeyPressed, bKeyHeld);
break;
case KEY_UP:
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
break;
case KEY_DOWN:
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
break;
case KEY_EXIT:
MAIN_Key_EXIT(bKeyPressed, bKeyHeld);
break;
case KEY_STAR:
MAIN_Key_STAR(bKeyPressed, bKeyHeld);
break;
case KEY_F:
GENERIC_Key_F(bKeyPressed, bKeyHeld);
break;
case KEY_PTT:
GENERIC_Key_PTT(bKeyPressed);
break;
default:
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
}
}

25
app/main.h Normal file
View File

@ -0,0 +1,25 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_MAIN_H
#define APP_MAIN_H
#include "driver/keyboard.h"
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
#endif

1295
app/menu.c Normal file

File diff suppressed because it is too large Load Diff

32
app/menu.h Normal file
View File

@ -0,0 +1,32 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_MENU_H
#define APP_MENU_H
#include "driver/keyboard.h"
int MENU_GetLimits(uint8_t Cursor, uint8_t *pMin, uint8_t *pMax);
void MENU_AcceptSetting(void);
void MENU_SelectNextCode(void);
void MENU_ShowCurrentSetting(void);
void MENU_StartCssScan(int8_t Direction);
void MENU_StopCssScan(void);
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
#endif

445
app/scanner.c Normal file
View File

@ -0,0 +1,445 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/generic.h"
#include "app/scanner.h"
#include "audio.h"
#include "driver/bk4819.h"
#include "frequencies.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
DCS_CodeType_t gScanCssResultType;
uint8_t gScanCssResultCode;
bool gFlagStartScan;
bool gFlagStopScan;
bool gScanSingleFrequency;
uint8_t gScannerEditState;
uint8_t gScanChannel;
uint32_t gScanFrequency;
bool gScanPauseMode;
SCAN_CssState_t gScanCssState;
volatile bool gScheduleScanListen = true;
volatile uint16_t ScanPauseDelayIn10msec;
uint8_t gScanProgressIndicator;
uint8_t gScanHitCount;
bool gScanUseCssResult;
uint8_t gScanState;
bool bScanKeepFrequency;
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
if (gScannerEditState == 1)
{
uint16_t Channel;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
INPUTBOX_Append(Key);
gRequestDisplayScreen = DISPLAY_SCANNER;
if (gInputBoxIndex < 3)
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
return;
}
gInputBoxIndex = 0;
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
if (IS_MR_CHANNEL(Channel))
{
#ifndef DISABLE_VOICE
gAnotherVoiceID = (VOICE_ID_t)Key;
#endif
gShowChPrefix = RADIO_CheckValidChannel(Channel, false, 0);
gScanChannel = (uint8_t)Channel;
return;
}
}
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
}
static void SCANNER_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
gRequestDisplayScreen = DISPLAY_MAIN;
gEeprom.CROSS_BAND_RX_TX = gBackupCROSS_BAND_RX_TX;
gUpdateStatus = true;
gFlagStopScan = true;
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
gFlagResetVfos = true;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
break;
case 1:
if (gInputBoxIndex)
{
gInputBox[--gInputBoxIndex] = 10;
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
}
// Fallthrough
case 2:
gScannerEditState = 0;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
}
}
}
static void SCANNER_Key_MENU(bool bKeyPressed, bool bKeyHeld)
{
uint8_t Channel;
if (bKeyHeld)
return;
if (!bKeyPressed)
return;
if (gScanCssState == SCAN_CSS_STATE_OFF && !gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (gScanCssState == SCAN_CSS_STATE_SCANNING)
{
if (gScanSingleFrequency)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
}
if (gScanCssState == SCAN_CSS_STATE_FAILED)
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
switch (gScannerEditState)
{
case 0:
if (!gScanSingleFrequency)
{
uint32_t Freq250;
uint32_t Freq625;
int16_t Delta250;
int16_t Delta625;
Freq250 = FREQUENCY_FloorToStep(gScanFrequency, 250, 0);
Freq625 = FREQUENCY_FloorToStep(gScanFrequency, 625, 0);
Delta250 = (short)gScanFrequency - (short)Freq250;
if (125 < Delta250)
{
Delta250 = 250 - Delta250;
Freq250 += 250;
}
Delta625 = (short)gScanFrequency - (short)Freq625;
if (312 < Delta625)
{
Delta625 = 625 - Delta625;
Freq625 += 625;
}
if (Delta625 < Delta250)
{
gStepSetting = STEP_6_25kHz;
gScanFrequency = Freq625;
}
else
{
gStepSetting = STEP_2_5kHz;
gScanFrequency = Freq250;
}
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
gScannerEditState = 1;
gScanChannel = gTxVfo->CHANNEL_SAVE;
gShowChPrefix = RADIO_CheckValidChannel(gTxVfo->CHANNEL_SAVE, false, 0);
}
else
{
gScannerEditState = 2;
}
gScanCssState = SCAN_CSS_STATE_FOUND;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_MEMORY_CHANNEL;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
break;
case 1:
if (gInputBoxIndex == 0)
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_SCANNER;
gScannerEditState = 2;
}
break;
case 2:
if (!gScanSingleFrequency)
{
RADIO_InitInfo(gTxVfo, gTxVfo->CHANNEL_SAVE, FREQUENCY_GetBand(gScanFrequency), gScanFrequency);
if (gScanUseCssResult)
{
gTxVfo->ConfigRX.CodeType = gScanCssResultType;
gTxVfo->ConfigRX.Code = gScanCssResultCode;
}
gTxVfo->ConfigTX = gTxVfo->ConfigRX;
gTxVfo->STEP_SETTING = gStepSetting;
}
else
{
RADIO_ConfigureChannel(0, 2);
RADIO_ConfigureChannel(1, 2);
gTxVfo->ConfigRX.CodeType = gScanCssResultType;
gTxVfo->ConfigRX.Code = gScanCssResultCode;
gTxVfo->ConfigTX.CodeType = gScanCssResultType;
gTxVfo->ConfigTX.Code = gScanCssResultCode;
}
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
{
Channel = gScanChannel;
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Channel;
}
else
{
Channel = gTxVfo->Band + FREQ_CHANNEL_FIRST;
gEeprom.FreqChannel[gEeprom.TX_CHANNEL] = Channel;
}
gTxVfo->CHANNEL_SAVE = Channel;
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
#ifndef DISABLE_VOICE
gAnotherVoiceID = VOICE_ID_CONFIRM;
#endif
gRequestDisplayScreen = DISPLAY_SCANNER;
gRequestSaveChannel = 2;
gScannerEditState = 0;
break;
default:
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
break;
}
}
static void SCANNER_Key_STAR(bool bKeyPressed, bool bKeyHeld)
{
if ((!bKeyHeld) && (bKeyPressed))
{
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gFlagStartScan = true;
}
return;
}
static void SCANNER_Key_UP_DOWN(bool bKeyPressed, bool pKeyHeld, int8_t Direction)
{
if (pKeyHeld)
{
if (!bKeyPressed)
return;
}
else
{
if (!bKeyPressed)
return;
gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
if (gScannerEditState == 1)
{
gScanChannel = NUMBER_AddWithWraparound(gScanChannel, Direction, 0, 199);
gShowChPrefix = RADIO_CheckValidChannel(gScanChannel, false, 0);
gRequestDisplayScreen = DISPLAY_SCANNER;
}
else
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
switch (Key)
{
case KEY_0:
case KEY_1:
case KEY_2:
case KEY_3:
case KEY_4:
case KEY_5:
case KEY_6:
case KEY_7:
case KEY_8:
case KEY_9:
SCANNER_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
break;
case KEY_MENU:
SCANNER_Key_MENU(bKeyPressed, bKeyHeld);
break;
case KEY_UP:
SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
break;
case KEY_DOWN:
SCANNER_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
break;
case KEY_EXIT:
SCANNER_Key_EXIT(bKeyPressed, bKeyHeld);
break;
case KEY_STAR:
SCANNER_Key_STAR(bKeyPressed, bKeyHeld);
break;
case KEY_PTT:
GENERIC_Key_PTT(bKeyPressed);
break;
default:
if (!bKeyHeld && bKeyPressed)
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
break;
}
}
void SCANNER_Start(void)
{
uint8_t BackupStep;
uint16_t BackupFrequency;
BK4819_StopScan();
RADIO_SelectVfos();
#ifndef DISABLE_NOAA
if (IS_NOAA_CHANNEL(gRxVfo->CHANNEL_SAVE))
gRxVfo->CHANNEL_SAVE = FREQ_CHANNEL_FIRST + 5;
#endif
BackupStep = gRxVfo->STEP_SETTING;
BackupFrequency = gRxVfo->StepFrequency;
RADIO_InitInfo(gRxVfo, gRxVfo->CHANNEL_SAVE, gRxVfo->Band, gRxVfo->pRX->Frequency);
gRxVfo->STEP_SETTING = BackupStep;
gRxVfo->StepFrequency = BackupFrequency;
RADIO_SetupRegisters(true);
#ifndef DISABLE_NOAA
gIsNoaaMode = false;
#endif
if (gScanSingleFrequency)
{
gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanFrequency = gRxVfo->pRX->Frequency;
gStepSetting = gRxVfo->STEP_SETTING;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
BK4819_SetScanFrequency(gScanFrequency);
}
else
{
gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF);
BK4819_EnableFrequencyScan();
}
gScanDelay = 21;
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
gScanHitCount = 0;
gScanUseCssResult = false;
gDTMF_RequestPending = false;
g_CxCSS_TAIL_Found = false;
g_CDCSS_Lost = false;
gCDCSSCodeType = 0;
g_CTCSS_Lost = false;
g_VOX_Lost = false;
g_SquelchLost = false;
gScannerEditState = 0;
gScanProgressIndicator = 0;
}
void SCANNER_Stop(void)
{
uint8_t Previous = gRestoreMrChannel;
gScanState = SCAN_OFF;
if (!bScanKeepFrequency)
{
if (IS_MR_CHANNEL(gNextMrChannel))
{
gEeprom.MrChannel[gEeprom.RX_CHANNEL] = gRestoreMrChannel;
gEeprom.ScreenChannel[gEeprom.RX_CHANNEL] = Previous;
RADIO_ConfigureChannel(gEeprom.RX_CHANNEL, 2);
}
else
{
gRxVfo->ConfigRX.Frequency = gRestoreFrequency;
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
}
RADIO_SetupRegisters(true);
gUpdateDisplay = true;
return;
}
if (!IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE))
{
RADIO_ApplyOffset(gRxVfo);
RADIO_ConfigureSquelchAndOutputPower(gRxVfo);
SETTINGS_SaveChannel(gRxVfo->CHANNEL_SAVE, gEeprom.RX_CHANNEL, gRxVfo, 1);
return;
}
SETTINGS_SaveVfoIndices();
}

59
app/scanner.h Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_SCANNER_H
#define APP_SCANNER_H
#include "dcs.h"
#include "driver/keyboard.h"
enum SCAN_CssState_t {
SCAN_CSS_STATE_OFF = 0U,
SCAN_CSS_STATE_SCANNING = 1U,
SCAN_CSS_STATE_FOUND = 2U,
SCAN_CSS_STATE_FAILED = 3U,
};
typedef enum SCAN_CssState_t SCAN_CssState_t;
enum {
SCAN_OFF = 0U,
};
extern DCS_CodeType_t gScanCssResultType;
extern uint8_t gScanCssResultCode;
extern bool gFlagStartScan;
extern bool gFlagStopScan;
extern bool gScanSingleFrequency;
extern uint8_t gScannerEditState;
extern uint8_t gScanChannel;
extern uint32_t gScanFrequency;
extern bool gScanPauseMode;
extern SCAN_CssState_t gScanCssState;
extern volatile bool gScheduleScanListen;
extern volatile uint16_t ScanPauseDelayIn10msec;
extern uint8_t gScanProgressIndicator;
extern uint8_t gScanHitCount;
extern bool gScanUseCssResult;
extern uint8_t gScanState;
extern bool bScanKeepFrequency;
void SCANNER_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
void SCANNER_Start(void);
void SCANNER_Stop(void);
#endif

520
app/uart.c Normal file
View File

@ -0,0 +1,520 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "app/fm.h"
#include "app/uart.h"
#include "board.h"
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/aes.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "sram-overlay.h"
#include "version.h"
#define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer))
typedef struct {
uint16_t ID;
uint16_t Size;
} Header_t;
typedef struct {
uint8_t Padding[2];
uint16_t ID;
} Footer_t;
typedef struct {
Header_t Header;
uint32_t Timestamp;
} CMD_0514_t;
typedef struct {
Header_t Header;
struct {
char Version[16];
bool bHasCustomAesKey;
bool bIsInLockScreen;
uint8_t Padding[2];
uint32_t Challenge[4];
} Data;
} REPLY_0514_t;
typedef struct {
Header_t Header;
uint16_t Offset;
uint8_t Size;
uint8_t Padding;
uint32_t Timestamp;
} CMD_051B_t;
typedef struct {
Header_t Header;
struct {
uint16_t Offset;
uint8_t Size;
uint8_t Padding;
uint8_t Data[128];
} Data;
} REPLY_051B_t;
typedef struct {
Header_t Header;
uint16_t Offset;
uint8_t Size;
bool bAllowPassword;
uint32_t Timestamp;
uint8_t Data[0];
} CMD_051D_t;
typedef struct {
Header_t Header;
struct {
uint16_t Offset;
} Data;
} REPLY_051D_t;
typedef struct {
Header_t Header;
struct {
uint16_t RSSI;
uint8_t ExNoiseIndicator;
uint8_t GlitchIndicator;
} Data;
} REPLY_0527_t;
typedef struct {
Header_t Header;
struct {
uint16_t Voltage;
uint16_t Current;
} Data;
} REPLY_0529_t;
typedef struct {
Header_t Header;
uint32_t Response[4];
} CMD_052D_t;
typedef struct {
Header_t Header;
struct {
bool bIsLocked;
uint8_t Padding[3];
} Data;
} REPLY_052D_t;
typedef struct {
Header_t Header;
uint32_t Timestamp;
} CMD_052F_t;
static const uint8_t Obfuscation[16] = { 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 };
static union {
uint8_t Buffer[256];
struct {
Header_t Header;
uint8_t Data[252];
};
} UART_Command;
static uint32_t Timestamp;
static uint16_t gUART_WriteIndex;
static bool bIsEncrypted = true;
static void SendReply(void *pReply, uint16_t Size)
{
Header_t Header;
Footer_t Footer;
uint8_t *pBytes;
uint16_t i;
if (bIsEncrypted) {
pBytes = (uint8_t *)pReply;
for (i = 0; i < Size; i++) {
pBytes[i] ^= Obfuscation[i % 16];
}
}
Header.ID = 0xCDAB;
Header.Size = Size;
UART_Send(&Header, sizeof(Header));
UART_Send(pReply, Size);
if (bIsEncrypted) {
Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF;
Footer.Padding[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF;
} else {
Footer.Padding[0] = 0xFF;
Footer.Padding[1] = 0xFF;
}
Footer.ID = 0xBADC;
UART_Send(&Footer, sizeof(Footer));
}
static void SendVersion(void)
{
REPLY_0514_t Reply;
Reply.Header.ID = 0x0515;
Reply.Header.Size = sizeof(Reply.Data);
strcpy(Reply.Data.Version, Version);
Reply.Data.bHasCustomAesKey = bHasCustomAesKey;
Reply.Data.bIsInLockScreen = bIsInLockScreen;
Reply.Data.Challenge[0] = gChallenge[0];
Reply.Data.Challenge[1] = gChallenge[1];
Reply.Data.Challenge[2] = gChallenge[2];
Reply.Data.Challenge[3] = gChallenge[3];
SendReply(&Reply, sizeof(Reply));
}
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{
uint8_t i;
uint32_t IV[4];
IV[0] = 0;
IV[1] = 0;
IV[2] = 0;
IV[3] = 0;
AES_Encrypt(pKey, IV, pIn, IV, true);
for (i = 0; i < 4; i++) {
if (IV[i] != pResponse[i]) {
return true;
}
}
return false;
}
static void CMD_0514(const uint8_t *pBuffer)
{
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer;
Timestamp = pCmd->Timestamp;
gFmRadioCountdown = 4;
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
SendVersion();
}
static void CMD_051B(const uint8_t *pBuffer)
{
const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer;
REPLY_051B_t Reply;
bool bLocked = false;
if (pCmd->Timestamp != Timestamp) {
return;
}
gFmRadioCountdown = 4;
memset(&Reply, 0, sizeof(Reply));
Reply.Header.ID = 0x051C;
Reply.Header.Size = pCmd->Size + 4;
Reply.Data.Offset = pCmd->Offset;
Reply.Data.Size = pCmd->Size;
if (bHasCustomAesKey) {
bLocked = gIsLocked;
}
if (!bLocked) {
EEPROM_ReadBuffer(pCmd->Offset, Reply.Data.Data, pCmd->Size);
}
SendReply(&Reply, pCmd->Size + 8);
}
static void CMD_051D(const uint8_t *pBuffer)
{
const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer;
REPLY_051D_t Reply;
bool bReloadEeprom;
bool bIsLocked;
if (pCmd->Timestamp != Timestamp) {
return;
}
bReloadEeprom = false;
gFmRadioCountdown = 4;
Reply.Header.ID = 0x051E;
Reply.Header.Size = sizeof(Reply.Data);
Reply.Data.Offset = pCmd->Offset;
bIsLocked = bHasCustomAesKey;
if (bHasCustomAesKey) {
bIsLocked = gIsLocked;
}
if (!bIsLocked) {
uint16_t i;
for (i = 0; i < (pCmd->Size / 8U); i++) {
uint16_t Offset = pCmd->Offset + (i * 8U);
if (Offset >= 0x0F30 && Offset < 0x0F40) {
if (!gIsLocked) {
bReloadEeprom = true;
}
}
if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !bIsInLockScreen || pCmd->bAllowPassword) {
EEPROM_WriteBuffer(Offset, &pCmd->Data[i * 8U]);
}
}
if (bReloadEeprom) {
BOARD_EEPROM_Init();
}
}
SendReply(&Reply, sizeof(Reply));
}
static void CMD_0527(void)
{
REPLY_0527_t Reply;
Reply.Header.ID = 0x0528;
Reply.Header.Size = sizeof(Reply.Data);
Reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF;
Reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F;
Reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63);
SendReply(&Reply, sizeof(Reply));
}
static void CMD_0529(void)
{
REPLY_0529_t Reply;
Reply.Header.ID = 0x52A;
Reply.Header.Size = sizeof(Reply.Data);
// Original doesn't actually send current!
BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current);
SendReply(&Reply, sizeof(Reply));
}
static void CMD_052D(const uint8_t *pBuffer)
{
const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer;
REPLY_052D_t Reply;
bool bIsLocked;
gFmRadioCountdown = 4;
Reply.Header.ID = 0x052E;
Reply.Header.Size = sizeof(Reply.Data);
bIsLocked = bHasCustomAesKey;
if (!bIsLocked) {
bIsLocked = IsBadChallenge(gCustomAesKey, gChallenge, pCmd->Response);
}
if (!bIsLocked) {
bIsLocked = IsBadChallenge(gDefaultAesKey, gChallenge, pCmd->Response);
if (bIsLocked) {
gTryCount++;
}
}
if (gTryCount < 3) {
if (!bIsLocked) {
gTryCount = 0;
}
} else {
gTryCount = 3;
bIsLocked = true;
}
gIsLocked = bIsLocked;
Reply.Data.bIsLocked = bIsLocked;
SendReply(&Reply, sizeof(Reply));
}
static void CMD_052F(const uint8_t *pBuffer)
{
const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer;
gEeprom.DUAL_WATCH = DUAL_WATCH_OFF;
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
gEeprom.RX_CHANNEL = 0;
gEeprom.DTMF_SIDE_TONE = false;
gEeprom.VfoInfo[0].FrequencyReverse = false;
gEeprom.VfoInfo[0].pRX = &gEeprom.VfoInfo[0].ConfigRX;
gEeprom.VfoInfo[0].pTX = &gEeprom.VfoInfo[0].ConfigTX;
gEeprom.VfoInfo[0].FREQUENCY_DEVIATION_SETTING = FREQUENCY_DEVIATION_OFF;
gEeprom.VfoInfo[0].DTMF_PTT_ID_TX_MODE = PTT_ID_OFF;
gEeprom.VfoInfo[0].DTMF_DECODING_ENABLE = false;
#ifndef DISABLE_NOAA
gIsNoaaMode = false;
#endif
if (gCurrentFunction == FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_FOREGROUND);
Timestamp = pCmd->Timestamp;
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
SendVersion();
}
bool UART_IsCommandAvailable(void)
{
uint16_t DmaLength;
uint16_t CommandLength;
uint16_t Index;
uint16_t TailIndex;
uint16_t Size;
uint16_t CRC;
uint16_t i;
DmaLength = DMA_CH0->ST & 0xFFFU;
while (1)
{
if (gUART_WriteIndex == DmaLength)
return false;
while (gUART_WriteIndex != DmaLength && UART_DMA_Buffer[gUART_WriteIndex] != 0xABU)
gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1);
if (gUART_WriteIndex == DmaLength)
return false;
if (gUART_WriteIndex < DmaLength)
CommandLength = DmaLength - gUART_WriteIndex;
else
CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - gUART_WriteIndex;
if (CommandLength < 8)
return 0;
if (UART_DMA_Buffer[DMA_INDEX(gUART_WriteIndex, 1)] == 0xCD)
break;
gUART_WriteIndex = DMA_INDEX(gUART_WriteIndex, 1);
}
Index = DMA_INDEX(gUART_WriteIndex, 2);
Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index];
if ((Size + 8) > sizeof(UART_DMA_Buffer))
{
gUART_WriteIndex = DmaLength;
return false;
}
if (CommandLength < (Size + 8))
return false;
Index = DMA_INDEX(Index, 2);
TailIndex = DMA_INDEX(Index, Size + 2);
if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA)
{
gUART_WriteIndex = DmaLength;
return false;
}
if (TailIndex < Index)
{
const uint16_t ChunkSize = sizeof(UART_DMA_Buffer) - Index;
memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, ChunkSize);
memcpy(UART_Command.Buffer + ChunkSize, UART_DMA_Buffer, TailIndex);
}
else
memcpy(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index);
TailIndex = DMA_INDEX(TailIndex, 2);
if (TailIndex < gUART_WriteIndex)
{
memset(UART_DMA_Buffer + gUART_WriteIndex, 0, sizeof(UART_DMA_Buffer) - gUART_WriteIndex);
memset(UART_DMA_Buffer, 0, TailIndex);
}
else
memset(UART_DMA_Buffer + gUART_WriteIndex, 0, TailIndex - gUART_WriteIndex);
gUART_WriteIndex = TailIndex;
if (UART_Command.Header.ID == 0x0514)
bIsEncrypted = false;
if (UART_Command.Header.ID == 0x6902)
bIsEncrypted = true;
if (bIsEncrypted)
for (i = 0; i < Size + 2; i++)
UART_Command.Buffer[i] ^= Obfuscation[i % 16];
CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);
return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true;
}
void UART_HandleCommand(void)
{
switch (UART_Command.Header.ID)
{
case 0x0514:
CMD_0514(UART_Command.Buffer);
break;
case 0x051B:
CMD_051B(UART_Command.Buffer);
break;
case 0x051D:
CMD_051D(UART_Command.Buffer);
break;
case 0x051F: // Not implementing non-authentic command
break;
case 0x0521: // Not implementing non-authentic command
break;
case 0x0527:
CMD_0527();
break;
case 0x0529:
CMD_0529();
break;
case 0x052D:
CMD_052D(UART_Command.Buffer);
break;
case 0x052F:
CMD_052F(UART_Command.Buffer);
break;
case 0x05DD:
overlay_FLASH_RebootToBootloader();
break;
}
}

26
app/uart.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_UART_H
#define APP_UART_H
#include <stdbool.h>
bool UART_IsCommandAvailable(void);
void UART_HandleCommand(void);
#endif

388
audio.c Normal file
View File

@ -0,0 +1,388 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app/fm.h"
#include "audio.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/bk1080.h"
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/systick.h"
#include "functions.h"
#include "misc.h"
#include "settings.h"
#include "ui/ui.h"
#ifndef DISABLE_VOICE
static const uint8_t VoiceClipLengthChinese[58] =
{
0x32, 0x32, 0x32, 0x37, 0x37, 0x32, 0x32, 0x32,
0x32, 0x37, 0x37, 0x32, 0x64, 0x64, 0x64, 0x64,
0x64, 0x69, 0x64, 0x69, 0x5A, 0x5F, 0x5F, 0x64,
0x64, 0x69, 0x64, 0x64, 0x69, 0x69, 0x69, 0x64,
0x64, 0x6E, 0x69, 0x5F, 0x64, 0x64, 0x64, 0x69,
0x69, 0x69, 0x64, 0x69, 0x64, 0x64, 0x55, 0x5F,
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
0x5A, 0x64,
};
static const uint8_t VoiceClipLengthEnglish[76] =
{
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
0x32, 0x32, 0x3C, 0x37, 0x46, 0x46, 0x4B, 0x82,
0x82, 0x6E, 0x82, 0x46, 0x96, 0x64, 0x46, 0x6E,
0x78, 0x6E, 0x87, 0x64, 0x96, 0x96, 0x46, 0x9B,
0x91, 0x82, 0x82, 0x73, 0x78, 0x64, 0x82, 0x6E,
0x78, 0x82, 0x87, 0x6E, 0x55, 0x78, 0x64, 0x69,
0x9B, 0x5A, 0x50, 0x3C, 0x32, 0x55, 0x64, 0x64,
0x50, 0x46, 0x46, 0x46, 0x4B, 0x4B, 0x50, 0x50,
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
0x41, 0x32, 0x3C, 0x37,
};
VOICE_ID_t gVoiceID[8];
uint8_t gVoiceReadIndex;
uint8_t gVoiceWriteIndex;
volatile uint16_t gCountdownToPlayNextVoice;
volatile bool gFlagPlayQueuedVoice;
VOICE_ID_t gAnotherVoiceID = VOICE_ID_INVALID;
#endif
BEEP_Type_t gBeepToPlay;
void AUDIO_PlayBeep(BEEP_Type_t Beep)
{
uint16_t ToneConfig;
uint16_t ToneFrequency;
uint16_t Duration;
if (Beep != BEEP_500HZ_60MS_DOUBLE_BEEP && Beep != BEEP_440HZ_500MS && !gEeprom.BEEP_CONTROL)
return;
#ifndef DISABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY)
return;
#endif
if (gCurrentFunction == FUNCTION_RECEIVE)
return;
if (gCurrentFunction == FUNCTION_MONITOR)
return;
ToneConfig = BK4819_ReadRegister(BK4819_REG_71);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_RX_TurnOn();
if (gFmRadioMode)
BK1080_Mute(true);
SYSTEM_DelayMs(20);
switch (Beep)
{
case BEEP_1KHZ_60MS_OPTIONAL:
ToneFrequency = 1000;
break;
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
ToneFrequency = 500;
break;
default:
ToneFrequency = 440;
break;
}
BK4819_PlayTone(ToneFrequency, true);
SYSTEM_DelayMs(2);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
SYSTEM_DelayMs(60);
switch (Beep)
{
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP:
BK4819_ExitTxMute();
SYSTEM_DelayMs(60);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
// Fallthrough
case BEEP_1KHZ_60MS_OPTIONAL:
BK4819_ExitTxMute();
Duration = 60;
break;
case BEEP_440HZ_500MS:
default:
BK4819_ExitTxMute();
Duration = 500;
break;
}
SYSTEM_DelayMs(Duration);
BK4819_EnterTxMute();
SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gVoxResumeCountdown = 80;
SYSTEM_DelayMs(5);
BK4819_TurnsOffTones_TurnsOnRX();
SYSTEM_DelayMs(5);
BK4819_WriteRegister(BK4819_REG_71, ToneConfig);
if (gEnableSpeaker)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
if (gFmRadioMode)
BK1080_Mute(false);
if (gCurrentFunction == FUNCTION_POWER_SAVE && gRxIdleMode)
BK4819_Sleep();
}
#ifndef DISABLE_VOICE
void AUDIO_PlayVoice(uint8_t VoiceID)
{
unsigned int i;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTEM_DelayMs(7);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
for (i = 0; i < 8; i++)
{
if ((VoiceID & 0x80U) == 0)
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
else
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
SYSTICK_DelayUs(1200);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTICK_DelayUs(1200);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
VoiceID <<= 1;
}
}
void AUDIO_PlaySingleVoice(bool bFlag)
{
uint8_t VoiceID;
uint8_t Delay;
VoiceID = gVoiceID[0];
if (gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF && gVoiceWriteIndex)
{
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{ // Chinese
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
goto Bailout;
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
{ // English
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
goto Bailout;
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
BK4819_SetAF(BK4819_AF_MUTE);
if (gFmRadioMode)
BK1080_Mute(true);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gVoxResumeCountdown = 2000;
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
if (gVoiceWriteIndex == 1)
Delay += 3;
if (bFlag)
{
SYSTEM_DelayMs(Delay * 10);
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
{
if (gRxVfo->IsAM)
BK4819_SetAF(BK4819_AF_AM);
else
BK4819_SetAF(BK4819_AF_OPEN);
}
if (gFmRadioMode)
BK1080_Mute(false);
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
gVoxResumeCountdown = 80;
return;
}
gVoiceReadIndex = 1;
gCountdownToPlayNextVoice = Delay;
gFlagPlayQueuedVoice = false;
return;
}
Bailout:
gVoiceReadIndex = 0;
gVoiceWriteIndex = 0;
}
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID)
{
if (Index >= 8)
return;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
gVoiceID[Index] = VoiceID;
gVoiceWriteIndex++;
}
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
{
uint16_t Remainder;
uint8_t Result;
uint8_t Count;
if (Index == 0)
{
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
Count = 0;
Result = Value / 1000U;
Remainder = Value % 1000U;
if (Remainder < 100U)
{
if (Remainder < 10U)
goto Skip;
}
else
{
Result = Remainder / 100U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 100U;
}
Result = Remainder / 10U;
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Result;
Count++;
Remainder -= Result * 10U;
Skip:
gVoiceID[gVoiceWriteIndex++] = (VOICE_ID_t)Remainder;
return Count + 1U;
}
void AUDIO_PlayQueuedVoice(void)
{
uint8_t VoiceID;
uint8_t Delay;
bool Skip;
Skip = false;
if (gVoiceReadIndex != gVoiceWriteIndex && gEeprom.VOICE_PROMPT != VOICE_PROMPT_OFF)
{
VoiceID = gVoiceID[gVoiceReadIndex];
if (gEeprom.VOICE_PROMPT == VOICE_PROMPT_CHINESE)
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthChinese))
{
Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE;
}
else
Skip = true;
}
else
{
if (VoiceID < ARRAY_SIZE(VoiceClipLengthEnglish))
{
Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE;
}
else
Skip = true;
}
gVoiceReadIndex++;
if (!Skip)
{
if (gVoiceReadIndex == gVoiceWriteIndex)
Delay += 3;
AUDIO_PlayVoice(VoiceID);
gCountdownToPlayNextVoice = Delay;
gFlagPlayQueuedVoice = false;
gVoxResumeCountdown = 2000;
return;
}
}
if (gCurrentFunction == FUNCTION_RECEIVE || gCurrentFunction == FUNCTION_MONITOR)
{
if (gRxVfo->IsAM)
BK4819_SetAF(BK4819_AF_AM);
else
BK4819_SetAF(BK4819_AF_OPEN);
}
if (gFmRadioMode)
BK1080_Mute(false);
if (!gEnableSpeaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
gVoxResumeCountdown = 80;
gVoiceWriteIndex = 0;
gVoiceReadIndex = 0;
}
#endif

146
audio.h Normal file
View File

@ -0,0 +1,146 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUDIO_H
#define AUDIO_H
#include <stdbool.h>
#include <stdint.h>
enum BEEP_Type_t
{
BEEP_NONE = 0,
BEEP_1KHZ_60MS_OPTIONAL,
BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL,
BEEP_440HZ_500MS,
BEEP_500HZ_60MS_DOUBLE_BEEP
};
typedef enum BEEP_Type_t BEEP_Type_t;
extern BEEP_Type_t gBeepToPlay;
void AUDIO_PlayBeep(BEEP_Type_t Beep);
#ifndef DISABLE_VOICE
enum
{
VOICE_ID_CHI_BASE = 0x10U,
VOICE_ID_ENG_BASE = 0x60U,
};
enum VOICE_ID_t
{
VOICE_ID_0 = 0x00U,
VOICE_ID_1 = 0x01U,
VOICE_ID_2 = 0x02U,
VOICE_ID_3 = 0x03U,
VOICE_ID_4 = 0x04U,
VOICE_ID_5 = 0x05U,
VOICE_ID_6 = 0x06U,
VOICE_ID_7 = 0x07U,
VOICE_ID_8 = 0x08U,
VOICE_ID_9 = 0x09U,
VOICE_ID_10 = 0x0AU,
VOICE_ID_100 = 0x0BU,
VOICE_ID_WELCOME = 0x0CU,
VOICE_ID_LOCK = 0x0DU,
VOICE_ID_UNLOCK = 0x0EU,
VOICE_ID_SCANNING_BEGIN = 0x0FU,
VOICE_ID_SCANNING_STOP = 0x10U,
VOICE_ID_SCRAMBLER_ON = 0x11U,
VOICE_ID_SCRAMBLER_OFF = 0x12U,
VOICE_ID_FUNCTION = 0x13U,
VOICE_ID_CTCSS = 0x14U,
VOICE_ID_DCS = 0x15U,
VOICE_ID_POWER = 0x16U,
VOICE_ID_SAVE_MODE = 0x17U,
VOICE_ID_MEMORY_CHANNEL = 0x18U,
VOICE_ID_DELETE_CHANNEL = 0x19U,
VOICE_ID_FREQUENCY_STEP = 0x1AU,
VOICE_ID_SQUELCH = 0x1BU,
VOICE_ID_TRANSMIT_OVER_TIME = 0x1CU,
VOICE_ID_BACKLIGHT_SELECTION = 0x1DU,
VOICE_ID_VOX = 0x1EU,
VOICE_ID_FREQUENCY_DIRECTION = 0x1FU,
VOICE_ID_OFFSET_FREQUENCY = 0x20U,
VOICE_ID_TRANSMITING_MEMORY = 0x21U,
VOICE_ID_RECEIVING_MEMORY = 0x22U,
VOICE_ID_EMERGENCY_CALL = 0x23U,
VOICE_ID_LOW_VOLTAGE = 0x24U,
VOICE_ID_CHANNEL_MODE = 0x25U,
VOICE_ID_FREQUENCY_MODE = 0x26U,
VOICE_ID_VOICE_PROMPT = 0x27U,
VOICE_ID_BAND_SELECTION = 0x28U,
VOICE_ID_DUAL_STANDBY = 0x29U,
VOICE_ID_CHANNEL_BANDWIDTH = 0x2AU,
VOICE_ID_OPTIONAL_SIGNAL = 0x2BU,
VOICE_ID_MUTE_MODE = 0x2CU,
VOICE_ID_BUSY_LOCKOUT = 0x2DU,
VOICE_ID_BEEP_PROMPT = 0x2EU,
VOICE_ID_ANI_CODE = 0x2FU,
VOICE_ID_INITIALISATION = 0x30U,
VOICE_ID_CONFIRM = 0x31U,
VOICE_ID_CANCEL = 0x32U,
VOICE_ID_ON = 0x33U,
VOICE_ID_OFF = 0x34U,
VOICE_ID_2_TONE = 0x35U,
VOICE_ID_5_TONE = 0x36U,
VOICE_ID_DIGITAL_SIGNAL = 0x37U,
VOICE_ID_REPEATER = 0x38U,
VOICE_ID_MENU = 0x39U,
VOICE_ID_11 = 0x3AU,
VOICE_ID_12 = 0x3BU,
VOICE_ID_13 = 0x3CU,
VOICE_ID_14 = 0x3DU,
VOICE_ID_15 = 0x3EU,
VOICE_ID_16 = 0x3FU,
VOICE_ID_17 = 0x40U,
VOICE_ID_18 = 0x41U,
VOICE_ID_19 = 0x42U,
VOICE_ID_20 = 0x43U,
VOICE_ID_30 = 0x44U,
VOICE_ID_40 = 0x45U,
VOICE_ID_50 = 0x46U,
VOICE_ID_60 = 0x47U,
VOICE_ID_70 = 0x48U,
VOICE_ID_80 = 0x49U,
VOICE_ID_90 = 0x4AU,
VOICE_ID_END = 0x4BU,
VOICE_ID_INVALID = 0xFFU,
};
typedef enum VOICE_ID_t VOICE_ID_t;
extern VOICE_ID_t gVoiceID[8];
extern uint8_t gVoiceReadIndex;
extern uint8_t gVoiceWriteIndex;
extern volatile uint16_t gCountdownToPlayNextVoice;
extern volatile bool gFlagPlayQueuedVoice;
extern VOICE_ID_t gAnotherVoiceID;
void AUDIO_PlayVoice(uint8_t VoiceID);
void AUDIO_PlaySingleVoice(bool bFlag);
void AUDIO_SetVoiceID(uint8_t Index, VOICE_ID_t VoiceID);
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value);
void AUDIO_PlayQueuedVoice(void);
#endif
#endif

75
bitmaps.c Normal file
View File

@ -0,0 +1,75 @@
#include "bitmaps.h"
const uint8_t BITMAP_PowerSave[8] = { 0x00, 0x26, 0x49, 0x49, 0x49, 0x49, 0x49, 0x32 };
const uint8_t BITMAP_BatteryLevel1[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 };
const uint8_t BITMAP_BatteryLevel2[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 };
const uint8_t BITMAP_BatteryLevel3[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x63 };
const uint8_t BITMAP_BatteryLevel4[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x41, 0x63 };
const uint8_t BITMAP_BatteryLevel5[18] = { 0x00, 0x3E, 0x22, 0x7F, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x41, 0x63 };
const uint8_t BITMAP_USB_C[9] = { 0x00, 0x1C, 0x27, 0x44, 0x44, 0x44, 0x44, 0x27, 0x1C };
const uint8_t BITMAP_KeyLock[9] = { 0x00, 0x7C, 0x46, 0x45, 0x45, 0x45, 0x45, 0x46, 0x7C };
const uint8_t BITMAP_F_Key[10] = { 0xFF, 0x81, 0xBD, 0x95, 0x95, 0x95, 0x95, 0x85, 0x81, 0xFF };
const uint8_t BITMAP_VOX[18] = { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x0, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 };
const uint8_t BITMAP_WX[12] = { 0x00, 0x7F, 0x20, 0x18, 0x20, 0x7F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 };
const uint8_t BITMAP_TDR[12] = { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x20, 0x18, 0x20, 0x7F };
#ifndef DISABLE_VOICE
const uint8_t BITMAP_VoicePrompt[9] = { 0x00, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0xFF, 0x18 };
#endif
const uint8_t BITMAP_FM[12] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F };
const uint8_t BITMAP_NOAA[12] = { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 };
const uint8_t BITMAP_Antenna[5] = { 0x03, 0x05, 0x7F, 0x05, 0x03 };
const uint8_t BITMAP_AntennaLevel1[3] = { 0x60, 0x60, 0x00 };
const uint8_t BITMAP_AntennaLevel2[3] = { 0x70, 0x70, 0x00 };
const uint8_t BITMAP_AntennaLevel3[3] = { 0x78, 0x78, 0x00 };
const uint8_t BITMAP_AntennaLevel4[3] = { 0x7C, 0x7C, 0x00 };
const uint8_t BITMAP_AntennaLevel5[3] = { 0x7E, 0x7E, 0x00 };
const uint8_t BITMAP_AntennaLevel6[3] = { 0x7F, 0x7F, 0x00 };
const uint8_t BITMAP_CurrentIndicator[8] = { 0xFF, 0xFF, 0x7E, 0x7E, 0x3C, 0x3C, 0x18, 0x18 };
const uint8_t BITMAP_VFO_Default[8] = { 0x00, 0x7F, 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08 };
const uint8_t BITMAP_VFO_NotDefault[8] = { 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08 };
const uint8_t BITMAP_TX[16] = { 0x00, 0x01, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x01, 0x00, 0x63, 0x22, 0x14, 0x08, 0x14, 0x22, 0x63 };
const uint8_t BITMAP_RX[16] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x19, 0x29, 0x46, 0x00, 0x63, 0x22, 0x14, 0x08, 0x14, 0x22, 0x63 };
const uint8_t BITMAP_M[8] = { 0x00, 0x7F, 0x02, 0x04, 0x18, 0x04, 0x02, 0x7F };
const uint8_t BITMAP_F[8] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01 };
const uint8_t BITMAP_ReverseMode[8] = { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x19, 0x29, 0x46 };
const uint8_t BITMAP_NarrowBand[8] = { 0x00, 0x7F, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7F };
const uint8_t BITMAP_DTMF[24] = {
0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x01,
0x01, 0x7F, 0x01, 0x01, 0x00, 0x7F, 0x02, 0x0C,
0x02, 0x7F, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,
};
const uint8_t BITMAP_Scramble[18] = {
0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x3E,
0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x09, 0x19,
0x29, 0x46,
};
const uint8_t BITMAP_Add[8] = { 0x00, 0x18, 0x18, 0x7E, 0x7E, 0x7E, 0x18, 0x18 };
const uint8_t BITMAP_Sub[8] = { 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C };
const uint8_t BITMAP_PowerHigh[8] = { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x7F };
const uint8_t BITMAP_PowerMid[8] = { 0x00, 0x7F, 0x02, 0x04, 0x18, 0x04, 0x02, 0x7F };
const uint8_t BITMAP_PowerLow[8] = { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 };
const uint8_t BITMAP_AM[12] = { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F };
const uint8_t BITMAP_CT[12] = { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 };
const uint8_t BITMAP_DCS[18] = { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32 };
const uint8_t BITMAP_ScanList[6] = { 0x08, 0x1C, 0x3E, 0x3E, 0x1C, 0x08 };

74
bitmaps.h Normal file
View File

@ -0,0 +1,74 @@
#ifndef BITMAP_H
#define BITMAP_H
#include <stdint.h>
extern const uint8_t BITMAP_PowerSave[8];
extern const uint8_t BITMAP_BatteryLevel1[18];
extern const uint8_t BITMAP_BatteryLevel2[18];
extern const uint8_t BITMAP_BatteryLevel3[18];
extern const uint8_t BITMAP_BatteryLevel4[18];
extern const uint8_t BITMAP_BatteryLevel5[18];
extern const uint8_t BITMAP_USB_C[9];
extern const uint8_t BITMAP_KeyLock[9];
extern const uint8_t BITMAP_F_Key[10];
extern const uint8_t BITMAP_VOX[18];
extern const uint8_t BITMAP_WX[12];
extern const uint8_t BITMAP_TDR[12];
#ifndef DISABLE_VOICE
extern const uint8_t BITMAP_VoicePrompt[9];
#endif
extern const uint8_t BITMAP_FM[12];
#ifndef DISABLE_NOAA
extern const uint8_t BITMAP_NOAA[12];
#endif
extern const uint8_t BITMAP_Antenna[5];
extern const uint8_t BITMAP_AntennaLevel1[3];
extern const uint8_t BITMAP_AntennaLevel2[3];
extern const uint8_t BITMAP_AntennaLevel3[3];
extern const uint8_t BITMAP_AntennaLevel4[3];
extern const uint8_t BITMAP_AntennaLevel5[3];
extern const uint8_t BITMAP_AntennaLevel6[3];
extern const uint8_t BITMAP_CurrentIndicator[8];
extern const uint8_t BITMAP_VFO_Default[8];
extern const uint8_t BITMAP_VFO_NotDefault[8];
extern const uint8_t BITMAP_TX[16];
extern const uint8_t BITMAP_RX[16];
extern const uint8_t BITMAP_M[8];
extern const uint8_t BITMAP_F[8];
extern const uint8_t BITMAP_ReverseMode[8];
extern const uint8_t BITMAP_NarrowBand[8];
extern const uint8_t BITMAP_DTMF[24];
extern const uint8_t BITMAP_Scramble[18];
extern const uint8_t BITMAP_Add[8];
extern const uint8_t BITMAP_Sub[8];
extern const uint8_t BITMAP_PowerHigh[8];
extern const uint8_t BITMAP_PowerMid[8];
extern const uint8_t BITMAP_PowerLow[8];
extern const uint8_t BITMAP_AM[12];
extern const uint8_t BITMAP_CT[12];
extern const uint8_t BITMAP_DCS[18];
extern const uint8_t BITMAP_ScanList[6];
#endif

615
board.c Normal file
View File

@ -0,0 +1,615 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include "app/dtmf.h"
#include "app/fm.h"
#include "board.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h"
#include "bsp/dp32g030/saradc.h"
#include "bsp/dp32g030/syscon.h"
#include "driver/adc.h"
#include "driver/bk1080.h"
#include "driver/bk4819.h"
#include "driver/crc.h"
#include "driver/eeprom.h"
#include "driver/flash.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/st7565.h"
#include "frequencies.h"
#include "helper/battery.h"
#include "misc.h"
#include "settings.h"
#include "sram-overlay.h"
void BOARD_FLASH_Init(void)
{
FLASH_Init(FLASH_READ_MODE_1_CYCLE);
FLASH_ConfigureTrimValues();
SYSTEM_ConfigureClocks();
overlay_FLASH_MainClock = 48000000;
overlay_FLASH_ClockMultiplier = 48;
FLASH_Init(FLASH_READ_MODE_2_CYCLE);
}
void BOARD_GPIO_Init(void)
{
GPIOA->DIR |= 0
| GPIO_DIR_10_BITS_OUTPUT
| GPIO_DIR_11_BITS_OUTPUT
| GPIO_DIR_12_BITS_OUTPUT
| GPIO_DIR_13_BITS_OUTPUT
;
GPIOA->DIR &= ~(0
| GPIO_DIR_3_MASK
| GPIO_DIR_4_MASK
| GPIO_DIR_5_MASK
| GPIO_DIR_6_MASK
);
GPIOB->DIR |= 0
| GPIO_DIR_6_BITS_OUTPUT
| GPIO_DIR_9_BITS_OUTPUT
| GPIO_DIR_11_BITS_OUTPUT
| GPIO_DIR_15_BITS_OUTPUT
;
GPIOC->DIR |= 0
| GPIO_DIR_0_BITS_OUTPUT
| GPIO_DIR_1_BITS_OUTPUT
| GPIO_DIR_2_BITS_OUTPUT
| GPIO_DIR_3_BITS_OUTPUT
| GPIO_DIR_4_BITS_OUTPUT
;
GPIOC->DIR &= ~(0
| GPIO_DIR_5_MASK
);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
}
void BOARD_PORTCON_Init(void)
{
// TODO: Need to redo these macros to make more sense.
// PORT A pin selection
PORTCON_PORTA_SEL0 &= 0
| PORTCON_PORTA_SEL0_A0_MASK
| PORTCON_PORTA_SEL0_A1_MASK
| PORTCON_PORTA_SEL0_A2_MASK
| PORTCON_PORTA_SEL0_A7_MASK
;
PORTCON_PORTA_SEL0 |= 0
| PORTCON_PORTA_SEL0_A0_BITS_GPIOA0
| PORTCON_PORTA_SEL0_A1_BITS_GPIOA1
| PORTCON_PORTA_SEL0_A2_BITS_GPIOA2
| PORTCON_PORTA_SEL0_A7_BITS_UART1_TX
;
PORTCON_PORTA_SEL1 &= 0
| PORTCON_PORTA_SEL1_A8_MASK
| PORTCON_PORTA_SEL1_A9_MASK
| PORTCON_PORTA_SEL1_A14_MASK
| PORTCON_PORTA_SEL1_A15_MASK
;
PORTCON_PORTA_SEL1 |= 0
| PORTCON_PORTA_SEL1_A8_BITS_UART1_RX
| PORTCON_PORTA_SEL1_A9_BITS_SARADC_CH4
| PORTCON_PORTA_SEL1_A14_BITS_SARADC_CH9
| PORTCON_PORTA_SEL1_A15_BITS_GPIOA15
;
// PORT B pin selection
PORTCON_PORTB_SEL0 &= 0
| PORTCON_PORTB_SEL0_B0_MASK
| PORTCON_PORTB_SEL0_B1_MASK
| PORTCON_PORTB_SEL0_B2_MASK
| PORTCON_PORTB_SEL0_B3_MASK
| PORTCON_PORTB_SEL0_B4_MASK
| PORTCON_PORTB_SEL0_B5_MASK
;
PORTCON_PORTB_SEL0 |= 0
| PORTCON_PORTB_SEL0_B0_BITS_GPIOB0
| PORTCON_PORTB_SEL0_B1_BITS_GPIOB1
| PORTCON_PORTB_SEL0_B2_BITS_GPIOB2
| PORTCON_PORTB_SEL0_B3_BITS_GPIOB3
| PORTCON_PORTB_SEL0_B4_BITS_GPIOB4
| PORTCON_PORTB_SEL0_B5_BITS_GPIOB5
| PORTCON_PORTB_SEL0_B7_BITS_SPI0_SSN
;
PORTCON_PORTB_SEL1 &= 0
| PORTCON_PORTB_SEL1_B8_MASK
| PORTCON_PORTB_SEL1_B10_MASK
| PORTCON_PORTB_SEL1_B12_MASK
| PORTCON_PORTB_SEL1_B13_MASK
;
PORTCON_PORTB_SEL1 |= 0
| PORTCON_PORTB_SEL1_B8_BITS_SPI0_CLK
| PORTCON_PORTB_SEL1_B10_BITS_SPI0_MOSI
| PORTCON_PORTB_SEL1_B11_BITS_SWDIO
| PORTCON_PORTB_SEL1_B12_BITS_GPIOB12
| PORTCON_PORTB_SEL1_B13_BITS_GPIOB13
| PORTCON_PORTB_SEL1_B14_BITS_SWCLK
;
// PORT C pin selection
PORTCON_PORTC_SEL0 &= 0
| PORTCON_PORTC_SEL0_C6_MASK
| PORTCON_PORTC_SEL0_C7_MASK
;
// PORT A pin configuration
PORTCON_PORTA_IE |= 0
| PORTCON_PORTA_IE_A3_BITS_ENABLE
| PORTCON_PORTA_IE_A4_BITS_ENABLE
| PORTCON_PORTA_IE_A5_BITS_ENABLE
| PORTCON_PORTA_IE_A6_BITS_ENABLE
| PORTCON_PORTA_IE_A8_BITS_ENABLE
;
PORTCON_PORTA_IE &= ~(0
| PORTCON_PORTA_IE_A10_MASK
| PORTCON_PORTA_IE_A11_MASK
| PORTCON_PORTA_IE_A12_MASK
| PORTCON_PORTA_IE_A13_MASK
);
PORTCON_PORTA_PU |= 0
| PORTCON_PORTA_PU_A3_BITS_ENABLE
| PORTCON_PORTA_PU_A4_BITS_ENABLE
| PORTCON_PORTA_PU_A5_BITS_ENABLE
| PORTCON_PORTA_PU_A6_BITS_ENABLE
;
PORTCON_PORTA_PU &= ~(0
| PORTCON_PORTA_PU_A10_MASK
| PORTCON_PORTA_PU_A11_MASK
| PORTCON_PORTA_PU_A12_MASK
| PORTCON_PORTA_PU_A13_MASK
);
PORTCON_PORTA_PD &= ~(0
| PORTCON_PORTA_PD_A3_MASK
| PORTCON_PORTA_PD_A4_MASK
| PORTCON_PORTA_PD_A5_MASK
| PORTCON_PORTA_PD_A6_MASK
| PORTCON_PORTA_PD_A10_MASK
| PORTCON_PORTA_PD_A11_MASK
| PORTCON_PORTA_PD_A12_MASK
| PORTCON_PORTA_PD_A13_MASK
);
PORTCON_PORTA_OD |= 0
| PORTCON_PORTA_OD_A3_BITS_ENABLE
| PORTCON_PORTA_OD_A4_BITS_ENABLE
| PORTCON_PORTA_OD_A5_BITS_ENABLE
| PORTCON_PORTA_OD_A6_BITS_ENABLE
;
PORTCON_PORTA_OD &= ~(0
| PORTCON_PORTA_OD_A10_MASK
| PORTCON_PORTA_OD_A11_MASK
| PORTCON_PORTA_OD_A12_MASK
| PORTCON_PORTA_OD_A13_MASK
);
// PORT B pin configuration
PORTCON_PORTB_IE |= 0
| PORTCON_PORTB_IE_B14_BITS_ENABLE
;
PORTCON_PORTB_IE &= ~(0
| PORTCON_PORTB_IE_B6_MASK
| PORTCON_PORTB_IE_B7_MASK
| PORTCON_PORTB_IE_B8_MASK
| PORTCON_PORTB_IE_B9_MASK
| PORTCON_PORTB_IE_B10_MASK
| PORTCON_PORTB_IE_B15_MASK
);
PORTCON_PORTB_PU &= ~(0
| PORTCON_PORTB_PU_B6_MASK
| PORTCON_PORTB_PU_B9_MASK
| PORTCON_PORTB_PU_B11_MASK
| PORTCON_PORTB_PU_B14_MASK
| PORTCON_PORTB_PU_B15_MASK
);
PORTCON_PORTB_PD &= ~(0
| PORTCON_PORTB_PD_B6_MASK
| PORTCON_PORTB_PD_B9_MASK
| PORTCON_PORTB_PD_B11_MASK
| PORTCON_PORTB_PD_B14_MASK
| PORTCON_PORTB_PD_B15_MASK
);
PORTCON_PORTB_OD &= ~(0
| PORTCON_PORTB_OD_B6_MASK
| PORTCON_PORTB_OD_B9_MASK
| PORTCON_PORTB_OD_B11_MASK
| PORTCON_PORTB_OD_B15_MASK
);
PORTCON_PORTB_OD |= 0
| PORTCON_PORTB_OD_B14_BITS_ENABLE
;
// PORT C pin configuration
PORTCON_PORTC_IE |= 0
| PORTCON_PORTC_IE_C5_BITS_ENABLE
;
PORTCON_PORTC_IE &= ~(0
| PORTCON_PORTC_IE_C0_MASK
| PORTCON_PORTC_IE_C1_MASK
| PORTCON_PORTC_IE_C2_MASK
| PORTCON_PORTC_IE_C3_MASK
| PORTCON_PORTC_IE_C4_MASK
);
PORTCON_PORTC_PU |= 0
| PORTCON_PORTC_PU_C5_BITS_ENABLE
;
PORTCON_PORTC_PU &= ~(0
| PORTCON_PORTC_PU_C0_MASK
| PORTCON_PORTC_PU_C1_MASK
| PORTCON_PORTC_PU_C2_MASK
| PORTCON_PORTC_PU_C3_MASK
| PORTCON_PORTC_PU_C4_MASK
);
PORTCON_PORTC_PD &= ~(0
| PORTCON_PORTC_PD_C0_MASK
| PORTCON_PORTC_PD_C1_MASK
| PORTCON_PORTC_PD_C2_MASK
| PORTCON_PORTC_PD_C3_MASK
| PORTCON_PORTC_PD_C4_MASK
| PORTCON_PORTC_PD_C5_MASK
);
PORTCON_PORTC_OD &= ~(0
| PORTCON_PORTC_OD_C0_MASK
| PORTCON_PORTC_OD_C1_MASK
| PORTCON_PORTC_OD_C2_MASK
| PORTCON_PORTC_OD_C3_MASK
| PORTCON_PORTC_OD_C4_MASK
);
PORTCON_PORTC_OD |= 0
| PORTCON_PORTC_OD_C5_BITS_ENABLE
;
}
void BOARD_ADC_Init(void)
{
ADC_Config_t Config;
Config.CLK_SEL = SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2;
Config.CH_SEL = ADC_CH4 | ADC_CH9;
Config.AVG = SARADC_CFG_AVG_VALUE_8_SAMPLE;
Config.CONT = SARADC_CFG_CONT_VALUE_SINGLE;
Config.MEM_MODE = SARADC_CFG_MEM_MODE_VALUE_CHANNEL;
Config.SMPL_CLK = SARADC_CFG_SMPL_CLK_VALUE_INTERNAL;
Config.SMPL_WIN = SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE;
Config.SMPL_SETUP = SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE;
Config.ADC_TRIG = SARADC_CFG_ADC_TRIG_VALUE_CPU;
Config.CALIB_KD_VALID = SARADC_CALIB_KD_VALID_VALUE_YES;
Config.CALIB_OFFSET_VALID = SARADC_CALIB_OFFSET_VALID_VALUE_YES;
Config.DMA_EN = SARADC_CFG_DMA_EN_VALUE_DISABLE;
Config.IE_CHx_EOC = SARADC_IE_CHx_EOC_VALUE_NONE;
Config.IE_FIFO_FULL = SARADC_IE_FIFO_FULL_VALUE_DISABLE;
Config.IE_FIFO_HFULL = SARADC_IE_FIFO_HFULL_VALUE_DISABLE;
ADC_Configure(&Config);
ADC_Enable();
ADC_SoftReset();
}
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent)
{
ADC_Start();
while (!ADC_CheckEndOfConversion(ADC_CH9)) {}
*pVoltage = ADC_GetValue(ADC_CH4);
*pCurrent = ADC_GetValue(ADC_CH9);
}
void BOARD_Init(void)
{
BOARD_PORTCON_Init();
BOARD_GPIO_Init();
BOARD_ADC_Init();
ST7565_Init();
BK1080_Init(0, false);
CRC_Init();
}
void BOARD_EEPROM_Init(void)
{
unsigned int i;
uint8_t Data[16];
memset(Data, 0, sizeof(Data));
// 0E70..0E77
EEPROM_ReadBuffer(0x0E70, Data, 8);
gEeprom.CHAN_1_CALL = IS_MR_CHANNEL(Data[0]) ? Data[0] : MR_CHANNEL_FIRST;
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 4;
gEeprom.TX_TIMEOUT_TIMER = (Data[2] < 11) ? Data[2] : 2;
#ifndef DISABLE_NOAA
gEeprom.NOAA_AUTO_SCAN = (Data[3] < 2) ? Data[3] : true;
#endif
gEeprom.KEY_LOCK = (Data[4] < 2) ? Data[4] : false;
gEeprom.VOX_SWITCH = (Data[5] < 2) ? Data[5] : false;
gEeprom.VOX_LEVEL = (Data[6] < 10) ? Data[6] : 5;
gEeprom.MIC_SENSITIVITY = (Data[7] < 5) ? Data[7] : 4;
// 0E78..0E7F
EEPROM_ReadBuffer(0x0E78, Data, 8);
gEeprom.CHANNEL_DISPLAY_MODE = (Data[1] < 3) ? Data[1] : MDF_FREQUENCY;
gEeprom.CROSS_BAND_RX_TX = (Data[2] < 3) ? Data[2] : CROSS_BAND_OFF;
gEeprom.BATTERY_SAVE = (Data[3] < 5) ? Data[3] : 4;
gEeprom.DUAL_WATCH = (Data[4] < 3) ? Data[4] : DUAL_WATCH_CHAN_A;
gEeprom.BACKLIGHT = (Data[5] < 6) ? Data[5] : 5;
gEeprom.TAIL_NOTE_ELIMINATION = (Data[6] < 2) ? Data[6] : true;
gEeprom.VFO_OPEN = (Data[7] < 2) ? Data[7] : true;
// 0E80..0E87
EEPROM_ReadBuffer(0x0E80, Data, 8);
gEeprom.ScreenChannel[0] = IS_VALID_CHANNEL(Data[0]) ? Data[0] : (FREQ_CHANNEL_FIRST + 5);
gEeprom.ScreenChannel[1] = IS_VALID_CHANNEL(Data[3]) ? Data[3] : (FREQ_CHANNEL_FIRST + 5);
gEeprom.MrChannel[0] = IS_MR_CHANNEL(Data[1]) ? Data[1] : MR_CHANNEL_FIRST;
gEeprom.MrChannel[1] = IS_MR_CHANNEL(Data[4]) ? Data[4] : MR_CHANNEL_FIRST;
gEeprom.FreqChannel[0] = IS_FREQ_CHANNEL(Data[2]) ? Data[2] : (FREQ_CHANNEL_FIRST + 5);
gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data[5]) ? Data[5] : (FREQ_CHANNEL_FIRST + 5);
#ifndef DISABLE_NOAA
gEeprom.NoaaChannel[0] = IS_NOAA_CHANNEL(Data[6]) ? Data[6] : NOAA_CHANNEL_FIRST;
gEeprom.NoaaChannel[1] = IS_NOAA_CHANNEL(Data[7]) ? Data[7] : NOAA_CHANNEL_FIRST;
#endif
// 0E88..0E8F
struct
{
uint16_t SelectedFrequency;
uint8_t SelectedChannel;
uint8_t IsMrMode;
uint8_t Padding[8];
} FM;
EEPROM_ReadBuffer(0x0E88, &FM, 8);
gEeprom.FM_LowerLimit = 760;
gEeprom.FM_UpperLimit = 1080;
if (FM.SelectedFrequency < gEeprom.FM_LowerLimit || FM.SelectedFrequency > gEeprom.FM_UpperLimit)
gEeprom.FM_SelectedFrequency = 760;
else
gEeprom.FM_SelectedFrequency = FM.SelectedFrequency;
gEeprom.FM_SelectedChannel = FM.SelectedChannel;
gEeprom.FM_IsMrMode = (FM.IsMrMode < 2) ? FM.IsMrMode : false;
// 0E40..0E67
EEPROM_ReadBuffer(0x0E40, gFM_Channels, sizeof(gFM_Channels));
FM_ConfigureChannelState();
// 0E90..0E97
EEPROM_ReadBuffer(0x0E90, Data, 8);
gEeprom.BEEP_CONTROL = (Data[0] < 2) ? Data[0] : true;
gEeprom.KEY_1_SHORT_PRESS_ACTION = (Data[1] < 9) ? Data[1] : 3;
gEeprom.KEY_1_LONG_PRESS_ACTION = (Data[2] < 9) ? Data[2] : 8;
gEeprom.KEY_2_SHORT_PRESS_ACTION = (Data[3] < 9) ? Data[3] : 1;
gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < 9) ? Data[4] : 6;
gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO;
gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : true;
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 3) ? Data[7] : POWER_ON_DISPLAY_MODE_MESSAGE;
// 0E98..0E9F
EEPROM_ReadBuffer(0x0E98, Data, 8);
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
// 0EA0..0EA7
#ifndef DISABLE_VOICE
EEPROM_ReadBuffer(0x0EA0, Data, 8);
gEeprom.VOICE_PROMPT = (Data[0] < 3) ? Data[0] : VOICE_PROMPT_ENGLISH;
#endif
// 0EA8..0EAF
EEPROM_ReadBuffer(0x0EA8, Data, 8);
gEeprom.ALARM_MODE = (Data[0] < 2) ? Data[0] : true;
gEeprom.ROGER = (Data[1] < 3) ? Data[1] : ROGER_MODE_OFF;
gEeprom.REPEATER_TAIL_TONE_ELIMINATION = (Data[2] < 11) ? Data[2] : 0;
gEeprom.TX_CHANNEL = (Data[3] < 2) ? Data[3] : 0;
// 0ED0..0ED7
EEPROM_ReadBuffer(0x0ED0, Data, 8);
gEeprom.DTMF_SIDE_TONE = (Data[0] < 2) ? Data[0] : true;
gEeprom.DTMF_SEPARATE_CODE = DTMF_ValidateCodes((char *)(Data + 1), 1) ? Data[1] : '*';
gEeprom.DTMF_GROUP_CALL_CODE = DTMF_ValidateCodes((char *)(Data + 2), 1) ? Data[2] : '#';
gEeprom.DTMF_DECODE_RESPONSE = (Data[3] < 4) ? Data[3] : 0;
gEeprom.DTMF_AUTO_RESET_TIME = (Data[4] < 61) ? Data[4] : 5;
gEeprom.DTMF_PRELOAD_TIME = (Data[5] < 101) ? Data[5] * 10 : 300;
gEeprom.DTMF_FIRST_CODE_PERSIST_TIME = (Data[6] < 101) ? Data[6] * 10 : 100;
gEeprom.DTMF_HASH_CODE_PERSIST_TIME = (Data[7] < 101) ? Data[7] * 10 : 100;
// 0ED8..0EDF
EEPROM_ReadBuffer(0x0ED8, Data, 8);
gEeprom.DTMF_CODE_PERSIST_TIME = (Data[0] < 101) ? Data[0] * 10 : 100;
gEeprom.DTMF_CODE_INTERVAL_TIME = (Data[1] < 101) ? Data[1] * 10 : 100;
gEeprom.PERMIT_REMOTE_KILL = (Data[2] < 2) ? Data[2] : true;
// 0EE0..0EE7
EEPROM_ReadBuffer(0x0EE0, Data, 8);
if (DTMF_ValidateCodes((char *)Data, 8))
memcpy(gEeprom.ANI_DTMF_ID, Data, 8);
else
// Original firmware overflows into the next string
memcpy(gEeprom.ANI_DTMF_ID, "123\0\0\0\0", 8);
// 0EE8..0EEF
EEPROM_ReadBuffer(0x0EE8, Data, 8);
if (DTMF_ValidateCodes((char *)Data, 8))
memcpy(gEeprom.KILL_CODE, Data, 8);
else
memcpy(gEeprom.KILL_CODE, "ABCD9\0\0", 8);
// 0EF0..0EF7
EEPROM_ReadBuffer(0x0EF0, Data, 8);
if (DTMF_ValidateCodes((char *)Data, 8))
memcpy(gEeprom.REVIVE_CODE, Data, 8);
else
memcpy(gEeprom.REVIVE_CODE, "9DCBA\0\0", 8);
// 0EF8..0F07
EEPROM_ReadBuffer(0x0EF8, Data, 16);
if (DTMF_ValidateCodes((char *)Data, 16))
memcpy(gEeprom.DTMF_UP_CODE, Data, 16);
else
memcpy(gEeprom.DTMF_UP_CODE, "12345\0\0\0\0\0\0\0\0\0\0", 16);
// 0F08..0F17
EEPROM_ReadBuffer(0x0F08, Data, 16);
if (DTMF_ValidateCodes((char *)Data, 16))
memcpy(gEeprom.DTMF_DOWN_CODE, Data, 16);
else
memcpy(gEeprom.DTMF_DOWN_CODE, "54321\0\0\0\0\0\0\0\0\0\0", 16);
// 0F18..0F1F
EEPROM_ReadBuffer(0x0F18, Data, 8);
gEeprom.SCAN_LIST_DEFAULT = (Data[0] < 2) ? Data[0] : false;
for (i = 0; i < 2; i++)
{
const unsigned int j = 1 + (i * 3);
gEeprom.SCAN_LIST_ENABLED[i] = (Data[j + 0] < 2) ? Data[j] : false;
gEeprom.SCANLIST_PRIORITY_CH1[i] = Data[j + 1];
gEeprom.SCANLIST_PRIORITY_CH2[i] = Data[j + 2];
}
// 0F40..0F47
EEPROM_ReadBuffer(0x0F40, Data, 8);
gSetting_F_LOCK = (Data[0] < 6) ? Data[0] : F_LOCK_OFF;
gUpperLimitFrequencyBandTable = UpperLimitFrequencyBandTable;
gLowerLimitFrequencyBandTable = LowerLimitFrequencyBandTable;
gSetting_350TX = (Data[1] < 2) ? Data[1] : false; // was true
gSetting_KILLED = (Data[2] < 2) ? Data[2] : false;
gSetting_200TX = (Data[3] < 2) ? Data[3] : false;
gSetting_500TX = (Data[4] < 2) ? Data[4] : false;
gSetting_350EN = (Data[5] < 2) ? Data[5] : true;
gSetting_ScrambleEnable = (Data[6] < 2) ? Data[6] : true;
if (!gEeprom.VFO_OPEN)
{
gEeprom.ScreenChannel[0] = gEeprom.MrChannel[0];
gEeprom.ScreenChannel[1] = gEeprom.MrChannel[1];
}
// 0D60..0E27
EEPROM_ReadBuffer(0x0D60, gMR_ChannelAttributes, sizeof(gMR_ChannelAttributes));
// 0F30..0F3F
EEPROM_ReadBuffer(0x0F30, gCustomAesKey, sizeof(gCustomAesKey));
bHasCustomAesKey = false;
for (i = 0; i < 4; i++)
{
if (gCustomAesKey[i] != 0xFFFFFFFFu)
{
bHasCustomAesKey = true;
return;
}
}
}
void BOARD_EEPROM_LoadMoreSettings(void)
{
// uint8_t Mic;
EEPROM_ReadBuffer(0x1EC0, gEEPROM_1EC0_0, 8);
memcpy(gEEPROM_1EC0_1, gEEPROM_1EC0_0, 8);
memcpy(gEEPROM_1EC0_2, gEEPROM_1EC0_0, 8);
memcpy(gEEPROM_1EC0_3, gEEPROM_1EC0_0, 8);
EEPROM_ReadBuffer(0x1EC8, gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[1], gEEPROM_RSSI_CALIB[0], 8);
memcpy(gEEPROM_RSSI_CALIB[2], gEEPROM_RSSI_CALIB[0], 8);
EEPROM_ReadBuffer(0x1F40, gBatteryCalibration, 12);
if (gBatteryCalibration[0] >= 5000)
{
gBatteryCalibration[0] = 1900;
gBatteryCalibration[1] = 2000;
}
gBatteryCalibration[5] = 2300;
EEPROM_ReadBuffer(0x1F50 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX1_THRESHOLD, 2);
EEPROM_ReadBuffer(0x1F68 + (gEeprom.VOX_LEVEL * 2), &gEeprom.VOX0_THRESHOLD, 2);
//EEPROM_ReadBuffer(0x1F80 + gEeprom.MIC_SENSITIVITY, &Mic, 1);
//gEeprom.MIC_SENSITIVITY_TUNING = (Mic < 32) ? Mic : 15;
gEeprom.MIC_SENSITIVITY_TUNING = gMicGain_dB2[gEeprom.MIC_SENSITIVITY];
struct
{
int16_t BK4819_XtalFreqLow;
uint16_t EEPROM_1F8A;
uint16_t EEPROM_1F8C;
uint8_t VOLUME_GAIN;
uint8_t DAC_GAIN;
} Misc;
EEPROM_ReadBuffer(0x1F88, &Misc, 8);
gEeprom.BK4819_XTAL_FREQ_LOW = ((Misc.BK4819_XtalFreqLow + 1000) < 2000) ? Misc.BK4819_XtalFreqLow : 0;
gEEPROM_1F8A = Misc.EEPROM_1F8A & 0x01FF;
gEEPROM_1F8C = Misc.EEPROM_1F8C & 0x01FF;
gEeprom.VOLUME_GAIN = (Misc.VOLUME_GAIN < 64) ? Misc.VOLUME_GAIN : 58;
gEeprom.DAC_GAIN = (Misc.DAC_GAIN < 16) ? Misc.DAC_GAIN : 8;
BK4819_WriteRegister(BK4819_REG_3B, gEeprom.BK4819_XTAL_FREQ_LOW + 22656);
}
void BOARD_FactoryReset(bool bIsAll)
{
uint8_t Template[8];
uint16_t i;
memset(Template, 0xFF, sizeof(Template));
for (i = 0x0C80; i < 0x1E00; i += 8)
{
if (
!(i >= 0x0EE0 && i < 0x0F18) && // ANI ID + DTMF codes
!(i >= 0x0F30 && i < 0x0F50) && // AES KEY + F LOCK + Scramble Enable
!(i >= 0x1C00 && i < 0x1E00) && // DTMF contacts
!(i >= 0x0EB0 && i < 0x0ED0) && // Welcome strings
!(i >= 0x0EA0 && i < 0x0EA8) && // Voice Prompt
(bIsAll ||
(
!(i >= 0x0D60 && i < 0x0E28) && // MR Channel Attributes
!(i >= 0x0F18 && i < 0x0F30) && // Scan List
!(i >= 0x0F50 && i < 0x1C00) && // MR Channel Names
!(i >= 0x0E40 && i < 0x0E70) && // FM Channels
!(i >= 0x0E88 && i < 0x0E90))) // FM settings
) {
EEPROM_WriteBuffer(i, Template);
}
}
}

33
board.h Normal file
View File

@ -0,0 +1,33 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BOARD_H
#define BOARD_H
#include <stdint.h>
void BOARD_FLASH_Init(void);
void BOARD_GPIO_Init(void);
void BOARD_PORTCON_Init(void);
void BOARD_ADC_Init(void);
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent);
void BOARD_Init(void);
void BOARD_EEPROM_Init(void);
void BOARD_EEPROM_LoadMoreSettings(void);
void BOARD_FactoryReset(bool bIsAll);
#endif

87
bsp/dp32g030/aes.h Normal file
View File

@ -0,0 +1,87 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_AES_H
#define HARDWARE_DP32G030_AES_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- AES -------- */
#define AES_BASE_ADDR 0x400BD000U
#define AES_BASE_SIZE 0x00000800U
#define AES_CR_ADDR (AES_BASE_ADDR + 0x0000U)
#define AES_CR (*(volatile uint32_t *)AES_CR_ADDR)
#define AES_CR_EN_SHIFT 0
#define AES_CR_EN_WIDTH 1
#define AES_CR_EN_MASK (((1U << AES_CR_EN_WIDTH) - 1U) << AES_CR_EN_SHIFT)
#define AES_CR_EN_VALUE_DISABLE 0U
#define AES_CR_EN_BITS_DISABLE (AES_CR_EN_VALUE_DISABLE << AES_CR_EN_SHIFT)
#define AES_CR_EN_VALUE_ENABLE 1U
#define AES_CR_EN_BITS_ENABLE (AES_CR_EN_VALUE_ENABLE << AES_CR_EN_SHIFT)
#define AES_CR_CHMOD_SHIFT 5
#define AES_CR_CHMOD_WIDTH 2
#define AES_CR_CHMOD_MASK (((1U << AES_CR_CHMOD_WIDTH) - 1U) << AES_CR_CHMOD_SHIFT)
#define AES_CR_CHMOD_VALUE_ECB 0U
#define AES_CR_CHMOD_BITS_ECB (AES_CR_CHMOD_VALUE_ECB << AES_CR_CHMOD_SHIFT)
#define AES_CR_CHMOD_VALUE_CBC 1U
#define AES_CR_CHMOD_BITS_CBC (AES_CR_CHMOD_VALUE_CBC << AES_CR_CHMOD_SHIFT)
#define AES_CR_CHMOD_VALUE_CTR 2U
#define AES_CR_CHMOD_BITS_CTR (AES_CR_CHMOD_VALUE_CTR << AES_CR_CHMOD_SHIFT)
#define AES_CR_CCFC_SHIFT 7
#define AES_CR_CCFC_WIDTH 1
#define AES_CR_CCFC_MASK (((1U << AES_CR_CCFC_WIDTH) - 1U) << AES_CR_CCFC_SHIFT)
#define AES_CR_CCFC_VALUE_SET 1U
#define AES_CR_CCFC_BITS_SET (AES_CR_CCFC_VALUE_SET << AES_CR_CCFC_SHIFT)
#define AES_SR_ADDR (AES_BASE_ADDR + 0x0004U)
#define AES_SR (*(volatile uint32_t *)AES_SR_ADDR)
#define AES_SR_CCF_SHIFT 0
#define AES_SR_CCF_WIDTH 1
#define AES_SR_CCF_MASK (((1U << AES_SR_CCF_WIDTH) - 1U) << AES_SR_CCF_SHIFT)
#define AES_SR_CCF_VALUE_NOT_COMPLETE 0U
#define AES_SR_CCF_BITS_NOT_COMPLETE (AES_SR_CCF_VALUE_NOT_COMPLETE << AES_SR_CCF_SHIFT)
#define AES_SR_CCF_VALUE_COMPLETE 1U
#define AES_SR_CCF_BITS_COMPLETE (AES_SR_CCF_VALUE_COMPLETE << AES_SR_CCF_SHIFT)
#define AES_DINR_ADDR (AES_BASE_ADDR + 0x0008U)
#define AES_DINR (*(volatile uint32_t *)AES_DINR_ADDR)
#define AES_DOUTR_ADDR (AES_BASE_ADDR + 0x000CU)
#define AES_DOUTR (*(volatile uint32_t *)AES_DOUTR_ADDR)
#define AES_KEYR0_ADDR (AES_BASE_ADDR + 0x0010U)
#define AES_KEYR0 (*(volatile uint32_t *)AES_KEYR0_ADDR)
#define AES_KEYR1_ADDR (AES_BASE_ADDR + 0x0014U)
#define AES_KEYR1 (*(volatile uint32_t *)AES_KEYR1_ADDR)
#define AES_KEYR2_ADDR (AES_BASE_ADDR + 0x0018U)
#define AES_KEYR2 (*(volatile uint32_t *)AES_KEYR2_ADDR)
#define AES_KEYR3_ADDR (AES_BASE_ADDR + 0x001CU)
#define AES_KEYR3 (*(volatile uint32_t *)AES_KEYR3_ADDR)
#define AES_IVR0_ADDR (AES_BASE_ADDR + 0x0020U)
#define AES_IVR0 (*(volatile uint32_t *)AES_IVR0_ADDR)
#define AES_IVR1_ADDR (AES_BASE_ADDR + 0x0024U)
#define AES_IVR1 (*(volatile uint32_t *)AES_IVR1_ADDR)
#define AES_IVR2_ADDR (AES_BASE_ADDR + 0x0028U)
#define AES_IVR2 (*(volatile uint32_t *)AES_IVR2_ADDR)
#define AES_IVR3_ADDR (AES_BASE_ADDR + 0x002CU)
#define AES_IVR3 (*(volatile uint32_t *)AES_IVR3_ADDR)
#endif

109
bsp/dp32g030/crc.h Normal file
View File

@ -0,0 +1,109 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_CRC_H
#define HARDWARE_DP32G030_CRC_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- CRC -------- */
#define CRC_BASE_ADDR 0x40003000U
#define CRC_BASE_SIZE 0x00000800U
#define CRC_CR_ADDR (CRC_BASE_ADDR + 0x0000U)
#define CRC_CR (*(volatile uint32_t *)CRC_CR_ADDR)
#define CRC_CR_CRC_EN_SHIFT 0
#define CRC_CR_CRC_EN_WIDTH 1
#define CRC_CR_CRC_EN_MASK (((1U << CRC_CR_CRC_EN_WIDTH) - 1U) << CRC_CR_CRC_EN_SHIFT)
#define CRC_CR_CRC_EN_VALUE_DISABLE 0U
#define CRC_CR_CRC_EN_BITS_DISABLE (CRC_CR_CRC_EN_VALUE_DISABLE << CRC_CR_CRC_EN_SHIFT)
#define CRC_CR_CRC_EN_VALUE_ENABLE 1U
#define CRC_CR_CRC_EN_BITS_ENABLE (CRC_CR_CRC_EN_VALUE_ENABLE << CRC_CR_CRC_EN_SHIFT)
#define CRC_CR_INPUT_REV_SHIFT 1
#define CRC_CR_INPUT_REV_WIDTH 1
#define CRC_CR_INPUT_REV_MASK (((1U << CRC_CR_INPUT_REV_WIDTH) - 1U) << CRC_CR_INPUT_REV_SHIFT)
#define CRC_CR_INPUT_REV_VALUE_NORMAL 0U
#define CRC_CR_INPUT_REV_BITS_NORMAL (CRC_CR_INPUT_REV_VALUE_NORMAL << CRC_CR_INPUT_REV_SHIFT)
#define CRC_CR_INPUT_REV_VALUE_REVERSED 1U
#define CRC_CR_INPUT_REV_BITS_REVERSED (CRC_CR_INPUT_REV_VALUE_REVERSED << CRC_CR_INPUT_REV_SHIFT)
#define CRC_CR_INPUT_INV_SHIFT 2
#define CRC_CR_INPUT_INV_WIDTH 2
#define CRC_CR_INPUT_INV_MASK (((1U << CRC_CR_INPUT_INV_WIDTH) - 1U) << CRC_CR_INPUT_INV_SHIFT)
#define CRC_CR_INPUT_INV_VALUE_NORMAL 0U
#define CRC_CR_INPUT_INV_BITS_NORMAL (CRC_CR_INPUT_INV_VALUE_NORMAL << CRC_CR_INPUT_INV_SHIFT)
#define CRC_CR_INPUT_INV_VALUE_BIT_INVERTED 1U
#define CRC_CR_INPUT_INV_BITS_BIT_INVERTED (CRC_CR_INPUT_INV_VALUE_BIT_INVERTED << CRC_CR_INPUT_INV_SHIFT)
#define CRC_CR_INPUT_INV_VALUE_BYTE_INVERTED 2U
#define CRC_CR_INPUT_INV_BITS_BYTE_INVERTED (CRC_CR_INPUT_INV_VALUE_BYTE_INVERTED << CRC_CR_INPUT_INV_SHIFT)
#define CRC_CR_INPUT_INV_VALUE_BIT_BYTE_INVERTED 3U
#define CRC_CR_INPUT_INV_BITS_BIT_BYTE_INVERTED (CRC_CR_INPUT_INV_VALUE_BIT_BYTE_INVERTED << CRC_CR_INPUT_INV_SHIFT)
#define CRC_CR_OUTPUT_REV_SHIFT 4
#define CRC_CR_OUTPUT_REV_WIDTH 1
#define CRC_CR_OUTPUT_REV_MASK (((1U << CRC_CR_OUTPUT_REV_WIDTH) - 1U) << CRC_CR_OUTPUT_REV_SHIFT)
#define CRC_CR_OUTPUT_REV_VALUE_NORMAL 0U
#define CRC_CR_OUTPUT_REV_BITS_NORMAL (CRC_CR_OUTPUT_REV_VALUE_NORMAL << CRC_CR_OUTPUT_REV_SHIFT)
#define CRC_CR_OUTPUT_REV_VALUE_REVERSED 1U
#define CRC_CR_OUTPUT_REV_BITS_REVERSED (CRC_CR_OUTPUT_REV_VALUE_REVERSED << CRC_CR_OUTPUT_REV_SHIFT)
#define CRC_CR_OUTPUT_INV_SHIFT 5
#define CRC_CR_OUTPUT_INV_WIDTH 2
#define CRC_CR_OUTPUT_INV_MASK (((1U << CRC_CR_OUTPUT_INV_WIDTH) - 1U) << CRC_CR_OUTPUT_INV_SHIFT)
#define CRC_CR_OUTPUT_INV_VALUE_NORMAL 0U
#define CRC_CR_OUTPUT_INV_BITS_NORMAL (CRC_CR_OUTPUT_INV_VALUE_NORMAL << CRC_CR_OUTPUT_INV_SHIFT)
#define CRC_CR_OUTPUT_INV_VALUE_BIT_INVERTED 1U
#define CRC_CR_OUTPUT_INV_BITS_BIT_INVERTED (CRC_CR_OUTPUT_INV_VALUE_BIT_INVERTED << CRC_CR_OUTPUT_INV_SHIFT)
#define CRC_CR_OUTPUT_INV_VALUE_BYTE_INVERTED 2U
#define CRC_CR_OUTPUT_INV_BITS_BYTE_INVERTED (CRC_CR_OUTPUT_INV_VALUE_BYTE_INVERTED << CRC_CR_OUTPUT_INV_SHIFT)
#define CRC_CR_OUTPUT_INV_VALUE_BIT_BYTE_INVERTED 3U
#define CRC_CR_OUTPUT_INV_BITS_BIT_BYTE_INVERTED (CRC_CR_OUTPUT_INV_VALUE_BIT_BYTE_INVERTED << CRC_CR_OUTPUT_INV_SHIFT)
#define CRC_CR_DATA_WIDTH_SHIFT 7
#define CRC_CR_DATA_WIDTH_WIDTH 2
#define CRC_CR_DATA_WIDTH_MASK (((1U << CRC_CR_DATA_WIDTH_WIDTH) - 1U) << CRC_CR_DATA_WIDTH_SHIFT)
#define CRC_CR_DATA_WIDTH_VALUE_32 0U
#define CRC_CR_DATA_WIDTH_BITS_32 (CRC_CR_DATA_WIDTH_VALUE_32 << CRC_CR_DATA_WIDTH_SHIFT)
#define CRC_CR_DATA_WIDTH_VALUE_16 1U
#define CRC_CR_DATA_WIDTH_BITS_16 (CRC_CR_DATA_WIDTH_VALUE_16 << CRC_CR_DATA_WIDTH_SHIFT)
#define CRC_CR_DATA_WIDTH_VALUE_8 2U
#define CRC_CR_DATA_WIDTH_BITS_8 (CRC_CR_DATA_WIDTH_VALUE_8 << CRC_CR_DATA_WIDTH_SHIFT)
#define CRC_CR_CRC_SEL_SHIFT 9
#define CRC_CR_CRC_SEL_WIDTH 2
#define CRC_CR_CRC_SEL_MASK (((1U << CRC_CR_CRC_SEL_WIDTH) - 1U) << CRC_CR_CRC_SEL_SHIFT)
#define CRC_CR_CRC_SEL_VALUE_CRC_16_CCITT 0U
#define CRC_CR_CRC_SEL_BITS_CRC_16_CCITT (CRC_CR_CRC_SEL_VALUE_CRC_16_CCITT << CRC_CR_CRC_SEL_SHIFT)
#define CRC_CR_CRC_SEL_VALUE_CRC_8_ATM 1U
#define CRC_CR_CRC_SEL_BITS_CRC_8_ATM (CRC_CR_CRC_SEL_VALUE_CRC_8_ATM << CRC_CR_CRC_SEL_SHIFT)
#define CRC_CR_CRC_SEL_VALUE_CRC_16 2U
#define CRC_CR_CRC_SEL_BITS_CRC_16 (CRC_CR_CRC_SEL_VALUE_CRC_16 << CRC_CR_CRC_SEL_SHIFT)
#define CRC_CR_CRC_SEL_VALUE_CRC_32_IEEE802_3 3U
#define CRC_CR_CRC_SEL_BITS_CRC_32_IEEE802_3 (CRC_CR_CRC_SEL_VALUE_CRC_32_IEEE802_3 << CRC_CR_CRC_SEL_SHIFT)
#define CRC_IV_ADDR (CRC_BASE_ADDR + 0x0004U)
#define CRC_IV (*(volatile uint32_t *)CRC_IV_ADDR)
#define CRC_DATAIN_ADDR (CRC_BASE_ADDR + 0x0008U)
#define CRC_DATAIN (*(volatile uint32_t *)CRC_DATAIN_ADDR)
#define CRC_DATAOUT_ADDR (CRC_BASE_ADDR + 0x000CU)
#define CRC_DATAOUT (*(volatile uint32_t *)CRC_DATAOUT_ADDR)
#endif

319
bsp/dp32g030/dma.h Normal file
View File

@ -0,0 +1,319 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_DMA_H
#define HARDWARE_DP32G030_DMA_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- DMA -------- */
#define DMA_BASE_ADDR 0x40001000U
#define DMA_BASE_SIZE 0x00000100U
#define DMA_CTR_ADDR (DMA_BASE_ADDR + 0x0000U)
#define DMA_CTR (*(volatile uint32_t *)DMA_CTR_ADDR)
#define DMA_CTR_DMAEN_SHIFT 0
#define DMA_CTR_DMAEN_WIDTH 1
#define DMA_CTR_DMAEN_MASK (((1U << DMA_CTR_DMAEN_WIDTH) - 1U) << DMA_CTR_DMAEN_SHIFT)
#define DMA_CTR_DMAEN_VALUE_DISABLE 0U
#define DMA_CTR_DMAEN_BITS_DISABLE (DMA_CTR_DMAEN_VALUE_DISABLE << DMA_CTR_DMAEN_SHIFT)
#define DMA_CTR_DMAEN_VALUE_ENABLE 1U
#define DMA_CTR_DMAEN_BITS_ENABLE (DMA_CTR_DMAEN_VALUE_ENABLE << DMA_CTR_DMAEN_SHIFT)
#define DMA_INTEN_ADDR (DMA_BASE_ADDR + 0x0004U)
#define DMA_INTEN (*(volatile uint32_t *)DMA_INTEN_ADDR)
#define DMA_INTEN_CH0_TC_INTEN_SHIFT 0
#define DMA_INTEN_CH0_TC_INTEN_WIDTH 1
#define DMA_INTEN_CH0_TC_INTEN_MASK (((1U << DMA_INTEN_CH0_TC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH0_TC_INTEN_SHIFT)
#define DMA_INTEN_CH0_TC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH0_TC_INTEN_BITS_DISABLE (DMA_INTEN_CH0_TC_INTEN_VALUE_DISABLE << DMA_INTEN_CH0_TC_INTEN_SHIFT)
#define DMA_INTEN_CH0_TC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH0_TC_INTEN_BITS_ENABLE (DMA_INTEN_CH0_TC_INTEN_VALUE_ENABLE << DMA_INTEN_CH0_TC_INTEN_SHIFT)
#define DMA_INTEN_CH1_TC_INTEN_SHIFT 1
#define DMA_INTEN_CH1_TC_INTEN_WIDTH 1
#define DMA_INTEN_CH1_TC_INTEN_MASK (((1U << DMA_INTEN_CH1_TC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH1_TC_INTEN_SHIFT)
#define DMA_INTEN_CH1_TC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH1_TC_INTEN_BITS_DISABLE (DMA_INTEN_CH1_TC_INTEN_VALUE_DISABLE << DMA_INTEN_CH1_TC_INTEN_SHIFT)
#define DMA_INTEN_CH1_TC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH1_TC_INTEN_BITS_ENABLE (DMA_INTEN_CH1_TC_INTEN_VALUE_ENABLE << DMA_INTEN_CH1_TC_INTEN_SHIFT)
#define DMA_INTEN_CH2_TC_INTEN_SHIFT 2
#define DMA_INTEN_CH2_TC_INTEN_WIDTH 1
#define DMA_INTEN_CH2_TC_INTEN_MASK (((1U << DMA_INTEN_CH2_TC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH2_TC_INTEN_SHIFT)
#define DMA_INTEN_CH2_TC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH2_TC_INTEN_BITS_DISABLE (DMA_INTEN_CH2_TC_INTEN_VALUE_DISABLE << DMA_INTEN_CH2_TC_INTEN_SHIFT)
#define DMA_INTEN_CH2_TC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH2_TC_INTEN_BITS_ENABLE (DMA_INTEN_CH2_TC_INTEN_VALUE_ENABLE << DMA_INTEN_CH2_TC_INTEN_SHIFT)
#define DMA_INTEN_CH3_TC_INTEN_SHIFT 3
#define DMA_INTEN_CH3_TC_INTEN_WIDTH 1
#define DMA_INTEN_CH3_TC_INTEN_MASK (((1U << DMA_INTEN_CH3_TC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH3_TC_INTEN_SHIFT)
#define DMA_INTEN_CH3_TC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH3_TC_INTEN_BITS_DISABLE (DMA_INTEN_CH3_TC_INTEN_VALUE_DISABLE << DMA_INTEN_CH3_TC_INTEN_SHIFT)
#define DMA_INTEN_CH3_TC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH3_TC_INTEN_BITS_ENABLE (DMA_INTEN_CH3_TC_INTEN_VALUE_ENABLE << DMA_INTEN_CH3_TC_INTEN_SHIFT)
#define DMA_INTEN_CH0_THC_INTEN_SHIFT 8
#define DMA_INTEN_CH0_THC_INTEN_WIDTH 1
#define DMA_INTEN_CH0_THC_INTEN_MASK (((1U << DMA_INTEN_CH0_THC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH0_THC_INTEN_SHIFT)
#define DMA_INTEN_CH0_THC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH0_THC_INTEN_BITS_DISABLE (DMA_INTEN_CH0_THC_INTEN_VALUE_DISABLE << DMA_INTEN_CH0_THC_INTEN_SHIFT)
#define DMA_INTEN_CH0_THC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH0_THC_INTEN_BITS_ENABLE (DMA_INTEN_CH0_THC_INTEN_VALUE_ENABLE << DMA_INTEN_CH0_THC_INTEN_SHIFT)
#define DMA_INTEN_CH1_THC_INTEN_SHIFT 9
#define DMA_INTEN_CH1_THC_INTEN_WIDTH 1
#define DMA_INTEN_CH1_THC_INTEN_MASK (((1U << DMA_INTEN_CH1_THC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH1_THC_INTEN_SHIFT)
#define DMA_INTEN_CH1_THC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH1_THC_INTEN_BITS_DISABLE (DMA_INTEN_CH1_THC_INTEN_VALUE_DISABLE << DMA_INTEN_CH1_THC_INTEN_SHIFT)
#define DMA_INTEN_CH1_THC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH1_THC_INTEN_BITS_ENABLE (DMA_INTEN_CH1_THC_INTEN_VALUE_ENABLE << DMA_INTEN_CH1_THC_INTEN_SHIFT)
#define DMA_INTEN_CH2_THC_INTEN_SHIFT 10
#define DMA_INTEN_CH2_THC_INTEN_WIDTH 1
#define DMA_INTEN_CH2_THC_INTEN_MASK (((1U << DMA_INTEN_CH2_THC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH2_THC_INTEN_SHIFT)
#define DMA_INTEN_CH2_THC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH2_THC_INTEN_BITS_DISABLE (DMA_INTEN_CH2_THC_INTEN_VALUE_DISABLE << DMA_INTEN_CH2_THC_INTEN_SHIFT)
#define DMA_INTEN_CH2_THC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH2_THC_INTEN_BITS_ENABLE (DMA_INTEN_CH2_THC_INTEN_VALUE_ENABLE << DMA_INTEN_CH2_THC_INTEN_SHIFT)
#define DMA_INTEN_CH3_THC_INTEN_SHIFT 11
#define DMA_INTEN_CH3_THC_INTEN_WIDTH 1
#define DMA_INTEN_CH3_THC_INTEN_MASK (((1U << DMA_INTEN_CH3_THC_INTEN_WIDTH) - 1U) << DMA_INTEN_CH3_THC_INTEN_SHIFT)
#define DMA_INTEN_CH3_THC_INTEN_VALUE_DISABLE 0U
#define DMA_INTEN_CH3_THC_INTEN_BITS_DISABLE (DMA_INTEN_CH3_THC_INTEN_VALUE_DISABLE << DMA_INTEN_CH3_THC_INTEN_SHIFT)
#define DMA_INTEN_CH3_THC_INTEN_VALUE_ENABLE 1U
#define DMA_INTEN_CH3_THC_INTEN_BITS_ENABLE (DMA_INTEN_CH3_THC_INTEN_VALUE_ENABLE << DMA_INTEN_CH3_THC_INTEN_SHIFT)
#define DMA_INTST_ADDR (DMA_BASE_ADDR + 0x0008U)
#define DMA_INTST (*(volatile uint32_t *)DMA_INTST_ADDR)
#define DMA_INTST_CH0_TC_INTST_SHIFT 0
#define DMA_INTST_CH0_TC_INTST_WIDTH 1
#define DMA_INTST_CH0_TC_INTST_MASK (((1U << DMA_INTST_CH0_TC_INTST_WIDTH) - 1U) << DMA_INTST_CH0_TC_INTST_SHIFT)
#define DMA_INTST_CH0_TC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH0_TC_INTST_BITS_NOT_SET (DMA_INTST_CH0_TC_INTST_VALUE_NOT_SET << DMA_INTST_CH0_TC_INTST_SHIFT)
#define DMA_INTST_CH0_TC_INTST_VALUE_SET 1U
#define DMA_INTST_CH0_TC_INTST_BITS_SET (DMA_INTST_CH0_TC_INTST_VALUE_SET << DMA_INTST_CH0_TC_INTST_SHIFT)
#define DMA_INTST_CH1_TC_INTST_SHIFT 1
#define DMA_INTST_CH1_TC_INTST_WIDTH 1
#define DMA_INTST_CH1_TC_INTST_MASK (((1U << DMA_INTST_CH1_TC_INTST_WIDTH) - 1U) << DMA_INTST_CH1_TC_INTST_SHIFT)
#define DMA_INTST_CH1_TC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH1_TC_INTST_BITS_NOT_SET (DMA_INTST_CH1_TC_INTST_VALUE_NOT_SET << DMA_INTST_CH1_TC_INTST_SHIFT)
#define DMA_INTST_CH1_TC_INTST_VALUE_SET 1U
#define DMA_INTST_CH1_TC_INTST_BITS_SET (DMA_INTST_CH1_TC_INTST_VALUE_SET << DMA_INTST_CH1_TC_INTST_SHIFT)
#define DMA_INTST_CH2_TC_INTST_SHIFT 2
#define DMA_INTST_CH2_TC_INTST_WIDTH 1
#define DMA_INTST_CH2_TC_INTST_MASK (((1U << DMA_INTST_CH2_TC_INTST_WIDTH) - 1U) << DMA_INTST_CH2_TC_INTST_SHIFT)
#define DMA_INTST_CH2_TC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH2_TC_INTST_BITS_NOT_SET (DMA_INTST_CH2_TC_INTST_VALUE_NOT_SET << DMA_INTST_CH2_TC_INTST_SHIFT)
#define DMA_INTST_CH2_TC_INTST_VALUE_SET 1U
#define DMA_INTST_CH2_TC_INTST_BITS_SET (DMA_INTST_CH2_TC_INTST_VALUE_SET << DMA_INTST_CH2_TC_INTST_SHIFT)
#define DMA_INTST_CH3_TC_INTST_SHIFT 3
#define DMA_INTST_CH3_TC_INTST_WIDTH 1
#define DMA_INTST_CH3_TC_INTST_MASK (((1U << DMA_INTST_CH3_TC_INTST_WIDTH) - 1U) << DMA_INTST_CH3_TC_INTST_SHIFT)
#define DMA_INTST_CH3_TC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH3_TC_INTST_BITS_NOT_SET (DMA_INTST_CH3_TC_INTST_VALUE_NOT_SET << DMA_INTST_CH3_TC_INTST_SHIFT)
#define DMA_INTST_CH3_TC_INTST_VALUE_SET 1U
#define DMA_INTST_CH3_TC_INTST_BITS_SET (DMA_INTST_CH3_TC_INTST_VALUE_SET << DMA_INTST_CH3_TC_INTST_SHIFT)
#define DMA_INTST_CH0_THC_INTST_SHIFT 8
#define DMA_INTST_CH0_THC_INTST_WIDTH 1
#define DMA_INTST_CH0_THC_INTST_MASK (((1U << DMA_INTST_CH0_THC_INTST_WIDTH) - 1U) << DMA_INTST_CH0_THC_INTST_SHIFT)
#define DMA_INTST_CH0_THC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH0_THC_INTST_BITS_NOT_SET (DMA_INTST_CH0_THC_INTST_VALUE_NOT_SET << DMA_INTST_CH0_THC_INTST_SHIFT)
#define DMA_INTST_CH0_THC_INTST_VALUE_SET 1U
#define DMA_INTST_CH0_THC_INTST_BITS_SET (DMA_INTST_CH0_THC_INTST_VALUE_SET << DMA_INTST_CH0_THC_INTST_SHIFT)
#define DMA_INTST_CH1_THC_INTST_SHIFT 9
#define DMA_INTST_CH1_THC_INTST_WIDTH 1
#define DMA_INTST_CH1_THC_INTST_MASK (((1U << DMA_INTST_CH1_THC_INTST_WIDTH) - 1U) << DMA_INTST_CH1_THC_INTST_SHIFT)
#define DMA_INTST_CH1_THC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH1_THC_INTST_BITS_NOT_SET (DMA_INTST_CH1_THC_INTST_VALUE_NOT_SET << DMA_INTST_CH1_THC_INTST_SHIFT)
#define DMA_INTST_CH1_THC_INTST_VALUE_SET 1U
#define DMA_INTST_CH1_THC_INTST_BITS_SET (DMA_INTST_CH1_THC_INTST_VALUE_SET << DMA_INTST_CH1_THC_INTST_SHIFT)
#define DMA_INTST_CH2_THC_INTST_SHIFT 10
#define DMA_INTST_CH2_THC_INTST_WIDTH 1
#define DMA_INTST_CH2_THC_INTST_MASK (((1U << DMA_INTST_CH2_THC_INTST_WIDTH) - 1U) << DMA_INTST_CH2_THC_INTST_SHIFT)
#define DMA_INTST_CH2_THC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH2_THC_INTST_BITS_NOT_SET (DMA_INTST_CH2_THC_INTST_VALUE_NOT_SET << DMA_INTST_CH2_THC_INTST_SHIFT)
#define DMA_INTST_CH2_THC_INTST_VALUE_SET 1U
#define DMA_INTST_CH2_THC_INTST_BITS_SET (DMA_INTST_CH2_THC_INTST_VALUE_SET << DMA_INTST_CH2_THC_INTST_SHIFT)
#define DMA_INTST_CH3_THC_INTST_SHIFT 11
#define DMA_INTST_CH3_THC_INTST_WIDTH 1
#define DMA_INTST_CH3_THC_INTST_MASK (((1U << DMA_INTST_CH3_THC_INTST_WIDTH) - 1U) << DMA_INTST_CH3_THC_INTST_SHIFT)
#define DMA_INTST_CH3_THC_INTST_VALUE_NOT_SET 0U
#define DMA_INTST_CH3_THC_INTST_BITS_NOT_SET (DMA_INTST_CH3_THC_INTST_VALUE_NOT_SET << DMA_INTST_CH3_THC_INTST_SHIFT)
#define DMA_INTST_CH3_THC_INTST_VALUE_SET 1U
#define DMA_INTST_CH3_THC_INTST_BITS_SET (DMA_INTST_CH3_THC_INTST_VALUE_SET << DMA_INTST_CH3_THC_INTST_SHIFT)
/* -------- DMA_CH0 -------- */
#define DMA_CH0_BASE_ADDR 0x40001100U
#define DMA_CH0_BASE_SIZE 0x00000020U
#define DMA_CH0 ((volatile DMA_Channel_t *)DMA_CH0_BASE_ADDR)
/* -------- DMA_CH1 -------- */
#define DMA_CH1_BASE_ADDR 0x40001120U
#define DMA_CH1_BASE_SIZE 0x00000020U
#define DMA_CH1 ((volatile DMA_Channel_t *)DMA_CH1_BASE_ADDR)
/* -------- DMA_CH2 -------- */
#define DMA_CH2_BASE_ADDR 0x40001140U
#define DMA_CH2_BASE_SIZE 0x00000020U
#define DMA_CH2 ((volatile DMA_Channel_t *)DMA_CH2_BASE_ADDR)
/* -------- DMA_CH3 -------- */
#define DMA_CH3_BASE_ADDR 0x40001160U
#define DMA_CH3_BASE_SIZE 0x00000020U
#define DMA_CH3 ((volatile DMA_Channel_t *)DMA_CH3_BASE_ADDR)
/* -------- DMA_CH -------- */
typedef struct {
uint32_t CTR;
uint32_t MOD;
uint32_t MSADDR;
uint32_t MDADDR;
uint32_t ST;
} DMA_Channel_t;
#define DMA_CH_CTR_CH_EN_SHIFT 0
#define DMA_CH_CTR_CH_EN_WIDTH 1
#define DMA_CH_CTR_CH_EN_MASK (((1U << DMA_CH_CTR_CH_EN_WIDTH) - 1U) << DMA_CH_CTR_CH_EN_SHIFT)
#define DMA_CH_CTR_CH_EN_VALUE_DISABLE 0U
#define DMA_CH_CTR_CH_EN_BITS_DISABLE (DMA_CH_CTR_CH_EN_VALUE_DISABLE << DMA_CH_CTR_CH_EN_SHIFT)
#define DMA_CH_CTR_CH_EN_VALUE_ENABLE 1U
#define DMA_CH_CTR_CH_EN_BITS_ENABLE (DMA_CH_CTR_CH_EN_VALUE_ENABLE << DMA_CH_CTR_CH_EN_SHIFT)
#define DMA_CH_CTR_LENGTH_SHIFT 1
#define DMA_CH_CTR_LENGTH_WIDTH 12
#define DMA_CH_CTR_LENGTH_MASK (((1U << DMA_CH_CTR_LENGTH_WIDTH) - 1U) << DMA_CH_CTR_LENGTH_SHIFT)
#define DMA_CH_CTR_LOOP_SHIFT 13
#define DMA_CH_CTR_LOOP_WIDTH 1
#define DMA_CH_CTR_LOOP_MASK (((1U << DMA_CH_CTR_LOOP_WIDTH) - 1U) << DMA_CH_CTR_LOOP_SHIFT)
#define DMA_CH_CTR_LOOP_VALUE_DISABLE 0U
#define DMA_CH_CTR_LOOP_BITS_DISABLE (DMA_CH_CTR_LOOP_VALUE_DISABLE << DMA_CH_CTR_LOOP_SHIFT)
#define DMA_CH_CTR_LOOP_VALUE_ENABLE 1U
#define DMA_CH_CTR_LOOP_BITS_ENABLE (DMA_CH_CTR_LOOP_VALUE_ENABLE << DMA_CH_CTR_LOOP_SHIFT)
#define DMA_CH_CTR_PRI_SHIFT 14
#define DMA_CH_CTR_PRI_WIDTH 2
#define DMA_CH_CTR_PRI_MASK (((1U << DMA_CH_CTR_PRI_WIDTH) - 1U) << DMA_CH_CTR_PRI_SHIFT)
#define DMA_CH_CTR_PRI_VALUE_LOW 0U
#define DMA_CH_CTR_PRI_BITS_LOW (DMA_CH_CTR_PRI_VALUE_LOW << DMA_CH_CTR_PRI_SHIFT)
#define DMA_CH_CTR_PRI_VALUE_MEDIUM 1U
#define DMA_CH_CTR_PRI_BITS_MEDIUM (DMA_CH_CTR_PRI_VALUE_MEDIUM << DMA_CH_CTR_PRI_SHIFT)
#define DMA_CH_CTR_PRI_VALUE_HIGH 2U
#define DMA_CH_CTR_PRI_BITS_HIGH (DMA_CH_CTR_PRI_VALUE_HIGH << DMA_CH_CTR_PRI_SHIFT)
#define DMA_CH_CTR_PRI_VALUE_HIGHEST 3U
#define DMA_CH_CTR_PRI_BITS_HIGHEST (DMA_CH_CTR_PRI_VALUE_HIGHEST << DMA_CH_CTR_PRI_SHIFT)
#define DMA_CH_CTR_SWREQ_SHIFT 16
#define DMA_CH_CTR_SWREQ_WIDTH 1
#define DMA_CH_CTR_SWREQ_MASK (((1U << DMA_CH_CTR_SWREQ_WIDTH) - 1U) << DMA_CH_CTR_SWREQ_SHIFT)
#define DMA_CH_CTR_SWREQ_VALUE_SET 1U
#define DMA_CH_CTR_SWREQ_BITS_SET (DMA_CH_CTR_SWREQ_VALUE_SET << DMA_CH_CTR_SWREQ_SHIFT)
#define DMA_CH_MOD_MS_ADDMOD_SHIFT 0
#define DMA_CH_MOD_MS_ADDMOD_WIDTH 1
#define DMA_CH_MOD_MS_ADDMOD_MASK (((1U << DMA_CH_MOD_MS_ADDMOD_WIDTH) - 1U) << DMA_CH_MOD_MS_ADDMOD_SHIFT)
#define DMA_CH_MOD_MS_ADDMOD_VALUE_NONE 0U
#define DMA_CH_MOD_MS_ADDMOD_BITS_NONE (DMA_CH_MOD_MS_ADDMOD_VALUE_NONE << DMA_CH_MOD_MS_ADDMOD_SHIFT)
#define DMA_CH_MOD_MS_ADDMOD_VALUE_INCREMENT 1U
#define DMA_CH_MOD_MS_ADDMOD_BITS_INCREMENT (DMA_CH_MOD_MS_ADDMOD_VALUE_INCREMENT << DMA_CH_MOD_MS_ADDMOD_SHIFT)
#define DMA_CH_MOD_MS_SIZE_SHIFT 1
#define DMA_CH_MOD_MS_SIZE_WIDTH 2
#define DMA_CH_MOD_MS_SIZE_MASK (((1U << DMA_CH_MOD_MS_SIZE_WIDTH) - 1U) << DMA_CH_MOD_MS_SIZE_SHIFT)
#define DMA_CH_MOD_MS_SIZE_VALUE_8BIT 0U
#define DMA_CH_MOD_MS_SIZE_BITS_8BIT (DMA_CH_MOD_MS_SIZE_VALUE_8BIT << DMA_CH_MOD_MS_SIZE_SHIFT)
#define DMA_CH_MOD_MS_SIZE_VALUE_16BIT 1U
#define DMA_CH_MOD_MS_SIZE_BITS_16BIT (DMA_CH_MOD_MS_SIZE_VALUE_16BIT << DMA_CH_MOD_MS_SIZE_SHIFT)
#define DMA_CH_MOD_MS_SIZE_VALUE_32BIT 2U
#define DMA_CH_MOD_MS_SIZE_BITS_32BIT (DMA_CH_MOD_MS_SIZE_VALUE_32BIT << DMA_CH_MOD_MS_SIZE_SHIFT)
#define DMA_CH_MOD_MS_SIZE_VALUE_KEEP 3U
#define DMA_CH_MOD_MS_SIZE_BITS_KEEP (DMA_CH_MOD_MS_SIZE_VALUE_KEEP << DMA_CH_MOD_MS_SIZE_SHIFT)
#define DMA_CH_MOD_MS_SEL_SHIFT 3
#define DMA_CH_MOD_MS_SEL_WIDTH 3
#define DMA_CH_MOD_MS_SEL_MASK (((1U << DMA_CH_MOD_MS_SEL_WIDTH) - 1U) << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_SRAM 0U
#define DMA_CH_MOD_MS_SEL_BITS_SRAM (DMA_CH_MOD_MS_SEL_VALUE_SRAM << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS0 1U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS0 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS0 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS1 2U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS1 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS2 3U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS2 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS2 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS3 4U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS3 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS3 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS4 5U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS4 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS4 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS5 6U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS5 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS5 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS6 7U
#define DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS6 (DMA_CH_MOD_MS_SEL_VALUE_HSREQ_MS6 << DMA_CH_MOD_MS_SEL_SHIFT)
#define DMA_CH_MOD_MD_ADDMOD_SHIFT 8
#define DMA_CH_MOD_MD_ADDMOD_WIDTH 1
#define DMA_CH_MOD_MD_ADDMOD_MASK (((1U << DMA_CH_MOD_MD_ADDMOD_WIDTH) - 1U) << DMA_CH_MOD_MD_ADDMOD_SHIFT)
#define DMA_CH_MOD_MD_ADDMOD_VALUE_NONE 0U
#define DMA_CH_MOD_MD_ADDMOD_BITS_NONE (DMA_CH_MOD_MD_ADDMOD_VALUE_NONE << DMA_CH_MOD_MD_ADDMOD_SHIFT)
#define DMA_CH_MOD_MD_ADDMOD_VALUE_INCREMENT 1U
#define DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT (DMA_CH_MOD_MD_ADDMOD_VALUE_INCREMENT << DMA_CH_MOD_MD_ADDMOD_SHIFT)
#define DMA_CH_MOD_MD_SIZE_SHIFT 9
#define DMA_CH_MOD_MD_SIZE_WIDTH 2
#define DMA_CH_MOD_MD_SIZE_MASK (((1U << DMA_CH_MOD_MD_SIZE_WIDTH) - 1U) << DMA_CH_MOD_MD_SIZE_SHIFT)
#define DMA_CH_MOD_MD_SIZE_VALUE_8BIT 0U
#define DMA_CH_MOD_MD_SIZE_BITS_8BIT (DMA_CH_MOD_MD_SIZE_VALUE_8BIT << DMA_CH_MOD_MD_SIZE_SHIFT)
#define DMA_CH_MOD_MD_SIZE_VALUE_16BIT 1U
#define DMA_CH_MOD_MD_SIZE_BITS_16BIT (DMA_CH_MOD_MD_SIZE_VALUE_16BIT << DMA_CH_MOD_MD_SIZE_SHIFT)
#define DMA_CH_MOD_MD_SIZE_VALUE_32BIT 2U
#define DMA_CH_MOD_MD_SIZE_BITS_32BIT (DMA_CH_MOD_MD_SIZE_VALUE_32BIT << DMA_CH_MOD_MD_SIZE_SHIFT)
#define DMA_CH_MOD_MD_SIZE_VALUE_KEEP 3U
#define DMA_CH_MOD_MD_SIZE_BITS_KEEP (DMA_CH_MOD_MD_SIZE_VALUE_KEEP << DMA_CH_MOD_MD_SIZE_SHIFT)
#define DMA_CH_MOD_MD_SEL_SHIFT 11
#define DMA_CH_MOD_MD_SEL_WIDTH 3
#define DMA_CH_MOD_MD_SEL_MASK (((1U << DMA_CH_MOD_MD_SEL_WIDTH) - 1U) << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_SRAM 0U
#define DMA_CH_MOD_MD_SEL_BITS_SRAM (DMA_CH_MOD_MD_SEL_VALUE_SRAM << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS0 1U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS0 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS0 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS1 2U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS1 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS1 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS2 3U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS2 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS2 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS3 4U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS3 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS3 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS4 5U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS4 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS4 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS5 6U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS5 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS5 << DMA_CH_MOD_MD_SEL_SHIFT)
#define DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS6 7U
#define DMA_CH_MOD_MD_SEL_BITS_HSREQ_MS6 (DMA_CH_MOD_MD_SEL_VALUE_HSREQ_MS6 << DMA_CH_MOD_MD_SEL_SHIFT)
#endif

165
bsp/dp32g030/flash.h Normal file
View File

@ -0,0 +1,165 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_FLASH_H
#define HARDWARE_DP32G030_FLASH_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- FLASH -------- */
#define FLASH_BASE_ADDR 0x4006F000U
#define FLASH_BASE_SIZE 0x00000800U
#define FLASH_CFG_ADDR (FLASH_BASE_ADDR + 0x0000U)
#define FLASH_CFG (*(volatile uint32_t *)FLASH_CFG_ADDR)
#define FLASH_CFG_READ_MD_SHIFT 0
#define FLASH_CFG_READ_MD_WIDTH 1
#define FLASH_CFG_READ_MD_MASK (((1U << FLASH_CFG_READ_MD_WIDTH) - 1U) << FLASH_CFG_READ_MD_SHIFT)
#define FLASH_CFG_READ_MD_VALUE_1_CYCLE 0U
#define FLASH_CFG_READ_MD_BITS_1_CYCLE (FLASH_CFG_READ_MD_VALUE_1_CYCLE << FLASH_CFG_READ_MD_SHIFT)
#define FLASH_CFG_READ_MD_VALUE_2_CYCLE 1U
#define FLASH_CFG_READ_MD_BITS_2_CYCLE (FLASH_CFG_READ_MD_VALUE_2_CYCLE << FLASH_CFG_READ_MD_SHIFT)
#define FLASH_CFG_NVR_SEL_SHIFT 1
#define FLASH_CFG_NVR_SEL_WIDTH 1
#define FLASH_CFG_NVR_SEL_MASK (((1U << FLASH_CFG_NVR_SEL_WIDTH) - 1U) << FLASH_CFG_NVR_SEL_SHIFT)
#define FLASH_CFG_NVR_SEL_VALUE_MAIN 0U
#define FLASH_CFG_NVR_SEL_BITS_MAIN (FLASH_CFG_NVR_SEL_VALUE_MAIN << FLASH_CFG_NVR_SEL_SHIFT)
#define FLASH_CFG_NVR_SEL_VALUE_NVR 1U
#define FLASH_CFG_NVR_SEL_BITS_NVR (FLASH_CFG_NVR_SEL_VALUE_NVR << FLASH_CFG_NVR_SEL_SHIFT)
#define FLASH_CFG_MODE_SHIFT 2
#define FLASH_CFG_MODE_WIDTH 3
#define FLASH_CFG_MODE_MASK (((1U << FLASH_CFG_MODE_WIDTH) - 1U) << FLASH_CFG_MODE_SHIFT)
#define FLASH_CFG_MODE_VALUE_READ_AHB 0U
#define FLASH_CFG_MODE_BITS_READ_AHB (FLASH_CFG_MODE_VALUE_READ_AHB << FLASH_CFG_MODE_SHIFT)
#define FLASH_CFG_MODE_VALUE_PROGRAM 1U
#define FLASH_CFG_MODE_BITS_PROGRAM (FLASH_CFG_MODE_VALUE_PROGRAM << FLASH_CFG_MODE_SHIFT)
#define FLASH_CFG_MODE_VALUE_ERASE 2U
#define FLASH_CFG_MODE_BITS_ERASE (FLASH_CFG_MODE_VALUE_ERASE << FLASH_CFG_MODE_SHIFT)
#define FLASH_CFG_MODE_VALUE_READ_APB 5U
#define FLASH_CFG_MODE_BITS_READ_APB (FLASH_CFG_MODE_VALUE_READ_APB << FLASH_CFG_MODE_SHIFT)
#define FLASH_CFG_DEEP_PD_SHIFT 31
#define FLASH_CFG_DEEP_PD_WIDTH 1
#define FLASH_CFG_DEEP_PD_MASK (((1U << FLASH_CFG_DEEP_PD_WIDTH) - 1U) << FLASH_CFG_DEEP_PD_SHIFT)
#define FLASH_CFG_DEEP_PD_VALUE_NORMAL 0U
#define FLASH_CFG_DEEP_PD_BITS_NORMAL (FLASH_CFG_DEEP_PD_VALUE_NORMAL << FLASH_CFG_DEEP_PD_SHIFT)
#define FLASH_CFG_DEEP_PD_VALUE_LOW_POWER 1U
#define FLASH_CFG_DEEP_PD_BITS_LOW_POWER (FLASH_CFG_DEEP_PD_VALUE_LOW_POWER << FLASH_CFG_DEEP_PD_SHIFT)
#define FLASH_ADDR_ADDR (FLASH_BASE_ADDR + 0x0004U)
#define FLASH_ADDR (*(volatile uint32_t *)FLASH_ADDR_ADDR)
#define FLASH_WDATA_ADDR (FLASH_BASE_ADDR + 0x0008U)
#define FLASH_WDATA (*(volatile uint32_t *)FLASH_WDATA_ADDR)
#define FLASH_RDATA_ADDR (FLASH_BASE_ADDR + 0x000CU)
#define FLASH_RDATA (*(volatile uint32_t *)FLASH_RDATA_ADDR)
#define FLASH_START_ADDR (FLASH_BASE_ADDR + 0x0010U)
#define FLASH_START (*(volatile uint32_t *)FLASH_START_ADDR)
#define FLASH_START_START_SHIFT 0
#define FLASH_START_START_WIDTH 1
#define FLASH_START_START_MASK (((1U << FLASH_START_START_WIDTH) - 1U) << FLASH_START_START_SHIFT)
#define FLASH_START_START_VALUE_START 1U
#define FLASH_START_START_BITS_START (FLASH_START_START_VALUE_START << FLASH_START_START_SHIFT)
#define FLASH_ST_ADDR (FLASH_BASE_ADDR + 0x0014U)
#define FLASH_ST (*(volatile uint32_t *)FLASH_ST_ADDR)
#define FLASH_ST_INIT_BUSY_SHIFT 0
#define FLASH_ST_INIT_BUSY_WIDTH 1
#define FLASH_ST_INIT_BUSY_MASK (((1U << FLASH_ST_INIT_BUSY_WIDTH) - 1U) << FLASH_ST_INIT_BUSY_SHIFT)
#define FLASH_ST_INIT_BUSY_VALUE_COMPLETE 0U
#define FLASH_ST_INIT_BUSY_BITS_COMPLETE (FLASH_ST_INIT_BUSY_VALUE_COMPLETE << FLASH_ST_INIT_BUSY_SHIFT)
#define FLASH_ST_INIT_BUSY_VALUE_BUSY 1U
#define FLASH_ST_INIT_BUSY_BITS_BUSY (FLASH_ST_INIT_BUSY_VALUE_BUSY << FLASH_ST_INIT_BUSY_SHIFT)
#define FLASH_ST_BUSY_SHIFT 1
#define FLASH_ST_BUSY_WIDTH 1
#define FLASH_ST_BUSY_MASK (((1U << FLASH_ST_BUSY_WIDTH) - 1U) << FLASH_ST_BUSY_SHIFT)
#define FLASH_ST_BUSY_VALUE_READY 0U
#define FLASH_ST_BUSY_BITS_READY (FLASH_ST_BUSY_VALUE_READY << FLASH_ST_BUSY_SHIFT)
#define FLASH_ST_BUSY_VALUE_BUSY 1U
#define FLASH_ST_BUSY_BITS_BUSY (FLASH_ST_BUSY_VALUE_BUSY << FLASH_ST_BUSY_SHIFT)
#define FLASH_ST_PROG_BUF_EMPTY_SHIFT 2
#define FLASH_ST_PROG_BUF_EMPTY_WIDTH 1
#define FLASH_ST_PROG_BUF_EMPTY_MASK (((1U << FLASH_ST_PROG_BUF_EMPTY_WIDTH) - 1U) << FLASH_ST_PROG_BUF_EMPTY_SHIFT)
#define FLASH_ST_PROG_BUF_EMPTY_VALUE_NOT_EMPTY 0U
#define FLASH_ST_PROG_BUF_EMPTY_BITS_NOT_EMPTY (FLASH_ST_PROG_BUF_EMPTY_VALUE_NOT_EMPTY << FLASH_ST_PROG_BUF_EMPTY_SHIFT)
#define FLASH_ST_PROG_BUF_EMPTY_VALUE_EMPTY 1U
#define FLASH_ST_PROG_BUF_EMPTY_BITS_EMPTY (FLASH_ST_PROG_BUF_EMPTY_VALUE_EMPTY << FLASH_ST_PROG_BUF_EMPTY_SHIFT)
#define FLASH_LOCK_ADDR (FLASH_BASE_ADDR + 0x0018U)
#define FLASH_LOCK (*(volatile uint32_t *)FLASH_LOCK_ADDR)
#define FLASH_LOCK_LOCK_SHIFT 0
#define FLASH_LOCK_LOCK_WIDTH 8
#define FLASH_LOCK_LOCK_MASK (((1U << FLASH_LOCK_LOCK_WIDTH) - 1U) << FLASH_LOCK_LOCK_SHIFT)
#define FLASH_LOCK_LOCK_VALUE_LOCK 85U
#define FLASH_LOCK_LOCK_BITS_LOCK (FLASH_LOCK_LOCK_VALUE_LOCK << FLASH_LOCK_LOCK_SHIFT)
#define FLASH_UNLOCK_ADDR (FLASH_BASE_ADDR + 0x001CU)
#define FLASH_UNLOCK (*(volatile uint32_t *)FLASH_UNLOCK_ADDR)
#define FLASH_UNLOCK_UNLOCK_SHIFT 0
#define FLASH_UNLOCK_UNLOCK_WIDTH 8
#define FLASH_UNLOCK_UNLOCK_MASK (((1U << FLASH_UNLOCK_UNLOCK_WIDTH) - 1U) << FLASH_UNLOCK_UNLOCK_SHIFT)
#define FLASH_UNLOCK_UNLOCK_VALUE_UNLOCK 170U
#define FLASH_UNLOCK_UNLOCK_BITS_UNLOCK (FLASH_UNLOCK_UNLOCK_VALUE_UNLOCK << FLASH_UNLOCK_UNLOCK_SHIFT)
#define FLASH_MASK_ADDR (FLASH_BASE_ADDR + 0x0020U)
#define FLASH_MASK (*(volatile uint32_t *)FLASH_MASK_ADDR)
#define FLASH_MASK_SEL_SHIFT 0
#define FLASH_MASK_SEL_WIDTH 2
#define FLASH_MASK_SEL_MASK (((1U << FLASH_MASK_SEL_WIDTH) - 1U) << FLASH_MASK_SEL_SHIFT)
#define FLASH_MASK_SEL_VALUE_NONE 0U
#define FLASH_MASK_SEL_BITS_NONE (FLASH_MASK_SEL_VALUE_NONE << FLASH_MASK_SEL_SHIFT)
#define FLASH_MASK_SEL_VALUE_2KB 1U
#define FLASH_MASK_SEL_BITS_2KB (FLASH_MASK_SEL_VALUE_2KB << FLASH_MASK_SEL_SHIFT)
#define FLASH_MASK_SEL_VALUE_4KB 2U
#define FLASH_MASK_SEL_BITS_4KB (FLASH_MASK_SEL_VALUE_4KB << FLASH_MASK_SEL_SHIFT)
#define FLASH_MASK_SEL_VALUE_8KB 3U
#define FLASH_MASK_SEL_BITS_8KB (FLASH_MASK_SEL_VALUE_8KB << FLASH_MASK_SEL_SHIFT)
#define FLASH_MASK_LOCK_SHIFT 2
#define FLASH_MASK_LOCK_WIDTH 1
#define FLASH_MASK_LOCK_MASK (((1U << FLASH_MASK_LOCK_WIDTH) - 1U) << FLASH_MASK_LOCK_SHIFT)
#define FLASH_MASK_LOCK_VALUE_NOT_SET 0U
#define FLASH_MASK_LOCK_BITS_NOT_SET (FLASH_MASK_LOCK_VALUE_NOT_SET << FLASH_MASK_LOCK_SHIFT)
#define FLASH_MASK_LOCK_VALUE_SET 1U
#define FLASH_MASK_LOCK_BITS_SET (FLASH_MASK_LOCK_VALUE_SET << FLASH_MASK_LOCK_SHIFT)
#define FLASH_ERASETIME_ADDR (FLASH_BASE_ADDR + 0x0024U)
#define FLASH_ERASETIME (*(volatile uint32_t *)FLASH_ERASETIME_ADDR)
#define FLASH_ERASETIME_TERASE_SHIFT 0
#define FLASH_ERASETIME_TERASE_WIDTH 19
#define FLASH_ERASETIME_TERASE_MASK (((1U << FLASH_ERASETIME_TERASE_WIDTH) - 1U) << FLASH_ERASETIME_TERASE_SHIFT)
#define FLASH_ERASETIME_TRCV_SHIFT 19
#define FLASH_ERASETIME_TRCV_WIDTH 12
#define FLASH_ERASETIME_TRCV_MASK (((1U << FLASH_ERASETIME_TRCV_WIDTH) - 1U) << FLASH_ERASETIME_TRCV_SHIFT)
#define FLASH_PROGTIME_ADDR (FLASH_BASE_ADDR + 0x0028U)
#define FLASH_PROGTIME (*(volatile uint32_t *)FLASH_PROGTIME_ADDR)
#define FLASH_PROGTIME_TPROG_SHIFT 0
#define FLASH_PROGTIME_TPROG_WIDTH 11
#define FLASH_PROGTIME_TPROG_MASK (((1U << FLASH_PROGTIME_TPROG_WIDTH) - 1U) << FLASH_PROGTIME_TPROG_SHIFT)
#define FLASH_PROGTIME_TPGS_SHIFT 11
#define FLASH_PROGTIME_TPGS_WIDTH 11
#define FLASH_PROGTIME_TPGS_MASK (((1U << FLASH_PROGTIME_TPGS_WIDTH) - 1U) << FLASH_PROGTIME_TPGS_SHIFT)
#endif

176
bsp/dp32g030/gpio.h Normal file
View File

@ -0,0 +1,176 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_GPIO_H
#define HARDWARE_DP32G030_GPIO_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- GPIOA -------- */
#define GPIOA_BASE_ADDR 0x40060000U
#define GPIOA_BASE_SIZE 0x00000800U
#define GPIOA ((volatile GPIO_Bank_t *)GPIOA_BASE_ADDR)
/* -------- GPIOB -------- */
#define GPIOB_BASE_ADDR 0x40060800U
#define GPIOB_BASE_SIZE 0x00000800U
#define GPIOB ((volatile GPIO_Bank_t *)GPIOB_BASE_ADDR)
/* -------- GPIOC -------- */
#define GPIOC_BASE_ADDR 0x40061000U
#define GPIOC_BASE_SIZE 0x00000800U
#define GPIOC ((volatile GPIO_Bank_t *)GPIOC_BASE_ADDR)
/* -------- GPIO -------- */
typedef struct {
uint32_t DATA;
uint32_t DIR;
} GPIO_Bank_t;
#define GPIO_DIR_0_SHIFT 0
#define GPIO_DIR_0_WIDTH 1
#define GPIO_DIR_0_MASK (((1U << GPIO_DIR_0_WIDTH) - 1U) << GPIO_DIR_0_SHIFT)
#define GPIO_DIR_0_VALUE_INPUT 0U
#define GPIO_DIR_0_BITS_INPUT (GPIO_DIR_0_VALUE_INPUT << GPIO_DIR_0_SHIFT)
#define GPIO_DIR_0_VALUE_OUTPUT 1U
#define GPIO_DIR_0_BITS_OUTPUT (GPIO_DIR_0_VALUE_OUTPUT << GPIO_DIR_0_SHIFT)
#define GPIO_DIR_1_SHIFT 1
#define GPIO_DIR_1_WIDTH 1
#define GPIO_DIR_1_MASK (((1U << GPIO_DIR_1_WIDTH) - 1U) << GPIO_DIR_1_SHIFT)
#define GPIO_DIR_1_VALUE_INPUT 0U
#define GPIO_DIR_1_BITS_INPUT (GPIO_DIR_1_VALUE_INPUT << GPIO_DIR_1_SHIFT)
#define GPIO_DIR_1_VALUE_OUTPUT 1U
#define GPIO_DIR_1_BITS_OUTPUT (GPIO_DIR_1_VALUE_OUTPUT << GPIO_DIR_1_SHIFT)
#define GPIO_DIR_2_SHIFT 2
#define GPIO_DIR_2_WIDTH 1
#define GPIO_DIR_2_MASK (((1U << GPIO_DIR_2_WIDTH) - 1U) << GPIO_DIR_2_SHIFT)
#define GPIO_DIR_2_VALUE_INPUT 0U
#define GPIO_DIR_2_BITS_INPUT (GPIO_DIR_2_VALUE_INPUT << GPIO_DIR_2_SHIFT)
#define GPIO_DIR_2_VALUE_OUTPUT 1U
#define GPIO_DIR_2_BITS_OUTPUT (GPIO_DIR_2_VALUE_OUTPUT << GPIO_DIR_2_SHIFT)
#define GPIO_DIR_3_SHIFT 3
#define GPIO_DIR_3_WIDTH 1
#define GPIO_DIR_3_MASK (((1U << GPIO_DIR_3_WIDTH) - 1U) << GPIO_DIR_3_SHIFT)
#define GPIO_DIR_3_VALUE_INPUT 0U
#define GPIO_DIR_3_BITS_INPUT (GPIO_DIR_3_VALUE_INPUT << GPIO_DIR_3_SHIFT)
#define GPIO_DIR_3_VALUE_OUTPUT 1U
#define GPIO_DIR_3_BITS_OUTPUT (GPIO_DIR_3_VALUE_OUTPUT << GPIO_DIR_3_SHIFT)
#define GPIO_DIR_4_SHIFT 4
#define GPIO_DIR_4_WIDTH 1
#define GPIO_DIR_4_MASK (((1U << GPIO_DIR_4_WIDTH) - 1U) << GPIO_DIR_4_SHIFT)
#define GPIO_DIR_4_VALUE_INPUT 0U
#define GPIO_DIR_4_BITS_INPUT (GPIO_DIR_4_VALUE_INPUT << GPIO_DIR_4_SHIFT)
#define GPIO_DIR_4_VALUE_OUTPUT 1U
#define GPIO_DIR_4_BITS_OUTPUT (GPIO_DIR_4_VALUE_OUTPUT << GPIO_DIR_4_SHIFT)
#define GPIO_DIR_5_SHIFT 5
#define GPIO_DIR_5_WIDTH 1
#define GPIO_DIR_5_MASK (((1U << GPIO_DIR_5_WIDTH) - 1U) << GPIO_DIR_5_SHIFT)
#define GPIO_DIR_5_VALUE_INPUT 0U
#define GPIO_DIR_5_BITS_INPUT (GPIO_DIR_5_VALUE_INPUT << GPIO_DIR_5_SHIFT)
#define GPIO_DIR_5_VALUE_OUTPUT 1U
#define GPIO_DIR_5_BITS_OUTPUT (GPIO_DIR_5_VALUE_OUTPUT << GPIO_DIR_5_SHIFT)
#define GPIO_DIR_6_SHIFT 6
#define GPIO_DIR_6_WIDTH 1
#define GPIO_DIR_6_MASK (((1U << GPIO_DIR_6_WIDTH) - 1U) << GPIO_DIR_6_SHIFT)
#define GPIO_DIR_6_VALUE_INPUT 0U
#define GPIO_DIR_6_BITS_INPUT (GPIO_DIR_6_VALUE_INPUT << GPIO_DIR_6_SHIFT)
#define GPIO_DIR_6_VALUE_OUTPUT 1U
#define GPIO_DIR_6_BITS_OUTPUT (GPIO_DIR_6_VALUE_OUTPUT << GPIO_DIR_6_SHIFT)
#define GPIO_DIR_7_SHIFT 7
#define GPIO_DIR_7_WIDTH 1
#define GPIO_DIR_7_MASK (((1U << GPIO_DIR_7_WIDTH) - 1U) << GPIO_DIR_7_SHIFT)
#define GPIO_DIR_7_VALUE_INPUT 0U
#define GPIO_DIR_7_BITS_INPUT (GPIO_DIR_7_VALUE_INPUT << GPIO_DIR_7_SHIFT)
#define GPIO_DIR_7_VALUE_OUTPUT 1U
#define GPIO_DIR_7_BITS_OUTPUT (GPIO_DIR_7_VALUE_OUTPUT << GPIO_DIR_7_SHIFT)
#define GPIO_DIR_8_SHIFT 8
#define GPIO_DIR_8_WIDTH 1
#define GPIO_DIR_8_MASK (((1U << GPIO_DIR_8_WIDTH) - 1U) << GPIO_DIR_8_SHIFT)
#define GPIO_DIR_8_VALUE_INPUT 0U
#define GPIO_DIR_8_BITS_INPUT (GPIO_DIR_8_VALUE_INPUT << GPIO_DIR_8_SHIFT)
#define GPIO_DIR_8_VALUE_OUTPUT 1U
#define GPIO_DIR_8_BITS_OUTPUT (GPIO_DIR_8_VALUE_OUTPUT << GPIO_DIR_8_SHIFT)
#define GPIO_DIR_9_SHIFT 9
#define GPIO_DIR_9_WIDTH 1
#define GPIO_DIR_9_MASK (((1U << GPIO_DIR_9_WIDTH) - 1U) << GPIO_DIR_9_SHIFT)
#define GPIO_DIR_9_VALUE_INPUT 0U
#define GPIO_DIR_9_BITS_INPUT (GPIO_DIR_9_VALUE_INPUT << GPIO_DIR_9_SHIFT)
#define GPIO_DIR_9_VALUE_OUTPUT 1U
#define GPIO_DIR_9_BITS_OUTPUT (GPIO_DIR_9_VALUE_OUTPUT << GPIO_DIR_9_SHIFT)
#define GPIO_DIR_10_SHIFT 10
#define GPIO_DIR_10_WIDTH 1
#define GPIO_DIR_10_MASK (((1U << GPIO_DIR_10_WIDTH) - 1U) << GPIO_DIR_10_SHIFT)
#define GPIO_DIR_10_VALUE_INPUT 0U
#define GPIO_DIR_10_BITS_INPUT (GPIO_DIR_10_VALUE_INPUT << GPIO_DIR_10_SHIFT)
#define GPIO_DIR_10_VALUE_OUTPUT 1U
#define GPIO_DIR_10_BITS_OUTPUT (GPIO_DIR_10_VALUE_OUTPUT << GPIO_DIR_10_SHIFT)
#define GPIO_DIR_11_SHIFT 11
#define GPIO_DIR_11_WIDTH 1
#define GPIO_DIR_11_MASK (((1U << GPIO_DIR_11_WIDTH) - 1U) << GPIO_DIR_11_SHIFT)
#define GPIO_DIR_11_VALUE_INPUT 0U
#define GPIO_DIR_11_BITS_INPUT (GPIO_DIR_11_VALUE_INPUT << GPIO_DIR_11_SHIFT)
#define GPIO_DIR_11_VALUE_OUTPUT 1U
#define GPIO_DIR_11_BITS_OUTPUT (GPIO_DIR_11_VALUE_OUTPUT << GPIO_DIR_11_SHIFT)
#define GPIO_DIR_12_SHIFT 12
#define GPIO_DIR_12_WIDTH 1
#define GPIO_DIR_12_MASK (((1U << GPIO_DIR_12_WIDTH) - 1U) << GPIO_DIR_12_SHIFT)
#define GPIO_DIR_12_VALUE_INPUT 0U
#define GPIO_DIR_12_BITS_INPUT (GPIO_DIR_12_VALUE_INPUT << GPIO_DIR_12_SHIFT)
#define GPIO_DIR_12_VALUE_OUTPUT 1U
#define GPIO_DIR_12_BITS_OUTPUT (GPIO_DIR_12_VALUE_OUTPUT << GPIO_DIR_12_SHIFT)
#define GPIO_DIR_13_SHIFT 13
#define GPIO_DIR_13_WIDTH 1
#define GPIO_DIR_13_MASK (((1U << GPIO_DIR_13_WIDTH) - 1U) << GPIO_DIR_13_SHIFT)
#define GPIO_DIR_13_VALUE_INPUT 0U
#define GPIO_DIR_13_BITS_INPUT (GPIO_DIR_13_VALUE_INPUT << GPIO_DIR_13_SHIFT)
#define GPIO_DIR_13_VALUE_OUTPUT 1U
#define GPIO_DIR_13_BITS_OUTPUT (GPIO_DIR_13_VALUE_OUTPUT << GPIO_DIR_13_SHIFT)
#define GPIO_DIR_14_SHIFT 14
#define GPIO_DIR_14_WIDTH 1
#define GPIO_DIR_14_MASK (((1U << GPIO_DIR_14_WIDTH) - 1U) << GPIO_DIR_14_SHIFT)
#define GPIO_DIR_14_VALUE_INPUT 0U
#define GPIO_DIR_14_BITS_INPUT (GPIO_DIR_14_VALUE_INPUT << GPIO_DIR_14_SHIFT)
#define GPIO_DIR_14_VALUE_OUTPUT 1U
#define GPIO_DIR_14_BITS_OUTPUT (GPIO_DIR_14_VALUE_OUTPUT << GPIO_DIR_14_SHIFT)
#define GPIO_DIR_15_SHIFT 15
#define GPIO_DIR_15_WIDTH 1
#define GPIO_DIR_15_MASK (((1U << GPIO_DIR_15_WIDTH) - 1U) << GPIO_DIR_15_SHIFT)
#define GPIO_DIR_15_VALUE_INPUT 0U
#define GPIO_DIR_15_BITS_INPUT (GPIO_DIR_15_VALUE_INPUT << GPIO_DIR_15_SHIFT)
#define GPIO_DIR_15_VALUE_OUTPUT 1U
#define GPIO_DIR_15_BITS_OUTPUT (GPIO_DIR_15_VALUE_OUTPUT << GPIO_DIR_15_SHIFT)
#endif

40
bsp/dp32g030/irq.h Normal file
View File

@ -0,0 +1,40 @@
#ifndef DP32G030_IRQ_H
#define DP32G030_IRQ_H
enum {
DP32_WWDT_IRQn = 0,
DP32_IWDT_IRQn,
DP32_RTC_IRQn,
DP32_DMA_IRQn,
DP32_SARADC_IRQn,
DP32_TIMER_BASE0_IRQn,
DP32_TIMER_BASE1_IRQn,
DP32_TIMER_PLUS0_IRQn,
DP32_TIMER_PLUS1_IRQn,
DP32_PWM_BASE0_IRQn,
DP32_PWM_BASE1_IRQn,
DP32_PWM_PLUS0_IRQn,
DP32_PWM_PLUS1_IRQn,
DP32_UART0_IRQn,
DP32_UART1_IRQn,
DP32_UART2_IRQn,
DP32_SPI0_IRQn,
DP32_SPI1_IRQn,
DP32_IIC0_IRQn,
DP32_IIC1_IRQn,
DP32_CMP_IRQn,
DP32_TIMER_BASE2_IRQn,
DP32_GPIOA5_IRQn,
DP32_GPIOA6_IRQn,
DP32_GPIOA7_IRQn,
DP32_GPIOB0_IRQn,
DP32_GPIOB1_IRQn,
DP32_GPIOC0_IRQn,
DP32_GPIOC1_IRQn,
DP32_GPIOA_IRQn,
DP32_GPIOB_IRQn,
DP32_GPIOC_IRQn,
};
#endif

65
bsp/dp32g030/pmu.h Normal file
View File

@ -0,0 +1,65 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_PMU_H
#define HARDWARE_DP32G030_PMU_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- PMU -------- */
#define PMU_BASE_ADDR 0x40000800U
#define PMU_BASE_SIZE 0x00000800U
#define PMU_SRC_CFG_ADDR (PMU_BASE_ADDR + 0x0010U)
#define PMU_SRC_CFG (*(volatile uint32_t *)PMU_SRC_CFG_ADDR)
#define PMU_SRC_CFG_RCHF_EN_SHIFT 0
#define PMU_SRC_CFG_RCHF_EN_WIDTH 1
#define PMU_SRC_CFG_RCHF_EN_MASK (((1U << PMU_SRC_CFG_RCHF_EN_WIDTH) - 1U) << PMU_SRC_CFG_RCHF_EN_SHIFT)
#define PMU_SRC_CFG_RCHF_EN_VALUE_DISABLE 0U
#define PMU_SRC_CFG_RCHF_EN_BITS_DISABLE (PMU_SRC_CFG_RCHF_EN_VALUE_DISABLE << PMU_SRC_CFG_RCHF_EN_SHIFT)
#define PMU_SRC_CFG_RCHF_EN_VALUE_ENABLE 1U
#define PMU_SRC_CFG_RCHF_EN_BITS_ENABLE (PMU_SRC_CFG_RCHF_EN_VALUE_ENABLE << PMU_SRC_CFG_RCHF_EN_SHIFT)
#define PMU_SRC_CFG_RCHF_SEL_SHIFT 1
#define PMU_SRC_CFG_RCHF_SEL_WIDTH 1
#define PMU_SRC_CFG_RCHF_SEL_MASK (((1U << PMU_SRC_CFG_RCHF_SEL_WIDTH) - 1U) << PMU_SRC_CFG_RCHF_SEL_SHIFT)
#define PMU_SRC_CFG_RCHF_SEL_VALUE_48MHZ 0U
#define PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ (PMU_SRC_CFG_RCHF_SEL_VALUE_48MHZ << PMU_SRC_CFG_RCHF_SEL_SHIFT)
#define PMU_SRC_CFG_RCHF_SEL_VALUE_24MHZ 1U
#define PMU_SRC_CFG_RCHF_SEL_BITS_24MHZ (PMU_SRC_CFG_RCHF_SEL_VALUE_24MHZ << PMU_SRC_CFG_RCHF_SEL_SHIFT)
#define PMU_TRIM_POW0_ADDR (PMU_BASE_ADDR + 0x0020U)
#define PMU_TRIM_POW0 (*(volatile uint32_t *)PMU_TRIM_POW0_ADDR)
#define PMU_TRIM_POW1_ADDR (PMU_BASE_ADDR + 0x0024U)
#define PMU_TRIM_POW1 (*(volatile uint32_t *)PMU_TRIM_POW1_ADDR)
#define PMU_TRIM_POW2_ADDR (PMU_BASE_ADDR + 0x0028U)
#define PMU_TRIM_POW2 (*(volatile uint32_t *)PMU_TRIM_POW2_ADDR)
#define PMU_TRIM_POW3_ADDR (PMU_BASE_ADDR + 0x002CU)
#define PMU_TRIM_POW3 (*(volatile uint32_t *)PMU_TRIM_POW3_ADDR)
#define PMU_TRIM_RCHF_ADDR (PMU_BASE_ADDR + 0x0030U)
#define PMU_TRIM_RCHF (*(volatile uint32_t *)PMU_TRIM_RCHF_ADDR)
#define PMU_TRIM_RCLF_ADDR (PMU_BASE_ADDR + 0x0034U)
#define PMU_TRIM_RCLF (*(volatile uint32_t *)PMU_TRIM_RCLF_ADDR)
#define PMU_TRIM_OPA_ADDR (PMU_BASE_ADDR + 0x0038U)
#define PMU_TRIM_OPA (*(volatile uint32_t *)PMU_TRIM_OPA_ADDR)
#define PMU_TRIM_PLL_ADDR (PMU_BASE_ADDR + 0x003CU)
#define PMU_TRIM_PLL (*(volatile uint32_t *)PMU_TRIM_PLL_ADDR)
#endif

2174
bsp/dp32g030/portcon.h Normal file

File diff suppressed because it is too large Load Diff

253
bsp/dp32g030/saradc.h Normal file
View File

@ -0,0 +1,253 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_SARADC_H
#define HARDWARE_DP32G030_SARADC_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- SARADC -------- */
#define SARADC_BASE_ADDR 0x400BA000U
#define SARADC_BASE_SIZE 0x00000800U
#define SARADC_CFG_ADDR (SARADC_BASE_ADDR + 0x0000U)
#define SARADC_CFG (*(volatile uint32_t *)SARADC_CFG_ADDR)
#define SARADC_CFG_CH_SEL_SHIFT 0
#define SARADC_CFG_CH_SEL_WIDTH 15
#define SARADC_CFG_CH_SEL_MASK (((1U << SARADC_CFG_CH_SEL_WIDTH) - 1U) << SARADC_CFG_CH_SEL_SHIFT)
#define SARADC_CFG_AVG_SHIFT 16
#define SARADC_CFG_AVG_WIDTH 2
#define SARADC_CFG_AVG_MASK (((1U << SARADC_CFG_AVG_WIDTH) - 1U) << SARADC_CFG_AVG_SHIFT)
#define SARADC_CFG_AVG_VALUE_1_SAMPLE 0U
#define SARADC_CFG_AVG_BITS_1_SAMPLE (SARADC_CFG_AVG_VALUE_1_SAMPLE << SARADC_CFG_AVG_SHIFT)
#define SARADC_CFG_AVG_VALUE_2_SAMPLE 1U
#define SARADC_CFG_AVG_BITS_2_SAMPLE (SARADC_CFG_AVG_VALUE_2_SAMPLE << SARADC_CFG_AVG_SHIFT)
#define SARADC_CFG_AVG_VALUE_4_SAMPLE 2U
#define SARADC_CFG_AVG_BITS_4_SAMPLE (SARADC_CFG_AVG_VALUE_4_SAMPLE << SARADC_CFG_AVG_SHIFT)
#define SARADC_CFG_AVG_VALUE_8_SAMPLE 3U
#define SARADC_CFG_AVG_BITS_8_SAMPLE (SARADC_CFG_AVG_VALUE_8_SAMPLE << SARADC_CFG_AVG_SHIFT)
#define SARADC_CFG_CONT_SHIFT 18
#define SARADC_CFG_CONT_WIDTH 1
#define SARADC_CFG_CONT_MASK (((1U << SARADC_CFG_CONT_WIDTH) - 1U) << SARADC_CFG_CONT_SHIFT)
#define SARADC_CFG_CONT_VALUE_SINGLE 0U
#define SARADC_CFG_CONT_BITS_SINGLE (SARADC_CFG_CONT_VALUE_SINGLE << SARADC_CFG_CONT_SHIFT)
#define SARADC_CFG_CONT_VALUE_CONTINUOUS 1U
#define SARADC_CFG_CONT_BITS_CONTINUOUS (SARADC_CFG_CONT_VALUE_CONTINUOUS << SARADC_CFG_CONT_SHIFT)
#define SARADC_CFG_SMPL_SETUP_SHIFT 19
#define SARADC_CFG_SMPL_SETUP_WIDTH 3
#define SARADC_CFG_SMPL_SETUP_MASK (((1U << SARADC_CFG_SMPL_SETUP_WIDTH) - 1U) << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE 0U
#define SARADC_CFG_SMPL_SETUP_BITS_1_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_1_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_2_CYCLE 1U
#define SARADC_CFG_SMPL_SETUP_BITS_2_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_2_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_4_CYCLE 2U
#define SARADC_CFG_SMPL_SETUP_BITS_4_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_4_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_8_CYCLE 3U
#define SARADC_CFG_SMPL_SETUP_BITS_8_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_8_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_16_CYCLE 4U
#define SARADC_CFG_SMPL_SETUP_BITS_16_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_16_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_32_CYCLE 5U
#define SARADC_CFG_SMPL_SETUP_BITS_32_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_32_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_64_CYCLE 6U
#define SARADC_CFG_SMPL_SETUP_BITS_64_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_64_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_SMPL_SETUP_VALUE_128_CYCLE 7U
#define SARADC_CFG_SMPL_SETUP_BITS_128_CYCLE (SARADC_CFG_SMPL_SETUP_VALUE_128_CYCLE << SARADC_CFG_SMPL_SETUP_SHIFT)
#define SARADC_CFG_MEM_MODE_SHIFT 22
#define SARADC_CFG_MEM_MODE_WIDTH 1
#define SARADC_CFG_MEM_MODE_MASK (((1U << SARADC_CFG_MEM_MODE_WIDTH) - 1U) << SARADC_CFG_MEM_MODE_SHIFT)
#define SARADC_CFG_MEM_MODE_VALUE_FIFO 0U
#define SARADC_CFG_MEM_MODE_BITS_FIFO (SARADC_CFG_MEM_MODE_VALUE_FIFO << SARADC_CFG_MEM_MODE_SHIFT)
#define SARADC_CFG_MEM_MODE_VALUE_CHANNEL 1U
#define SARADC_CFG_MEM_MODE_BITS_CHANNEL (SARADC_CFG_MEM_MODE_VALUE_CHANNEL << SARADC_CFG_MEM_MODE_SHIFT)
#define SARADC_CFG_SMPL_CLK_SHIFT 23
#define SARADC_CFG_SMPL_CLK_WIDTH 1
#define SARADC_CFG_SMPL_CLK_MASK (((1U << SARADC_CFG_SMPL_CLK_WIDTH) - 1U) << SARADC_CFG_SMPL_CLK_SHIFT)
#define SARADC_CFG_SMPL_CLK_VALUE_EXTERNAL 0U
#define SARADC_CFG_SMPL_CLK_BITS_EXTERNAL (SARADC_CFG_SMPL_CLK_VALUE_EXTERNAL << SARADC_CFG_SMPL_CLK_SHIFT)
#define SARADC_CFG_SMPL_CLK_VALUE_INTERNAL 1U
#define SARADC_CFG_SMPL_CLK_BITS_INTERNAL (SARADC_CFG_SMPL_CLK_VALUE_INTERNAL << SARADC_CFG_SMPL_CLK_SHIFT)
#define SARADC_CFG_SMPL_WIN_SHIFT 24
#define SARADC_CFG_SMPL_WIN_WIDTH 3
#define SARADC_CFG_SMPL_WIN_MASK (((1U << SARADC_CFG_SMPL_WIN_WIDTH) - 1U) << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_1_CYCLE 0U
#define SARADC_CFG_SMPL_WIN_BITS_1_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_1_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_3_CYCLE 1U
#define SARADC_CFG_SMPL_WIN_BITS_3_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_3_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_5_CYCLE 2U
#define SARADC_CFG_SMPL_WIN_BITS_5_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_5_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_7_CYCLE 3U
#define SARADC_CFG_SMPL_WIN_BITS_7_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_7_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_9_CYCLE 4U
#define SARADC_CFG_SMPL_WIN_BITS_9_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_9_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_11_CYCLE 5U
#define SARADC_CFG_SMPL_WIN_BITS_11_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_11_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_13_CYCLE 6U
#define SARADC_CFG_SMPL_WIN_BITS_13_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_13_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE 7U
#define SARADC_CFG_SMPL_WIN_BITS_15_CYCLE (SARADC_CFG_SMPL_WIN_VALUE_15_CYCLE << SARADC_CFG_SMPL_WIN_SHIFT)
#define SARADC_CFG_ADC_EN_SHIFT 27
#define SARADC_CFG_ADC_EN_WIDTH 1
#define SARADC_CFG_ADC_EN_MASK (((1U << SARADC_CFG_ADC_EN_WIDTH) - 1U) << SARADC_CFG_ADC_EN_SHIFT)
#define SARADC_CFG_ADC_EN_VALUE_DISABLE 0U
#define SARADC_CFG_ADC_EN_BITS_DISABLE (SARADC_CFG_ADC_EN_VALUE_DISABLE << SARADC_CFG_ADC_EN_SHIFT)
#define SARADC_CFG_ADC_EN_VALUE_ENABLE 1U
#define SARADC_CFG_ADC_EN_BITS_ENABLE (SARADC_CFG_ADC_EN_VALUE_ENABLE << SARADC_CFG_ADC_EN_SHIFT)
#define SARADC_CFG_ADC_TRIG_SHIFT 28
#define SARADC_CFG_ADC_TRIG_WIDTH 1
#define SARADC_CFG_ADC_TRIG_MASK (((1U << SARADC_CFG_ADC_TRIG_WIDTH) - 1U) << SARADC_CFG_ADC_TRIG_SHIFT)
#define SARADC_CFG_ADC_TRIG_VALUE_CPU 0U
#define SARADC_CFG_ADC_TRIG_BITS_CPU (SARADC_CFG_ADC_TRIG_VALUE_CPU << SARADC_CFG_ADC_TRIG_SHIFT)
#define SARADC_CFG_ADC_TRIG_VALUE_EXTERNAL 1U
#define SARADC_CFG_ADC_TRIG_BITS_EXTERNAL (SARADC_CFG_ADC_TRIG_VALUE_EXTERNAL << SARADC_CFG_ADC_TRIG_SHIFT)
#define SARADC_CFG_DMA_EN_SHIFT 29
#define SARADC_CFG_DMA_EN_WIDTH 1
#define SARADC_CFG_DMA_EN_MASK (((1U << SARADC_CFG_DMA_EN_WIDTH) - 1U) << SARADC_CFG_DMA_EN_SHIFT)
#define SARADC_CFG_DMA_EN_VALUE_DISABLE 0U
#define SARADC_CFG_DMA_EN_BITS_DISABLE (SARADC_CFG_DMA_EN_VALUE_DISABLE << SARADC_CFG_DMA_EN_SHIFT)
#define SARADC_CFG_DMA_EN_VALUE_ENABLE 1U
#define SARADC_CFG_DMA_EN_BITS_ENABLE (SARADC_CFG_DMA_EN_VALUE_ENABLE << SARADC_CFG_DMA_EN_SHIFT)
#define SARADC_START_ADDR (SARADC_BASE_ADDR + 0x0004U)
#define SARADC_START (*(volatile uint32_t *)SARADC_START_ADDR)
#define SARADC_START_START_SHIFT 0
#define SARADC_START_START_WIDTH 1
#define SARADC_START_START_MASK (((1U << SARADC_START_START_WIDTH) - 1U) << SARADC_START_START_SHIFT)
#define SARADC_START_START_VALUE_DISABLE 0U
#define SARADC_START_START_BITS_DISABLE (SARADC_START_START_VALUE_DISABLE << SARADC_START_START_SHIFT)
#define SARADC_START_START_VALUE_ENABLE 1U
#define SARADC_START_START_BITS_ENABLE (SARADC_START_START_VALUE_ENABLE << SARADC_START_START_SHIFT)
#define SARADC_START_SOFT_RESET_SHIFT 2
#define SARADC_START_SOFT_RESET_WIDTH 1
#define SARADC_START_SOFT_RESET_MASK (((1U << SARADC_START_SOFT_RESET_WIDTH) - 1U) << SARADC_START_SOFT_RESET_SHIFT)
#define SARADC_START_SOFT_RESET_VALUE_ASSERT 0U
#define SARADC_START_SOFT_RESET_BITS_ASSERT (SARADC_START_SOFT_RESET_VALUE_ASSERT << SARADC_START_SOFT_RESET_SHIFT)
#define SARADC_START_SOFT_RESET_VALUE_DEASSERT 1U
#define SARADC_START_SOFT_RESET_BITS_DEASSERT (SARADC_START_SOFT_RESET_VALUE_DEASSERT << SARADC_START_SOFT_RESET_SHIFT)
#define SARADC_IE_ADDR (SARADC_BASE_ADDR + 0x0008U)
#define SARADC_IE (*(volatile uint32_t *)SARADC_IE_ADDR)
#define SARADC_IE_CHx_EOC_SHIFT 0
#define SARADC_IE_CHx_EOC_WIDTH 16
#define SARADC_IE_CHx_EOC_MASK (((1U << SARADC_IE_CHx_EOC_WIDTH) - 1U) << SARADC_IE_CHx_EOC_SHIFT)
#define SARADC_IE_CHx_EOC_VALUE_NONE 0U
#define SARADC_IE_CHx_EOC_BITS_NONE (SARADC_IE_CHx_EOC_VALUE_NONE << SARADC_IE_CHx_EOC_SHIFT)
#define SARADC_IE_CHx_EOC_VALUE_ALL 65535U
#define SARADC_IE_CHx_EOC_BITS_ALL (SARADC_IE_CHx_EOC_VALUE_ALL << SARADC_IE_CHx_EOC_SHIFT)
#define SARADC_IE_FIFO_FULL_SHIFT 16
#define SARADC_IE_FIFO_FULL_WIDTH 1
#define SARADC_IE_FIFO_FULL_MASK (((1U << SARADC_IE_FIFO_FULL_WIDTH) - 1U) << SARADC_IE_FIFO_FULL_SHIFT)
#define SARADC_IE_FIFO_FULL_VALUE_DISABLE 0U
#define SARADC_IE_FIFO_FULL_BITS_DISABLE (SARADC_IE_FIFO_FULL_VALUE_DISABLE << SARADC_IE_FIFO_FULL_SHIFT)
#define SARADC_IE_FIFO_FULL_VALUE_ENABLE 1U
#define SARADC_IE_FIFO_FULL_BITS_ENABLE (SARADC_IE_FIFO_FULL_VALUE_ENABLE << SARADC_IE_FIFO_FULL_SHIFT)
#define SARADC_IE_FIFO_HFULL_SHIFT 17
#define SARADC_IE_FIFO_HFULL_WIDTH 1
#define SARADC_IE_FIFO_HFULL_MASK (((1U << SARADC_IE_FIFO_HFULL_WIDTH) - 1U) << SARADC_IE_FIFO_HFULL_SHIFT)
#define SARADC_IE_FIFO_HFULL_VALUE_DISABLE 0U
#define SARADC_IE_FIFO_HFULL_BITS_DISABLE (SARADC_IE_FIFO_HFULL_VALUE_DISABLE << SARADC_IE_FIFO_HFULL_SHIFT)
#define SARADC_IE_FIFO_HFULL_VALUE_ENABLE 1U
#define SARADC_IE_FIFO_HFULL_BITS_ENABLE (SARADC_IE_FIFO_HFULL_VALUE_ENABLE << SARADC_IE_FIFO_HFULL_SHIFT)
#define SARADC_IF_ADDR (SARADC_BASE_ADDR + 0x000CU)
#define SARADC_IF (*(volatile uint32_t *)SARADC_IF_ADDR)
#define SARADC_IF_CHx_EOC_SHIFT 0
#define SARADC_IF_CHx_EOC_WIDTH 16
#define SARADC_IF_CHx_EOC_MASK (((1U << SARADC_IF_CHx_EOC_WIDTH) - 1U) << SARADC_IF_CHx_EOC_SHIFT)
#define SARADC_IF_FIFO_FULL_SHIFT 16
#define SARADC_IF_FIFO_FULL_WIDTH 1
#define SARADC_IF_FIFO_FULL_MASK (((1U << SARADC_IF_FIFO_FULL_WIDTH) - 1U) << SARADC_IF_FIFO_FULL_SHIFT)
#define SARADC_IF_FIFO_FULL_VALUE_NOT_SET 0U
#define SARADC_IF_FIFO_FULL_BITS_NOT_SET (SARADC_IF_FIFO_FULL_VALUE_NOT_SET << SARADC_IF_FIFO_FULL_SHIFT)
#define SARADC_IF_FIFO_FULL_VALUE_SET 1U
#define SARADC_IF_FIFO_FULL_BITS_SET (SARADC_IF_FIFO_FULL_VALUE_SET << SARADC_IF_FIFO_FULL_SHIFT)
#define SARADC_IF_FIFO_HFULL_SHIFT 17
#define SARADC_IF_FIFO_HFULL_WIDTH 1
#define SARADC_IF_FIFO_HFULL_MASK (((1U << SARADC_IF_FIFO_HFULL_WIDTH) - 1U) << SARADC_IF_FIFO_HFULL_SHIFT)
#define SARADC_IF_FIFO_HFULL_VALUE_NOT_SET 0U
#define SARADC_IF_FIFO_HFULL_BITS_NOT_SET (SARADC_IF_FIFO_HFULL_VALUE_NOT_SET << SARADC_IF_FIFO_HFULL_SHIFT)
#define SARADC_IF_FIFO_HFULL_VALUE_SET 1U
#define SARADC_IF_FIFO_HFULL_BITS_SET (SARADC_IF_FIFO_HFULL_VALUE_SET << SARADC_IF_FIFO_HFULL_SHIFT)
#define SARADC_CH0_ADDR (SARADC_BASE_ADDR + 0x0010U)
#define SARADC_CH0 (*(volatile uint32_t *)SARADC_CH0_ADDR)
#define SARADC_EXTTRIG_SEL_ADDR (SARADC_BASE_ADDR + 0x00B0U)
#define SARADC_EXTTRIG_SEL (*(volatile uint32_t *)SARADC_EXTTRIG_SEL_ADDR)
#define SARADC_CALIB_OFFSET_ADDR (SARADC_BASE_ADDR + 0x00F0U)
#define SARADC_CALIB_OFFSET (*(volatile uint32_t *)SARADC_CALIB_OFFSET_ADDR)
#define SARADC_CALIB_OFFSET_OFFSET_SHIFT 0
#define SARADC_CALIB_OFFSET_OFFSET_WIDTH 8
#define SARADC_CALIB_OFFSET_OFFSET_MASK (((1U << SARADC_CALIB_OFFSET_OFFSET_WIDTH) - 1U) << SARADC_CALIB_OFFSET_OFFSET_SHIFT)
#define SARADC_CALIB_OFFSET_VALID_SHIFT 16
#define SARADC_CALIB_OFFSET_VALID_WIDTH 1
#define SARADC_CALIB_OFFSET_VALID_MASK (((1U << SARADC_CALIB_OFFSET_VALID_WIDTH) - 1U) << SARADC_CALIB_OFFSET_VALID_SHIFT)
#define SARADC_CALIB_OFFSET_VALID_VALUE_NO 0U
#define SARADC_CALIB_OFFSET_VALID_BITS_NO (SARADC_CALIB_OFFSET_VALID_VALUE_NO << SARADC_CALIB_OFFSET_VALID_SHIFT)
#define SARADC_CALIB_OFFSET_VALID_VALUE_YES 1U
#define SARADC_CALIB_OFFSET_VALID_BITS_YES (SARADC_CALIB_OFFSET_VALID_VALUE_YES << SARADC_CALIB_OFFSET_VALID_SHIFT)
#define SARADC_CALIB_KD_ADDR (SARADC_BASE_ADDR + 0x00F4U)
#define SARADC_CALIB_KD (*(volatile uint32_t *)SARADC_CALIB_KD_ADDR)
#define SARADC_CALIB_KD_KD_SHIFT 0
#define SARADC_CALIB_KD_KD_WIDTH 8
#define SARADC_CALIB_KD_KD_MASK (((1U << SARADC_CALIB_KD_KD_WIDTH) - 1U) << SARADC_CALIB_KD_KD_SHIFT)
#define SARADC_CALIB_KD_VALID_SHIFT 16
#define SARADC_CALIB_KD_VALID_WIDTH 1
#define SARADC_CALIB_KD_VALID_MASK (((1U << SARADC_CALIB_KD_VALID_WIDTH) - 1U) << SARADC_CALIB_KD_VALID_SHIFT)
#define SARADC_CALIB_KD_VALID_VALUE_NO 0U
#define SARADC_CALIB_KD_VALID_BITS_NO (SARADC_CALIB_KD_VALID_VALUE_NO << SARADC_CALIB_KD_VALID_SHIFT)
#define SARADC_CALIB_KD_VALID_VALUE_YES 1U
#define SARADC_CALIB_KD_VALID_BITS_YES (SARADC_CALIB_KD_VALID_VALUE_YES << SARADC_CALIB_KD_VALID_SHIFT)
/* -------- ADC_CHx -------- */
typedef struct {
uint32_t STAT;
uint32_t DATA;
} ADC_Channel_t;
#define ADC_CHx_STAT_EOC_SHIFT 0
#define ADC_CHx_STAT_EOC_WIDTH 1
#define ADC_CHx_STAT_EOC_MASK (((1U << ADC_CHx_STAT_EOC_WIDTH) - 1U) << ADC_CHx_STAT_EOC_SHIFT)
#define ADC_CHx_STAT_EOC_VALUE_NOT_COMPLETE 0U
#define ADC_CHx_STAT_EOC_BITS_NOT_COMPLETE (ADC_CHx_STAT_EOC_VALUE_NOT_COMPLETE << ADC_CHx_STAT_EOC_SHIFT)
#define ADC_CHx_STAT_EOC_VALUE_COMPLETE 1U
#define ADC_CHx_STAT_EOC_BITS_COMPLETE (ADC_CHx_STAT_EOC_VALUE_COMPLETE << ADC_CHx_STAT_EOC_SHIFT)
#define ADC_CHx_DATA_DATA_SHIFT 0
#define ADC_CHx_DATA_DATA_WIDTH 12
#define ADC_CHx_DATA_DATA_MASK (((1U << ADC_CHx_DATA_DATA_WIDTH) - 1U) << ADC_CHx_DATA_DATA_SHIFT)
#define ADC_CHx_DATA_NUM_SHIFT 12
#define ADC_CHx_DATA_NUM_WIDTH 4
#define ADC_CHx_DATA_NUM_MASK (((1U << ADC_CHx_DATA_NUM_WIDTH) - 1U) << ADC_CHx_DATA_NUM_SHIFT)
#endif

240
bsp/dp32g030/spi.h Normal file
View File

@ -0,0 +1,240 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_SPI_H
#define HARDWARE_DP32G030_SPI_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- SPI0 -------- */
#define SPI0_BASE_ADDR 0x400B8000U
#define SPI0_BASE_SIZE 0x00000800U
#define SPI0 ((volatile SPI_Port_t *)SPI0_BASE_ADDR)
/* -------- SPI1 -------- */
#define SPI1_BASE_ADDR 0x400B8800U
#define SPI1_BASE_SIZE 0x00000800U
#define SPI1 ((volatile SPI_Port_t *)SPI1_BASE_ADDR)
/* -------- SPI -------- */
typedef struct {
uint32_t CR;
uint32_t WDR;
uint32_t RDR;
uint32_t Reserved_000C[1];
uint32_t IE;
uint32_t IF;
uint32_t FIFOST;
} SPI_Port_t;
#define SPI_CR_SPR_SHIFT 0
#define SPI_CR_SPR_WIDTH 3
#define SPI_CR_SPR_MASK (((1U << SPI_CR_SPR_WIDTH) - 1U) << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_4 0U
#define SPI_CR_SPR_BITS_FPCLK_DIV_4 (SPI_CR_SPR_VALUE_FPCLK_DIV_4 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_8 1U
#define SPI_CR_SPR_BITS_FPCLK_DIV_8 (SPI_CR_SPR_VALUE_FPCLK_DIV_8 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_16 2U
#define SPI_CR_SPR_BITS_FPCLK_DIV_16 (SPI_CR_SPR_VALUE_FPCLK_DIV_16 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_32 3U
#define SPI_CR_SPR_BITS_FPCLK_DIV_32 (SPI_CR_SPR_VALUE_FPCLK_DIV_32 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_64 4U
#define SPI_CR_SPR_BITS_FPCLK_DIV_64 (SPI_CR_SPR_VALUE_FPCLK_DIV_64 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_128 5U
#define SPI_CR_SPR_BITS_FPCLK_DIV_128 (SPI_CR_SPR_VALUE_FPCLK_DIV_128 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_256 6U
#define SPI_CR_SPR_BITS_FPCLK_DIV_256 (SPI_CR_SPR_VALUE_FPCLK_DIV_256 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPR_VALUE_FPCLK_DIV_512 7U
#define SPI_CR_SPR_BITS_FPCLK_DIV_512 (SPI_CR_SPR_VALUE_FPCLK_DIV_512 << SPI_CR_SPR_SHIFT)
#define SPI_CR_SPE_SHIFT 3
#define SPI_CR_SPE_WIDTH 1
#define SPI_CR_SPE_MASK (((1U << SPI_CR_SPE_WIDTH) - 1U) << SPI_CR_SPE_SHIFT)
#define SPI_CR_SPE_VALUE_DISABLE 0U
#define SPI_CR_SPE_BITS_DISABLE (SPI_CR_SPE_VALUE_DISABLE << SPI_CR_SPE_SHIFT)
#define SPI_CR_SPE_VALUE_ENABLE 1U
#define SPI_CR_SPE_BITS_ENABLE (SPI_CR_SPE_VALUE_ENABLE << SPI_CR_SPE_SHIFT)
#define SPI_CR_CPHA_SHIFT 4
#define SPI_CR_CPHA_WIDTH 1
#define SPI_CR_CPHA_MASK (((1U << SPI_CR_CPHA_WIDTH) - 1U) << SPI_CR_CPHA_SHIFT)
#define SPI_CR_CPOL_SHIFT 5
#define SPI_CR_CPOL_WIDTH 1
#define SPI_CR_CPOL_MASK (((1U << SPI_CR_CPOL_WIDTH) - 1U) << SPI_CR_CPOL_SHIFT)
#define SPI_CR_MSTR_SHIFT 6
#define SPI_CR_MSTR_WIDTH 1
#define SPI_CR_MSTR_MASK (((1U << SPI_CR_MSTR_WIDTH) - 1U) << SPI_CR_MSTR_SHIFT)
#define SPI_CR_LSB_SHIFT 7
#define SPI_CR_LSB_WIDTH 1
#define SPI_CR_LSB_MASK (((1U << SPI_CR_LSB_WIDTH) - 1U) << SPI_CR_LSB_SHIFT)
#define SPI_CR_CPHA_DATA_HOLD_S_SHIFT 8
#define SPI_CR_CPHA_DATA_HOLD_S_WIDTH 4
#define SPI_CR_CPHA_DATA_HOLD_S_MASK (((1U << SPI_CR_CPHA_DATA_HOLD_S_WIDTH) - 1U) << SPI_CR_CPHA_DATA_HOLD_S_SHIFT)
#define SPI_CR_MSR_SSN_SHIFT 12
#define SPI_CR_MSR_SSN_WIDTH 1
#define SPI_CR_MSR_SSN_MASK (((1U << SPI_CR_MSR_SSN_WIDTH) - 1U) << SPI_CR_MSR_SSN_SHIFT)
#define SPI_CR_MSR_SSN_VALUE_DISABLE 0U
#define SPI_CR_MSR_SSN_BITS_DISABLE (SPI_CR_MSR_SSN_VALUE_DISABLE << SPI_CR_MSR_SSN_SHIFT)
#define SPI_CR_MSR_SSN_VALUE_ENABLE 1U
#define SPI_CR_MSR_SSN_BITS_ENABLE (SPI_CR_MSR_SSN_VALUE_ENABLE << SPI_CR_MSR_SSN_SHIFT)
#define SPI_CR_RXDMAEN_SHIFT 13
#define SPI_CR_RXDMAEN_WIDTH 1
#define SPI_CR_RXDMAEN_MASK (((1U << SPI_CR_RXDMAEN_WIDTH) - 1U) << SPI_CR_RXDMAEN_SHIFT)
#define SPI_CR_TXDMAEN_SHIFT 14
#define SPI_CR_TXDMAEN_WIDTH 1
#define SPI_CR_TXDMAEN_MASK (((1U << SPI_CR_TXDMAEN_WIDTH) - 1U) << SPI_CR_TXDMAEN_SHIFT)
#define SPI_CR_RF_CLR_SHIFT 15
#define SPI_CR_RF_CLR_WIDTH 1
#define SPI_CR_RF_CLR_MASK (((1U << SPI_CR_RF_CLR_WIDTH) - 1U) << SPI_CR_RF_CLR_SHIFT)
#define SPI_CR_TF_CLR_SHIFT 16
#define SPI_CR_TF_CLR_WIDTH 1
#define SPI_CR_TF_CLR_MASK (((1U << SPI_CR_TF_CLR_WIDTH) - 1U) << SPI_CR_TF_CLR_SHIFT)
#define SPI_IE_RXFIFO_OVF_SHIFT 0
#define SPI_IE_RXFIFO_OVF_WIDTH 1
#define SPI_IE_RXFIFO_OVF_MASK (((1U << SPI_IE_RXFIFO_OVF_WIDTH) - 1U) << SPI_IE_RXFIFO_OVF_SHIFT)
#define SPI_IE_RXFIFO_OVF_VALUE_DISABLE 0U
#define SPI_IE_RXFIFO_OVF_BITS_DISABLE (SPI_IE_RXFIFO_OVF_VALUE_DISABLE << SPI_IE_RXFIFO_OVF_SHIFT)
#define SPI_IE_RXFIFO_OVF_VALUE_ENABLE 1U
#define SPI_IE_RXFIFO_OVF_BITS_ENABLE (SPI_IE_RXFIFO_OVF_VALUE_ENABLE << SPI_IE_RXFIFO_OVF_SHIFT)
#define SPI_IE_RXFIFO_FULL_SHIFT 1
#define SPI_IE_RXFIFO_FULL_WIDTH 1
#define SPI_IE_RXFIFO_FULL_MASK (((1U << SPI_IE_RXFIFO_FULL_WIDTH) - 1U) << SPI_IE_RXFIFO_FULL_SHIFT)
#define SPI_IE_RXFIFO_FULL_VALUE_DISABLE 0U
#define SPI_IE_RXFIFO_FULL_BITS_DISABLE (SPI_IE_RXFIFO_FULL_VALUE_DISABLE << SPI_IE_RXFIFO_FULL_SHIFT)
#define SPI_IE_RXFIFO_FULL_VALUE_ENABLE 1U
#define SPI_IE_RXFIFO_FULL_BITS_ENABLE (SPI_IE_RXFIFO_FULL_VALUE_ENABLE << SPI_IE_RXFIFO_FULL_SHIFT)
#define SPI_IE_RXFIFO_HFULL_SHIFT 2
#define SPI_IE_RXFIFO_HFULL_WIDTH 1
#define SPI_IE_RXFIFO_HFULL_MASK (((1U << SPI_IE_RXFIFO_HFULL_WIDTH) - 1U) << SPI_IE_RXFIFO_HFULL_SHIFT)
#define SPI_IE_RXFIFO_HFULL_VALUE_DISABLE 0U
#define SPI_IE_RXFIFO_HFULL_BITS_DISABLE (SPI_IE_RXFIFO_HFULL_VALUE_DISABLE << SPI_IE_RXFIFO_HFULL_SHIFT)
#define SPI_IE_RXFIFO_HFULL_VALUE_ENABLE 1U
#define SPI_IE_RXFIFO_HFULL_BITS_ENABLE (SPI_IE_RXFIFO_HFULL_VALUE_ENABLE << SPI_IE_RXFIFO_HFULL_SHIFT)
#define SPI_IE_TXFIFO_EMPTY_SHIFT 3
#define SPI_IE_TXFIFO_EMPTY_WIDTH 1
#define SPI_IE_TXFIFO_EMPTY_MASK (((1U << SPI_IE_TXFIFO_EMPTY_WIDTH) - 1U) << SPI_IE_TXFIFO_EMPTY_SHIFT)
#define SPI_IE_TXFIFO_EMPTY_VALUE_DISABLE 0U
#define SPI_IE_TXFIFO_EMPTY_BITS_DISABLE (SPI_IE_TXFIFO_EMPTY_VALUE_DISABLE << SPI_IE_TXFIFO_EMPTY_SHIFT)
#define SPI_IE_TXFIFO_EMPTY_VALUE_ENABLE 1U
#define SPI_IE_TXFIFO_EMPTY_BITS_ENABLE (SPI_IE_TXFIFO_EMPTY_VALUE_ENABLE << SPI_IE_TXFIFO_EMPTY_SHIFT)
#define SPI_IE_TXFIFO_HFULL_SHIFT 4
#define SPI_IE_TXFIFO_HFULL_WIDTH 1
#define SPI_IE_TXFIFO_HFULL_MASK (((1U << SPI_IE_TXFIFO_HFULL_WIDTH) - 1U) << SPI_IE_TXFIFO_HFULL_SHIFT)
#define SPI_IE_TXFIFO_HFULL_VALUE_DISABLE 0U
#define SPI_IE_TXFIFO_HFULL_BITS_DISABLE (SPI_IE_TXFIFO_HFULL_VALUE_DISABLE << SPI_IE_TXFIFO_HFULL_SHIFT)
#define SPI_IE_TXFIFO_HFULL_VALUE_ENABLE 1U
#define SPI_IE_TXFIFO_HFULL_BITS_ENABLE (SPI_IE_TXFIFO_HFULL_VALUE_ENABLE << SPI_IE_TXFIFO_HFULL_SHIFT)
#define SPI_FIFOST_RFE_SHIFT 0
#define SPI_FIFOST_RFE_WIDTH 1
#define SPI_FIFOST_RFE_MASK (((1U << SPI_FIFOST_RFE_WIDTH) - 1U) << SPI_FIFOST_RFE_SHIFT)
#define SPI_FIFOST_RFE_VALUE_NOT_EMPTY 0U
#define SPI_FIFOST_RFE_BITS_NOT_EMPTY (SPI_FIFOST_RFE_VALUE_NOT_EMPTY << SPI_FIFOST_RFE_SHIFT)
#define SPI_FIFOST_RFE_VALUE_EMPTY 1U
#define SPI_FIFOST_RFE_BITS_EMPTY (SPI_FIFOST_RFE_VALUE_EMPTY << SPI_FIFOST_RFE_SHIFT)
#define SPI_FIFOST_RFF_SHIFT 1
#define SPI_FIFOST_RFF_WIDTH 1
#define SPI_FIFOST_RFF_MASK (((1U << SPI_FIFOST_RFF_WIDTH) - 1U) << SPI_FIFOST_RFF_SHIFT)
#define SPI_FIFOST_RFF_VALUE_NOT_FULL 0U
#define SPI_FIFOST_RFF_BITS_NOT_FULL (SPI_FIFOST_RFF_VALUE_NOT_FULL << SPI_FIFOST_RFF_SHIFT)
#define SPI_FIFOST_RFF_VALUE_FULL 1U
#define SPI_FIFOST_RFF_BITS_FULL (SPI_FIFOST_RFF_VALUE_FULL << SPI_FIFOST_RFF_SHIFT)
#define SPI_FIFOST_RFHF_SHIFT 2
#define SPI_FIFOST_RFHF_WIDTH 1
#define SPI_FIFOST_RFHF_MASK (((1U << SPI_FIFOST_RFHF_WIDTH) - 1U) << SPI_FIFOST_RFHF_SHIFT)
#define SPI_FIFOST_RFHF_VALUE_NOT_HALF_FULL 0U
#define SPI_FIFOST_RFHF_BITS_NOT_HALF_FULL (SPI_FIFOST_RFHF_VALUE_NOT_HALF_FULL << SPI_FIFOST_RFHF_SHIFT)
#define SPI_FIFOST_RFHF_VALUE_HALF_FULL 1U
#define SPI_FIFOST_RFHF_BITS_HALF_FULL (SPI_FIFOST_RFHF_VALUE_HALF_FULL << SPI_FIFOST_RFHF_SHIFT)
#define SPI_FIFOST_TFE_SHIFT 3
#define SPI_FIFOST_TFE_WIDTH 1
#define SPI_FIFOST_TFE_MASK (((1U << SPI_FIFOST_TFE_WIDTH) - 1U) << SPI_FIFOST_TFE_SHIFT)
#define SPI_FIFOST_TFE_VALUE_NOT_EMPTY 0U
#define SPI_FIFOST_TFE_BITS_NOT_EMPTY (SPI_FIFOST_TFE_VALUE_NOT_EMPTY << SPI_FIFOST_TFE_SHIFT)
#define SPI_FIFOST_TFE_VALUE_EMPTY 1U
#define SPI_FIFOST_TFE_BITS_EMPTY (SPI_FIFOST_TFE_VALUE_EMPTY << SPI_FIFOST_TFE_SHIFT)
#define SPI_FIFOST_TFF_SHIFT 4
#define SPI_FIFOST_TFF_WIDTH 1
#define SPI_FIFOST_TFF_MASK (((1U << SPI_FIFOST_TFF_WIDTH) - 1U) << SPI_FIFOST_TFF_SHIFT)
#define SPI_FIFOST_TFF_VALUE_NOT_FULL 0U
#define SPI_FIFOST_TFF_BITS_NOT_FULL (SPI_FIFOST_TFF_VALUE_NOT_FULL << SPI_FIFOST_TFF_SHIFT)
#define SPI_FIFOST_TFF_VALUE_FULL 1U
#define SPI_FIFOST_TFF_BITS_FULL (SPI_FIFOST_TFF_VALUE_FULL << SPI_FIFOST_TFF_SHIFT)
#define SPI_FIFOST_TFHF_SHIFT 5
#define SPI_FIFOST_TFHF_WIDTH 1
#define SPI_FIFOST_TFHF_MASK (((1U << SPI_FIFOST_TFHF_WIDTH) - 1U) << SPI_FIFOST_TFHF_SHIFT)
#define SPI_FIFOST_TFHF_VALUE_NOT_HALF_FULL 0U
#define SPI_FIFOST_TFHF_BITS_NOT_HALF_FULL (SPI_FIFOST_TFHF_VALUE_NOT_HALF_FULL << SPI_FIFOST_TFHF_SHIFT)
#define SPI_FIFOST_TFHF_VALUE_HALF_FULL 1U
#define SPI_FIFOST_TFHF_BITS_HALF_FULL (SPI_FIFOST_TFHF_VALUE_HALF_FULL << SPI_FIFOST_TFHF_SHIFT)
#define SPI_FIFOST_RF_LEVEL_SHIFT 6
#define SPI_FIFOST_RF_LEVEL_WIDTH 3
#define SPI_FIFOST_RF_LEVEL_MASK (((1U << SPI_FIFOST_RF_LEVEL_WIDTH) - 1U) << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_0_BYTE 0U
#define SPI_FIFOST_RF_LEVEL_BITS_0_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_0_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_1_BYTE 1U
#define SPI_FIFOST_RF_LEVEL_BITS_1_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_1_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_2_BYTE 2U
#define SPI_FIFOST_RF_LEVEL_BITS_2_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_2_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_3_BYTE 3U
#define SPI_FIFOST_RF_LEVEL_BITS_3_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_3_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_4_BYTE 4U
#define SPI_FIFOST_RF_LEVEL_BITS_4_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_4_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_5_BYTE 5U
#define SPI_FIFOST_RF_LEVEL_BITS_5_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_5_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_6_BYTE 6U
#define SPI_FIFOST_RF_LEVEL_BITS_6_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_6_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_RF_LEVEL_VALUE_7_BYTE 7U
#define SPI_FIFOST_RF_LEVEL_BITS_7_BYTE (SPI_FIFOST_RF_LEVEL_VALUE_7_BYTE << SPI_FIFOST_RF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_SHIFT 9
#define SPI_FIFOST_TF_LEVEL_WIDTH 3
#define SPI_FIFOST_TF_LEVEL_MASK (((1U << SPI_FIFOST_TF_LEVEL_WIDTH) - 1U) << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_0_BYTE 0U
#define SPI_FIFOST_TF_LEVEL_BITS_0_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_0_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_1_BYTE 1U
#define SPI_FIFOST_TF_LEVEL_BITS_1_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_1_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_2_BYTE 2U
#define SPI_FIFOST_TF_LEVEL_BITS_2_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_2_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_3_BYTE 3U
#define SPI_FIFOST_TF_LEVEL_BITS_3_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_3_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_4_BYTE 4U
#define SPI_FIFOST_TF_LEVEL_BITS_4_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_4_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_5_BYTE 5U
#define SPI_FIFOST_TF_LEVEL_BITS_5_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_5_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_6_BYTE 6U
#define SPI_FIFOST_TF_LEVEL_BITS_6_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_6_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#define SPI_FIFOST_TF_LEVEL_VALUE_7_BYTE 7U
#define SPI_FIFOST_TF_LEVEL_BITS_7_BYTE (SPI_FIFOST_TF_LEVEL_VALUE_7_BYTE << SPI_FIFOST_TF_LEVEL_SHIFT)
#endif

348
bsp/dp32g030/syscon.h Normal file
View File

@ -0,0 +1,348 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_SYSCON_H
#define HARDWARE_DP32G030_SYSCON_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- SYSCON -------- */
#define SYSCON_BASE_ADDR 0x40000000U
#define SYSCON_BASE_SIZE 0x00000800U
#define SYSCON_CLK_SEL_ADDR (SYSCON_BASE_ADDR + 0x0000U)
#define SYSCON_CLK_SEL (*(volatile uint32_t *)SYSCON_CLK_SEL_ADDR)
#define SYSCON_CLK_SEL_SYS_SHIFT 0
#define SYSCON_CLK_SEL_SYS_WIDTH 1
#define SYSCON_CLK_SEL_SYS_MASK (((1U << SYSCON_CLK_SEL_SYS_WIDTH) - 1U) << SYSCON_CLK_SEL_SYS_SHIFT)
#define SYSCON_CLK_SEL_SYS_VALUE_RCHF 0U
#define SYSCON_CLK_SEL_SYS_BITS_RCHF (SYSCON_CLK_SEL_SYS_VALUE_RCHF << SYSCON_CLK_SEL_SYS_SHIFT)
#define SYSCON_CLK_SEL_SYS_VALUE_DIV_CLK 1U
#define SYSCON_CLK_SEL_SYS_BITS_DIV_CLK (SYSCON_CLK_SEL_SYS_VALUE_DIV_CLK << SYSCON_CLK_SEL_SYS_SHIFT)
#define SYSCON_CLK_SEL_DIV_SHIFT 1
#define SYSCON_CLK_SEL_DIV_WIDTH 3
#define SYSCON_CLK_SEL_DIV_MASK (((1U << SYSCON_CLK_SEL_DIV_WIDTH) - 1U) << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_1 0U
#define SYSCON_CLK_SEL_DIV_BITS_1 (SYSCON_CLK_SEL_DIV_VALUE_1 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_2 1U
#define SYSCON_CLK_SEL_DIV_BITS_2 (SYSCON_CLK_SEL_DIV_VALUE_2 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_4 2U
#define SYSCON_CLK_SEL_DIV_BITS_4 (SYSCON_CLK_SEL_DIV_VALUE_4 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_8 3U
#define SYSCON_CLK_SEL_DIV_BITS_8 (SYSCON_CLK_SEL_DIV_VALUE_8 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_16 4U
#define SYSCON_CLK_SEL_DIV_BITS_16 (SYSCON_CLK_SEL_DIV_VALUE_16 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_DIV_VALUE_32 5U
#define SYSCON_CLK_SEL_DIV_BITS_32 (SYSCON_CLK_SEL_DIV_VALUE_32 << SYSCON_CLK_SEL_DIV_SHIFT)
#define SYSCON_CLK_SEL_SRC_SHIFT 4
#define SYSCON_CLK_SEL_SRC_WIDTH 3
#define SYSCON_CLK_SEL_SRC_MASK (((1U << SYSCON_CLK_SEL_SRC_WIDTH) - 1U) << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_SRC_VALUE_RCHF 0U
#define SYSCON_CLK_SEL_SRC_BITS_RCHF (SYSCON_CLK_SEL_SRC_VALUE_RCHF << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_SRC_VALUE_RCLF 1U
#define SYSCON_CLK_SEL_SRC_BITS_RCLF (SYSCON_CLK_SEL_SRC_VALUE_RCLF << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_SRC_VALUE_XTAH 2U
#define SYSCON_CLK_SEL_SRC_BITS_XTAH (SYSCON_CLK_SEL_SRC_VALUE_XTAH << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_SRC_VALUE_XTAL 3U
#define SYSCON_CLK_SEL_SRC_BITS_XTAL (SYSCON_CLK_SEL_SRC_VALUE_XTAL << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_SRC_VALUE_PLL 4U
#define SYSCON_CLK_SEL_SRC_BITS_PLL (SYSCON_CLK_SEL_SRC_VALUE_PLL << SYSCON_CLK_SEL_SRC_SHIFT)
#define SYSCON_CLK_SEL_W_PLL_SHIFT 7
#define SYSCON_CLK_SEL_W_PLL_WIDTH 1
#define SYSCON_CLK_SEL_W_PLL_MASK (((1U << SYSCON_CLK_SEL_W_PLL_WIDTH) - 1U) << SYSCON_CLK_SEL_W_PLL_SHIFT)
#define SYSCON_CLK_SEL_W_PLL_VALUE_RCHF 0U
#define SYSCON_CLK_SEL_W_PLL_BITS_RCHF (SYSCON_CLK_SEL_W_PLL_VALUE_RCHF << SYSCON_CLK_SEL_W_PLL_SHIFT)
#define SYSCON_CLK_SEL_W_PLL_VALUE_XTAH 1U
#define SYSCON_CLK_SEL_W_PLL_BITS_XTAH (SYSCON_CLK_SEL_W_PLL_VALUE_XTAH << SYSCON_CLK_SEL_W_PLL_SHIFT)
#define SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT 9
#define SYSCON_CLK_SEL_R_SARADC_SMPL_WIDTH 2
#define SYSCON_CLK_SEL_R_SARADC_SMPL_MASK (((1U << SYSCON_CLK_SEL_R_SARADC_SMPL_WIDTH) - 1U) << SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV1 0U
#define SYSCON_CLK_SEL_R_SARADC_SMPL_BITS_DIV1 (SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV1 << SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV2 1U
#define SYSCON_CLK_SEL_R_SARADC_SMPL_BITS_DIV2 (SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV2 << SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV4 2U
#define SYSCON_CLK_SEL_R_SARADC_SMPL_BITS_DIV4 (SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV4 << SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV8 3U
#define SYSCON_CLK_SEL_R_SARADC_SMPL_BITS_DIV8 (SYSCON_CLK_SEL_R_SARADC_SMPL_VALUE_DIV8 << SYSCON_CLK_SEL_R_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT 10
#define SYSCON_CLK_SEL_W_SARADC_SMPL_WIDTH 2
#define SYSCON_CLK_SEL_W_SARADC_SMPL_MASK (((1U << SYSCON_CLK_SEL_W_SARADC_SMPL_WIDTH) - 1U) << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV1 0U
#define SYSCON_CLK_SEL_W_SARADC_SMPL_BITS_DIV1 (SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV1 << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2 1U
#define SYSCON_CLK_SEL_W_SARADC_SMPL_BITS_DIV2 (SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV2 << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV4 2U
#define SYSCON_CLK_SEL_W_SARADC_SMPL_BITS_DIV4 (SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV4 << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV8 3U
#define SYSCON_CLK_SEL_W_SARADC_SMPL_BITS_DIV8 (SYSCON_CLK_SEL_W_SARADC_SMPL_VALUE_DIV8 << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
#define SYSCON_CLK_SEL_R_PLL_SHIFT 11
#define SYSCON_CLK_SEL_R_PLL_WIDTH 1
#define SYSCON_CLK_SEL_R_PLL_MASK (((1U << SYSCON_CLK_SEL_R_PLL_WIDTH) - 1U) << SYSCON_CLK_SEL_R_PLL_SHIFT)
#define SYSCON_CLK_SEL_R_PLL_VALUE_RCHF 0U
#define SYSCON_CLK_SEL_R_PLL_BITS_RCHF (SYSCON_CLK_SEL_R_PLL_VALUE_RCHF << SYSCON_CLK_SEL_R_PLL_SHIFT)
#define SYSCON_CLK_SEL_R_PLL_VALUE_XTAH 1U
#define SYSCON_CLK_SEL_R_PLL_BITS_XTAH (SYSCON_CLK_SEL_R_PLL_VALUE_XTAH << SYSCON_CLK_SEL_R_PLL_SHIFT)
#define SYSCON_DIV_CLK_GATE_ADDR (SYSCON_BASE_ADDR + 0x0004U)
#define SYSCON_DIV_CLK_GATE (*(volatile uint32_t *)SYSCON_DIV_CLK_GATE_ADDR)
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_SHIFT 0
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_WIDTH 1
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_MASK (((1U << SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_WIDTH) - 1U) << SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_SHIFT)
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_VALUE_DISABLE 0U
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_DISABLE (SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_VALUE_DISABLE << SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_SHIFT)
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_VALUE_ENABLE 1U
#define SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_BITS_ENABLE (SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_VALUE_ENABLE << SYSCON_DIV_CLK_GATE_DIV_CLK_GATE_SHIFT)
#define SYSCON_DEV_CLK_GATE_ADDR (SYSCON_BASE_ADDR + 0x0008U)
#define SYSCON_DEV_CLK_GATE (*(volatile uint32_t *)SYSCON_DEV_CLK_GATE_ADDR)
#define SYSCON_DEV_CLK_GATE_GPIOA_SHIFT 0
#define SYSCON_DEV_CLK_GATE_GPIOA_WIDTH 1
#define SYSCON_DEV_CLK_GATE_GPIOA_MASK (((1U << SYSCON_DEV_CLK_GATE_GPIOA_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_GPIOA_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOA_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_GPIOA_BITS_DISABLE (SYSCON_DEV_CLK_GATE_GPIOA_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_GPIOA_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOA_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_GPIOA_BITS_ENABLE (SYSCON_DEV_CLK_GATE_GPIOA_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_GPIOA_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOB_SHIFT 1
#define SYSCON_DEV_CLK_GATE_GPIOB_WIDTH 1
#define SYSCON_DEV_CLK_GATE_GPIOB_MASK (((1U << SYSCON_DEV_CLK_GATE_GPIOB_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_GPIOB_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOB_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_GPIOB_BITS_DISABLE (SYSCON_DEV_CLK_GATE_GPIOB_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_GPIOB_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOB_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_GPIOB_BITS_ENABLE (SYSCON_DEV_CLK_GATE_GPIOB_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_GPIOB_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOC_SHIFT 2
#define SYSCON_DEV_CLK_GATE_GPIOC_WIDTH 1
#define SYSCON_DEV_CLK_GATE_GPIOC_MASK (((1U << SYSCON_DEV_CLK_GATE_GPIOC_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_GPIOC_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOC_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_GPIOC_BITS_DISABLE (SYSCON_DEV_CLK_GATE_GPIOC_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_GPIOC_SHIFT)
#define SYSCON_DEV_CLK_GATE_GPIOC_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_GPIOC_BITS_ENABLE (SYSCON_DEV_CLK_GATE_GPIOC_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_GPIOC_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC0_SHIFT 4
#define SYSCON_DEV_CLK_GATE_IIC0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_IIC0_MASK (((1U << SYSCON_DEV_CLK_GATE_IIC0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_IIC0_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_IIC0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_IIC0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_IIC0_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_IIC0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_IIC0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_IIC0_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC1_SHIFT 5
#define SYSCON_DEV_CLK_GATE_IIC1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_IIC1_MASK (((1U << SYSCON_DEV_CLK_GATE_IIC1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_IIC1_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_IIC1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_IIC1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_IIC1_SHIFT)
#define SYSCON_DEV_CLK_GATE_IIC1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_IIC1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_IIC1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_IIC1_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART0_SHIFT 6
#define SYSCON_DEV_CLK_GATE_UART0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_UART0_MASK (((1U << SYSCON_DEV_CLK_GATE_UART0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_UART0_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_UART0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_UART0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_UART0_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_UART0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_UART0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_UART0_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART1_SHIFT 7
#define SYSCON_DEV_CLK_GATE_UART1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_UART1_MASK (((1U << SYSCON_DEV_CLK_GATE_UART1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_UART1_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_UART1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_UART1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_UART1_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_UART1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_UART1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_UART1_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART2_SHIFT 8
#define SYSCON_DEV_CLK_GATE_UART2_WIDTH 1
#define SYSCON_DEV_CLK_GATE_UART2_MASK (((1U << SYSCON_DEV_CLK_GATE_UART2_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_UART2_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART2_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_UART2_BITS_DISABLE (SYSCON_DEV_CLK_GATE_UART2_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_UART2_SHIFT)
#define SYSCON_DEV_CLK_GATE_UART2_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_UART2_BITS_ENABLE (SYSCON_DEV_CLK_GATE_UART2_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_UART2_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI0_SHIFT 10
#define SYSCON_DEV_CLK_GATE_SPI0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_SPI0_MASK (((1U << SYSCON_DEV_CLK_GATE_SPI0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_SPI0_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_SPI0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_SPI0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_SPI0_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_SPI0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_SPI0_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI1_SHIFT 11
#define SYSCON_DEV_CLK_GATE_SPI1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_SPI1_MASK (((1U << SYSCON_DEV_CLK_GATE_SPI1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_SPI1_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_SPI1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_SPI1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_SPI1_SHIFT)
#define SYSCON_DEV_CLK_GATE_SPI1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_SPI1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_SPI1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_SPI1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_SHIFT 12
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_MASK (((1U << SYSCON_DEV_CLK_GATE_TIMER_BASE0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_TIMER_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_SHIFT 13
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_MASK (((1U << SYSCON_DEV_CLK_GATE_TIMER_BASE1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_TIMER_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_SHIFT 14
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_WIDTH 1
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_MASK (((1U << SYSCON_DEV_CLK_GATE_TIMER_BASE2_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_TIMER_BASE2_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_BITS_DISABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE2_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE2_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_TIMER_BASE2_BITS_ENABLE (SYSCON_DEV_CLK_GATE_TIMER_BASE2_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_TIMER_BASE2_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_SHIFT 15
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_MASK (((1U << SYSCON_DEV_CLK_GATE_TIMER_PLUS0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_TIMER_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_TIMER_PLUS0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_TIMER_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_TIMER_PLUS0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_TIMER_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_SHIFT 16
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_MASK (((1U << SYSCON_DEV_CLK_GATE_TIMER_PLUS1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_TIMER_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_TIMER_PLUS1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_TIMER_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_TIMER_PLUS1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_TIMER_PLUS1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_TIMER_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_SHIFT 17
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_MASK (((1U << SYSCON_DEV_CLK_GATE_PWM_BASE0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_PWM_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_PWM_BASE0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_PWM_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_PWM_BASE0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_PWM_BASE0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_PWM_BASE0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_SHIFT 18
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_MASK (((1U << SYSCON_DEV_CLK_GATE_PWM_BASE1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_PWM_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_PWM_BASE1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_PWM_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_PWM_BASE1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_PWM_BASE1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_PWM_BASE1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_SHIFT 20
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_WIDTH 1
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_MASK (((1U << SYSCON_DEV_CLK_GATE_PWM_PLUS0_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_PWM_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_DISABLE (SYSCON_DEV_CLK_GATE_PWM_PLUS0_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_PWM_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_PWM_PLUS0_BITS_ENABLE (SYSCON_DEV_CLK_GATE_PWM_PLUS0_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_PWM_PLUS0_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_SHIFT 21
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_WIDTH 1
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_MASK (((1U << SYSCON_DEV_CLK_GATE_PWM_PLUS1_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_PWM_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_BITS_DISABLE (SYSCON_DEV_CLK_GATE_PWM_PLUS1_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_PWM_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_PWM_PLUS1_BITS_ENABLE (SYSCON_DEV_CLK_GATE_PWM_PLUS1_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_PWM_PLUS1_SHIFT)
#define SYSCON_DEV_CLK_GATE_RTC_SHIFT 22
#define SYSCON_DEV_CLK_GATE_RTC_WIDTH 1
#define SYSCON_DEV_CLK_GATE_RTC_MASK (((1U << SYSCON_DEV_CLK_GATE_RTC_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_RTC_SHIFT)
#define SYSCON_DEV_CLK_GATE_RTC_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_RTC_BITS_DISABLE (SYSCON_DEV_CLK_GATE_RTC_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_RTC_SHIFT)
#define SYSCON_DEV_CLK_GATE_RTC_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_RTC_BITS_ENABLE (SYSCON_DEV_CLK_GATE_RTC_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_RTC_SHIFT)
#define SYSCON_DEV_CLK_GATE_IWDT_SHIFT 23
#define SYSCON_DEV_CLK_GATE_IWDT_WIDTH 1
#define SYSCON_DEV_CLK_GATE_IWDT_MASK (((1U << SYSCON_DEV_CLK_GATE_IWDT_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_IWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_IWDT_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_IWDT_BITS_DISABLE (SYSCON_DEV_CLK_GATE_IWDT_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_IWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_IWDT_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_IWDT_BITS_ENABLE (SYSCON_DEV_CLK_GATE_IWDT_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_IWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_WWDT_SHIFT 24
#define SYSCON_DEV_CLK_GATE_WWDT_WIDTH 1
#define SYSCON_DEV_CLK_GATE_WWDT_MASK (((1U << SYSCON_DEV_CLK_GATE_WWDT_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_WWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_WWDT_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_WWDT_BITS_DISABLE (SYSCON_DEV_CLK_GATE_WWDT_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_WWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_WWDT_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_WWDT_BITS_ENABLE (SYSCON_DEV_CLK_GATE_WWDT_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_WWDT_SHIFT)
#define SYSCON_DEV_CLK_GATE_SARADC_SHIFT 25
#define SYSCON_DEV_CLK_GATE_SARADC_WIDTH 1
#define SYSCON_DEV_CLK_GATE_SARADC_MASK (((1U << SYSCON_DEV_CLK_GATE_SARADC_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_SARADC_SHIFT)
#define SYSCON_DEV_CLK_GATE_SARADC_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_SARADC_BITS_DISABLE (SYSCON_DEV_CLK_GATE_SARADC_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_SARADC_SHIFT)
#define SYSCON_DEV_CLK_GATE_SARADC_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE (SYSCON_DEV_CLK_GATE_SARADC_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_SARADC_SHIFT)
#define SYSCON_DEV_CLK_GATE_CRC_SHIFT 27
#define SYSCON_DEV_CLK_GATE_CRC_WIDTH 1
#define SYSCON_DEV_CLK_GATE_CRC_MASK (((1U << SYSCON_DEV_CLK_GATE_CRC_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_CRC_SHIFT)
#define SYSCON_DEV_CLK_GATE_CRC_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_CRC_BITS_DISABLE (SYSCON_DEV_CLK_GATE_CRC_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_CRC_SHIFT)
#define SYSCON_DEV_CLK_GATE_CRC_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_CRC_BITS_ENABLE (SYSCON_DEV_CLK_GATE_CRC_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_CRC_SHIFT)
#define SYSCON_DEV_CLK_GATE_AES_SHIFT 28
#define SYSCON_DEV_CLK_GATE_AES_WIDTH 1
#define SYSCON_DEV_CLK_GATE_AES_MASK (((1U << SYSCON_DEV_CLK_GATE_AES_WIDTH) - 1U) << SYSCON_DEV_CLK_GATE_AES_SHIFT)
#define SYSCON_DEV_CLK_GATE_AES_VALUE_DISABLE 0U
#define SYSCON_DEV_CLK_GATE_AES_BITS_DISABLE (SYSCON_DEV_CLK_GATE_AES_VALUE_DISABLE << SYSCON_DEV_CLK_GATE_AES_SHIFT)
#define SYSCON_DEV_CLK_GATE_AES_VALUE_ENABLE 1U
#define SYSCON_DEV_CLK_GATE_AES_BITS_ENABLE (SYSCON_DEV_CLK_GATE_AES_VALUE_ENABLE << SYSCON_DEV_CLK_GATE_AES_SHIFT)
#define SYSCON_RC_FREQ_DELTA_ADDR (SYSCON_BASE_ADDR + 0x0078U)
#define SYSCON_RC_FREQ_DELTA (*(volatile uint32_t *)SYSCON_RC_FREQ_DELTA_ADDR)
#define SYSCON_RC_FREQ_DELTA_RCLF_DELTA_SHIFT 0
#define SYSCON_RC_FREQ_DELTA_RCLF_DELTA_WIDTH 10
#define SYSCON_RC_FREQ_DELTA_RCLF_DELTA_MASK (((1U << SYSCON_RC_FREQ_DELTA_RCLF_DELTA_WIDTH) - 1U) << SYSCON_RC_FREQ_DELTA_RCLF_DELTA_SHIFT)
#define SYSCON_RC_FREQ_DELTA_RCLF_SIG_SHIFT 10
#define SYSCON_RC_FREQ_DELTA_RCLF_SIG_WIDTH 1
#define SYSCON_RC_FREQ_DELTA_RCLF_SIG_MASK (((1U << SYSCON_RC_FREQ_DELTA_RCLF_SIG_WIDTH) - 1U) << SYSCON_RC_FREQ_DELTA_RCLF_SIG_SHIFT)
#define SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT 11
#define SYSCON_RC_FREQ_DELTA_RCHF_DELTA_WIDTH 20
#define SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK (((1U << SYSCON_RC_FREQ_DELTA_RCHF_DELTA_WIDTH) - 1U) << SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT)
#define SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT 31
#define SYSCON_RC_FREQ_DELTA_RCHF_SIG_WIDTH 1
#define SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK (((1U << SYSCON_RC_FREQ_DELTA_RCHF_SIG_WIDTH) - 1U) << SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT)
#define SYSCON_VREF_VOLT_DELTA_ADDR (SYSCON_BASE_ADDR + 0x007CU)
#define SYSCON_VREF_VOLT_DELTA (*(volatile uint32_t *)SYSCON_VREF_VOLT_DELTA_ADDR)
#define SYSCON_CHIP_ID0_ADDR (SYSCON_BASE_ADDR + 0x0080U)
#define SYSCON_CHIP_ID0 (*(volatile uint32_t *)SYSCON_CHIP_ID0_ADDR)
#define SYSCON_CHIP_ID1_ADDR (SYSCON_BASE_ADDR + 0x0084U)
#define SYSCON_CHIP_ID1 (*(volatile uint32_t *)SYSCON_CHIP_ID1_ADDR)
#define SYSCON_CHIP_ID2_ADDR (SYSCON_BASE_ADDR + 0x0088U)
#define SYSCON_CHIP_ID2 (*(volatile uint32_t *)SYSCON_CHIP_ID2_ADDR)
#define SYSCON_CHIP_ID3_ADDR (SYSCON_BASE_ADDR + 0x008CU)
#define SYSCON_CHIP_ID3 (*(volatile uint32_t *)SYSCON_CHIP_ID3_ADDR)
#endif

439
bsp/dp32g030/uart.h Normal file
View File

@ -0,0 +1,439 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HARDWARE_DP32G030_UART_H
#define HARDWARE_DP32G030_UART_H
#if !defined(__ASSEMBLY__)
#include <stdint.h>
#endif
/* -------- UART0 -------- */
#define UART0_BASE_ADDR 0x4006B000U
#define UART0_BASE_SIZE 0x00000800U
#define UART0 ((volatile UART_Port_t *)UART0_BASE_ADDR)
/* -------- UART1 -------- */
#define UART1_BASE_ADDR 0x4006B800U
#define UART1_BASE_SIZE 0x00000800U
#define UART1 ((volatile UART_Port_t *)UART1_BASE_ADDR)
/* -------- UART2 -------- */
#define UART2_BASE_ADDR 0x4006C000U
#define UART2_BASE_SIZE 0x00000800U
#define UART2 ((volatile UART_Port_t *)UART2_BASE_ADDR)
/* -------- UART -------- */
typedef struct {
uint32_t CTRL;
uint32_t BAUD;
uint32_t TDR;
uint32_t RDR;
uint32_t IE;
uint32_t IF;
uint32_t FIFO;
uint32_t FC;
uint32_t RXTO;
} UART_Port_t;
#define UART_CTRL_UARTEN_SHIFT 0
#define UART_CTRL_UARTEN_WIDTH 1
#define UART_CTRL_UARTEN_MASK (((1U << UART_CTRL_UARTEN_WIDTH) - 1U) << UART_CTRL_UARTEN_SHIFT)
#define UART_CTRL_UARTEN_VALUE_DISABLE 0U
#define UART_CTRL_UARTEN_BITS_DISABLE (UART_CTRL_UARTEN_VALUE_DISABLE << UART_CTRL_UARTEN_SHIFT)
#define UART_CTRL_UARTEN_VALUE_ENABLE 1U
#define UART_CTRL_UARTEN_BITS_ENABLE (UART_CTRL_UARTEN_VALUE_ENABLE << UART_CTRL_UARTEN_SHIFT)
#define UART_CTRL_RXEN_SHIFT 1
#define UART_CTRL_RXEN_WIDTH 1
#define UART_CTRL_RXEN_MASK (((1U << UART_CTRL_RXEN_WIDTH) - 1U) << UART_CTRL_RXEN_SHIFT)
#define UART_CTRL_RXEN_VALUE_DISABLE 0U
#define UART_CTRL_RXEN_BITS_DISABLE (UART_CTRL_RXEN_VALUE_DISABLE << UART_CTRL_RXEN_SHIFT)
#define UART_CTRL_RXEN_VALUE_ENABLE 1U
#define UART_CTRL_RXEN_BITS_ENABLE (UART_CTRL_RXEN_VALUE_ENABLE << UART_CTRL_RXEN_SHIFT)
#define UART_CTRL_TXEN_SHIFT 2
#define UART_CTRL_TXEN_WIDTH 1
#define UART_CTRL_TXEN_MASK (((1U << UART_CTRL_TXEN_WIDTH) - 1U) << UART_CTRL_TXEN_SHIFT)
#define UART_CTRL_TXEN_VALUE_DISABLE 0U
#define UART_CTRL_TXEN_BITS_DISABLE (UART_CTRL_TXEN_VALUE_DISABLE << UART_CTRL_TXEN_SHIFT)
#define UART_CTRL_TXEN_VALUE_ENABLE 1U
#define UART_CTRL_TXEN_BITS_ENABLE (UART_CTRL_TXEN_VALUE_ENABLE << UART_CTRL_TXEN_SHIFT)
#define UART_CTRL_RXDMAEN_SHIFT 3
#define UART_CTRL_RXDMAEN_WIDTH 1
#define UART_CTRL_RXDMAEN_MASK (((1U << UART_CTRL_RXDMAEN_WIDTH) - 1U) << UART_CTRL_RXDMAEN_SHIFT)
#define UART_CTRL_RXDMAEN_VALUE_DISABLE 0U
#define UART_CTRL_RXDMAEN_BITS_DISABLE (UART_CTRL_RXDMAEN_VALUE_DISABLE << UART_CTRL_RXDMAEN_SHIFT)
#define UART_CTRL_RXDMAEN_VALUE_ENABLE 1U
#define UART_CTRL_RXDMAEN_BITS_ENABLE (UART_CTRL_RXDMAEN_VALUE_ENABLE << UART_CTRL_RXDMAEN_SHIFT)
#define UART_CTRL_TXDMAEN_SHIFT 4
#define UART_CTRL_TXDMAEN_WIDTH 1
#define UART_CTRL_TXDMAEN_MASK (((1U << UART_CTRL_TXDMAEN_WIDTH) - 1U) << UART_CTRL_TXDMAEN_SHIFT)
#define UART_CTRL_TXDMAEN_VALUE_DISABLE 0U
#define UART_CTRL_TXDMAEN_BITS_DISABLE (UART_CTRL_TXDMAEN_VALUE_DISABLE << UART_CTRL_TXDMAEN_SHIFT)
#define UART_CTRL_TXDMAEN_VALUE_ENABLE 1U
#define UART_CTRL_TXDMAEN_BITS_ENABLE (UART_CTRL_TXDMAEN_VALUE_ENABLE << UART_CTRL_TXDMAEN_SHIFT)
#define UART_CTRL_NINEBIT_SHIFT 5
#define UART_CTRL_NINEBIT_WIDTH 1
#define UART_CTRL_NINEBIT_MASK (((1U << UART_CTRL_NINEBIT_WIDTH) - 1U) << UART_CTRL_NINEBIT_SHIFT)
#define UART_CTRL_NINEBIT_VALUE_DISABLE 0U
#define UART_CTRL_NINEBIT_BITS_DISABLE (UART_CTRL_NINEBIT_VALUE_DISABLE << UART_CTRL_NINEBIT_SHIFT)
#define UART_CTRL_NINEBIT_VALUE_ENABLE 1U
#define UART_CTRL_NINEBIT_BITS_ENABLE (UART_CTRL_NINEBIT_VALUE_ENABLE << UART_CTRL_NINEBIT_SHIFT)
#define UART_CTRL_PAREN_SHIFT 6
#define UART_CTRL_PAREN_WIDTH 1
#define UART_CTRL_PAREN_MASK (((1U << UART_CTRL_PAREN_WIDTH) - 1U) << UART_CTRL_PAREN_SHIFT)
#define UART_CTRL_PAREN_VALUE_DISABLE 0U
#define UART_CTRL_PAREN_BITS_DISABLE (UART_CTRL_PAREN_VALUE_DISABLE << UART_CTRL_PAREN_SHIFT)
#define UART_CTRL_PAREN_VALUE_ENABLE 1U
#define UART_CTRL_PAREN_BITS_ENABLE (UART_CTRL_PAREN_VALUE_ENABLE << UART_CTRL_PAREN_SHIFT)
#define UART_IE_TXDONE_SHIFT 2
#define UART_IE_TXDONE_WIDTH 1
#define UART_IE_TXDONE_MASK (((1U << UART_IE_TXDONE_WIDTH) - 1U) << UART_IE_TXDONE_SHIFT)
#define UART_IE_TXDONE_VALUE_DISABLE 0U
#define UART_IE_TXDONE_BITS_DISABLE (UART_IE_TXDONE_VALUE_DISABLE << UART_IE_TXDONE_SHIFT)
#define UART_IE_TXDONE_VALUE_ENABLE 1U
#define UART_IE_TXDONE_BITS_ENABLE (UART_IE_TXDONE_VALUE_ENABLE << UART_IE_TXDONE_SHIFT)
#define UART_IE_PARITYE_SHIFT 3
#define UART_IE_PARITYE_WIDTH 1
#define UART_IE_PARITYE_MASK (((1U << UART_IE_PARITYE_WIDTH) - 1U) << UART_IE_PARITYE_SHIFT)
#define UART_IE_PARITYE_VALUE_DISABLE 0U
#define UART_IE_PARITYE_BITS_DISABLE (UART_IE_PARITYE_VALUE_DISABLE << UART_IE_PARITYE_SHIFT)
#define UART_IE_PARITYE_VALUE_ENABLE 1U
#define UART_IE_PARITYE_BITS_ENABLE (UART_IE_PARITYE_VALUE_ENABLE << UART_IE_PARITYE_SHIFT)
#define UART_IE_STOPE_SHIFT 4
#define UART_IE_STOPE_WIDTH 1
#define UART_IE_STOPE_MASK (((1U << UART_IE_STOPE_WIDTH) - 1U) << UART_IE_STOPE_SHIFT)
#define UART_IE_STOPE_VALUE_DISABLE 0U
#define UART_IE_STOPE_BITS_DISABLE (UART_IE_STOPE_VALUE_DISABLE << UART_IE_STOPE_SHIFT)
#define UART_IE_STOPE_VALUE_ENABLE 1U
#define UART_IE_STOPE_BITS_ENABLE (UART_IE_STOPE_VALUE_ENABLE << UART_IE_STOPE_SHIFT)
#define UART_IE_RXTO_SHIFT 5
#define UART_IE_RXTO_WIDTH 1
#define UART_IE_RXTO_MASK (((1U << UART_IE_RXTO_WIDTH) - 1U) << UART_IE_RXTO_SHIFT)
#define UART_IE_RXTO_VALUE_DISABLE 0U
#define UART_IE_RXTO_BITS_DISABLE (UART_IE_RXTO_VALUE_DISABLE << UART_IE_RXTO_SHIFT)
#define UART_IE_RXTO_VALUE_ENABLE 1U
#define UART_IE_RXTO_BITS_ENABLE (UART_IE_RXTO_VALUE_ENABLE << UART_IE_RXTO_SHIFT)
#define UART_IE_RXFIFO_SHIFT 6
#define UART_IE_RXFIFO_WIDTH 1
#define UART_IE_RXFIFO_MASK (((1U << UART_IE_RXFIFO_WIDTH) - 1U) << UART_IE_RXFIFO_SHIFT)
#define UART_IE_RXFIFO_VALUE_DISABLE 0U
#define UART_IE_RXFIFO_BITS_DISABLE (UART_IE_RXFIFO_VALUE_DISABLE << UART_IE_RXFIFO_SHIFT)
#define UART_IE_RXFIFO_VALUE_ENABLE 1U
#define UART_IE_RXFIFO_BITS_ENABLE (UART_IE_RXFIFO_VALUE_ENABLE << UART_IE_RXFIFO_SHIFT)
#define UART_IE_TXFIFO_SHIFT 7
#define UART_IE_TXFIFO_WIDTH 1
#define UART_IE_TXFIFO_MASK (((1U << UART_IE_TXFIFO_WIDTH) - 1U) << UART_IE_TXFIFO_SHIFT)
#define UART_IE_TXFIFO_VALUE_DISABLE 0U
#define UART_IE_TXFIFO_BITS_DISABLE (UART_IE_TXFIFO_VALUE_DISABLE << UART_IE_TXFIFO_SHIFT)
#define UART_IE_TXFIFO_VALUE_ENABLE 1U
#define UART_IE_TXFIFO_BITS_ENABLE (UART_IE_TXFIFO_VALUE_ENABLE << UART_IE_TXFIFO_SHIFT)
#define UART_IE_RXFIFO_OVF_SHIFT 8
#define UART_IE_RXFIFO_OVF_WIDTH 1
#define UART_IE_RXFIFO_OVF_MASK (((1U << UART_IE_RXFIFO_OVF_WIDTH) - 1U) << UART_IE_RXFIFO_OVF_SHIFT)
#define UART_IE_RXFIFO_OVF_VALUE_DISABLE 0U
#define UART_IE_RXFIFO_OVF_BITS_DISABLE (UART_IE_RXFIFO_OVF_VALUE_DISABLE << UART_IE_RXFIFO_OVF_SHIFT)
#define UART_IE_RXFIFO_OVF_VALUE_ENABLE 1U
#define UART_IE_RXFIFO_OVF_BITS_ENABLE (UART_IE_RXFIFO_OVF_VALUE_ENABLE << UART_IE_RXFIFO_OVF_SHIFT)
#define UART_IE_ABRD_OVF_SHIFT 9
#define UART_IE_ABRD_OVF_WIDTH 1
#define UART_IE_ABRD_OVF_MASK (((1U << UART_IE_ABRD_OVF_WIDTH) - 1U) << UART_IE_ABRD_OVF_SHIFT)
#define UART_IE_ABRD_OVF_VALUE_DISABLE 0U
#define UART_IE_ABRD_OVF_BITS_DISABLE (UART_IE_ABRD_OVF_VALUE_DISABLE << UART_IE_ABRD_OVF_SHIFT)
#define UART_IE_ABRD_OVF_VALUE_ENABLE 1U
#define UART_IE_ABRD_OVF_BITS_ENABLE (UART_IE_ABRD_OVF_VALUE_ENABLE << UART_IE_ABRD_OVF_SHIFT)
#define UART_IF_TXDONE_SHIFT 2
#define UART_IF_TXDONE_WIDTH 1
#define UART_IF_TXDONE_MASK (((1U << UART_IF_TXDONE_WIDTH) - 1U) << UART_IF_TXDONE_SHIFT)
#define UART_IF_TXDONE_VALUE_NOT_SET 0U
#define UART_IF_TXDONE_BITS_NOT_SET (UART_IF_TXDONE_VALUE_NOT_SET << UART_IF_TXDONE_SHIFT)
#define UART_IF_TXDONE_VALUE_SET 1U
#define UART_IF_TXDONE_BITS_SET (UART_IF_TXDONE_VALUE_SET << UART_IF_TXDONE_SHIFT)
#define UART_IF_PARITYE_SHIFT 3
#define UART_IF_PARITYE_WIDTH 1
#define UART_IF_PARITYE_MASK (((1U << UART_IF_PARITYE_WIDTH) - 1U) << UART_IF_PARITYE_SHIFT)
#define UART_IF_PARITYE_VALUE_NOT_SET 0U
#define UART_IF_PARITYE_BITS_NOT_SET (UART_IF_PARITYE_VALUE_NOT_SET << UART_IF_PARITYE_SHIFT)
#define UART_IF_PARITYE_VALUE_SET 1U
#define UART_IF_PARITYE_BITS_SET (UART_IF_PARITYE_VALUE_SET << UART_IF_PARITYE_SHIFT)
#define UART_IF_STOPE_SHIFT 4
#define UART_IF_STOPE_WIDTH 1
#define UART_IF_STOPE_MASK (((1U << UART_IF_STOPE_WIDTH) - 1U) << UART_IF_STOPE_SHIFT)
#define UART_IF_STOPE_VALUE_NOT_SET 0U
#define UART_IF_STOPE_BITS_NOT_SET (UART_IF_STOPE_VALUE_NOT_SET << UART_IF_STOPE_SHIFT)
#define UART_IF_STOPE_VALUE_SET 1U
#define UART_IF_STOPE_BITS_SET (UART_IF_STOPE_VALUE_SET << UART_IF_STOPE_SHIFT)
#define UART_IF_RXTO_SHIFT 5
#define UART_IF_RXTO_WIDTH 1
#define UART_IF_RXTO_MASK (((1U << UART_IF_RXTO_WIDTH) - 1U) << UART_IF_RXTO_SHIFT)
#define UART_IF_RXTO_VALUE_NOT_SET 0U
#define UART_IF_RXTO_BITS_NOT_SET (UART_IF_RXTO_VALUE_NOT_SET << UART_IF_RXTO_SHIFT)
#define UART_IF_RXTO_VALUE_SET 1U
#define UART_IF_RXTO_BITS_SET (UART_IF_RXTO_VALUE_SET << UART_IF_RXTO_SHIFT)
#define UART_IF_RXFIFO_SHIFT 6
#define UART_IF_RXFIFO_WIDTH 1
#define UART_IF_RXFIFO_MASK (((1U << UART_IF_RXFIFO_WIDTH) - 1U) << UART_IF_RXFIFO_SHIFT)
#define UART_IF_RXFIFO_VALUE_NOT_SET 0U
#define UART_IF_RXFIFO_BITS_NOT_SET (UART_IF_RXFIFO_VALUE_NOT_SET << UART_IF_RXFIFO_SHIFT)
#define UART_IF_RXFIFO_VALUE_SET 1U
#define UART_IF_RXFIFO_BITS_SET (UART_IF_RXFIFO_VALUE_SET << UART_IF_RXFIFO_SHIFT)
#define UART_IF_TXFIFO_SHIFT 7
#define UART_IF_TXFIFO_WIDTH 1
#define UART_IF_TXFIFO_MASK (((1U << UART_IF_TXFIFO_WIDTH) - 1U) << UART_IF_TXFIFO_SHIFT)
#define UART_IF_TXFIFO_VALUE_NOT_SET 0U
#define UART_IF_TXFIFO_BITS_NOT_SET (UART_IF_TXFIFO_VALUE_NOT_SET << UART_IF_TXFIFO_SHIFT)
#define UART_IF_TXFIFO_VALUE_SET 1U
#define UART_IF_TXFIFO_BITS_SET (UART_IF_TXFIFO_VALUE_SET << UART_IF_TXFIFO_SHIFT)
#define UART_IF_RXFIFO_OVF_SHIFT 8
#define UART_IF_RXFIFO_OVF_WIDTH 1
#define UART_IF_RXFIFO_OVF_MASK (((1U << UART_IF_RXFIFO_OVF_WIDTH) - 1U) << UART_IF_RXFIFO_OVF_SHIFT)
#define UART_IF_RXFIFO_OVF_VALUE_NOT_SET 0U
#define UART_IF_RXFIFO_OVF_BITS_NOT_SET (UART_IF_RXFIFO_OVF_VALUE_NOT_SET << UART_IF_RXFIFO_OVF_SHIFT)
#define UART_IF_RXFIFO_OVF_VALUE_SET 1U
#define UART_IF_RXFIFO_OVF_BITS_SET (UART_IF_RXFIFO_OVF_VALUE_SET << UART_IF_RXFIFO_OVF_SHIFT)
#define UART_IF_ABRD_OVF_SHIFT 9
#define UART_IF_ABRD_OVF_WIDTH 1
#define UART_IF_ABRD_OVF_MASK (((1U << UART_IF_ABRD_OVF_WIDTH) - 1U) << UART_IF_ABRD_OVF_SHIFT)
#define UART_IF_ABRD_OVF_VALUE_NOT_SET 0U
#define UART_IF_ABRD_OVF_BITS_NOT_SET (UART_IF_ABRD_OVF_VALUE_NOT_SET << UART_IF_ABRD_OVF_SHIFT)
#define UART_IF_ABRD_OVF_VALUE_SET 1U
#define UART_IF_ABRD_OVF_BITS_SET (UART_IF_ABRD_OVF_VALUE_SET << UART_IF_ABRD_OVF_SHIFT)
#define UART_IF_RXFIFO_EMPTY_SHIFT 10
#define UART_IF_RXFIFO_EMPTY_WIDTH 1
#define UART_IF_RXFIFO_EMPTY_MASK (((1U << UART_IF_RXFIFO_EMPTY_WIDTH) - 1U) << UART_IF_RXFIFO_EMPTY_SHIFT)
#define UART_IF_RXFIFO_EMPTY_VALUE_NOT_SET 0U
#define UART_IF_RXFIFO_EMPTY_BITS_NOT_SET (UART_IF_RXFIFO_EMPTY_VALUE_NOT_SET << UART_IF_RXFIFO_EMPTY_SHIFT)
#define UART_IF_RXFIFO_EMPTY_VALUE_SET 1U
#define UART_IF_RXFIFO_EMPTY_BITS_SET (UART_IF_RXFIFO_EMPTY_VALUE_SET << UART_IF_RXFIFO_EMPTY_SHIFT)
#define UART_IF_RXFIFO_FULL_SHIFT 11
#define UART_IF_RXFIFO_FULL_WIDTH 1
#define UART_IF_RXFIFO_FULL_MASK (((1U << UART_IF_RXFIFO_FULL_WIDTH) - 1U) << UART_IF_RXFIFO_FULL_SHIFT)
#define UART_IF_RXFIFO_FULL_VALUE_NOT_SET 0U
#define UART_IF_RXFIFO_FULL_BITS_NOT_SET (UART_IF_RXFIFO_FULL_VALUE_NOT_SET << UART_IF_RXFIFO_FULL_SHIFT)
#define UART_IF_RXFIFO_FULL_VALUE_SET 1U
#define UART_IF_RXFIFO_FULL_BITS_SET (UART_IF_RXFIFO_FULL_VALUE_SET << UART_IF_RXFIFO_FULL_SHIFT)
#define UART_IF_RXFIFO_HFULL_SHIFT 12
#define UART_IF_RXFIFO_HFULL_WIDTH 1
#define UART_IF_RXFIFO_HFULL_MASK (((1U << UART_IF_RXFIFO_HFULL_WIDTH) - 1U) << UART_IF_RXFIFO_HFULL_SHIFT)
#define UART_IF_RXFIFO_HFULL_VALUE_NOT_SET 0U
#define UART_IF_RXFIFO_HFULL_BITS_NOT_SET (UART_IF_RXFIFO_HFULL_VALUE_NOT_SET << UART_IF_RXFIFO_HFULL_SHIFT)
#define UART_IF_RXFIFO_HFULL_VALUE_SET 1U
#define UART_IF_RXFIFO_HFULL_BITS_SET (UART_IF_RXFIFO_HFULL_VALUE_SET << UART_IF_RXFIFO_HFULL_SHIFT)
#define UART_IF_TXFIFO_EMPTY_SHIFT 13
#define UART_IF_TXFIFO_EMPTY_WIDTH 1
#define UART_IF_TXFIFO_EMPTY_MASK (((1U << UART_IF_TXFIFO_EMPTY_WIDTH) - 1U) << UART_IF_TXFIFO_EMPTY_SHIFT)
#define UART_IF_TXFIFO_EMPTY_VALUE_NOT_SET 0U
#define UART_IF_TXFIFO_EMPTY_BITS_NOT_SET (UART_IF_TXFIFO_EMPTY_VALUE_NOT_SET << UART_IF_TXFIFO_EMPTY_SHIFT)
#define UART_IF_TXFIFO_EMPTY_VALUE_SET 1U
#define UART_IF_TXFIFO_EMPTY_BITS_SET (UART_IF_TXFIFO_EMPTY_VALUE_SET << UART_IF_TXFIFO_EMPTY_SHIFT)
#define UART_IF_TXFIFO_FULL_SHIFT 14
#define UART_IF_TXFIFO_FULL_WIDTH 1
#define UART_IF_TXFIFO_FULL_MASK (((1U << UART_IF_TXFIFO_FULL_WIDTH) - 1U) << UART_IF_TXFIFO_FULL_SHIFT)
#define UART_IF_TXFIFO_FULL_VALUE_NOT_SET 0U
#define UART_IF_TXFIFO_FULL_BITS_NOT_SET (UART_IF_TXFIFO_FULL_VALUE_NOT_SET << UART_IF_TXFIFO_FULL_SHIFT)
#define UART_IF_TXFIFO_FULL_VALUE_SET 1U
#define UART_IF_TXFIFO_FULL_BITS_SET (UART_IF_TXFIFO_FULL_VALUE_SET << UART_IF_TXFIFO_FULL_SHIFT)
#define UART_IF_TXFIFO_HFULL_SHIFT 15
#define UART_IF_TXFIFO_HFULL_WIDTH 1
#define UART_IF_TXFIFO_HFULL_MASK (((1U << UART_IF_TXFIFO_HFULL_WIDTH) - 1U) << UART_IF_TXFIFO_HFULL_SHIFT)
#define UART_IF_TXFIFO_HFULL_VALUE_NOT_SET 0U
#define UART_IF_TXFIFO_HFULL_BITS_NOT_SET (UART_IF_TXFIFO_HFULL_VALUE_NOT_SET << UART_IF_TXFIFO_HFULL_SHIFT)
#define UART_IF_TXFIFO_HFULL_VALUE_SET 1U
#define UART_IF_TXFIFO_HFULL_BITS_SET (UART_IF_TXFIFO_HFULL_VALUE_SET << UART_IF_TXFIFO_HFULL_SHIFT)
#define UART_IF_TXBUSY_SHIFT 16
#define UART_IF_TXBUSY_WIDTH 1
#define UART_IF_TXBUSY_MASK (((1U << UART_IF_TXBUSY_WIDTH) - 1U) << UART_IF_TXBUSY_SHIFT)
#define UART_IF_TXBUSY_VALUE_NOT_SET 0U
#define UART_IF_TXBUSY_BITS_NOT_SET (UART_IF_TXBUSY_VALUE_NOT_SET << UART_IF_TXBUSY_SHIFT)
#define UART_IF_TXBUSY_VALUE_SET 1U
#define UART_IF_TXBUSY_BITS_SET (UART_IF_TXBUSY_VALUE_SET << UART_IF_TXBUSY_SHIFT)
#define UART_IF_RF_LEVEL_SHIFT 17
#define UART_IF_RF_LEVEL_WIDTH 3
#define UART_IF_RF_LEVEL_MASK (((1U << UART_IF_RF_LEVEL_WIDTH) - 1U) << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_0_8_BYTE 0U
#define UART_IF_RF_LEVEL_BITS_0_8_BYTE (UART_IF_RF_LEVEL_VALUE_0_8_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_1_BYTE 1U
#define UART_IF_RF_LEVEL_BITS_1_BYTE (UART_IF_RF_LEVEL_VALUE_1_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_2_BYTE 2U
#define UART_IF_RF_LEVEL_BITS_2_BYTE (UART_IF_RF_LEVEL_VALUE_2_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_3_BYTE 3U
#define UART_IF_RF_LEVEL_BITS_3_BYTE (UART_IF_RF_LEVEL_VALUE_3_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_4_BYTE 4U
#define UART_IF_RF_LEVEL_BITS_4_BYTE (UART_IF_RF_LEVEL_VALUE_4_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_5_BYTE 5U
#define UART_IF_RF_LEVEL_BITS_5_BYTE (UART_IF_RF_LEVEL_VALUE_5_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_6_BYTE 6U
#define UART_IF_RF_LEVEL_BITS_6_BYTE (UART_IF_RF_LEVEL_VALUE_6_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_RF_LEVEL_VALUE_7_BYTE 7U
#define UART_IF_RF_LEVEL_BITS_7_BYTE (UART_IF_RF_LEVEL_VALUE_7_BYTE << UART_IF_RF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_SHIFT 20
#define UART_IF_TF_LEVEL_WIDTH 3
#define UART_IF_TF_LEVEL_MASK (((1U << UART_IF_TF_LEVEL_WIDTH) - 1U) << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_0_8_BYTE 0U
#define UART_IF_TF_LEVEL_BITS_0_8_BYTE (UART_IF_TF_LEVEL_VALUE_0_8_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_1_BYTE 1U
#define UART_IF_TF_LEVEL_BITS_1_BYTE (UART_IF_TF_LEVEL_VALUE_1_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_2_BYTE 2U
#define UART_IF_TF_LEVEL_BITS_2_BYTE (UART_IF_TF_LEVEL_VALUE_2_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_3_BYTE 3U
#define UART_IF_TF_LEVEL_BITS_3_BYTE (UART_IF_TF_LEVEL_VALUE_3_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_4_BYTE 4U
#define UART_IF_TF_LEVEL_BITS_4_BYTE (UART_IF_TF_LEVEL_VALUE_4_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_5_BYTE 5U
#define UART_IF_TF_LEVEL_BITS_5_BYTE (UART_IF_TF_LEVEL_VALUE_5_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_6_BYTE 6U
#define UART_IF_TF_LEVEL_BITS_6_BYTE (UART_IF_TF_LEVEL_VALUE_6_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_IF_TF_LEVEL_VALUE_7_BYTE 7U
#define UART_IF_TF_LEVEL_BITS_7_BYTE (UART_IF_TF_LEVEL_VALUE_7_BYTE << UART_IF_TF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_SHIFT 0
#define UART_FIFO_RF_LEVEL_WIDTH 3
#define UART_FIFO_RF_LEVEL_MASK (((1U << UART_FIFO_RF_LEVEL_WIDTH) - 1U) << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_1_BYTE 0U
#define UART_FIFO_RF_LEVEL_BITS_1_BYTE (UART_FIFO_RF_LEVEL_VALUE_1_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_2_BYTE 1U
#define UART_FIFO_RF_LEVEL_BITS_2_BYTE (UART_FIFO_RF_LEVEL_VALUE_2_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_3_BYTE 2U
#define UART_FIFO_RF_LEVEL_BITS_3_BYTE (UART_FIFO_RF_LEVEL_VALUE_3_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_4_BYTE 3U
#define UART_FIFO_RF_LEVEL_BITS_4_BYTE (UART_FIFO_RF_LEVEL_VALUE_4_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_5_BYTE 4U
#define UART_FIFO_RF_LEVEL_BITS_5_BYTE (UART_FIFO_RF_LEVEL_VALUE_5_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_6_BYTE 5U
#define UART_FIFO_RF_LEVEL_BITS_6_BYTE (UART_FIFO_RF_LEVEL_VALUE_6_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_7_BYTE 6U
#define UART_FIFO_RF_LEVEL_BITS_7_BYTE (UART_FIFO_RF_LEVEL_VALUE_7_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_RF_LEVEL_VALUE_8_BYTE 7U
#define UART_FIFO_RF_LEVEL_BITS_8_BYTE (UART_FIFO_RF_LEVEL_VALUE_8_BYTE << UART_FIFO_RF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_SHIFT 3
#define UART_FIFO_TF_LEVEL_WIDTH 3
#define UART_FIFO_TF_LEVEL_MASK (((1U << UART_FIFO_TF_LEVEL_WIDTH) - 1U) << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_0_BYTE 0U
#define UART_FIFO_TF_LEVEL_BITS_0_BYTE (UART_FIFO_TF_LEVEL_VALUE_0_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_1_BYTE 1U
#define UART_FIFO_TF_LEVEL_BITS_1_BYTE (UART_FIFO_TF_LEVEL_VALUE_1_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_2_BYTE 2U
#define UART_FIFO_TF_LEVEL_BITS_2_BYTE (UART_FIFO_TF_LEVEL_VALUE_2_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_3_BYTE 3U
#define UART_FIFO_TF_LEVEL_BITS_3_BYTE (UART_FIFO_TF_LEVEL_VALUE_3_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_4_BYTE 4U
#define UART_FIFO_TF_LEVEL_BITS_4_BYTE (UART_FIFO_TF_LEVEL_VALUE_4_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_5_BYTE 5U
#define UART_FIFO_TF_LEVEL_BITS_5_BYTE (UART_FIFO_TF_LEVEL_VALUE_5_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_6_BYTE 6U
#define UART_FIFO_TF_LEVEL_BITS_6_BYTE (UART_FIFO_TF_LEVEL_VALUE_6_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_TF_LEVEL_VALUE_7_BYTE 7U
#define UART_FIFO_TF_LEVEL_BITS_7_BYTE (UART_FIFO_TF_LEVEL_VALUE_7_BYTE << UART_FIFO_TF_LEVEL_SHIFT)
#define UART_FIFO_RF_CLR_SHIFT 6
#define UART_FIFO_RF_CLR_WIDTH 1
#define UART_FIFO_RF_CLR_MASK (((1U << UART_FIFO_RF_CLR_WIDTH) - 1U) << UART_FIFO_RF_CLR_SHIFT)
#define UART_FIFO_RF_CLR_VALUE_DISABLE 0U
#define UART_FIFO_RF_CLR_BITS_DISABLE (UART_FIFO_RF_CLR_VALUE_DISABLE << UART_FIFO_RF_CLR_SHIFT)
#define UART_FIFO_RF_CLR_VALUE_ENABLE 1U
#define UART_FIFO_RF_CLR_BITS_ENABLE (UART_FIFO_RF_CLR_VALUE_ENABLE << UART_FIFO_RF_CLR_SHIFT)
#define UART_FIFO_TF_CLR_SHIFT 7
#define UART_FIFO_TF_CLR_WIDTH 1
#define UART_FIFO_TF_CLR_MASK (((1U << UART_FIFO_TF_CLR_WIDTH) - 1U) << UART_FIFO_TF_CLR_SHIFT)
#define UART_FIFO_TF_CLR_VALUE_DISABLE 0U
#define UART_FIFO_TF_CLR_BITS_DISABLE (UART_FIFO_TF_CLR_VALUE_DISABLE << UART_FIFO_TF_CLR_SHIFT)
#define UART_FIFO_TF_CLR_VALUE_ENABLE 1U
#define UART_FIFO_TF_CLR_BITS_ENABLE (UART_FIFO_TF_CLR_VALUE_ENABLE << UART_FIFO_TF_CLR_SHIFT)
#define UART_FC_CTSEN_SHIFT 0
#define UART_FC_CTSEN_WIDTH 1
#define UART_FC_CTSEN_MASK (((1U << UART_FC_CTSEN_WIDTH) - 1U) << UART_FC_CTSEN_SHIFT)
#define UART_FC_CTSEN_VALUE_DISABLE 0U
#define UART_FC_CTSEN_BITS_DISABLE (UART_FC_CTSEN_VALUE_DISABLE << UART_FC_CTSEN_SHIFT)
#define UART_FC_CTSEN_VALUE_ENABLE 1U
#define UART_FC_CTSEN_BITS_ENABLE (UART_FC_CTSEN_VALUE_ENABLE << UART_FC_CTSEN_SHIFT)
#define UART_FC_RTSEN_SHIFT 1
#define UART_FC_RTSEN_WIDTH 1
#define UART_FC_RTSEN_MASK (((1U << UART_FC_RTSEN_WIDTH) - 1U) << UART_FC_RTSEN_SHIFT)
#define UART_FC_RTSEN_VALUE_DISABLE 0U
#define UART_FC_RTSEN_BITS_DISABLE (UART_FC_RTSEN_VALUE_DISABLE << UART_FC_RTSEN_SHIFT)
#define UART_FC_RTSEN_VALUE_ENABLE 1U
#define UART_FC_RTSEN_BITS_ENABLE (UART_FC_RTSEN_VALUE_ENABLE << UART_FC_RTSEN_SHIFT)
#define UART_FC_CTSPOL_SHIFT 2
#define UART_FC_CTSPOL_WIDTH 1
#define UART_FC_CTSPOL_MASK (((1U << UART_FC_CTSPOL_WIDTH) - 1U) << UART_FC_CTSPOL_SHIFT)
#define UART_FC_CTSPOL_VALUE_LOW 0U
#define UART_FC_CTSPOL_BITS_LOW (UART_FC_CTSPOL_VALUE_LOW << UART_FC_CTSPOL_SHIFT)
#define UART_FC_CTSPOL_VALUE_HIGH 1U
#define UART_FC_CTSPOL_BITS_HIGH (UART_FC_CTSPOL_VALUE_HIGH << UART_FC_CTSPOL_SHIFT)
#define UART_FC_RTSPOL_SHIFT 3
#define UART_FC_RTSPOL_WIDTH 1
#define UART_FC_RTSPOL_MASK (((1U << UART_FC_RTSPOL_WIDTH) - 1U) << UART_FC_RTSPOL_SHIFT)
#define UART_FC_RTSPOL_VALUE_LOW 0U
#define UART_FC_RTSPOL_BITS_LOW (UART_FC_RTSPOL_VALUE_LOW << UART_FC_RTSPOL_SHIFT)
#define UART_FC_RTSPOL_VALUE_HIGH 1U
#define UART_FC_RTSPOL_BITS_HIGH (UART_FC_RTSPOL_VALUE_HIGH << UART_FC_RTSPOL_SHIFT)
#define UART_FC_CTS_SIGNAL_SHIFT 4
#define UART_FC_CTS_SIGNAL_WIDTH 1
#define UART_FC_CTS_SIGNAL_MASK (((1U << UART_FC_CTS_SIGNAL_WIDTH) - 1U) << UART_FC_CTS_SIGNAL_SHIFT)
#define UART_FC_CTS_SIGNAL_VALUE_LOW 0U
#define UART_FC_CTS_SIGNAL_BITS_LOW (UART_FC_CTS_SIGNAL_VALUE_LOW << UART_FC_CTS_SIGNAL_SHIFT)
#define UART_FC_CTS_SIGNAL_VALUE_HIGH 1U
#define UART_FC_CTS_SIGNAL_BITS_HIGH (UART_FC_CTS_SIGNAL_VALUE_HIGH << UART_FC_CTS_SIGNAL_SHIFT)
#define UART_FC_RTS_SIGNAL_SHIFT 5
#define UART_FC_RTS_SIGNAL_WIDTH 1
#define UART_FC_RTS_SIGNAL_MASK (((1U << UART_FC_RTS_SIGNAL_WIDTH) - 1U) << UART_FC_RTS_SIGNAL_SHIFT)
#define UART_FC_RTS_SIGNAL_VALUE_LOW 0U
#define UART_FC_RTS_SIGNAL_BITS_LOW (UART_FC_RTS_SIGNAL_VALUE_LOW << UART_FC_RTS_SIGNAL_SHIFT)
#define UART_FC_RTS_SIGNAL_VALUE_HIGH 1U
#define UART_FC_RTS_SIGNAL_BITS_HIGH (UART_FC_RTS_SIGNAL_VALUE_HIGH << UART_FC_RTS_SIGNAL_SHIFT)
#endif

143
dcs.c Normal file
View File

@ -0,0 +1,143 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dcs.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
const uint16_t CTCSS_Options[50] = {
0x029E, 0x02B5, 0x02CF, 0x02E8,
0x0302, 0x031D, 0x0339, 0x0356,
0x0375, 0x0393, 0x03B4, 0x03CE,
0x03E8, 0x040B, 0x0430, 0x0455,
0x047C, 0x04A4, 0x04CE, 0x04F9,
0x0526, 0x0555, 0x0585, 0x05B6,
0x05EA, 0x061F, 0x063E, 0x0656,
0x0677, 0x068F, 0x06B1, 0x06CA,
0x06ED, 0x0707, 0x072B, 0x0746,
0x076B, 0x0788, 0x07AE, 0x07CB,
0x07F3, 0x0811, 0x083B, 0x0885,
0x08D1, 0x08F3, 0x0920, 0x0972,
0x09C7, 0x09ED,
};
const uint16_t DCS_Options[104] = {
0x0013, 0x0015, 0x0016, 0x0019,
0x001A, 0x001E, 0x0023, 0x0027,
0x0029, 0x002B, 0x002C, 0x0035,
0x0039, 0x003A, 0x003B, 0x003C,
0x004C, 0x004D, 0x004E, 0x0052,
0x0055, 0x0059, 0x005A, 0x005C,
0x0063, 0x0065, 0x006A, 0x006D,
0x006E, 0x0072, 0x0075, 0x007A,
0x007C, 0x0085, 0x008A, 0x0093,
0x0095, 0x0096, 0x00A3, 0x00A4,
0x00A5, 0x00A6, 0x00A9, 0x00AA,
0x00AD, 0x00B1, 0x00B3, 0x00B5,
0x00B6, 0x00B9, 0x00BC, 0x00C6,
0x00C9, 0x00CD, 0x00D5, 0x00D9,
0x00DA, 0x00E3, 0x00E6, 0x00E9,
0x00EE, 0x00F4, 0x00F5, 0x00F9,
0x0109, 0x010A, 0x010B, 0x0113,
0x0119, 0x011A, 0x0125, 0x0126,
0x012A, 0x012C, 0x012D, 0x0132,
0x0134, 0x0135, 0x0136, 0x0143,
0x0146, 0x014E, 0x0153, 0x0156,
0x015A, 0x0166, 0x0175, 0x0186,
0x018A, 0x0194, 0x0197, 0x0199,
0x019A, 0x01AC, 0x01B2, 0x01B4,
0x01C3, 0x01CA, 0x01D3, 0x01D9,
0x01DA, 0x01DC, 0x01E3, 0x01EC,
};
static uint32_t DCS_CalculateGolay(uint32_t CodeWord)
{
uint32_t Word;
uint8_t i;
Word = CodeWord;
for (i = 0; i < 12; i++) {
Word <<= 1;
if (Word & 0x1000) {
Word ^= 0x08EA;
}
}
return CodeWord | ((Word & 0x0FFE) << 11);
}
uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option)
{
uint32_t Code;
Code = DCS_CalculateGolay(DCS_Options[Option] + 0x800U);
if (CodeType == CODE_TYPE_REVERSE_DIGITAL) {
Code ^= 0x7FFFFF;
}
return Code;
}
uint8_t DCS_GetCdcssCode(uint32_t Code)
{
uint8_t i;
for (i = 0; i < 23; i++) {
uint32_t Shift;
if (((Code >> 9) & 0x7U) == 4) {
uint8_t j;
for (j = 0; j < ARRAY_SIZE(DCS_Options); j++) {
if (DCS_Options[j] == (Code & 0x1FF)) {
if (DCS_GetGolayCodeWord(2, j) == Code) {
return j;
}
}
}
}
Shift = Code >> 1;
if (Code & 1U) {
Shift |= 0x400000U;
}
Code = Shift;
}
return 0xFF;
}
uint8_t DCS_GetCtcssCode(uint16_t Code)
{
uint8_t i;
int Smallest;
uint8_t Result = 0xFF;
Smallest = ARRAY_SIZE(CTCSS_Options);
for (i = 0; i < ARRAY_SIZE(CTCSS_Options); i++) {
int Delta;
Delta = Code - CTCSS_Options[i];
if (Delta < 0) {
Delta = -(Code - CTCSS_Options[i]);
}
if (Delta < Smallest) {
Smallest = Delta;
Result = i;
}
}
return Result;
}

44
dcs.h Normal file
View File

@ -0,0 +1,44 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DCS_H
#define DCS_H
#include <stdint.h>
enum DCS_CodeType_t {
CODE_TYPE_OFF = 0x00U,
CODE_TYPE_CONTINUOUS_TONE = 0x01U,
CODE_TYPE_DIGITAL = 0x02U,
CODE_TYPE_REVERSE_DIGITAL = 0x03U,
};
typedef enum DCS_CodeType_t DCS_CodeType_t;
enum {
CDCSS_POSITIVE_CODE = 1U,
CDCSS_NEGATIVE_CODE = 2U,
};
extern const uint16_t CTCSS_Options[50];
extern const uint16_t DCS_Options[104];
uint32_t DCS_GetGolayCodeWord(DCS_CodeType_t CodeType, uint8_t Option);
uint8_t DCS_GetCdcssCode(uint32_t Code);
uint8_t DCS_GetCtcssCode(uint16_t Code);
#endif

120
dp32g030.cfg Normal file
View File

@ -0,0 +1,120 @@
transport select swd
adapter speed 32000
reset_config srst_only srst_nogate connect_assert_srst
gdb_breakpoint_override hard
set _CHIP_NAME DP32G0xx
# Create a new dap, with name chip and role CPU, -enable let's OpenOCD to know to add it to the scan
swd newdap $_CHIP_NAME cpu -enable
# Create the DAP instance, this must be explicitly created according to the OpenOCD docs
dap create $_CHIP_NAME.dap -chain-position $_CHIP_NAME.cpu
# Set up the GDB target for the CPU, cortex_m is the CPU type,
target create $_CHIP_NAME.cpu cortex_m -dap $_CHIP_NAME.dap
set _SECTOR_SIZE 512
proc uv_clear_flash_sector {sector_number} {
echo [format "Erasing sector 0x%02x = offset 0x%04x" [expr {$sector_number}] [expr {$sector_number*256}] ]
write_memory 0x4006F000 32 {0x09} ;#set erasing mode
write_memory 0x4006F004 32 [expr {$sector_number << 6}]
write_memory 0x4006F01c 32 {0xAA} ;#unlock flash
write_memory 0x4006F010 32 {0x01} ;#set OPSTART=1
read_memory 0x4006F014 32 1 ;#check status for 0x02
uv_wait_busy
write_memory 0x4006F018 32 {0x55} ;#lock flash
}
proc uv_clear_whole_flash {} {
for {set i 0} {$i < 0x100} {incr i} {
uv_clear_flash_sector $i
}
}
proc uv_clear_sectors {sectors_count} {
for {set i 0} {$i < $sectors_count} {incr i} {
uv_clear_flash_sector $i
}
}
proc uv_flash_unlock {} {
write_memory 0x4006F01c 32 {0xAA} ;#unlock flash
uv_wait_busy
}
proc uv_flash_lock {} {
write_memory 0x4006F018 32 {0x55} ;#lock flash
uv_wait_busy
}
proc uv_flash_write {address value} {
write_memory 0x4006F000 32 {0x05} ;#set writing mode
write_memory 0x4006F004 32 [expr {($address>>2)+0xC000}] ;#set address in flash
write_memory 0x4006F008 32 $value ;#set data
write_memory 0x4006F010 32 {0x01} ;#set OPSTART=1
while {1} {
set status [read_memory 0x4006F014 32 1]
if {($status & 0x4) != 0} {
break
}
}
uv_wait_busy
}
proc uv_wait_busy {} {
while {1} {
set status [read_memory 0x4006F014 32 1]
if {($status & 0x2) == 0} {
break
}
}
}
proc write_image {filename address} {
global _SECTOR_SIZE
set fs [file size $filename]
set fd [open $filename "rb"]
echo "Checking mask"
set status [read_memory 0x4006F020 32 1]
if {$status != 6} {
echo "Changing mask"
write_memory 0x4006F020 32 0
uv_wait_busy
write_memory 0x4006F020 32 6
uv_wait_busy
set status [read_memory 0x4006F020 32 1]
if {$status != 6} {
echo [format "Cannot set flash mask %d!" $status]
close $fd
return
}
}
uv_clear_sectors [expr {(($fs+$_SECTOR_SIZE-1)&(0x10000000-$_SECTOR_SIZE))/($_SECTOR_SIZE/2)}]
uv_flash_unlock
set addr $address
while {![eof $fd]} {
set data [read $fd 4]
if {[string length $data] == 4} {
set b0 [scan [string index $data 0] %c]
set b1 [scan [string index $data 1] %c]
set b2 [scan [string index $data 2] %c]
set b3 [scan [string index $data 3] %c]
set i_data [expr {$b0 | $b1 << 8 | $b2 << 16 | $b3 << 24}]
echo [format "Writing 0x%04x to address 0x%04x (%02d %%)" $i_data $addr [expr {(100*($addr+4)/$fs)}]]
uv_flash_write $addr $i_data
incr addr 4
}
}
uv_flash_lock
close $fd
}
# dap init
init
halt
# reset halt

165
driver/adc.c Normal file
View File

@ -0,0 +1,165 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ARMCM0.h"
#include "adc.h"
#include "bsp/dp32g030/irq.h"
#include "bsp/dp32g030/saradc.h"
#include "bsp/dp32g030/syscon.h"
uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask)
{
if (Mask & ADC_CH15) return 15U;
if (Mask & ADC_CH14) return 14U;
if (Mask & ADC_CH13) return 13U;
if (Mask & ADC_CH12) return 12U;
if (Mask & ADC_CH11) return 11U;
if (Mask & ADC_CH10) return 10U;
if (Mask & ADC_CH9) return 9U;
if (Mask & ADC_CH8) return 8U;
if (Mask & ADC_CH7) return 7U;
if (Mask & ADC_CH6) return 6U;
if (Mask & ADC_CH5) return 5U;
if (Mask & ADC_CH4) return 4U;
if (Mask & ADC_CH3) return 3U;
if (Mask & ADC_CH2) return 2U;
if (Mask & ADC_CH1) return 1U;
if (Mask & ADC_CH0) return 0U;
return 0U;
}
void ADC_Disable(void)
{
SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_DISABLE;
}
void ADC_Enable(void)
{
SARADC_CFG = (SARADC_CFG & ~SARADC_CFG_ADC_EN_MASK) | SARADC_CFG_ADC_EN_BITS_ENABLE;
}
void ADC_SoftReset(void)
{
SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_ASSERT;
SARADC_START = (SARADC_START & ~SARADC_START_SOFT_RESET_MASK) | SARADC_START_SOFT_RESET_BITS_DEASSERT;
}
// The firmware thinks W_SARADC_SMPL_CLK_SEL is at [8:7] but the TRM says it's at [10:9]
#define FW_R_SARADC_SMPL_SHIFT 7
#define FW_R_SARADC_SMPL_MASK (3U << FW_R_SARADC_SMPL_SHIFT)
uint32_t ADC_GetClockConfig(void)
{
uint32_t Value;
Value = SYSCON_CLK_SEL;
Value = 0
| (Value & ~(SYSCON_CLK_SEL_R_PLL_MASK | FW_R_SARADC_SMPL_MASK))
| (((Value & SYSCON_CLK_SEL_R_PLL_MASK) >> SYSCON_CLK_SEL_R_PLL_SHIFT) << SYSCON_CLK_SEL_W_PLL_SHIFT)
| (((Value & FW_R_SARADC_SMPL_MASK) >> FW_R_SARADC_SMPL_SHIFT) << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT)
;
return Value;
}
void ADC_Configure(ADC_Config_t *pAdc)
{
SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SARADC_MASK) | SYSCON_DEV_CLK_GATE_SARADC_BITS_ENABLE;
ADC_Disable();
SYSCON_CLK_SEL = (ADC_GetClockConfig() & ~SYSCON_CLK_SEL_W_SARADC_SMPL_MASK) | ((pAdc->CLK_SEL << SYSCON_CLK_SEL_W_SARADC_SMPL_SHIFT) & SYSCON_CLK_SEL_W_SARADC_SMPL_MASK);
SARADC_CFG = 0
| (SARADC_CFG & ~(0
| SARADC_CFG_CH_SEL_MASK
| SARADC_CFG_AVG_MASK
| SARADC_CFG_CONT_MASK
| SARADC_CFG_SMPL_SETUP_MASK
| SARADC_CFG_MEM_MODE_MASK
| SARADC_CFG_SMPL_CLK_MASK
| SARADC_CFG_SMPL_WIN_MASK
| SARADC_CFG_ADC_TRIG_MASK
| SARADC_CFG_DMA_EN_MASK
))
| ((pAdc->CH_SEL << SARADC_CFG_CH_SEL_SHIFT) & SARADC_CFG_CH_SEL_MASK)
| ((pAdc->AVG << SARADC_CFG_AVG_SHIFT) & SARADC_CFG_AVG_MASK)
| ((pAdc->CONT << SARADC_CFG_CONT_SHIFT) & SARADC_CFG_CONT_MASK)
| ((pAdc->SMPL_SETUP << SARADC_CFG_SMPL_SETUP_SHIFT) & SARADC_CFG_SMPL_SETUP_MASK)
| ((pAdc->MEM_MODE << SARADC_CFG_MEM_MODE_SHIFT) & SARADC_CFG_MEM_MODE_MASK)
| ((pAdc->SMPL_CLK << SARADC_CFG_SMPL_CLK_SHIFT) & SARADC_CFG_SMPL_CLK_MASK)
| ((pAdc->SMPL_WIN << SARADC_CFG_SMPL_WIN_SHIFT) & SARADC_CFG_SMPL_WIN_MASK)
| ((pAdc->ADC_TRIG << SARADC_CFG_ADC_TRIG_SHIFT) & SARADC_CFG_ADC_TRIG_MASK)
| ((pAdc->DMA_EN << SARADC_CFG_DMA_EN_SHIFT) & SARADC_CFG_DMA_EN_MASK)
;
SARADC_EXTTRIG_SEL = pAdc->EXTTRIG_SEL;
if (pAdc->CALIB_OFFSET_VALID) {
SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_YES;
} else {
SARADC_CALIB_OFFSET = (SARADC_CALIB_OFFSET & ~SARADC_CALIB_OFFSET_VALID_MASK) | SARADC_CALIB_OFFSET_VALID_BITS_NO;
}
if (pAdc->CALIB_KD_VALID) {
SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_YES;
} else {
SARADC_CALIB_KD = (SARADC_CALIB_KD & ~SARADC_CALIB_KD_VALID_MASK) | SARADC_CALIB_KD_VALID_BITS_NO;
}
SARADC_IF = 0xFFFFFFFF;
SARADC_IE = 0
| (SARADC_IE & ~(0
| SARADC_IE_CHx_EOC_MASK
| SARADC_IE_FIFO_FULL_MASK
| SARADC_IE_FIFO_HFULL_MASK
))
| ((pAdc->IE_CHx_EOC << SARADC_IE_CHx_EOC_SHIFT) & SARADC_IE_CHx_EOC_MASK)
| ((pAdc->IE_FIFO_FULL << SARADC_IE_FIFO_FULL_SHIFT) & SARADC_IE_FIFO_FULL_MASK)
| ((pAdc->IE_FIFO_HFULL << SARADC_IE_FIFO_HFULL_SHIFT) & SARADC_IE_FIFO_HFULL_MASK)
;
if (SARADC_IE == 0) {
NVIC_DisableIRQ(DP32_SARADC_IRQn);
} else {
NVIC_EnableIRQ(DP32_SARADC_IRQn);
}
}
void ADC_Start(void)
{
SARADC_START = (SARADC_START & ~SARADC_START_START_MASK) | SARADC_START_START_BITS_ENABLE;
}
bool ADC_CheckEndOfConversion(ADC_CH_MASK Mask)
{
volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0;
uint8_t Channel = ADC_GetChannelNumber(Mask);
return (pChannels[Channel].STAT & ADC_CHx_STAT_EOC_MASK) >> ADC_CHx_STAT_EOC_SHIFT;
}
uint16_t ADC_GetValue(ADC_CH_MASK Mask)
{
volatile ADC_Channel_t *pChannels = (volatile ADC_Channel_t *)&SARADC_CH0;
uint8_t Channel = ADC_GetChannelNumber(Mask);
SARADC_IF = 1 << Channel; // TODO: Or just use 'Mask'
return (pChannels[Channel].DATA & ADC_CHx_DATA_DATA_MASK) >> ADC_CHx_DATA_DATA_SHIFT;
}

74
driver/adc.h Normal file
View File

@ -0,0 +1,74 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_ADC_H
#define DRIVER_ADC_H
#include <stdbool.h>
#include <stdint.h>
enum ADC_CH_MASK {
ADC_CH0 = 0x0001U,
ADC_CH1 = 0x0002U,
ADC_CH2 = 0x0004U,
ADC_CH3 = 0x0008U,
ADC_CH4 = 0x0010U,
ADC_CH5 = 0x0020U,
ADC_CH6 = 0x0040U,
ADC_CH7 = 0x0080U,
ADC_CH8 = 0x0100U,
ADC_CH9 = 0x0200U,
ADC_CH10 = 0x0400U,
ADC_CH11 = 0x0800U,
ADC_CH12 = 0x1000U,
ADC_CH13 = 0x2000U,
ADC_CH14 = 0x4000U,
ADC_CH15 = 0x8000U,
};
typedef enum ADC_CH_MASK ADC_CH_MASK;
typedef struct {
uint8_t CLK_SEL;
ADC_CH_MASK CH_SEL;
uint8_t AVG;
uint8_t CONT;
uint8_t MEM_MODE;
uint8_t SMPL_CLK;
uint8_t SMPL_SETUP;
uint8_t SMPL_WIN;
uint8_t ADC_TRIG;
uint16_t EXTTRIG_SEL;
bool CALIB_OFFSET_VALID;
bool CALIB_KD_VALID;
uint8_t DMA_EN;
uint16_t IE_CHx_EOC;
uint8_t IE_FIFO_HFULL;
uint8_t IE_FIFO_FULL;
} ADC_Config_t;
uint8_t ADC_GetChannelNumber(ADC_CH_MASK Mask);
void ADC_Disable(void);
void ADC_Enable(void);
void ADC_SoftReset(void);
uint32_t ADC_GetClockConfig(void);
void ADC_Configure(ADC_Config_t *pAdc);
void ADC_Start(void);
bool ADC_CheckEndOfConversion(ADC_CH_MASK Mask);
uint16_t ADC_GetValue(ADC_CH_MASK Mask);
#endif

72
driver/aes.c Normal file
View File

@ -0,0 +1,72 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdbool.h>
#include "bsp/dp32g030/aes.h"
#include "driver/aes.h"
static void AES_Setup_ENC_CBC(bool IsDecrypt, const void *pKey, const void *pIv)
{
const uint32_t *pK = (const uint32_t *)pKey;
const uint32_t *pI = (const uint32_t *)pIv;
AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_DISABLE;
AES_CR = AES_CR_CHMOD_BITS_CBC;
AES_KEYR3 = pK[0];
AES_KEYR2 = pK[1];
AES_KEYR1 = pK[2];
AES_KEYR0 = pK[3];
AES_IVR3 = pI[0];
AES_IVR2 = pI[1];
AES_IVR1 = pI[2];
AES_IVR0 = pI[3];
AES_CR = (AES_CR & ~AES_CR_EN_MASK) | AES_CR_EN_BITS_ENABLE;
}
static void AES_Transform(const void *pIn, void *pOut)
{
const uint32_t *pI = (const uint32_t *)pIn;
uint32_t *pO = (uint32_t *)pOut;
AES_DINR = pI[0];
AES_DINR = pI[1];
AES_DINR = pI[2];
AES_DINR = pI[3];
while ((AES_SR & AES_SR_CCF_MASK) == AES_SR_CCF_BITS_NOT_COMPLETE) {
}
pO[0] = AES_DOUTR;
pO[1] = AES_DOUTR;
pO[2] = AES_DOUTR;
pO[3] = AES_DOUTR;
AES_CR |= AES_CR_CCFC_BITS_SET;
}
void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks)
{
const uint8_t *pI = (const uint8_t *)pIn;
uint8_t *pO = (uint8_t *)pOut;
uint8_t i;
AES_Setup_ENC_CBC(0, pKey, pIv);
for (i = 0; i < NumBlocks; i++) {
AES_Transform(pI + (i * 16), pO + (i * 16));
}
}

25
driver/aes.h Normal file
View File

@ -0,0 +1,25 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_AES_H
#define DRIVER_AES_H
#include <stdint.h>
void AES_Encrypt(const void *pKey, const void *pIv, const void *pIn, void *pOut, uint8_t NumBlocks);
#endif

37
driver/backlight.c Normal file
View File

@ -0,0 +1,37 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "backlight.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
#include "settings.h"
uint8_t gBacklightCountdown;
void BACKLIGHT_TurnOn(void)
{
if (gEeprom.BACKLIGHT)
{
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
#if 0
gBacklightCountdown = 1 + (gEeprom.BACKLIGHT * 2);
#else
// much longer backlight times
gBacklightCountdown = (gEeprom.BACKLIGHT * 20) - 19;
#endif
}
}

27
driver/backlight.h Normal file
View File

@ -0,0 +1,27 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_BACKLIGHT_H
#define DRIVER_BACKLIGHT_H
#include <stdint.h>
extern uint8_t gBacklightCountdown;
void BACKLIGHT_TurnOn(void);
#endif

57
driver/bk1080-regs.h Normal file
View File

@ -0,0 +1,57 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BK1080_REGS_H
#define BK1080_REGS_H
enum BK1080_Register_t {
BK1080_REG_00 = 0x00U,
BK1080_REG_02_POWER_CONFIGURATION = 0x02U,
BK1080_REG_03_CHANNEL = 0x03U,
BK1080_REG_05_SYSTEM_CONFIGURATION2 = 0x05U,
BK1080_REG_07 = 0x07U,
BK1080_REG_10 = 0x0AU,
BK1080_REG_25_INTERNAL = 0x19U,
};
typedef enum BK1080_Register_t BK1080_Register_t;
// REG 07
#define BK1080_REG_07_SHIFT_FREQD 4
#define BK1080_REG_07_SHIFT_SNR 0
#define BK1080_REG_07_MASK_FREQD (0xFFFU << BK1080_REG_07_SHIFT_FREQD)
#define BK1080_REG_07_MASK_SNR (0x00FU << BK1080_REG_07_SHIFT_SNR)
#define BK1080_REG_07_GET_FREQD(x) (((x) & BK1080_REG_07_MASK_FREQD) >> BK1080_REG_07_SHIFT_FREQD)
#define BK1080_REG_07_GET_SNR(x) (((x) & BK1080_REG_07_MASK_SNR) >> BK1080_REG_07_SHIFT_SNR)
// REG 10
#define BK1080_REG_10_SHIFT_AFCRL 12
#define BK1080_REG_10_SHIFT_RSSI 0
#define BK1080_REG_10_MASK_AFCRL (0x01U << BK1080_REG_10_SHIFT_AFCRL)
#define BK1080_REG_10_MASK_RSSI (0xFFU << BK1080_REG_10_SHIFT_RSSI)
#define BK1080_REG_10_AFCRL_NOT_RAILED (0U << BK1080_REG_10_SHIFT_AFCRL)
#define BK1080_REG_10_AFCRL_RAILED (1U << BK1080_REG_10_SHIFT_AFCRL)
#define BK1080_REG_10_GET_RSSI(x) (((x) & BK1080_REG_10_MASK_RSSI) >> BK1080_REG_10_SHIFT_RSSI)
#endif

115
driver/bk1080.c Normal file
View File

@ -0,0 +1,115 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/gpio.h"
#include "bk1080.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/system.h"
#include "misc.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
static const uint16_t BK1080_RegisterTable[] = {
0x0008, 0x1080, 0x0201, 0x0000,
0x40C0, 0x0A1F, 0x002E, 0x02FF,
0x5B11, 0x0000, 0x411E, 0x0000,
0xCE00, 0x0000, 0x0000, 0x1000,
0x3197, 0x0000, 0x13FF, 0x9852,
0x0000, 0x0000, 0x0008, 0x0000,
0x51E1, 0xA8BC, 0x2645, 0x00E4,
0x1CD8, 0x3A50, 0xEAE0, 0x3000,
0x0200, 0x0000,
};
static bool gIsInitBK1080;
uint16_t BK1080_BaseFrequency;
uint16_t BK1080_FrequencyDeviation;
void BK1080_Init(uint16_t Frequency, bool bDoScan)
{
uint8_t i;
if (bDoScan) {
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
if (!gIsInitBK1080) {
for (i = 0; i < ARRAY_SIZE(BK1080_RegisterTable); i++) {
BK1080_WriteRegister(i, BK1080_RegisterTable[i]);
}
SYSTEM_DelayMs(250);
BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA83C);
BK1080_WriteRegister(BK1080_REG_25_INTERNAL, 0xA8BC);
SYSTEM_DelayMs(60);
gIsInitBK1080 = true;
} else {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201);
}
BK1080_WriteRegister(BK1080_REG_05_SYSTEM_CONFIGURATION2, 0x0A5F);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760);
SYSTEM_DelayMs(10);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000);
} else {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0241);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_BK1080);
}
}
uint16_t BK1080_ReadRegister(BK1080_Register_t Register)
{
uint8_t Value[2];
I2C_Start();
I2C_Write(0x80);
I2C_Write((Register << 1) | I2C_READ);
I2C_ReadBuffer(Value, sizeof(Value));
I2C_Stop();
return (Value[0] << 8) | Value[1];
}
void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value)
{
I2C_Start();
I2C_Write(0x80);
I2C_Write((Register << 1) | I2C_WRITE);
Value = ((Value >> 8) & 0xFF) | ((Value & 0xFF) << 8);
I2C_WriteBuffer(&Value, sizeof(Value));
I2C_Stop();
}
void BK1080_Mute(bool Mute)
{
if (Mute) {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x4201);
} else {
BK1080_WriteRegister(BK1080_REG_02_POWER_CONFIGURATION, 0x0201);
}
}
void BK1080_SetFrequency(uint16_t Frequency)
{
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, Frequency - 760);
SYSTEM_DelayMs(10);
BK1080_WriteRegister(BK1080_REG_03_CHANNEL, (Frequency - 760) | 0x8000);
}
void BK1080_GetFrequencyDeviation(uint16_t Frequency)
{
BK1080_BaseFrequency = Frequency;
BK1080_FrequencyDeviation = BK1080_ReadRegister(BK1080_REG_07) / 16;
}

35
driver/bk1080.h Normal file
View File

@ -0,0 +1,35 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_BK1080_H
#define DRIVER_BK1080_H
#include <stdbool.h>
#include <stdint.h>
#include "driver/bk1080-regs.h"
extern uint16_t BK1080_BaseFrequency;
extern uint16_t BK1080_FrequencyDeviation;
void BK1080_Init(uint16_t Frequency, bool bDoScan);
uint16_t BK1080_ReadRegister(BK1080_Register_t Register);
void BK1080_WriteRegister(BK1080_Register_t Register, uint16_t Value);
void BK1080_Mute(bool Mute);
void BK1080_SetFrequency(uint16_t Frequency);
void BK1080_GetFrequencyDeviation(uint16_t Frequency);
#endif

353
driver/bk4819-regs.h Normal file
View File

@ -0,0 +1,353 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BK4819_REGS_H
#define BK4819_REGS_H
enum BK4819_REGISTER_t {
BK4819_REG_00 = 0x00U,
BK4819_REG_02 = 0x02U,
BK4819_REG_06 = 0x06U,
BK4819_REG_07 = 0x07U,
BK4819_REG_08 = 0x08U,
BK4819_REG_09 = 0x09U,
BK4819_REG_0B = 0x0BU,
BK4819_REG_0C = 0x0CU,
BK4819_REG_0D = 0x0DU,
BK4819_REG_0E = 0x0EU,
BK4819_REG_10 = 0x10U,
BK4819_REG_11 = 0x11U,
BK4819_REG_12 = 0x12U,
BK4819_REG_13 = 0x13U,
BK4819_REG_14 = 0x14U,
BK4819_REG_19 = 0x19U,
BK4819_REG_1F = 0x1FU,
BK4819_REG_20 = 0x20U,
BK4819_REG_21 = 0x21U,
BK4819_REG_24 = 0x24U,
BK4819_REG_28 = 0x28U,
BK4819_REG_29 = 0x29U,
BK4819_REG_2B = 0x2BU,
BK4819_REG_30 = 0x30U,
BK4819_REG_31 = 0x31U,
BK4819_REG_32 = 0x32U,
BK4819_REG_33 = 0x33U,
BK4819_REG_36 = 0x36U,
BK4819_REG_37 = 0x37U,
BK4819_REG_38 = 0x38U,
BK4819_REG_39 = 0x39U,
BK4819_REG_3A = 0x3AU,
BK4819_REG_3B = 0x3BU,
BK4819_REG_3C = 0x3CU,
BK4819_REG_3E = 0x3EU,
BK4819_REG_3F = 0x3FU,
BK4819_REG_43 = 0x43U,
BK4819_REG_46 = 0x46U,
BK4819_REG_47 = 0x47U,
BK4819_REG_48 = 0x48U,
BK4819_REG_49 = 0x49U,
BK4819_REG_4D = 0x4DU,
BK4819_REG_4E = 0x4EU,
BK4819_REG_4F = 0x4FU,
BK4819_REG_50 = 0x50U,
BK4819_REG_51 = 0x51U,
BK4819_REG_52 = 0x52U,
BK4819_REG_58 = 0x58U,
BK4819_REG_59 = 0x59U,
BK4819_REG_5A = 0x5AU,
BK4819_REG_5B = 0x5BU,
BK4819_REG_5C = 0x5CU,
BK4819_REG_5D = 0x5DU,
BK4819_REG_5F = 0x5FU,
BK4819_REG_63 = 0x63U,
BK4819_REG_64 = 0x64U,
BK4819_REG_65 = 0x65U,
BK4819_REG_67 = 0x67U,
BK4819_REG_68 = 0x68U,
BK4819_REG_69 = 0x69U,
BK4819_REG_6A = 0x6AU,
BK4819_REG_6F = 0x6FU,
BK4819_REG_70 = 0x70U,
BK4819_REG_71 = 0x71U,
BK4819_REG_72 = 0x72U,
BK4819_REG_78 = 0x78U,
BK4819_REG_79 = 0x79U,
BK4819_REG_7A = 0x7AU,
BK4819_REG_7B = 0x7BU,
BK4819_REG_7C = 0x7CU,
BK4819_REG_7D = 0x7DU,
BK4819_REG_7E = 0x7EU,
};
typedef enum BK4819_REGISTER_t BK4819_REGISTER_t;
enum BK4819_GPIO_PIN_t {
BK4819_GPIO6_PIN2 = 0,
BK4819_GPIO5_PIN1 = 1,
BK4819_GPIO4_PIN32 = 2,
BK4819_GPIO3_PIN31 = 3,
BK4819_GPIO2_PIN30 = 4,
BK4819_GPIO1_PIN29_RED = 5,
BK4819_GPIO0_PIN28_GREEN = 6,
};
typedef enum BK4819_GPIO_PIN_t BK4819_GPIO_PIN_t;
// REG 02
#define BK4819_REG_02_SHIFT_FSK_TX_FINISHED 15
#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY 14
#define BK4819_REG_02_SHIFT_FSK_RX_FINISHED 13
#define BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL 12
#define BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND 11
#define BK4819_REG_02_SHIFT_CxCSS_TAIL 10
#define BK4819_REG_02_SHIFT_CDCSS_FOUND 9
#define BK4819_REG_02_SHIFT_CDCSS_LOST 8
#define BK4819_REG_02_SHIFT_CTCSS_FOUND 7
#define BK4819_REG_02_SHIFT_CTCSS_LOST 6
#define BK4819_REG_02_SHIFT_VOX_FOUND 5
#define BK4819_REG_02_SHIFT_VOX_LOST 4
#define BK4819_REG_02_SHIFT_SQUELCH_FOUND 3
#define BK4819_REG_02_SHIFT_SQUELCH_LOST 2
#define BK4819_REG_02_SHIFT_FSK_RX_SYNC 1
#define BK4819_REG_02_MASK_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX)
#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY)
#define BK4819_REG_02_MASK_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED)
#define BK4819_REG_02_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL)
#define BK4819_REG_02_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND)
#define BK4819_REG_02_MASK_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL)
#define BK4819_REG_02_MASK_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND)
#define BK4819_REG_02_MASK_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST)
#define BK4819_REG_02_MASK_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND)
#define BK4819_REG_02_MASK_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST)
#define BK4819_REG_02_MASK_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND)
#define BK4819_REG_02_MASK_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST)
#define BK4819_REG_02_MASK_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND)
#define BK4819_REG_02_MASK_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST)
#define BK4819_REG_02_MASK_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC)
#define BK4819_REG_02_FSK_TX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_TX_FINISHED)
#define BK4819_REG_02_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_EMPTY)
#define BK4819_REG_02_FSK_RX_FINISHED (1U << BK4819_REG_02_SHIFT_FSK_RX_FINISHED)
#define BK4819_REG_02_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_02_SHIFT_FSK_FIFO_ALMOST_FULL)
#define BK4819_REG_02_DTMF_5TONE_FOUND (1U << BK4819_REG_02_SHIFT_DTMF_5TONE_FOUND)
#define BK4819_REG_02_CxCSS_TAIL (1U << BK4819_REG_02_SHIFT_CxCSS_TAIL)
#define BK4819_REG_02_CDCSS_FOUND (1U << BK4819_REG_02_SHIFT_CDCSS_FOUND)
#define BK4819_REG_02_CDCSS_LOST (1U << BK4819_REG_02_SHIFT_CDCSS_LOST)
#define BK4819_REG_02_CTCSS_FOUND (1U << BK4819_REG_02_SHIFT_CTCSS_FOUND)
#define BK4819_REG_02_CTCSS_LOST (1U << BK4819_REG_02_SHIFT_CTCSS_LOST)
#define BK4819_REG_02_VOX_FOUND (1U << BK4819_REG_02_SHIFT_VOX_FOUND)
#define BK4819_REG_02_VOX_LOST (1U << BK4819_REG_02_SHIFT_VOX_LOST)
#define BK4819_REG_02_SQUELCH_FOUND (1U << BK4819_REG_02_SHIFT_SQUELCH_FOUND)
#define BK4819_REG_02_SQUELCH_LOST (1U << BK4819_REG_02_SHIFT_SQUELCH_LOST)
#define BK4819_REG_02_FSK_RX_SYNC (1U << BK4819_REG_02_SHIFT_FSK_RX_SYNC)
// REG 07
#define BK4819_REG_07_SHIFT_FREQUENCY_MODE 13
#define BK4819_REG_07_SHIFT_FREQUENCY 0
#define BK4819_REG_07_MASK_FREQUENCY_MODE (0x0007U << BK4819_REG_07_SHIFT_FREQUENCY_MODE)
#define BK4819_REG_07_MASK_FREQUENCY (0x1FFFU << BK4819_REG_07_SHIFT_FREQUENCY)
#define BK4819_REG_07_MODE_CTC1 (0U << BK4819_REG_07_SHIFT_FREQUENCY_MODE)
#define BK4819_REG_07_MODE_CTC2 (1U << BK4819_REG_07_SHIFT_FREQUENCY_MODE)
#define BK4819_REG_07_MODE_CDCSS (2U << BK4819_REG_07_SHIFT_FREQUENCY_MODE)
// REG 24
#define BK4819_REG_24_SHIFT_UNKNOWN_15 15
#define BK4819_REG_24_SHIFT_THRESHOLD 7
#define BK4819_REG_24_SHIFT_UNKNOWN_6 6
#define BK4819_REG_24_SHIFT_ENABLE 5
#define BK4819_REG_24_SHIFT_SELECT 4
#define BK4819_REG_24_SHIFT_MAX_SYMBOLS 0
#define BK4819_REG_24_MASK_THRESHOLD (0x2FU << BK4819_REG_24_SHIFT_THRESHOLD)
#define BK4819_REG_24_MASK_ENABLE (0x01U << BK4819_REG_24_SHIFT_ENABLE)
#define BK4819_REG_24_MASK_SELECT (0x04U << BK4819_REG_24_SHIFT_SELECT)
#define BK4819_REG_24_MASK_MAX_SYMBOLS (0x0FU << BK4819_REG_24_SHIFT_MAX_SYMBOLS)
#define BK4819_REG_24_ENABLE (0x01U << BK4819_REG_24_SHIFT_ENABLE)
#define BK4819_REG_24_DISABLE (0x00U << BK4819_REG_24_SHIFT_ENABLE)
#define BK4819_REG_24_SELECT_DTMF (0x01U << BK4819_REG_24_SHIFT_SELECT)
#define BK4819_REG_24_SELECT_SELCALL (0x00U << BK4819_REG_24_SHIFT_SELECT)
// REG 30
#define BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB 15
#define BK4819_REG_30_SHIFT_ENABLE_UNKNOWN 14
#define BK4819_REG_30_SHIFT_ENABLE_RX_LINK 10
#define BK4819_REG_30_SHIFT_ENABLE_AF_DAC 9
#define BK4819_REG_30_SHIFT_ENABLE_DISC_MODE 8
#define BK4819_REG_30_SHIFT_ENABLE_PLL_VCO 4
#define BK4819_REG_30_SHIFT_ENABLE_PA_GAIN 3
#define BK4819_REG_30_SHIFT_ENABLE_MIC_ADC 2
#define BK4819_REG_30_SHIFT_ENABLE_TX_DSP 1
#define BK4819_REG_30_SHIFT_ENABLE_RX_DSP 0
#define BK4819_REG_30_MASK_ENABLE_VCO_CALIB (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB)
#define BK4819_REG_30_MASK_ENABLE_UNKNOWN (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN)
#define BK4819_REG_30_MASK_ENABLE_RX_LINK (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK)
#define BK4819_REG_30_MASK_ENABLE_AF_DAC (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC)
#define BK4819_REG_30_MASK_ENABLE_DISC_MODE (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE)
#define BK4819_REG_30_MASK_ENABLE_PLL_VCO (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO)
#define BK4819_REG_30_MASK_ENABLE_PA_GAIN (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN)
#define BK4819_REG_30_MASK_ENABLE_MIC_ADC (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC)
#define BK4819_REG_30_MASK_ENABLE_TX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP)
#define BK4819_REG_30_MASK_ENABLE_RX_DSP (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP)
enum {
BK4819_REG_30_ENABLE_VCO_CALIB = (0x1U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB),
BK4819_REG_30_DISABLE_VCO_CALIB = (0x0U << BK4819_REG_30_SHIFT_ENABLE_VCO_CALIB),
BK4819_REG_30_ENABLE_UNKNOWN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN),
BK4819_REG_30_DISABLE_UNKNOWN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_UNKNOWN),
BK4819_REG_30_ENABLE_RX_LINK = (0xFU << BK4819_REG_30_SHIFT_ENABLE_RX_LINK),
BK4819_REG_30_DISABLE_RX_LINK = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_LINK),
BK4819_REG_30_ENABLE_AF_DAC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC),
BK4819_REG_30_DISABLE_AF_DAC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_AF_DAC),
BK4819_REG_30_ENABLE_DISC_MODE = (0x1U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE),
BK4819_REG_30_DISABLE_DISC_MODE = (0x0U << BK4819_REG_30_SHIFT_ENABLE_DISC_MODE),
BK4819_REG_30_ENABLE_PLL_VCO = (0xFU << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO),
BK4819_REG_30_DISABLE_PLL_VCO = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PLL_VCO),
BK4819_REG_30_ENABLE_PA_GAIN = (0x1U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN),
BK4819_REG_30_DISABLE_PA_GAIN = (0x0U << BK4819_REG_30_SHIFT_ENABLE_PA_GAIN),
BK4819_REG_30_ENABLE_MIC_ADC = (0x1U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC),
BK4819_REG_30_DISABLE_MIC_ADC = (0x0U << BK4819_REG_30_SHIFT_ENABLE_MIC_ADC),
BK4819_REG_30_ENABLE_TX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP),
BK4819_REG_30_DISABLE_TX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_TX_DSP),
BK4819_REG_30_ENABLE_RX_DSP = (0x1U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP),
BK4819_REG_30_DISABLE_RX_DSP = (0x0U << BK4819_REG_30_SHIFT_ENABLE_RX_DSP),
};
// REG 3F
#define BK4819_REG_3F_SHIFT_FSK_TX_FINISHED 15
#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY 14
#define BK4819_REG_3F_SHIFT_FSK_RX_FINISHED 13
#define BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL 12
#define BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND 11
#define BK4819_REG_3F_SHIFT_CxCSS_TAIL 10
#define BK4819_REG_3F_SHIFT_CDCSS_FOUND 9
#define BK4819_REG_3F_SHIFT_CDCSS_LOST 8
#define BK4819_REG_3F_SHIFT_CTCSS_FOUND 7
#define BK4819_REG_3F_SHIFT_CTCSS_LOST 6
#define BK4819_REG_3F_SHIFT_VOX_FOUND 5
#define BK4819_REG_3F_SHIFT_VOX_LOST 4
#define BK4819_REG_3F_SHIFT_SQUELCH_FOUND 3
#define BK4819_REG_3F_SHIFT_SQUELCH_LOST 2
#define BK4819_REG_3F_SHIFT_FSK_RX_SYNC 1
#define BK4819_REG_3F_MASK_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX)
#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY)
#define BK4819_REG_3F_MASK_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED)
#define BK4819_REG_3F_MASK_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL)
#define BK4819_REG_3F_MASK_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND)
#define BK4819_REG_3F_MASK_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL)
#define BK4819_REG_3F_MASK_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND)
#define BK4819_REG_3F_MASK_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST)
#define BK4819_REG_3F_MASK_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND)
#define BK4819_REG_3F_MASK_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST)
#define BK4819_REG_3F_MASK_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND)
#define BK4819_REG_3F_MASK_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST)
#define BK4819_REG_3F_MASK_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND)
#define BK4819_REG_3F_MASK_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST)
#define BK4819_REG_3F_MASK_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC)
#define BK4819_REG_3F_FSK_TX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_TX_FINISHED)
#define BK4819_REG_3F_FSK_FIFO_ALMOST_EMPTY (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_EMPTY)
#define BK4819_REG_3F_FSK_RX_FINISHED (1U << BK4819_REG_3F_SHIFT_FSK_RX_FINISHED)
#define BK4819_REG_3F_FSK_FIFO_ALMOST_FULL (1U << BK4819_REG_3F_SHIFT_FSK_FIFO_ALMOST_FULL)
#define BK4819_REG_3F_DTMF_5TONE_FOUND (1U << BK4819_REG_3F_SHIFT_DTMF_5TONE_FOUND)
#define BK4819_REG_3F_CxCSS_TAIL (1U << BK4819_REG_3F_SHIFT_CxCSS_TAIL)
#define BK4819_REG_3F_CDCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CDCSS_FOUND)
#define BK4819_REG_3F_CDCSS_LOST (1U << BK4819_REG_3F_SHIFT_CDCSS_LOST)
#define BK4819_REG_3F_CTCSS_FOUND (1U << BK4819_REG_3F_SHIFT_CTCSS_FOUND)
#define BK4819_REG_3F_CTCSS_LOST (1U << BK4819_REG_3F_SHIFT_CTCSS_LOST)
#define BK4819_REG_3F_VOX_FOUND (1U << BK4819_REG_3F_SHIFT_VOX_FOUND)
#define BK4819_REG_3F_VOX_LOST (1U << BK4819_REG_3F_SHIFT_VOX_LOST)
#define BK4819_REG_3F_SQUELCH_FOUND (1U << BK4819_REG_3F_SHIFT_SQUELCH_FOUND)
#define BK4819_REG_3F_SQUELCH_LOST (1U << BK4819_REG_3F_SHIFT_SQUELCH_LOST)
#define BK4819_REG_3F_FSK_RX_SYNC (1U << BK4819_REG_3F_SHIFT_FSK_RX_SYNC)
// REG 51
#define BK4819_REG_51_SHIFT_ENABLE_CxCSS 15
#define BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT 14
#define BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY 13
#define BK4819_REG_51_SHIFT_CxCSS_MODE 12
#define BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH 11
#define BK4819_REG_51_SHIFT_1050HZ_DETECTION 10
#define BK4819_REG_51_SHIFT_AUTO_CDCSS_BW 9
#define BK4819_REG_51_SHIFT_AUTO_CTCSS_BW 8
#define BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1 0
#define BK4819_REG_51_MASK_ENABLE_CxCSS (0x01U << BK4819_REG_51_SHIFT_ENABLE_CxCSS)
#define BK4819_REG_51_MASK_GPIO6_PIN2_INPUT (0x01U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT)
#define BK4819_REG_51_MASK_TX_CDCSS_POLARITY (0x01U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY)
#define BK4819_REG_51_MASK_CxCSS_MODE (0x01U << BK4819_REG_51_SHIFT_CxCSS_MODE)
#define BK4819_REG_51_MASK_CDCSS_BIT_WIDTH (0x01U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH)
#define BK4819_REG_51_MASK_1050HZ_DETECTION (0x01U << BK4819_REG_51_SHIFT_1050HZ_DETECTION)
#define BK4819_REG_51_MASK_AUTO_CDCSS_BW (0x01U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW)
#define BK4819_REG_51_MASK_AUTO_CTCSS_BW (0x01U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW)
#define BK4819_REG_51_MASK_CxCSS_TX_GAIN1 (0x7FU << BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1)
enum {
BK4819_REG_51_ENABLE_CxCSS = (1U << BK4819_REG_51_SHIFT_ENABLE_CxCSS),
BK4819_REG_51_DISABLE_CxCSS = (0U << BK4819_REG_51_SHIFT_ENABLE_CxCSS),
BK4819_REG_51_GPIO6_PIN2_INPUT = (1U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT),
BK4819_REG_51_GPIO6_PIN2_NORMAL = (0U << BK4819_REG_51_SHIFT_GPIO6_PIN2_INPUT),
BK4819_REG_51_TX_CDCSS_NEGATIVE = (1U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY),
BK4819_REG_51_TX_CDCSS_POSITIVE = (0U << BK4819_REG_51_SHIFT_TX_CDCSS_POLARITY),
BK4819_REG_51_MODE_CTCSS = (1U << BK4819_REG_51_SHIFT_CxCSS_MODE),
BK4819_REG_51_MODE_CDCSS = (0U << BK4819_REG_51_SHIFT_CxCSS_MODE),
BK4819_REG_51_CDCSS_24_BIT = (1U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH),
BK4819_REG_51_CDCSS_23_BIT = (0U << BK4819_REG_51_SHIFT_CDCSS_BIT_WIDTH),
BK4819_REG_51_1050HZ_DETECTION = (1U << BK4819_REG_51_SHIFT_1050HZ_DETECTION),
BK4819_REG_51_1050HZ_NO_DETECTION = (0U << BK4819_REG_51_SHIFT_1050HZ_DETECTION),
BK4819_REG_51_AUTO_CDCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW),
BK4819_REG_51_AUTO_CDCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CDCSS_BW),
BK4819_REG_51_AUTO_CTCSS_BW_DISABLE = (1U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW),
BK4819_REG_51_AUTO_CTCSS_BW_ENABLE = (0U << BK4819_REG_51_SHIFT_AUTO_CTCSS_BW),
};
// REG 70
#define BK4819_REG_70_SHIFT_ENABLE_TONE1 15
#define BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN 8
#define BK4819_REG_70_SHIFT_ENABLE_TONE2 7
#define BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN 0
#define BK4819_REG_70_MASK_ENABLE_TONE1 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE1)
#define BK4819_REG_70_MASK_TONE1_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)
#define BK4819_REG_70_MASK_ENABLE_TONE2 (0x01U << BK4819_REG_70_SHIFT_ENABLE_TONE2)
#define BK4819_REG_70_MASK_TONE2_TUNING_GAIN (0x7FU << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN)
enum {
BK4819_REG_70_ENABLE_TONE1 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE1),
BK4819_REG_70_ENABLE_TONE2 = (1U << BK4819_REG_70_SHIFT_ENABLE_TONE2),
};
#endif

975
driver/bk4819.c Normal file
View File

@ -0,0 +1,975 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bk4819.h"
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h"
#include "driver/system.h"
#include "driver/systick.h"
static const uint16_t FSK_RogerTable[7] = {0xF1A2, 0x7446, 0x61A4, 0x6544, 0x4E8A, 0xE044, 0xEA84};
static uint16_t gBK4819_GpioOutState;
bool gRxIdleMode;
__inline uint16_t scale_freq(const uint16_t freq)
{
// return (uint16_t)(freq * 10.32444); // argh - floating point
// return ((uint32_t)freq * 1032444u) / 100000u;
return ((uint32_t)freq * 1353245u) >> 17;
}
void BK4819_Init(void)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
BK4819_WriteRegister(BK4819_REG_00, 0x8000);
BK4819_WriteRegister(BK4819_REG_00, 0x0000);
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
BK4819_WriteRegister(BK4819_REG_36, 0x0022);
BK4819_SetAGC(0);
BK4819_WriteRegister(BK4819_REG_19, 0x1041);
BK4819_WriteRegister(BK4819_REG_7D, 0xE940);
BK4819_WriteRegister(BK4819_REG_48, 0xB3A8);
BK4819_WriteRegister(BK4819_REG_09, 0x006F);
BK4819_WriteRegister(BK4819_REG_09, 0x106B);
BK4819_WriteRegister(BK4819_REG_09, 0x2067);
BK4819_WriteRegister(BK4819_REG_09, 0x3062);
BK4819_WriteRegister(BK4819_REG_09, 0x4050);
BK4819_WriteRegister(BK4819_REG_09, 0x5047);
BK4819_WriteRegister(BK4819_REG_09, 0x603A);
BK4819_WriteRegister(BK4819_REG_09, 0x702C);
BK4819_WriteRegister(BK4819_REG_09, 0x8041);
BK4819_WriteRegister(BK4819_REG_09, 0x9037);
BK4819_WriteRegister(BK4819_REG_09, 0xA025);
BK4819_WriteRegister(BK4819_REG_09, 0xB017);
BK4819_WriteRegister(BK4819_REG_09, 0xC0E4);
BK4819_WriteRegister(BK4819_REG_09, 0xD0CB);
BK4819_WriteRegister(BK4819_REG_09, 0xE0B5);
BK4819_WriteRegister(BK4819_REG_09, 0xF09F);
BK4819_WriteRegister(BK4819_REG_1F, 0x5454);
BK4819_WriteRegister(BK4819_REG_3E, 0xA037);
gBK4819_GpioOutState = 0x9000;
BK4819_WriteRegister(BK4819_REG_33, 0x9000);
BK4819_WriteRegister(BK4819_REG_3F, 0);
}
static uint16_t BK4819_ReadU16(void)
{
unsigned int i;
uint16_t Value;
PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_ENABLE;
GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_INPUT;
SYSTICK_DelayUs(1);
Value = 0;
for (i = 0; i < 16; i++)
{
Value <<= 1;
Value |= GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
}
PORTCON_PORTC_IE = (PORTCON_PORTC_IE & ~PORTCON_PORTC_IE_C2_MASK) | PORTCON_PORTC_IE_C2_BITS_DISABLE;
GPIOC->DIR = (GPIOC->DIR & ~GPIO_DIR_2_MASK) | GPIO_DIR_2_BITS_OUTPUT;
return Value;
}
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register)
{
uint16_t Value;
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
BK4819_WriteU8(Register | 0x80);
Value = BK4819_ReadU16();
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
return Value;
}
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data)
{
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
BK4819_WriteU8(Register);
SYSTICK_DelayUs(1);
BK4819_WriteU16(Data);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCN);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
}
void BK4819_WriteU8(uint8_t Data)
{
unsigned int i;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
for (i = 0; i < 8; i++)
{
if ((Data & 0x80U) == 0)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
else
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
Data <<= 1;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
}
}
void BK4819_WriteU16(uint16_t Data)
{
unsigned int i;
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
for (i = 0; i < 16; i++)
{
if ((Data & 0x8000U) == 0U)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
else
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SDA);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
Data <<= 1;
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_BK4819_SCL);
SYSTICK_DelayUs(1);
}
}
void BK4819_SetAGC(uint8_t Value)
{
if (Value == 0)
{
BK4819_WriteRegister(BK4819_REG_13, 0x03BE);
BK4819_WriteRegister(BK4819_REG_12, 0x037B);
BK4819_WriteRegister(BK4819_REG_11, 0x027B);
BK4819_WriteRegister(BK4819_REG_10, 0x007A);
BK4819_WriteRegister(BK4819_REG_14, 0x0019);
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x8420);
}
else
if (Value == 1)
{
unsigned int i;
BK4819_WriteRegister(BK4819_REG_13, 0x03BE);
BK4819_WriteRegister(BK4819_REG_12, 0x037C);
BK4819_WriteRegister(BK4819_REG_11, 0x027B);
BK4819_WriteRegister(BK4819_REG_10, 0x007A);
BK4819_WriteRegister(BK4819_REG_14, 0x0018);
BK4819_WriteRegister(BK4819_REG_49, 0x2A38);
BK4819_WriteRegister(BK4819_REG_7B, 0x318C);
BK4819_WriteRegister(BK4819_REG_7C, 0x595E);
BK4819_WriteRegister(BK4819_REG_20, 0x8DEF);
for (i = 0; i < 8; i++)
// Bug? The bit 0x2000 below overwrites the (i << 13)
BK4819_WriteRegister(BK4819_REG_06, ((i << 13) | 0x2500u) + 0x036u);
}
}
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet)
{
if (bSet)
gBK4819_GpioOutState |= (0x40u >> Pin);
else
gBK4819_GpioOutState &= ~(0x40u >> Pin);
BK4819_WriteRegister(BK4819_REG_33, gBK4819_GpioOutState);
}
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord)
{
// Enable CDCSS
// Transmit positive CDCSS code
// CDCSS Mode
// CDCSS 23bit
// Enable Auto CDCSS Bw Mode
// Enable Auto CTCSS Bw Mode
// CTCSS/CDCSS Tx Gain1 Tuning = 51
BK4819_WriteRegister(BK4819_REG_51, 0
| BK4819_REG_51_ENABLE_CxCSS
| BK4819_REG_51_GPIO6_PIN2_NORMAL
| BK4819_REG_51_TX_CDCSS_POSITIVE
| BK4819_REG_51_MODE_CDCSS
| BK4819_REG_51_CDCSS_23_BIT
| BK4819_REG_51_1050HZ_NO_DETECTION
| BK4819_REG_51_AUTO_CDCSS_BW_ENABLE
| BK4819_REG_51_AUTO_CTCSS_BW_ENABLE
| (51U << BK4819_REG_51_SHIFT_CxCSS_TX_GAIN1));
// CTC1 Frequency Control Word = 2775
BK4819_WriteRegister(BK4819_REG_07, 0
| BK4819_REG_07_MODE_CTC1
| (2775u << BK4819_REG_07_SHIFT_FREQUENCY));
// Set the code word
BK4819_WriteRegister(BK4819_REG_08, 0x0000 | ((CodeWord >> 0) & 0xFFF));
BK4819_WriteRegister(BK4819_REG_08, 0x8000 | ((CodeWord >> 12) & 0xFFF));
}
void BK4819_SetCTCSSFrequency(uint32_t FreqControlWord)
{
uint16_t Config;
if (FreqControlWord == 2625)
{ // Enables 1050Hz detection mode
// Enable TxCTCSS
// CTCSS Mode
// 1050/4 Detect Enable
// Enable Auto CDCSS Bw Mode
// Enable Auto CTCSS Bw Mode
// CTCSS/CDCSS Tx Gain1 Tuning = 74
Config = 0x944A;
}
else
{
// Enable TxCTCSS
// CTCSS Mode
// Enable Auto CDCSS Bw Mode
// Enable Auto CTCSS Bw Mode
// CTCSS/CDCSS Tx Gain1 Tuning = 74
Config = 0x904A;
}
BK4819_WriteRegister(BK4819_REG_51, Config);
// CTC1 Frequency Control Word
BK4819_WriteRegister(BK4819_REG_07, 0
| BK4819_REG_07_MODE_CTC1
| ((FreqControlWord * 2065) / 1000) << BK4819_REG_07_SHIFT_FREQUENCY);
}
void BK4819_Set55HzTailDetection(void)
{
// CTC2 Frequency Control Word = round_nearest(25391 / 55) = 462
BK4819_WriteRegister(BK4819_REG_07, (1U << 13) | 462);
}
void BK4819_EnableVox(uint16_t VoxEnableThreshold, uint16_t VoxDisableThreshold)
{
//VOX Algorithm
//if (voxamp>VoxEnableThreshold) VOX = 1;
//else
//if (voxamp<VoxDisableThreshold) (After Delay) VOX = 0;
const uint16_t REG_31_Value = BK4819_ReadRegister(BK4819_REG_31);
// 0xA000 is undocumented?
BK4819_WriteRegister(BK4819_REG_46, 0xA000 | (VoxEnableThreshold & 0x07FF));
// 0x1800 is undocumented?
BK4819_WriteRegister(BK4819_REG_79, 0x1800 | (VoxDisableThreshold & 0x07FF));
// Bottom 12 bits are undocumented, 15:12 vox disable delay *128ms
BK4819_WriteRegister(BK4819_REG_7A, 0x289A); // vox disable delay = 128*5 = 640ms
// Enable VOX
BK4819_WriteRegister(BK4819_REG_31, REG_31_Value | 4u); // bit 2 - VOX Enable
}
void BK4819_SetFilterBandwidth(BK4819_FilterBandwidth_t Bandwidth)
{
if (Bandwidth == BK4819_FILTER_BW_WIDE)
BK4819_WriteRegister(BK4819_REG_43, 0x3028);
else
if (Bandwidth == BK4819_FILTER_BW_NARROW)
BK4819_WriteRegister(BK4819_REG_43, 0x4048);
//BK4819_WriteRegister(BK4819_REG_43, 0x790C); // fastest squelch, https://github.com/fagci/uv-k5-firmware-fagci-mod
}
void BK4819_SetupPowerAmplifier(uint16_t Bias, uint32_t Frequency)
{
uint8_t Gain;
if (Bias > 255)
Bias = 255;
if (Frequency < 28000000)
{
// Gain 1 = 1
// Gain 2 = 0
Gain = 0x08U;
}
else
{
// Gain 1 = 4
// Gain 2 = 2
Gain = 0x22U;
}
// Enable PACTLoutput
BK4819_WriteRegister(BK4819_REG_36, (Bias << 8) | 0x80U | Gain);
}
void BK4819_SetFrequency(uint32_t Frequency)
{
BK4819_WriteRegister(BK4819_REG_38, (Frequency >> 0) & 0xFFFF);
BK4819_WriteRegister(BK4819_REG_39, (Frequency >> 16) & 0xFFFF);
}
void BK4819_SetupSquelch(uint8_t SquelchOpenRSSIThresh, uint8_t SquelchCloseRSSIThresh, uint8_t SquelchOpenNoiseThresh, uint8_t SquelchCloseNoiseThresh, uint8_t SquelchCloseGlitchThresh, uint8_t SquelchOpenGlitchThresh)
{
BK4819_WriteRegister(BK4819_REG_70, 0);
#if 1
BK4819_WriteRegister(BK4819_REG_4D, 0xA000 | SquelchCloseGlitchThresh);
#else
// fastest squelch, https://github.com/fagci/uv-k5-firmware-fagci-mod
// this doesn't work !
BK4819_WriteRegister(BK4819_REG_4D, 0b01000000 | SquelchCloseGlitchThresh);
#endif
// 0x6f = 0110 1111 meaning the default sql delays from the datasheet are used (101 and 111)
BK4819_WriteRegister(BK4819_REG_4E, 0x6F00 | SquelchOpenGlitchThresh);
BK4819_WriteRegister(BK4819_REG_4F, (SquelchCloseNoiseThresh << 8) | SquelchOpenNoiseThresh);
BK4819_WriteRegister(BK4819_REG_78, (SquelchOpenRSSIThresh << 8) | SquelchCloseRSSIThresh);
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_RX_TurnOn();
}
void BK4819_SetAF(BK4819_AF_Type_t AF)
{
// AF Output Inverse Mode = Inverse
// Undocumented bits 0x2040
BK4819_WriteRegister(BK4819_REG_47, 0x6040 | (AF << 8));
}
void BK4819_RX_TurnOn(void)
{
// DSP Voltage Setting = 1
// ANA LDO = 2.7v
// VCO LDO = 2.7v
// RF LDO = 2.7v
// PLL LDO = 2.7v
// ANA LDO bypass
// VCO LDO bypass
// RF LDO bypass
// PLL LDO bypass
// Reserved bit is 1 instead of 0
// Enable DSP
// Enable XTAL
// Enable Band Gap
BK4819_WriteRegister(BK4819_REG_37, 0x1F0F);
// Turn off everything
BK4819_WriteRegister(BK4819_REG_30, 0);
// Enable VCO Calibration
// Enable RX Link
// Enable AF DAC
// Enable PLL/VCO
// Disable PA Gain
// Disable MIC ADC
// Disable TX DSP
// Enable RX DSP
BK4819_WriteRegister(BK4819_REG_30, 0xBFF1);
}
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency)
{
if (Frequency < 28000000)
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, true);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
}
else
if (Frequency == 0xFFFFFFFF)
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, false);
}
else
{
BK4819_ToggleGpioOut(BK4819_GPIO2_PIN30, false);
BK4819_ToggleGpioOut(BK4819_GPIO3_PIN31, true);
}
}
void BK4819_DisableScramble(void)
{
const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31);
BK4819_WriteRegister(BK4819_REG_31, Value & 0xFFFD);
}
void BK4819_EnableScramble(uint8_t Type)
{
const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31);
BK4819_WriteRegister(BK4819_REG_31, Value | 2u);
BK4819_WriteRegister(BK4819_REG_71, 0x68DC + (Type * 1032));
}
void BK4819_DisableVox(void)
{
const uint16_t Value = BK4819_ReadRegister(BK4819_REG_31);
BK4819_WriteRegister(BK4819_REG_31, Value & 0xFFFB);
}
void BK4819_DisableDTMF(void)
{
BK4819_WriteRegister(BK4819_REG_24, 0);
}
void BK4819_EnableDTMF(void)
{
BK4819_WriteRegister(BK4819_REG_21, 0x06D8);
BK4819_WriteRegister(BK4819_REG_24, 0
| (1U << BK4819_REG_24_SHIFT_UNKNOWN_15)
| (24 << BK4819_REG_24_SHIFT_THRESHOLD)
| (1U << BK4819_REG_24_SHIFT_UNKNOWN_6)
| BK4819_REG_24_ENABLE
| BK4819_REG_24_SELECT_DTMF
| (14U << BK4819_REG_24_SHIFT_MAX_SYMBOLS));
}
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch)
{
uint16_t ToneConfig;
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_BEEP);
if (bTuningGainSwitch == 0)
ToneConfig = 0 | BK4819_REG_70_ENABLE_TONE1 | (96U << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
else
ToneConfig = 0 | BK4819_REG_70_ENABLE_TONE1 | (28U << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN);
BK4819_WriteRegister(BK4819_REG_70, ToneConfig);
BK4819_WriteRegister(BK4819_REG_30, 0);
BK4819_WriteRegister(BK4819_REG_30, 0
| BK4819_REG_30_ENABLE_AF_DAC
| BK4819_REG_30_ENABLE_DISC_MODE
| BK4819_REG_30_ENABLE_TX_DSP);
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
}
void BK4819_EnterTxMute(void)
{
BK4819_WriteRegister(BK4819_REG_50, 0xBB20);
}
void BK4819_ExitTxMute(void)
{
BK4819_WriteRegister(BK4819_REG_50, 0x3B20);
}
void BK4819_Sleep(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0);
BK4819_WriteRegister(BK4819_REG_37, 0x1D00);
}
void BK4819_TurnsOffTones_TurnsOnRX(void)
{
BK4819_WriteRegister(BK4819_REG_70, 0);
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_ExitTxMute();
BK4819_WriteRegister(BK4819_REG_30, 0);
BK4819_WriteRegister(BK4819_REG_30, 0
| BK4819_REG_30_ENABLE_VCO_CALIB
| BK4819_REG_30_ENABLE_RX_LINK
| BK4819_REG_30_ENABLE_AF_DAC
| BK4819_REG_30_ENABLE_DISC_MODE
| BK4819_REG_30_ENABLE_PLL_VCO
| BK4819_REG_30_ENABLE_RX_DSP);
}
#ifndef DISABLE_AIRCOPY
void BK4819_SetupAircopy(void)
{
BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2, tuning gain 48
BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Tone2 baudrate 1200
BK4819_WriteRegister(BK4819_REG_58, 0x00C1); // FSK Enable, FSK 1.2K RX Bandwidth, Preamble 0xAA or 0x55, RX Gain 0, RX Mode
// (FSK1.2K, FSK2.4K Rx and NOAA SAME Rx), TX Mode FSK 1.2K and FSK 2.4K Tx
BK4819_WriteRegister(BK4819_REG_5C, 0x5665); // Enable CRC among other things we don't know yet
BK4819_WriteRegister(BK4819_REG_5D, 0x4700); // FSK Data Length 72 Bytes (0xabcd + 2 byte length + 64 byte payload + 2 byte CRC + 0xdcba)
}
#endif
void BK4819_ResetFSK(void)
{
BK4819_WriteRegister(BK4819_REG_3F, 0x0000); // Disable interrupts
BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Sync length 4 bytes, 7 byte preamble
SYSTEM_DelayMs(30);
BK4819_Idle();
}
void BK4819_Idle(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0x0000);
}
void BK4819_ExitBypass(void)
{
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_7E, 0x302E);
}
void BK4819_PrepareTransmit(void)
{
BK4819_ExitBypass();
BK4819_ExitTxMute();
BK4819_TxOn_Beep();
}
void BK4819_TxOn_Beep(void)
{
BK4819_WriteRegister(BK4819_REG_37, 0x1D0F);
BK4819_WriteRegister(BK4819_REG_52, 0x028F);
BK4819_WriteRegister(BK4819_REG_30, 0x0000);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
}
void BK4819_ExitSubAu(void)
{
BK4819_WriteRegister(BK4819_REG_51, 0x0000);
}
void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void)
{
if (gRxIdleMode)
{
BK4819_ToggleGpioOut(BK4819_GPIO6_PIN2, true);
BK4819_RX_TurnOn();
}
}
void BK4819_EnterDTMF_TX(bool bLocalLoopback)
{
BK4819_EnableDTMF();
BK4819_EnterTxMute();
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, 0
| BK4819_REG_70_MASK_ENABLE_TONE1
| (83 << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN)
| BK4819_REG_70_MASK_ENABLE_TONE2
| (83 << BK4819_REG_70_SHIFT_TONE2_TUNING_GAIN));
BK4819_EnableTXLink();
}
void BK4819_ExitDTMF_TX(bool bKeep)
{
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
BK4819_DisableDTMF();
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
if (!bKeep)
BK4819_ExitTxMute();
}
void BK4819_EnableTXLink(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0
| BK4819_REG_30_ENABLE_VCO_CALIB
| BK4819_REG_30_ENABLE_UNKNOWN
| BK4819_REG_30_DISABLE_RX_LINK
| BK4819_REG_30_ENABLE_AF_DAC
| BK4819_REG_30_ENABLE_DISC_MODE
| BK4819_REG_30_ENABLE_PLL_VCO
| BK4819_REG_30_ENABLE_PA_GAIN
| BK4819_REG_30_DISABLE_MIC_ADC
| BK4819_REG_30_ENABLE_TX_DSP
| BK4819_REG_30_DISABLE_RX_DSP);
}
void BK4819_PlayDTMF(char Code)
{
switch (Code)
{
case '0':
BK4819_WriteRegister(BK4819_REG_71, 0x25F3);
BK4819_WriteRegister(BK4819_REG_72, 0x35E1);
break;
case '1':
BK4819_WriteRegister(BK4819_REG_71, 0x1C1C);
BK4819_WriteRegister(BK4819_REG_72, 0x30C2);
break;
case '2':
BK4819_WriteRegister(BK4819_REG_71, 0x1C1C);
BK4819_WriteRegister(BK4819_REG_72, 0x35E1);
break;
case '3':
BK4819_WriteRegister(BK4819_REG_71, 0x1C1C);
BK4819_WriteRegister(BK4819_REG_72, 0x3B91);
break;
case '4':
BK4819_WriteRegister(BK4819_REG_71, 0x1F0E);
BK4819_WriteRegister(BK4819_REG_72, 0x30C2);
break;
case '5':
BK4819_WriteRegister(BK4819_REG_71, 0x1F0E);
BK4819_WriteRegister(BK4819_REG_72, 0x35E1);
break;
case '6':
BK4819_WriteRegister(BK4819_REG_71, 0x1F0E);
BK4819_WriteRegister(BK4819_REG_72, 0x3B91);
break;
case '7':
BK4819_WriteRegister(BK4819_REG_71, 0x225C);
BK4819_WriteRegister(BK4819_REG_72, 0x30C2);
break;
case '8':
BK4819_WriteRegister(BK4819_REG_71, 0x225c);
BK4819_WriteRegister(BK4819_REG_72, 0x35E1);
break;
case '9':
BK4819_WriteRegister(BK4819_REG_71, 0x225C);
BK4819_WriteRegister(BK4819_REG_72, 0x3B91);
break;
case 'A':
BK4819_WriteRegister(BK4819_REG_71, 0x1C1C);
BK4819_WriteRegister(BK4819_REG_72, 0x41DC);
break;
case 'B':
BK4819_WriteRegister(BK4819_REG_71, 0x1F0E);
BK4819_WriteRegister(BK4819_REG_72, 0x41DC);
break;
case 'C':
BK4819_WriteRegister(BK4819_REG_71, 0x225C);
BK4819_WriteRegister(BK4819_REG_72, 0x41DC);
break;
case 'D':
BK4819_WriteRegister(BK4819_REG_71, 0x25F3);
BK4819_WriteRegister(BK4819_REG_72, 0x41DC);
break;
case '*':
BK4819_WriteRegister(BK4819_REG_71, 0x25F3);
BK4819_WriteRegister(BK4819_REG_72, 0x30C2);
break;
case '#':
BK4819_WriteRegister(BK4819_REG_71, 0x25F3);
BK4819_WriteRegister(BK4819_REG_72, 0x3B91);
break;
}
}
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime)
{
unsigned int i;
for (i = 0; pString[i]; i++)
{
uint16_t Delay;
BK4819_PlayDTMF(pString[i]);
BK4819_ExitTxMute();
if (bDelayFirst && i == 0)
Delay = FirstCodePersistTime;
else
if (pString[i] == '*' || pString[i] == '#')
Delay = HashCodePersistTime;
else
Delay = CodePersistTime;
SYSTEM_DelayMs(Delay);
BK4819_EnterTxMute();
SYSTEM_DelayMs(CodeInternalTime);
}
}
void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency)
{
BK4819_EnterTxMute();
BK4819_WriteRegister(BK4819_REG_70, 0 | BK4819_REG_70_MASK_ENABLE_TONE1 | (96U << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
BK4819_EnableTXLink();
SYSTEM_DelayMs(50);
BK4819_ExitTxMute();
}
void BK4819_GenTail(uint8_t Tail)
{
switch (Tail)
{
case 0: // CTC134
BK4819_WriteRegister(BK4819_REG_52, 0x828F);
break;
case 1: // CTC120
BK4819_WriteRegister(BK4819_REG_52, 0xA28F);
break;
case 2: // CTC180
BK4819_WriteRegister(BK4819_REG_52, 0xC28F);
break;
case 3: // CTC240
BK4819_WriteRegister(BK4819_REG_52, 0xE28F);
break;
case 4: // CTC55
BK4819_WriteRegister(BK4819_REG_07, 0x046f);
break;
}
}
void BK4819_EnableCDCSS(void)
{
BK4819_GenTail(0); // CTC134
BK4819_WriteRegister(BK4819_REG_51, 0x804A);
}
void BK4819_EnableCTCSS(void)
{
BK4819_GenTail(4); // CTC55
BK4819_WriteRegister(BK4819_REG_51, 0x904A);
}
uint16_t BK4819_GetRSSI(void)
{
return BK4819_ReadRegister(BK4819_REG_67) & 0x01FF;
}
bool BK4819_GetFrequencyScanResult(uint32_t *pFrequency)
{
const uint16_t High = BK4819_ReadRegister(BK4819_REG_0D);
const bool Finished = (High & 0x8000) == 0;
if (Finished)
{
const uint16_t Low = BK4819_ReadRegister(BK4819_REG_0E);
*pFrequency = (uint32_t)((High & 0x7FF) << 16) | Low;
}
return Finished;
}
BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t *pCtcssFreq)
{
uint16_t Low;
uint16_t High = BK4819_ReadRegister(BK4819_REG_69);
if ((High & 0x8000) == 0)
{
Low = BK4819_ReadRegister(BK4819_REG_6A);
*pCdcssFreq = ((High & 0xFFF) << 12) | (Low & 0xFFF);
return BK4819_CSS_RESULT_CDCSS;
}
Low = BK4819_ReadRegister(BK4819_REG_68);
if ((Low & 0x8000) == 0)
{
*pCtcssFreq = ((Low & 0x1FFF) * 4843) / 10000;
return BK4819_CSS_RESULT_CTCSS;
}
return BK4819_CSS_RESULT_NOT_FOUND;
}
void BK4819_DisableFrequencyScan(void)
{
BK4819_WriteRegister(BK4819_REG_32, 0x0244);
}
void BK4819_EnableFrequencyScan(void)
{
BK4819_WriteRegister(BK4819_REG_32, 0x0245);
}
void BK4819_SetScanFrequency(uint32_t Frequency)
{
BK4819_SetFrequency(Frequency);
BK4819_WriteRegister(BK4819_REG_51, 0
| BK4819_REG_51_DISABLE_CxCSS
| BK4819_REG_51_GPIO6_PIN2_NORMAL
| BK4819_REG_51_TX_CDCSS_POSITIVE
| BK4819_REG_51_MODE_CDCSS
| BK4819_REG_51_CDCSS_23_BIT
| BK4819_REG_51_1050HZ_NO_DETECTION
| BK4819_REG_51_AUTO_CDCSS_BW_DISABLE
| BK4819_REG_51_AUTO_CTCSS_BW_DISABLE);
BK4819_RX_TurnOn();
}
void BK4819_Disable(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0);
}
void BK4819_StopScan(void)
{
BK4819_DisableFrequencyScan();
BK4819_Disable();
}
uint8_t BK4819_GetDTMF_5TONE_Code(void)
{
return (BK4819_ReadRegister(BK4819_REG_0B) >> 8) & 0x0F;
}
uint8_t BK4819_GetCDCSSCodeType(void)
{
return (BK4819_ReadRegister(BK4819_REG_0C) >> 14) & 3;
}
uint8_t BK4819_GetCTCType(void)
{
return (BK4819_ReadRegister(BK4819_REG_0C) >> 10) & 3;
}
void BK4819_SendFSKData(uint16_t *pData)
{
unsigned int i;
uint8_t Timeout = 200;
SYSTEM_DelayMs(20);
BK4819_WriteRegister(BK4819_REG_3F, BK4819_REG_3F_FSK_TX_FINISHED);
BK4819_WriteRegister(BK4819_REG_59, 0x8068);
BK4819_WriteRegister(BK4819_REG_59, 0x0068);
for (i = 0; i < 36; i++)
BK4819_WriteRegister(BK4819_REG_5F, pData[i]);
SYSTEM_DelayMs(20);
BK4819_WriteRegister(BK4819_REG_59, 0x2868);
while (Timeout-- && (BK4819_ReadRegister(BK4819_REG_0C) & 1u) == 0)
SYSTEM_DelayMs(5);
BK4819_WriteRegister(BK4819_REG_02, 0);
SYSTEM_DelayMs(20);
BK4819_ResetFSK();
}
void BK4819_PrepareFSKReceive(void)
{
BK4819_ResetFSK();
BK4819_WriteRegister(BK4819_REG_02, 0);
BK4819_WriteRegister(BK4819_REG_3F, 0);
BK4819_RX_TurnOn();
BK4819_WriteRegister(BK4819_REG_3F, 0 | BK4819_REG_3F_FSK_RX_FINISHED | BK4819_REG_3F_FSK_FIFO_ALMOST_FULL);
// Clear RX FIFO
// FSK Preamble Length 7 bytes
// FSK SyncLength Selection
BK4819_WriteRegister(BK4819_REG_59, 0x4068);
// Enable FSK Scramble
// Enable FSK RX
// FSK Preamble Length 7 bytes
// FSK SyncLength Selection
BK4819_WriteRegister(BK4819_REG_59, 0x3068);
}
void BK4819_PlayRoger(void)
{
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, 0xE000);
BK4819_EnableTXLink();
SYSTEM_DelayMs(50);
BK4819_WriteRegister(BK4819_REG_71, 0x142A);
BK4819_ExitTxMute();
SYSTEM_DelayMs(80);
BK4819_EnterTxMute();
BK4819_WriteRegister(BK4819_REG_71, 0x1C3B);
BK4819_ExitTxMute();
SYSTEM_DelayMs(80);
BK4819_EnterTxMute();
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE);
}
void BK4819_PlayRogerMDC(void)
{
unsigned int i;
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_58, 0x37C3); // FSK Enable, RX Bandwidth FFSK1200/1800, 0xAA or 0x55 Preamble, 11 RX Gain,
// 101 RX Mode, FFSK1200/1800 TX
BK4819_WriteRegister(BK4819_REG_72, 0x3065); // Set Tone2 to 1200Hz
BK4819_WriteRegister(BK4819_REG_70, 0x00E0); // Enable Tone2 and Set Tone2 Gain
BK4819_WriteRegister(BK4819_REG_5D, 0x0D00); // Set FSK data length to 13 bytes
BK4819_WriteRegister(BK4819_REG_59, 0x8068); // 4 byte sync length, 6 byte preamble, clear TX FIFO
BK4819_WriteRegister(BK4819_REG_59, 0x0068); // Same, but clear TX FIFO is now unset (clearing done)
BK4819_WriteRegister(BK4819_REG_5A, 0x5555); // First two sync bytes
BK4819_WriteRegister(BK4819_REG_5B, 0x55AA); // End of sync bytes. Total 4 bytes: 555555aa
BK4819_WriteRegister(BK4819_REG_5C, 0xAA30); // Disable CRC
// Send the data from the roger table
for (i = 0; i < 7; i++)
BK4819_WriteRegister(BK4819_REG_5F, FSK_RogerTable[i]);
SYSTEM_DelayMs(20);
// 4 sync bytes, 6 byte preamble, Enable FSK TX
BK4819_WriteRegister(BK4819_REG_59, 0x0868);
SYSTEM_DelayMs(180);
// Stop FSK TX, reset Tone2, disable FSK
BK4819_WriteRegister(BK4819_REG_59, 0x0068);
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
BK4819_WriteRegister(BK4819_REG_58, 0x0000);
}
void BK4819_Enable_AfDac_DiscMode_TxDsp(void)
{
BK4819_WriteRegister(BK4819_REG_30, 0x0000);
BK4819_WriteRegister(BK4819_REG_30, 0x0302);
}
void BK4819_GetVoxAmp(uint16_t *pResult)
{
*pResult = BK4819_ReadRegister(BK4819_REG_64) & 0x7FFF;
}
void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency)
{
BK4819_WriteRegister(BK4819_REG_71, scale_freq(Frequency));
}
void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code)
{
BK4819_EnableDTMF();
BK4819_EnterTxMute();
BK4819_SetAF(bLocalLoopback ? BK4819_AF_BEEP : BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, 0xD3D3);
BK4819_EnableTXLink();
SYSTEM_DelayMs(50);
BK4819_PlayDTMF(Code);
BK4819_ExitTxMute();
}

150
driver/bk4819.h Normal file
View File

@ -0,0 +1,150 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_BK4819_h
#define DRIVER_BK4819_h
#include <stdbool.h>
#include <stdint.h>
#include "driver/bk4819-regs.h"
enum BK4819_AF_Type_t
{
BK4819_AF_MUTE = 0U,
BK4819_AF_OPEN = 1U,
BK4819_AF_ALAM = 2U,
BK4819_AF_BEEP = 3U,
BK4819_AF_CTCO = 6U,
BK4819_AF_AM = 7U,
BK4819_AF_FSKO = 8U,
};
typedef enum BK4819_AF_Type_t BK4819_AF_Type_t;
enum BK4819_FilterBandwidth_t
{
BK4819_FILTER_BW_WIDE = 0U,
BK4819_FILTER_BW_NARROW = 1U,
};
typedef enum BK4819_FilterBandwidth_t BK4819_FilterBandwidth_t;
enum BK4819_CssScanResult_t
{
BK4819_CSS_RESULT_NOT_FOUND = 0U,
BK4819_CSS_RESULT_CTCSS = 1U,
BK4819_CSS_RESULT_CDCSS = 2U,
};
typedef enum BK4819_CssScanResult_t BK4819_CssScanResult_t;
extern bool gRxIdleMode;
void BK4819_Init(void);
uint16_t BK4819_ReadRegister(BK4819_REGISTER_t Register);
void BK4819_WriteRegister(BK4819_REGISTER_t Register, uint16_t Data);
void BK4819_WriteU8(uint8_t Data);
void BK4819_WriteU16(uint16_t Data);
void BK4819_SetAGC(uint8_t Value);
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord);
void BK4819_SetCTCSSFrequency(uint32_t BaudRate);
void BK4819_Set55HzTailDetection(void);
void BK4819_EnableVox(uint16_t Vox1Threshold, uint16_t Vox0Threshold);
void BK4819_SetFilterBandwidth(BK4819_FilterBandwidth_t Bandwidth);
void BK4819_SetupPowerAmplifier(uint16_t Bias, uint32_t Frequency);
void BK4819_SetFrequency(uint32_t Frequency);
void BK4819_SetupSquelch(
uint8_t SquelchOpenRSSIThresh,
uint8_t SquelchCloseRSSIThresh,
uint8_t SquelchOpenNoiseThresh,
uint8_t SquelchCloseNoiseThresh,
uint8_t SquelchCloseGlitchThresh,
uint8_t SquelchOpenGlitchThresh);
void BK4819_SetAF(BK4819_AF_Type_t AF);
void BK4819_RX_TurnOn(void);
void BK4819_PickRXFilterPathBasedOnFrequency(uint32_t Frequency);
void BK4819_DisableScramble(void);
void BK4819_EnableScramble(uint8_t Type);
void BK4819_DisableVox(void);
void BK4819_DisableDTMF(void);
void BK4819_EnableDTMF(void);
void BK4819_PlayTone(uint16_t Frequency, bool bTuningGainSwitch);
void BK4819_EnterTxMute(void);
void BK4819_ExitTxMute(void);
void BK4819_Sleep(void);
void BK4819_TurnsOffTones_TurnsOnRX(void);
#ifndef DISABLE_AIRCOPY
void BK4819_SetupAircopy(void);
#endif
void BK4819_ResetFSK(void);
void BK4819_Idle(void);
void BK4819_ExitBypass(void);
void BK4819_PrepareTransmit(void);
void BK4819_TxOn_Beep(void);
void BK4819_ExitSubAu(void);
void BK4819_Conditional_RX_TurnOn_and_GPIO6_Enable(void);
void BK4819_EnterDTMF_TX(bool bLocalLoopback);
void BK4819_ExitDTMF_TX(bool bKeep);
void BK4819_EnableTXLink(void);
void BK4819_PlayDTMF(char Code);
void BK4819_PlayDTMFString(const char *pString, bool bDelayFirst, uint16_t FirstCodePersistTime, uint16_t HashCodePersistTime, uint16_t CodePersistTime, uint16_t CodeInternalTime);
void BK4819_TransmitTone(bool bLocalLoopback, uint32_t Frequency);
void BK4819_GenTail(uint8_t Tail);
void BK4819_EnableCDCSS(void);
void BK4819_EnableCTCSS(void);
uint16_t BK4819_GetRSSI(void);
bool BK4819_GetFrequencyScanResult(uint32_t *pFrequency);
BK4819_CssScanResult_t BK4819_GetCxCSSScanResult(uint32_t *pCdcssFreq, uint16_t *pCtcssFreq);
void BK4819_DisableFrequencyScan(void);
void BK4819_EnableFrequencyScan(void);
void BK4819_SetScanFrequency(uint32_t Frequency);
void BK4819_Disable(void);
void BK4819_StopScan(void);
uint8_t BK4819_GetDTMF_5TONE_Code(void);
uint8_t BK4819_GetCDCSSCodeType(void);
uint8_t BK4819_GetCTCType(void);
void BK4819_SendFSKData(uint16_t *pData);
void BK4819_PrepareFSKReceive(void);
void BK4819_PlayRoger(void);
void BK4819_PlayRogerMDC(void);
void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
void BK4819_GetVoxAmp(uint16_t *pResult);
void BK4819_SetScrambleFrequencyControlWord(uint32_t Frequency);
void BK4819_PlayDTMFEx(bool bLocalLoopback, char Code);
#endif

50
driver/crc.c Normal file
View File

@ -0,0 +1,50 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/crc.h"
#include "driver/crc.h"
void CRC_Init(void)
{
CRC_CR = 0
| CRC_CR_CRC_EN_BITS_DISABLE
| CRC_CR_INPUT_REV_BITS_NORMAL
| CRC_CR_INPUT_INV_BITS_NORMAL
| CRC_CR_OUTPUT_REV_BITS_NORMAL
| CRC_CR_OUTPUT_INV_BITS_NORMAL
| CRC_CR_DATA_WIDTH_BITS_8
| CRC_CR_CRC_SEL_BITS_CRC_16_CCITT
;
CRC_IV = 0;
}
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size)
{
const uint8_t *pData = (const uint8_t *)pBuffer;
uint16_t i, Crc;
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_ENABLE;
for (i = 0; i < Size; i++) {
CRC_DATAIN = pData[i];
}
Crc = (uint16_t)CRC_DATAOUT;
CRC_CR = (CRC_CR & ~CRC_CR_CRC_EN_MASK) | CRC_CR_CRC_EN_BITS_DISABLE;
return Crc;
}

26
driver/crc.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_CRC_H
#define DRIVER_CRC_H
#include <stdint.h>
void CRC_Init(void);
uint16_t CRC_Calculate(const void *pBuffer, uint16_t Size);
#endif

55
driver/eeprom.c Normal file
View File

@ -0,0 +1,55 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver/eeprom.h"
#include "driver/i2c.h"
#include "driver/system.h"
void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size)
{
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_Start();
I2C_Write(0xA1);
I2C_ReadBuffer(pBuffer, Size);
I2C_Stop();
}
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer)
{
I2C_Start();
I2C_Write(0xA0);
I2C_Write((Address >> 8) & 0xFF);
I2C_Write((Address >> 0) & 0xFF);
I2C_WriteBuffer(pBuffer, 8);
I2C_Stop();
SYSTEM_DelayMs(10);
}

26
driver/eeprom.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_EEPROM_H
#define DRIVER_EEPROM_H
#include <stdint.h>
void EEPROM_ReadBuffer(uint16_t Address, void *pBuffer, uint8_t Size);
void EEPROM_WriteBuffer(uint16_t Address, const void *pBuffer);
#endif

34
driver/flash.c Normal file
View File

@ -0,0 +1,34 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver/flash.h"
#include "sram-overlay.h"
void FLASH_Init(FLASH_READ_MODE ReadMode)
{
overlay_FLASH_Init(ReadMode);
}
void FLASH_ConfigureTrimValues(void)
{
overlay_FLASH_ConfigureTrimValues();
}
uint32_t FLASH_ReadNvrWord(uint32_t Address)
{
return overlay_FLASH_ReadNvrWord(Address);
}

59
driver/flash.h Normal file
View File

@ -0,0 +1,59 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_FLASH_H
#define DRIVER_FLASH_H
#include "bsp/dp32g030/flash.h"
enum FLASH_READ_MODE {
FLASH_READ_MODE_1_CYCLE = FLASH_CFG_READ_MD_VALUE_1_CYCLE,
FLASH_READ_MODE_2_CYCLE = FLASH_CFG_READ_MD_VALUE_2_CYCLE,
};
typedef enum FLASH_READ_MODE FLASH_READ_MODE;
enum FLASH_MASK_SELECTION {
FLASH_MASK_SELECTION_NONE = FLASH_MASK_SEL_VALUE_NONE,
FLASH_MASK_SELECTION_2KB = FLASH_MASK_SEL_VALUE_2KB,
FLASH_MASK_SELECTION_4KB = FLASH_MASK_SEL_VALUE_4KB,
FLASH_MASK_SELECTION_8KB = FLASH_MASK_SEL_VALUE_8KB,
};
typedef enum FLASH_MASK_SELECTION FLASH_MASK_SELECTION;
enum FLASH_MODE {
FLASH_MODE_READ_AHB = FLASH_CFG_MODE_VALUE_READ_AHB,
FLASH_MODE_PROGRAM = FLASH_CFG_MODE_VALUE_PROGRAM,
FLASH_MODE_ERASE = FLASH_CFG_MODE_VALUE_ERASE,
FLASH_MODE_READ_APB = FLASH_CFG_MODE_VALUE_READ_APB,
};
typedef enum FLASH_MODE FLASH_MODE;
enum FLASH_AREA {
FLASH_AREA_MAIN = FLASH_CFG_NVR_SEL_VALUE_MAIN,
FLASH_AREA_NVR = FLASH_CFG_NVR_SEL_VALUE_NVR,
};
typedef enum FLASH_AREA FLASH_AREA;
void FLASH_Init(FLASH_READ_MODE ReadMode);
void FLASH_ConfigureTrimValues(void);
uint32_t FLASH_ReadNvrWord(uint32_t Address);
#endif

38
driver/gpio.c Normal file
View File

@ -0,0 +1,38 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver/gpio.h"
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg &= ~(1U << Bit);
}
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit)
{
return (*pReg >> Bit) & 1U;
}
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg ^= 1U << Bit;
}
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit)
{
*pReg |= 1U << Bit;
}

69
driver/gpio.h Normal file
View File

@ -0,0 +1,69 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_GPIO_H
#define DRIVER_GPIO_H
#include <stdint.h>
enum GPIOA_PINS {
GPIOA_PIN_KEYBOARD_0 = 3,
GPIOA_PIN_KEYBOARD_1 = 4,
GPIOA_PIN_KEYBOARD_2 = 5,
GPIOA_PIN_KEYBOARD_3 = 6,
GPIOA_PIN_KEYBOARD_4 = 10, // Shared with I2C!
GPIOA_PIN_KEYBOARD_5 = 11, // Shared with I2C!
GPIOA_PIN_KEYBOARD_6 = 12, // Shared with voice chip!
GPIOA_PIN_KEYBOARD_7 = 13, // Shared with voice chip!
GPIOA_PIN_I2C_SCL = 10, // Shared with keyboard!
GPIOA_PIN_I2C_SDA = 11, // Shared with keyboard!
GPIOA_PIN_VOICE_0 = 12, // Shared with keyboard!
GPIOA_PIN_VOICE_1 = 13, // Shared with keyboard!
};
enum GPIOB_PINS {
GPIOB_PIN_BACKLIGHT = 6,
GPIOB_PIN_ST7565_A0 = 9,
GPIOB_PIN_ST7565_RES = 11, // Shared with SWD!
GPIOB_PIN_SWD_IO = 11, // Shared with ST7565!
GPIOB_PIN_SWD_CLK = 14,
GPIOB_PIN_BK1080 = 15,
};
enum GPIOC_PINS {
GPIOC_PIN_BK4819_SCN = 0,
GPIOC_PIN_BK4819_SCL = 1,
GPIOC_PIN_BK4819_SDA = 2,
GPIOC_PIN_FLASHLIGHT = 3,
GPIOC_PIN_AUDIO_PATH = 4,
GPIOC_PIN_PTT = 5,
};
void GPIO_ClearBit(volatile uint32_t *pReg, uint8_t Bit);
uint8_t GPIO_CheckBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_FlipBit(volatile uint32_t *pReg, uint8_t Bit);
void GPIO_SetBit(volatile uint32_t *pReg, uint8_t Bit);
#endif

169
driver/i2c.c Normal file
View File

@ -0,0 +1,169 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/portcon.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "driver/systick.h"
void I2C_Start(void)
{
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
}
void I2C_Stop(void)
{
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
SYSTICK_DelayUs(1);
}
uint8_t I2C_Read(bool bFinal)
{
uint8_t i, Data;
PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE;
PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK;
GPIOA->DIR &= ~GPIO_DIR_11_MASK;
Data = 0;
for (i = 0; i < 8; i++) {
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
Data <<= 1;
SYSTICK_DelayUs(1);
if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA)) {
Data |= 1U;
}
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
}
PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK;
PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE;
GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT;
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
if (bFinal) {
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
} else {
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
}
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
return Data;
}
int I2C_Write(uint8_t Data)
{
uint8_t i;
int ret = -1;
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
for (i = 0; i < 8; i++) {
if ((Data & 0x80) == 0) {
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
} else {
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
}
Data <<= 1;
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
}
PORTCON_PORTA_IE |= PORTCON_PORTA_IE_A11_BITS_ENABLE;
PORTCON_PORTA_OD &= ~PORTCON_PORTA_OD_A11_MASK;
GPIOA->DIR &= ~GPIO_DIR_11_MASK;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
for (i = 0; i < 255; i++) {
if (GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA) == 0) {
ret = 0;
break;
}
}
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_I2C_SCL);
SYSTICK_DelayUs(1);
PORTCON_PORTA_IE &= ~PORTCON_PORTA_IE_A11_MASK;
PORTCON_PORTA_OD |= PORTCON_PORTA_OD_A11_BITS_ENABLE;
GPIOA->DIR |= GPIO_DIR_11_BITS_OUTPUT;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_I2C_SDA);
return ret;
}
int I2C_ReadBuffer(void *pBuffer, uint8_t Size)
{
uint8_t *pData = (uint8_t *)pBuffer;
uint8_t i;
if (Size == 1) {
*pData = I2C_Read(true);
return 1;
}
for (i = 0; i < Size - 1; i++) {
SYSTICK_DelayUs(1);
pData[i] = I2C_Read(false);
}
SYSTICK_DelayUs(1);
pData[i++] = I2C_Read(true);
return Size;
}
int I2C_WriteBuffer(const void *pBuffer, uint8_t Size)
{
const uint8_t *pData = (const uint8_t *)pBuffer;
uint8_t i;
for (i = 0; i < Size; i++) {
if (I2C_Write(*pData++) < 0) {
return -1;
}
}
return 0;
}

38
driver/i2c.h Normal file
View File

@ -0,0 +1,38 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_I2C_H
#define DRIVER_I2C_H
#include <stdbool.h>
#include <stdint.h>
enum {
I2C_WRITE = 0U,
I2C_READ = 1U,
};
void I2C_Start(void);
void I2C_Stop(void);
uint8_t I2C_Read(bool bFinal);
int I2C_Write(uint8_t Data);
int I2C_ReadBuffer(void *pBuffer, uint8_t Size);
int I2C_WriteBuffer(const void *pBuffer, uint8_t Size);
#endif

157
driver/keyboard.c Normal file
View File

@ -0,0 +1,157 @@
/* Copyright 2023 Manuel Jinger
* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/gpio.h"
#include "driver/gpio.h"
#include "driver/keyboard.h"
#include "driver/systick.h"
KEY_Code_t gKeyReading0 = KEY_INVALID;
KEY_Code_t gKeyReading1 = KEY_INVALID;
uint16_t gDebounceCounter;
bool gWasFKeyPressed;
KEY_Code_t KEYBOARD_Poll(void)
{
KEY_Code_t Key = KEY_INVALID;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
SYSTICK_DelayUs(1);
// Keys connected to gnd
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) {
Key = KEY_SIDE1;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) {
Key = KEY_SIDE2;
goto Bye;
}
// Original doesn't do PTT
// First row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) {
Key = KEY_MENU;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) {
Key = KEY_1;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) {
Key = KEY_4;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) {
Key = KEY_7;
goto Bye;
}
// Second row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) {
Key = KEY_UP;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) {
Key = KEY_2;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) {
Key = KEY_5;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) {
Key = KEY_8;
goto Bye;
}
// Third row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
SYSTICK_DelayUs(1);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) {
Key = KEY_DOWN;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) {
Key = KEY_3;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) {
Key = KEY_6;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) {
Key = KEY_9;
goto Bye;
}
// Fourth row
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
SYSTICK_DelayUs(1);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
SYSTICK_DelayUs(1);
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_0)) {
Key = KEY_EXIT;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_1)) {
Key = KEY_STAR;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_2)) {
Key = KEY_0;
goto Bye;
}
if (!GPIO_CheckBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_3)) {
Key = KEY_F;
goto Bye;
}
Bye:
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_4);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_5);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_6);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_KEYBOARD_7);
return Key;
}

57
driver/keyboard.h Normal file
View File

@ -0,0 +1,57 @@
/* Copyright 2023 Manuel Jinger
* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_KEYBOARD_H
#define DRIVER_KEYBOARD_H
#include <stdbool.h>
#include <stdint.h>
enum KEY_Code_t {
KEY_0 = 0,
KEY_1 = 1,
KEY_2 = 2,
KEY_3 = 3,
KEY_4 = 4,
KEY_5 = 5,
KEY_6 = 6,
KEY_7 = 7,
KEY_8 = 8,
KEY_9 = 9,
KEY_MENU = 10,
KEY_UP = 11,
KEY_DOWN = 12,
KEY_EXIT = 13,
KEY_STAR = 14,
KEY_F = 15,
KEY_PTT = 21,
KEY_SIDE2 = 22,
KEY_SIDE1 = 23,
KEY_INVALID = 255,
};
typedef enum KEY_Code_t KEY_Code_t;
extern KEY_Code_t gKeyReading0;
extern KEY_Code_t gKeyReading1;
extern uint16_t gDebounceCounter;
extern bool gWasFKeyPressed;
KEY_Code_t KEYBOARD_Poll(void);
#endif

116
driver/spi.c Normal file
View File

@ -0,0 +1,116 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ARMCM0.h"
#include "bsp/dp32g030/spi.h"
#include "bsp/dp32g030/syscon.h"
#include "bsp/dp32g030/irq.h"
#include "driver/spi.h"
void SPI0_Init(void)
{
SPI_Config_t Config;
SPI_Disable(&SPI0->CR);
Config.TXFIFO_EMPTY = 0;
Config.RXFIFO_HFULL = 0;
Config.RXFIFO_FULL = 0;
Config.RXFIFO_OVF = 0;
Config.MSTR = 1;
Config.SPR = 2;
Config.CPHA = 1;
Config.CPOL = 1;
Config.LSB = 0;
Config.TF_CLR = 0;
Config.RF_CLR = 0;
Config.TXFIFO_HFULL = 0;
SPI_Configure(SPI0, &Config);
SPI_Enable(&SPI0->CR);
}
void SPI_WaitForUndocumentedTxFifoStatusBit(void)
{
uint32_t Timeout;
Timeout = 0;
do {
// Undocumented bit!
if ((SPI0->IF & 0x20) == 0) {
break;
}
Timeout++;
} while (Timeout <= 100000);
}
void SPI_Disable(volatile uint32_t *pCR)
{
*pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_DISABLE;
}
void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig)
{
if (pPort == SPI0) {
SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI0_MASK) | SYSCON_DEV_CLK_GATE_SPI0_BITS_ENABLE;
} else if (pPort == SPI1) {
SYSCON_DEV_CLK_GATE = (SYSCON_DEV_CLK_GATE & ~SYSCON_DEV_CLK_GATE_SPI1_MASK) | SYSCON_DEV_CLK_GATE_SPI1_BITS_ENABLE;
}
SPI_Disable(&pPort->CR);
pPort->CR = 0
| (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))
| ((pConfig->SPR << SPI_CR_SPR_SHIFT) & SPI_CR_SPR_MASK)
| ((pConfig->CPHA << SPI_CR_CPHA_SHIFT) & SPI_CR_CPHA_MASK)
| ((pConfig->CPOL << SPI_CR_CPOL_SHIFT) & SPI_CR_CPOL_MASK)
| ((pConfig->MSTR << SPI_CR_MSTR_SHIFT) & SPI_CR_MSTR_MASK)
| ((pConfig->LSB << SPI_CR_LSB_SHIFT) & SPI_CR_LSB_MASK)
| ((pConfig->RF_CLR << SPI_CR_RF_CLR_SHIFT) & SPI_CR_RF_CLR_MASK)
| ((pConfig->TF_CLR << SPI_CR_TF_CLR_SHIFT) & SPI_CR_TF_CLR_MASK)
;
pPort->IE = 0
| ((pConfig->RXFIFO_OVF << SPI_IE_RXFIFO_OVF_SHIFT) & SPI_IE_RXFIFO_OVF_MASK)
| ((pConfig->RXFIFO_FULL << SPI_IE_RXFIFO_FULL_SHIFT) & SPI_IE_RXFIFO_FULL_MASK)
| ((pConfig->RXFIFO_HFULL << SPI_IE_RXFIFO_HFULL_SHIFT) & SPI_IE_RXFIFO_HFULL_MASK)
| ((pConfig->TXFIFO_EMPTY << SPI_IE_TXFIFO_EMPTY_SHIFT) & SPI_IE_TXFIFO_EMPTY_MASK)
| ((pConfig->TXFIFO_HFULL << SPI_IE_TXFIFO_HFULL_SHIFT) & SPI_IE_TXFIFO_HFULL_MASK)
;
if (pPort->IE) {
if (pPort == SPI0) {
NVIC_EnableIRQ(DP32_SPI0_IRQn);
} else if (pPort == SPI1) {
NVIC_EnableIRQ(DP32_SPI1_IRQn);
}
}
}
void SPI_ToggleMasterMode(volatile uint32_t *pCR, bool bIsMaster)
{
if (bIsMaster) {
*pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_ENABLE;
} else {
*pCR = (*pCR & ~SPI_CR_MSR_SSN_MASK) | SPI_CR_MSR_SSN_BITS_DISABLE;
}
}
void SPI_Enable(volatile uint32_t *pCR)
{
*pCR = (*pCR & ~SPI_CR_SPE_MASK) | SPI_CR_SPE_BITS_ENABLE;
}

47
driver/spi.h Normal file
View File

@ -0,0 +1,47 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_SPI_H
#define DRIVER_SPI_H
#include <stdbool.h>
#include <stdint.h>
typedef struct {
uint8_t MSTR;
uint8_t SPR;
uint8_t CPHA;
uint8_t CPOL;
uint8_t LSB;
uint8_t TF_CLR;
uint8_t RF_CLR;
uint8_t TXFIFO_HFULL;
uint8_t TXFIFO_EMPTY;
uint8_t RXFIFO_HFULL;
uint8_t RXFIFO_FULL;
uint8_t RXFIFO_OVF;
} SPI_Config_t;
void SPI0_Init(void);
void SPI_WaitForUndocumentedTxFifoStatusBit(void);
void SPI_Disable(volatile uint32_t *pCR);
void SPI_Configure(volatile SPI_Port_t *pPort, SPI_Config_t *pConfig);
void SPI_ToggleMasterMode(volatile uint32_t *pCr, bool bIsMaster);
void SPI_Enable(volatile uint32_t *pCR);
#endif

176
driver/st7565.c Normal file
View File

@ -0,0 +1,176 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include "bsp/dp32g030/gpio.h"
#include "bsp/dp32g030/spi.h"
#include "driver/gpio.h"
#include "driver/spi.h"
#include "driver/st7565.h"
#include "driver/system.h"
uint8_t gStatusLine[128];
uint8_t gFrameBuffer[7][128];
void ST7565_DrawLine(uint8_t Column, uint8_t Line, uint16_t Size, const uint8_t *pBitmap, bool bIsClearMode)
{
uint16_t i;
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_SelectColumnAndLine(Column + 4U, Line);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
if (!bIsClearMode) {
for (i = 0; i < Size; i++) {
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = pBitmap[i];
}
} else {
for (i = 0; i < Size; i++) {
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = 0;
}
}
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitFullScreen(void)
{
uint8_t Line;
uint8_t Column;
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0x40);
for (Line = 0; Line < 7; Line++) {
ST7565_SelectColumnAndLine(4U, Line + 1U);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (Column = 0; Column < 128; Column++) {
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = gFrameBuffer[Line][Column];
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
SYSTEM_DelayMs(20);
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_BlitStatusLine(void)
{
uint8_t i;
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0x40);
ST7565_SelectColumnAndLine(4, 0);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (i = 0; i < 0x80; i++) {
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = gStatusLine[i];
}
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_FillScreen(uint8_t Value)
{
uint8_t i, j;
SPI_ToggleMasterMode(&SPI0->CR, false);
for (i = 0; i < 8; i++) {
ST7565_SelectColumnAndLine(0, i);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
for (j = 0; j < 132; j++) {
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = Value;
}
SPI_WaitForUndocumentedTxFifoStatusBit();
}
SPI_ToggleMasterMode(&SPI0->CR, true);
}
void ST7565_Init(void)
{
SPI0_Init();
ST7565_Configure_GPIO_B11();
SPI_ToggleMasterMode(&SPI0->CR, false);
ST7565_WriteByte(0xE2);
SYSTEM_DelayMs(0x78);
ST7565_WriteByte(0xA2);
ST7565_WriteByte(0xC0);
ST7565_WriteByte(0xA1);
ST7565_WriteByte(0xA6);
ST7565_WriteByte(0xA4);
ST7565_WriteByte(0x24);
ST7565_WriteByte(0x81);
ST7565_WriteByte(0x1F);
ST7565_WriteByte(0x2B);
SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2E);
SYSTEM_DelayMs(1);
ST7565_WriteByte(0x2F);
ST7565_WriteByte(0x2F);
ST7565_WriteByte(0x2F);
ST7565_WriteByte(0x2F);
SYSTEM_DelayMs(0x28);
ST7565_WriteByte(0x40);
ST7565_WriteByte(0xAF);
SPI_WaitForUndocumentedTxFifoStatusBit();
SPI_ToggleMasterMode(&SPI0->CR, true);
ST7565_FillScreen(0x00);
}
void ST7565_Configure_GPIO_B11(void)
{
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(1);
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(20);
GPIO_SetBit(&GPIOB->DATA, GPIOB_PIN_ST7565_RES);
SYSTEM_DelayMs(120);
}
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line)
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = Line + 0xB0;
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = ((Column >> 4) & 0x0F) | 0x10;
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = ((Column >> 0) & 0x0F);
SPI_WaitForUndocumentedTxFifoStatusBit();
}
void ST7565_WriteByte(uint8_t Value)
{
GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_ST7565_A0);
while ((SPI0->FIFOST & SPI_FIFOST_TFF_MASK) != SPI_FIFOST_TFF_BITS_NOT_FULL) {
}
SPI0->WDR = Value;
}

36
driver/st7565.h Normal file
View File

@ -0,0 +1,36 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_ST7565_H
#define DRIVER_ST7565_H
#include <stdbool.h>
#include <stdint.h>
extern uint8_t gStatusLine[128];
extern uint8_t gFrameBuffer[7][128];
void ST7565_DrawLine(uint8_t Column, uint8_t Line, uint16_t Size, const uint8_t *pBitmap, bool bIsClearMode);
void ST7565_BlitFullScreen(void);
void ST7565_BlitStatusLine(void);
void ST7565_FillScreen(uint8_t Value);
void ST7565_Init(void);
void ST7565_Configure_GPIO_B11(void);
void ST7565_SelectColumnAndLine(uint8_t Column, uint8_t Line);
void ST7565_WriteByte(uint8_t Value);
#endif

40
driver/system.c Normal file
View File

@ -0,0 +1,40 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bsp/dp32g030/pmu.h"
#include "bsp/dp32g030/syscon.h"
#include "driver/system.h"
#include "driver/systick.h"
void SYSTEM_DelayMs(uint32_t Delay)
{
SYSTICK_DelayUs(Delay * 1000);
}
void SYSTEM_ConfigureClocks(void)
{
// Set source clock from external crystal
PMU_SRC_CFG = (PMU_SRC_CFG & ~(PMU_SRC_CFG_RCHF_SEL_MASK | PMU_SRC_CFG_RCHF_EN_MASK))
| PMU_SRC_CFG_RCHF_SEL_BITS_48MHZ
| PMU_SRC_CFG_RCHF_EN_BITS_ENABLE;
// Divide by 2
SYSCON_CLK_SEL = SYSCON_CLK_SEL_DIV_BITS_2;
// Disable division clock gate
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;
}

26
driver/system.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_SYSTEM_H
#define DRIVER_SYSTEM_H
#include <stdint.h>
void SYSTEM_DelayMs(uint32_t Delay);
void SYSTEM_ConfigureClocks(void);
#endif

54
driver/systick.c Normal file
View File

@ -0,0 +1,54 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ARMCM0.h"
#include "driver/systick.h"
#include "misc.h"
// 0x20000324
static uint32_t gTickMultiplier;
void SYSTICK_Init(void)
{
SysTick_Config(480000);
gTickMultiplier = 48;
}
void SYSTICK_DelayUs(uint32_t Delay)
{
uint32_t i;
uint32_t Start;
uint32_t Previous;
uint32_t Current;
uint32_t Delta;
i = 0;
Start = SysTick->LOAD;
Previous = SysTick->VAL;
do {
do {
Current = SysTick->VAL;
} while (Current == Previous);
if (Current < Previous) {
Delta = -Current;
} else {
Delta = Start - Current;
}
i += Delta + Previous;
Previous = Current;
} while (i < Delay * gTickMultiplier);
}

26
driver/systick.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRIVER_SYSTICK_H
#define DRIVER_SYSTICK_H
#include <stdint.h>
void SYSTICK_Init(void);
void SYSTICK_DelayUs(uint32_t Delay);
#endif

104
driver/uart.c Normal file
View File

@ -0,0 +1,104 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdbool.h>
#include "bsp/dp32g030/dma.h"
#include "bsp/dp32g030/syscon.h"
#include "bsp/dp32g030/uart.h"
#include "driver/uart.h"
static bool UART_IsLogEnabled;
uint8_t UART_DMA_Buffer[256];
void UART_Init(void)
{
uint32_t Delta;
uint32_t Positive;
uint32_t Frequency;
UART1->CTRL = (UART1->CTRL & ~UART_CTRL_UARTEN_MASK) | UART_CTRL_UARTEN_BITS_DISABLE;
Delta = SYSCON_RC_FREQ_DELTA;
Positive = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_SIG_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_SIG_SHIFT;
Frequency = (Delta & SYSCON_RC_FREQ_DELTA_RCHF_DELTA_MASK) >> SYSCON_RC_FREQ_DELTA_RCHF_DELTA_SHIFT;
if (Positive) {
Frequency += 48000000U;
} else {
Frequency = 48000000U - Frequency;
}
UART1->BAUD = Frequency / 39053U;
UART1->CTRL = UART_CTRL_RXEN_BITS_ENABLE | UART_CTRL_TXEN_BITS_ENABLE | UART_CTRL_RXDMAEN_BITS_ENABLE;
UART1->RXTO = 4;
UART1->FC = 0;
UART1->FIFO = UART_FIFO_RF_LEVEL_BITS_8_BYTE | UART_FIFO_RF_CLR_BITS_ENABLE | UART_FIFO_TF_CLR_BITS_ENABLE;
UART1->IE = 0;
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_DISABLE;
DMA_CH0->MSADDR = (uint32_t)(uintptr_t)&UART1->RDR;
DMA_CH0->MDADDR = (uint32_t)(uintptr_t)UART_DMA_Buffer;
DMA_CH0->MOD = 0
// Source
| DMA_CH_MOD_MS_ADDMOD_BITS_NONE
| DMA_CH_MOD_MS_SIZE_BITS_8BIT
| DMA_CH_MOD_MS_SEL_BITS_HSREQ_MS1
// Destination
| DMA_CH_MOD_MD_ADDMOD_BITS_INCREMENT
| DMA_CH_MOD_MD_SIZE_BITS_8BIT
| DMA_CH_MOD_MD_SEL_BITS_SRAM
;
DMA_INTEN = 0;
DMA_INTST = 0
| DMA_INTST_CH0_TC_INTST_BITS_SET
| DMA_INTST_CH1_TC_INTST_BITS_SET
| DMA_INTST_CH2_TC_INTST_BITS_SET
| DMA_INTST_CH3_TC_INTST_BITS_SET
| DMA_INTST_CH0_THC_INTST_BITS_SET
| DMA_INTST_CH1_THC_INTST_BITS_SET
| DMA_INTST_CH2_THC_INTST_BITS_SET
| DMA_INTST_CH3_THC_INTST_BITS_SET
;
DMA_CH0->CTR = 0
| DMA_CH_CTR_CH_EN_BITS_ENABLE
| ((0xFF << DMA_CH_CTR_LENGTH_SHIFT) & DMA_CH_CTR_LENGTH_MASK)
| DMA_CH_CTR_LOOP_BITS_ENABLE
| DMA_CH_CTR_PRI_BITS_MEDIUM
;
UART1->IF = UART_IF_RXTO_BITS_SET;
DMA_CTR = (DMA_CTR & ~DMA_CTR_DMAEN_MASK) | DMA_CTR_DMAEN_BITS_ENABLE;
UART1->CTRL |= UART_CTRL_UARTEN_BITS_ENABLE;
}
void UART_Send(const void *pBuffer, uint32_t Size)
{
const uint8_t *pData = (const uint8_t *)pBuffer;
uint32_t i;
for (i = 0; i < Size; i++) {
UART1->TDR = pData[i];
while ((UART1->IF & UART_IF_TXFIFO_FULL_MASK) != UART_IF_TXFIFO_FULL_BITS_NOT_SET) {
}
}
}
void UART_LogSend(const void *pBuffer, uint32_t Size)
{
if (UART_IsLogEnabled) {
UART_Send(pBuffer, Size);
}
}

30
driver/uart.h Normal file
View File

@ -0,0 +1,30 @@
/* Copyright 2023 Dual Tachyon
* https://github.com/DualTachyon
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef DRIVER_UART_H
#define DRIVER_UART_H
#include <stdint.h>
extern uint8_t UART_DMA_Buffer[256];
void UART_Init(void);
void UART_Send(const void *pBuffer, uint32_t Size);
void UART_LogSend(const void *pBuffer, uint32_t Size);
#endif

20
external/CMSIS_5/.gitattributes vendored Normal file
View File

@ -0,0 +1,20 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text
*.txt text
*.xsd text
*.pdsc text
*.svd text
*.bat text
# Declare files that will always have CRLF line endings on checkout.
*.uvproj text eol=crlf
*.uvproj text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
# Script files
*.py text eol=lf
*.sh text eol=lf

View File

@ -0,0 +1,16 @@
{
"problemMatcher": [
{
"owner": "fileheader",
"severity": "error",
"pattern": [
{
"regexp": "^(.*):(\\d+):(.*)$",
"file": 1,
"line": 2,
"message": 3
}
]
}
]
}

View File

@ -0,0 +1,16 @@
{
"problemMatcher": [
{
"owner": "fileheader",
"severity": "error",
"pattern": [
{
"regexp": "^(.*):(\\d+);(.*);(.*)$",
"file": 1,
"line": 2,
"message": 4
}
]
}
]
}

View File

@ -0,0 +1,27 @@
name: Caller CoreValidation
on:
push:
branches: [ main ]
pull_request:
paths:
- .github/workflows/caller-corevalidation.yml
- CMSIS/Core/**/*
- CMSIS/Core_A/**/*
- CMSIS/CoreValidation/**/*
- Device/ARM/**/*
workflow_dispatch:
jobs:
upload_pr_number:
runs-on: ubuntu-latest
steps:
- name: Save PR number
env:
PR_NUMBER: ${{ github.event.number }}
run: |
mkdir -p ./pr
echo -n $PR_NUMBER > ./pr/pr_number
- uses: actions/upload-artifact@v3
with:
name: pr_number
path: pr/

View File

@ -0,0 +1,92 @@
name: "CodeQL"
on:
workflow_dispatch:
push:
branches: [ develop ]
paths:
- 'CMSIS/Core/**'
- 'CMSIS/Core_A/**'
- 'CMSIS/CoreValidation/**'
- 'Device/ARM/**'
pull_request:
branches: [ develop ]
paths:
- '.github/workflows/codeql-analysis.yml'
- 'CMSIS/Core/**'
- 'CMSIS/Core_A/**'
- 'CMSIS/CoreValidation/**'
- 'Device/ARM/**'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
env:
CMSIS_PACK_ROOT: /tmp/.packs-${{ github.run_id }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install build dependencies
run: |
sudo apt install gcc-arm-none-eabi ninja-build cmake
- name: Cache pack folder
id: cache-packs
uses: actions/cache@v3
with:
key: packs-${{ github.run_id }}
restore-keys: |
packs-
path: /tmp/.packs-${{ github.run_id }}
- name: Install CMSIS-Toolbox
run: |
wget https://github.com/Open-CMSIS-Pack/cmsis-toolbox/releases/download/1.5.0/cmsis-toolbox.sh
chmod +x cmsis-toolbox.sh
sudo ./cmsis-toolbox.sh <<EOI
/opt/ctools
$CMSIS_PACK_ROOT
$(dirname $(which arm-none-eabi-gcc 2>/dev/null))
EOI
echo "/opt/ctools/bin" >> $GITHUB_PATH
echo "cpackget : $(which cpackget)"
echo "csolution: $(which csolution)"
echo "cbuild : $(which cbuild)"
- name: Initialize packs folder
if: steps.cache-packs.outputs.cache-hit != 'true'
run: cpackget init https://www.keil.com/pack/index.pidx
- name: Update pack index
if: steps.cache-packs.outputs.cache-hit == 'true'
run: cpackget update-index
- name: Install build.py requirements
run: pip install -r requirements.txt
working-directory: CMSIS/CoreValidation/Project
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: cpp
queries: security-and-quality
- name: Build projects
working-directory: CMSIS/CoreValidation/Project
run: |
pip install -r requirements.txt
cpackget add -a -f cpacklist.txt
python build.py --verbose -c GCC -d "CM[047]*" -d "CM[23]3*" -o low build || echo "Something failed!"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@ -0,0 +1,44 @@
name: Publish CoreValidation Test Results
on:
workflow_run:
workflows: ["CoreValidation"]
branches-ignore: ["develop"]
types:
- completed
jobs:
publish-test-results:
name: Publish CoreValidation Test Results
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
checks: write
pull-requests: write
if: github.event.workflow_run.conclusion != 'skipped'
steps:
- name: Download test results
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
mkdir -p artifacts && cd artifacts
artifacts_url=${{ github.event.workflow_run.artifacts_url }}
gh api "$artifacts_url" -q '.artifacts[] | select(.name=="tests" or .name=="EventFile") | [.name, .archive_download_url] | @tsv' | \
while read artifact; do
IFS=$'\t' read name url <<< "$artifact"
gh api $url > "$name.zip"
unzip -d "$name" "$name.zip"
done
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
with:
commit: ${{ github.event.workflow_run.head_sha }}
event_file: artifacts/EventFile/event.json
report_individual_runs: true
event_name: ${{ github.event.workflow_run.event }}
junit_files: "artifacts/**/*.junit"

View File

@ -0,0 +1,161 @@
# This workflow is triggered whenever "Caller CoreValidation" workflow is completed (which is called by PR).
# This workflow ideally should be triggered also by PR, but forked PR has limited permissions which does not
# allow to use `configure-aws-credentials` actions and using secrets.
# It will update its status back to the caller PR as "CoreValidation" check name
name: CoreValidation
on:
workflow_run:
workflows:
- Caller CoreValidation
types:
- completed
# The env variables relate to an ARM AWS account for CMSIS_5
# If you are forking CMSIS_5 repo, please use your own info.
env:
AWS_ASSUME_ROLE: ${{ secrets.AWS_ASSUME_ROLE }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
AWS_IAM_PROFILE: ${{ secrets.AWS_IAM_PROFILE }}
AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }}
AWS_SECURITY_GROUP_ID: ${{ secrets.AWS_SECURITY_GROUP_ID }}
AWS_SUBNET_ID: ${{ secrets.AWS_SUBNET_ID }}
jobs:
set_pending_status_to_pr:
runs-on: ubuntu-latest
steps:
- name: Set a pending status to the PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.event.workflow_run.head_commit.id }} \
--header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
--header 'content-type: application/json' \
--data '{
"state": "pending",
"context": "CoreValidation",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}' \
--fail
ci_test:
runs-on: ubuntu-latest
needs: set_pending_status_to_pr
permissions:
id-token: write
contents: read
outputs:
avhresult: ${{ steps.avh.conclusion }}
testbadge: ${{ steps.avh.outputs.badge }}
steps:
- name: Download workflow artifact
uses: dawidd6/action-download-artifact@v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: caller-corevalidation.yml
run_id: ${{ github.event.workflow_run.id }}
- name: Read the pr_num file
id: pr_num_reader
uses: juliangruber/read-file-action@v1.1.6
with:
path: ./pr_number/pr_number
trim: true
- name: Clone this repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Checkout PR
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
gh pr checkout ${{ steps.pr_num_reader.outputs.content }}
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install AVH Client for Python
run: |
pip install git+https://github.com/ARM-software/avhclient.git@v0.1
- uses: ammaraskar/gcc-problem-matcher@master
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
role-to-assume: ${{ env.AWS_ASSUME_ROLE }}
aws-region: ${{ env.AWS_DEFAULT_REGION }}
- name: Run tests
id: avh
run: |
avhclient -b aws execute --specfile CMSIS/CoreValidation/Project/avh.yml
- name: Archive build results
uses: actions/upload-artifact@v3
with:
name: builds
path: CMSIS/CoreValidation/Project/Core_Validation-*.zip
retention-days: 1
if-no-files-found: error
if: always()
- name: Archive test results
uses: actions/upload-artifact@v3
with:
name: tests
path: CMSIS/CoreValidation/Project/Core_Validation-*.junit
retention-days: 1
if-no-files-found: error
if: always()
- name: Archive event file
uses: actions/upload-artifact@v3
with:
name: EventFile
path: ${{ github.event_path }}
set_success_status_to_pr:
runs-on: ubuntu-latest
needs: ci_test
if: ${{ success() }}
steps:
- name: Set success status to the PR
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.event.workflow_run.head_commit.id }} \
--header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
--header 'content-type: application/json' \
--data '{
"state": "success",
"context": "CoreValidation",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}' \
--fail
set_failure_status_to_pr:
runs-on: ubuntu-latest
needs: ci_test
if: ${{ failure() }}
steps:
- name: Set failure status to the PR
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.event.workflow_run.head_commit.id }} \
--header "authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
--header 'content-type: application/json' \
--data '{
"state": "failure",
"context": "CoreValidation",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}' \
--fail

View File

@ -0,0 +1,42 @@
name: File header
on:
pull_request:
branches: [ develop ]
paths:
- 'CMSIS/Core/**'
- 'CMSIS/Core_A/**'
- 'CMSIS/RTOS2/Include/**'
- 'CMSIS/RTOS2/Source/**'
- 'Device/**'
permissions:
contents: read
pull-requests: write
jobs:
check:
name: Check file header
runs-on: ubuntu-latest
steps:
- name: Calculate depth
id: depth
run: |
echo ::set-output name=GIT_COMMITS::$((${{ github.event.pull_request.commits }} + 1))
- name: Checkout repository
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: ${{ steps.depth.outputs.GIT_COMMITS }}
- id: files
uses: jitterbit/get-changed-files@v1
- name: Check changed files
run: |
echo "GIT_COMMITS=${{ steps.depth.outputs.GIT_COMMITS }}"
echo "::add-matcher::.github/fileheader.json"
RC=0
for changed_file in ${{ steps.files.outputs.added_modified }}; do
./CMSIS/Utilities/check_header.sh -v -b HEAD~${{ github.event.pull_request.commits }} ${changed_file} || RC=1
done
echo "::remove-matcher owner=fileheader::"
exit $RC

View File

@ -0,0 +1,65 @@
name: Publish Documentation
on:
workflow_dispatch:
pull_request:
branches: [ develop ]
paths:
- '.github/workflows/gh-pages.yaml'
- 'CMSIS/Utilities/check_links.sh'
- 'CMSIS/DoxyGen/**'
push:
branches: [ develop ]
paths:
- '.github/workflows/gh-pages.yaml'
- 'CMSIS/Utilities/check_links.sh'
- 'CMSIS/DoxyGen/**'
jobs:
docs:
name: Build develop documentation
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- name: Install Doxygen 1.8.6
run: |
wget http://archive.ubuntu.com/ubuntu/pool/main/d/doxygen/doxygen_1.8.6-2_amd64.deb
sudo dpkg -i doxygen_1.8.6-2_amd64.deb
- name: Install mscgen 0.20
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y mscgen=0.20-12
- name: Install linkchecker
run: |
sudo pip install LinkChecker
- name: Generate doxygen
run: CMSIS/DoxyGen/gen_doc.sh
- name: Run linkchecker
run: |
echo "::add-matcher::.github/linkchecker.json"
CMSIS/Utilities/check_links.sh CMSIS/Documentation/index.html
- name: Upload documentation
if: ${{ github.event_name == 'pull_request' }}
uses: actions/upload-artifact@v2
with:
path: CMSIS/Documentation/**
- name: Archive documentation
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
run: |
cd CMSIS/Documentation
tar -cvjf /tmp/doc.tbz2 .
- uses: actions/checkout@v2
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
with:
ref: gh-pages
- name: Publish documentation
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }}
run: |
rm -r develop
mkdir develop
cd develop
tar -xvjf /tmp/doc.tbz2
git config user.name github-actions
git config user.email github-actions@github.com
git add .
git commit -m "Update develop documentation"
git push

View File

@ -0,0 +1,31 @@
name: Pack Description
on:
pull_request:
branches: [ develop ]
paths:
- 'ARM.CMSIS.pdsc'
permissions:
contents: read
pull-requests: write
jobs:
check:
name: Check pack description schema
runs-on: ubuntu-latest
steps:
- name: Install xmllint
run: |
sudo apt-get update
sudo apt-get install libxml2-utils
- name: Checkout repository
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Run xmllint
run: |
curl https://raw.githubusercontent.com/Open-CMSIS-Pack/Open-CMSIS-Pack-Spec/main/schema/PACK.xsd -o CMSIS/Utilities/PACK.xsd
echo "::add-matcher::.github/xmllint.json"
xmllint --noout --schema "$(realpath -m ./CMSIS/Utilities/PACK.xsd)" "ARM.CMSIS.pdsc"
echo "::remove-matcher owner=xmllint::"

View File

@ -0,0 +1,41 @@
name: Release Documentation
on:
release:
types: [published]
jobs:
docs:
name: Build release documentation
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- name: Install Doxygen 1.8.6
run: |
wget http://archive.ubuntu.com/ubuntu/pool/main/d/doxygen/doxygen_1.8.6-2_amd64.deb
sudo dpkg -i doxygen_1.8.6-2_amd64.deb
- name: Install mscgen 0.20
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y mscgen=0.20-12
- name: Generate doxygen
run: CMSIS/DoxyGen/gen_doc.sh
- name: Archive documentation
run: |
cd CMSIS/Documentation
tar -cvjf /tmp/doc.tbz2 .
- uses: actions/checkout@v2
with:
ref: gh-pages
- name: Publish documentation
run: |
RELEASE=$(echo $GITHUB_REF | sed 's/refs\/tags\///')
mkdir ${RELEASE}
rm latest
ln -s ${RELEASE} latest
cd ${RELEASE}
tar -xvjf /tmp/doc.tbz2
git config user.name github-actions
git config user.email github-actions@github.com
git add . ../latest
git commit -m "Update documentation for release ${RELEASE}"
git push

16
external/CMSIS_5/.github/xmllint.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"problemMatcher": [
{
"owner": "xmllint",
"severity": "error",
"pattern": [
{
"regexp": "^(.*):(\\d+):(.*)$",
"file": 1,
"line": 2,
"message": 3
}
]
}
]
}

24
external/CMSIS_5/.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
*.breadcrumb
*.junit
**/__pycache__
Local_Release/
CMSIS/Documentation/
CMSIS/RTOS2/RTX/Library/ARM/MDK/RTX_CM.uvguix.*
CMSIS/CoreValidation/Project/*.zip
CMSIS/CoreValidation/Project/*.junit
CMSIS/CoreValidation/Project/Validation.*/
CMSIS/CoreValidation/Project/Bootloader.*/
*.uvguix.*
*.uvmpw.uvgui.*
*.zip
docker/dependenciesFiles
CMSIS/RTOS/RTX/LIB/**/*.a
CMSIS/RTOS/RTX/LIB/**/*.lib
CMSIS/RTOS2/RTX/Library/**/*.a
CMSIS/RTOS2/RTX/Library/**/*.lib
output
.DS_Store
internal.cp310-win_amd64.pyd
CMSIS/Utilities/Darwin64
CMSIS/Utilities/Linux64
CMSIS/Utilities/Win32

2964
external/CMSIS_5/ARM.CMSIS.pdsc vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,441 @@
/******************************************************************************
* @file cachel1_armv7.h
* @brief CMSIS Level 1 Cache API for Armv7-M and later
* @version V1.0.3
* @date 17. March 2023
******************************************************************************/
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_CACHEL1_ARMV7_H
#define ARM_CACHEL1_ARMV7_H
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_CacheFunctions Cache Functions
\brief Functions that configure Instruction and Data cache.
@{
*/
/* Cache Size ID Register Macros */
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
#ifndef __SCB_DCACHE_LINE_SIZE
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
#ifndef __SCB_ICACHE_LINE_SIZE
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
#endif
/**
\brief Enable I-Cache
\details Turns on I-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */
__DSB();
__ISB();
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable I-Cache
\details Turns off I-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate I-Cache
\details Invalidates I-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache (void)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
__DSB();
__ISB();
SCB->ICIALLU = 0UL;
__DSB();
__ISB();
#endif
}
/**
\brief I-Cache Invalidate by address
\details Invalidates I-Cache for the given address.
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
I-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] isize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize)
{
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if ( isize > 0 ) {
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_ICACHE_LINE_SIZE;
op_size -= __SCB_ICACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief Enable D-Cache
\details Turns on D-Cache
*/
__STATIC_FORCEINLINE void SCB_EnableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
__DSB();
__ISB();
#endif
}
/**
\brief Disable D-Cache
\details Turns off D-Cache
*/
__STATIC_FORCEINLINE void SCB_DisableDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
struct {
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
} locals
#if ((defined(__GNUC__) || defined(__clang__)) && !defined(__OPTIMIZE__))
__ALIGNED(__SCB_DCACHE_LINE_SIZE)
#endif
;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
__DSB();
#if !defined(__OPTIMIZE__)
/*
* For the endless loop issue with no optimization builds.
* More details, see https://github.com/ARM-software/CMSIS_5/issues/620
*
* The issue only happens when local variables are in stack. If
* local variables are saved in general purpose register, then the function
* is OK.
*
* When local variables are in stack, after disabling the cache, flush the
* local variables cache line for data consistency.
*/
/* Clean and invalidate the local variable cache. */
#if defined(__ICCARM__)
/* As we can't align the stack to the cache line size, invalidate each of the variables */
SCB->DCCIMVAC = (uint32_t)&locals.sets;
SCB->DCCIMVAC = (uint32_t)&locals.ways;
SCB->DCCIMVAC = (uint32_t)&locals.ccsidr;
#else
SCB->DCCIMVAC = (uint32_t)&locals;
#endif
__DSB();
__ISB();
#endif
locals.ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
locals.sets = (uint32_t)(CCSIDR_SETS(locals.ccsidr));
do {
locals.ways = (uint32_t)(CCSIDR_WAYS(locals.ccsidr));
do {
SCB->DCCISW = (((locals.sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((locals.ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (locals.ways-- != 0U);
} while(locals.sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Invalidate D-Cache
\details Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean D-Cache
\details Cleans D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief Clean & Invalidate D-Cache
\details Cleans and Invalidates D-Cache
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
uint32_t ccsidr;
uint32_t sets;
uint32_t ways;
SCB->CSSELR = 0U; /* select Level 1 data cache */
__DSB();
ccsidr = SCB->CCSIDR;
/* clean & invalidate D-Cache */
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
do {
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
do {
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
#if defined ( __CC_ARM )
__schedule_barrier();
#endif
} while (ways-- != 0U);
} while(sets-- != 0U);
__DSB();
__ISB();
#endif
}
/**
\brief D-Cache Invalidate by address
\details Invalidates D-Cache for the given address.
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are invalidated.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean by address
\details Cleans D-Cache for the given address
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned.
\param[in] addr address
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/**
\brief D-Cache Clean and Invalidate by address
\details Cleans and invalidates D_Cache for the given address
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity.
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated.
\param[in] addr address (aligned to 32-byte boundary)
\param[in] dsize size of memory block (in number of bytes)
*/
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize)
{
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if ( dsize > 0 ) {
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
__DSB();
do {
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
op_addr += __SCB_DCACHE_LINE_SIZE;
op_size -= __SCB_DCACHE_LINE_SIZE;
} while ( op_size > 0 );
__DSB();
__ISB();
}
#endif
}
/*@} end of CMSIS_Core_CacheFunctions */
#endif /* ARM_CACHEL1_ARMV7_H */

View File

@ -0,0 +1,894 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
* @version V5.4.0
* @date 20. January 2023
******************************************************************************/
/*
* Copyright (c) 2009-2023 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* __ARM_ARCH_8_1M_MAIN__ not applicable */
/* CMSIS compiler control DSP macros */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __ARM_FEATURE_DSP 1
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static __forceinline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __memory_changed()
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit"), zero_init))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
/* ######################### Startup and Lowlevel Init ######################## */
#ifndef __PROGRAM_START
#define __PROGRAM_START __main
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __Vectors
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET")))
#endif
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value != 0U; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return result;
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing special-purpose register PRIMASK.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting special-purpose register PRIMASK.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
__ISB();
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing special-purpose register FAULTMASK.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting special-purpose register FAULTMASK.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
/*@} end of CMSIS_Core_RegAccFunctions */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2))
#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,303 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.3.0
* @date 04. April 2023
******************************************************************************/
/*
* Copyright (c) 2009-2023 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* TI Arm Clang Compiler (tiarmclang)
*/
#elif defined (__ti__)
#include "cmsis_tiarmclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler (armcl)
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#ifndef __NO_INIT
#define __NO_INIT __attribute__ ((section (".bss.noinit")))
#endif
#ifndef __ALIAS
#define __ALIAS(x) __attribute__ ((alias(x)))
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.5
* @date 02. February 2022
******************************************************************************/
/*
* Copyright (c) 2009-2022 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

Some files were not shown because too many files have changed in this diff Show More