Merge pull request #33 from fagci/main

refactor: mv spectrum_fagci to another target
pull/49/head release-43
Piotr Lewandowski (SQ9P) 2023-07-16 00:06:56 +02:00 zatwierdzone przez GitHub
commit 027d5b46df
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
11 zmienionych plików z 634 dodań i 2 usunięć

Wyświetl plik

@ -36,7 +36,7 @@ jobs:
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_PROJECT_rssi_printer_encoded:BOOL=ON
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --target rssi_printer_encoded rssi_sbar_encoded pong_encoded most_useless_mod_encoded spectrum_encoded messenger_encoded
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --target rssi_printer_encoded rssi_sbar_encoded pong_encoded most_useless_mod_encoded spectrum_encoded spectrum_fagci_encoded messenger_encoded
- name: Upload rssi_printer_encoded as artifact
uses: actions/upload-artifact@v2
@ -68,6 +68,12 @@ jobs:
name: spectrum_encoded
path: ${{github.workspace}}/build/src/spectrum/spectrum_encoded.bin
- name: Upload spectrum_fagci_encoded as artifact
uses: actions/upload-artifact@v2
with:
name: spectrum_fagci_encoded
path: ${{github.workspace}}/build/src/spectrum_fagci/spectrum_encoded.bin
- name: Upload messenger_encoded as artifact
uses: actions/upload-artifact@v2
with:
@ -139,6 +145,16 @@ jobs:
asset_name: ${{ format('uv_k5_26_spectrum_v{0}.bin', github.run_number) }}
asset_content_type: application/octet-stream
- name: Upload Release Asset spectrum_fagci_encoded
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{github.workspace}}/build/src/spectrum_fagci/spectrum_encoded.bin
asset_name: ${{ format('uv_k5_26_spectrum_fagci_v{0}.bin', github.run_number) }}
asset_content_type: application/octet-stream
- name: Upload Release Asset messenger_encoded
uses: actions/upload-release-asset@v1.0.2
env:

Wyświetl plik

@ -4,5 +4,6 @@ add_subdirectory(rssi_sbar)
add_subdirectory(most_useless_mod)
add_subdirectory(pong)
add_subdirectory(spectrum)
add_subdirectory(spectrum_fagci)
add_subdirectory(t9_texting)
add_subdirectory(messenger)
add_subdirectory(messenger)

Wyświetl plik

@ -0,0 +1,79 @@
set(NAME spectrum_fagci)
set(MCU_TARGET_FILES_DIR ../mcu_target_common)
add_executable(${NAME}
main.cpp
hardware/hardware.cpp
dp32g030.s
)
target_link_libraries(${NAME}
orginal_fw
uv_k5_system
lcd
)
target_include_directories(${NAME} PUBLIC
./
Drivers/CMSIS/Device/ST/STM32G0xx/Include
Drivers/CMSIS/DSP/Include
Drivers/CMSIS/Include
)
target_compile_definitions(${NAME} PRIVATE
${STM32_DEFINES}
$<$<CONFIG:Debug>:DEBUG_ENABLED>
)
target_compile_options(${NAME} PRIVATE
${COMPILER_OPTIONS}
-flto
)
target_link_options(${NAME} PRIVATE
#-print-multi-lib
-T ${CMAKE_CURRENT_SOURCE_DIR}/memory.ld
-flto
-mcpu=cortex-m0
-mthumb
-mfpu=auto
-mfloat-abi=soft
-specs=nosys.specs
-specs=nano.specs
-lc
-lm
-lnosys
-Wl,-Map=${PROJECT_NAME}.map,--cref
-Wl,--gc-sections
-Wl,--print-memory-usage
-Wstack-usage=128
-Wno-register
)
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND arm-none-eabi-size ${NAME}
)
#convert to hex
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND arm-none-eabi-objcopy -O ihex ${NAME} ${NAME}.hex
COMMAND arm-none-eabi-objcopy -O binary ${NAME} ${NAME}.bin
)
get_target_property(BOOTLOADER_BIN_PATH orginal_fw BOOTLOADER_BIN_PATH)
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "generating full binary with bootloader to ${NAME}_with_bootloader.bin"
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/fw_merger.py ${BOOTLOADER_BIN_PATH} ${NAME}.bin ${NAME}_with_bootloader.bin
)
add_custom_target(${NAME}_flash
COMMAND openocd -f interface/cmsis-dap.cfg -f ${PROJECT_SOURCE_DIR}/openocd_scripts/dp32g030.cfg -c "write_image ${PROJECT_SOURCE_DIR}/build/src/rssi_printer/rssi_printer.bin 0x1000" -c "halt" -c "shutdown"
DEPENDS ${NAME}
)
add_custom_target(${NAME}_encoded
COMMAND python ${PROJECT_SOURCE_DIR}/tools/fw_tools/python-utils/fw_pack.py ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin ${CMAKE_CURRENT_SOURCE_DIR}/../orginal_fw/k5_26_encrypted_18to1300MHz.ver.bin ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_encoded.bin
DEPENDS ${NAME}
)

Wyświetl plik

@ -0,0 +1,18 @@
.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler

Wyświetl plik

@ -0,0 +1,17 @@
#include "registers.hpp"
class CExec final
{
public:
CExec(){};
void InterruptCallback()
{
CheckButtons();
}
private:
void CheckButtons() const
{
}
};

Wyświetl plik

@ -0,0 +1,16 @@
import sys
def merge_files(in1, in2, out):
f1 = open(in1, 'rb')
f2 = open(in2, 'rb')
fo = open(out, 'wb')
fo.write(f1.read())
fo.write(f2.read())
fo.close()
f1.close()
f2.close()
if __name__ == '__main__':
args = sys.argv
merge_files(args[1], args[2], args[3])

Wyświetl plik

@ -0,0 +1,50 @@
#include "hardware.hpp"
#include "registers.hpp"
using namespace Hardware;
void TPower::EnableDbg()
{
GPIOB->DIR &= ~(GPIO_PIN_11|GPIO_PIN_14);
// PB11 alternate fx to SWDIO
GPIO->PORTB_SEL1 &= ~(0b1111 << 12);
GPIO->PORTB_SEL1 |= (0b1 << 12);
// PB14 alternate fx to SWDIO
GPIO->PORTB_SEL1 &= ~(0b1111 << 24);
GPIO->PORTB_SEL1 |= (0b1 << 24);
}
void TSystem::Delay(unsigned int u32Ticks)
{
for(volatile unsigned int i = 0; i < u32Ticks; i++)
{
__asm volatile ("dsb sy" : : : "memory");
}
}
void TFlashLight::On()
{
GPIOC->DATA |= 1 << 3;
}
void TFlashLight::Off()
{
GPIOC->DATA &= ~(1 << 3);
}
void TFlashLight::Toggle()
{
GPIOC->DATA ^= 1 << 3;
}
void TFlashLight::BlinkSync(unsigned char u8BlinksCnt)
{
for(unsigned char i = 0; i < u8BlinksCnt*2; i++)
{
Toggle();
System.Delay(200000);
}
Off();
}

Wyświetl plik

@ -0,0 +1,29 @@
namespace Hardware
{
struct TPower
{
void EnableDbg();
};
struct TSystem
{
static void Delay(unsigned int u32Ticks);
};
struct TFlashLight
{
TFlashLight(TSystem& Sys) :System(Sys){};
void On();
void Off();
void Toggle();
void BlinkSync(unsigned char u8BlinksCnt);
TSystem& System;
};
struct THardware
{
TPower Power;
TSystem System;
TFlashLight FlashLight = {System};
};
}

Wyświetl plik

@ -0,0 +1,50 @@
#include "system.hpp"
#include "hardware/hardware.hpp"
#include "registers.hpp"
#include "uv_k5_display.hpp"
#include "spectrum.hpp"
#include <string.h>
Hardware::THardware Hw;
const System::TOrgFunctions& Fw = System::OrgFunc_01_26;
const System::TOrgData& FwData = System::OrgData_01_26;
CSpectrum<System::OrgFunc_01_26, System::OrgData_01_26> Spectrum;
int main()
{
Fw.IRQ_RESET();
return 0;
}
extern "C" void Reset_Handler()
{
Fw.IRQ_RESET();
}
extern "C" void SysTick_Handler()
{
unsigned int u32Dummy;
System::TCortexM0Stacking* pStackedRegs =
(System::TCortexM0Stacking*)(((unsigned int*)&u32Dummy) + 1);
static bool bFirstInit = false;
if(!bFirstInit)
{
System::CopyDataSection();
__libc_init_array();
bFirstInit = true;
}
bool bPreventWhileKeypadPolling = pStackedRegs->LR > (unsigned int)Fw.PollKeyboard &&
pStackedRegs->PC < (unsigned int)Fw.PollKeyboard + 0x100; // i made a mistake and compared PC and LR, but this works fine xD
static unsigned int u32StupidCounter = 1;
if(u32StupidCounter++ > 200 && !bPreventWhileKeypadPolling)
{
Spectrum.Handle();
}
Fw.IRQ_SYSTICK();
}

Wyświetl plik

@ -0,0 +1,90 @@
ENTRY(Reset_Handler)
MEMORY
{
RAM (rwx) : ORIGIN = 0x2000138C, LENGTH = 256
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 60K
}
_estack = 0x20001388;
EXTERN(VectorTable)
SECTIONS
{
. = 0x0;
.isr_vectors :
{
. = ALIGN(4);
KEEP(*(.isr_vectors))
. = ALIGN(4);
} >FLASH
.org_fw_rest :
{
. = ALIGN(4);
KEEP(*(.org_fw_rest))
} > FLASH
.org_vectors :
{
. = ALIGN(4);
__org_vectors_start = .;
KEEP(*(.org_vectors))
} > FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >FLASH
.preinit_array :
{
__preinit_array_start = .;
KEEP (*(.preinit_array*))
__preinit_array_end = .;
} >FLASH
.init_array :
{
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
__init_array_end = .;
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
_flash_data_start = .;
} >FLASH
_sidata = LOADADDR(.data);
.data : AT (_flash_data_start)
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
*(.ramsection)
_edata = .;
} >RAM
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss)
_ebss = .;
} >RAM
}

Wyświetl plik

@ -0,0 +1,266 @@
#pragma once
#include "system.hpp"
#include "uv_k5_display.hpp"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
static constexpr auto operator""_Hz(unsigned long long Hertz) {
return Hertz / 10;
}
static constexpr auto operator""_KHz(unsigned long long KiloHertz) {
return KiloHertz * 1000_Hz;
}
static constexpr auto operator""_MHz(unsigned long long KiloHertz) {
return KiloHertz * 1000_KHz;
}
template <const System::TOrgFunctions &Fw, const System::TOrgData &FwData>
class CSpectrum {
public:
static constexpr u8 EnableKey = 13;
static constexpr auto DrawingSizeY = 16 + 6 * 8;
static constexpr auto DrawingEndY = 42;
static constexpr u32 BarPos = 640; // 5 * 128
u8 rssiHistory[128] = {};
u8 rssiMin = 255, rssiMax = 0;
u8 highestPeakX = 0;
u8 highestPeakT = 0;
u8 highestPeakRssi = 0;
u32 highestPeakF = 0;
u32 FStart;
CSpectrum()
: DisplayBuff(FwData.pDisplayBuffer), FontSmallNr(FwData.pSmallDigs),
Display(DisplayBuff), bDisplayCleared(true), u32ScanRange(1600_KHz),
working(0), scanDelay(800), isUserInput(false) {
Display.SetFont(&FontSmallNr);
};
inline void Measure() {
u8 rssi = 0;
u8 xPeak = 0;
u32 fPeak, fMeasure = FStart;
rssiMin = 255;
rssiMax = 0;
for (u8 i = 0; i < 64; ++i, fMeasure += 25_KHz) {
rssi = rssiHistory[i] = GetRssi(fMeasure);
if (rssi > rssiMax) {
rssiMax = rssi;
fPeak = fMeasure;
xPeak = i << 1;
}
if (rssi < rssiMin) {
rssiMin = rssi;
}
}
++highestPeakT;
if (rssiMax > highestPeakRssi || highestPeakT >= 8) {
highestPeakT = 0;
highestPeakRssi = rssiMax;
highestPeakX = xPeak;
highestPeakF = fPeak;
}
}
inline void DrawSpectrum() {
u8 rssi, sub;
for (u8 i = 0; i < 128; ++i) {
rssi = rssiHistory[i >> 1];
sub = clamp(rssi - rssiMin, 0, DrawingSizeY);
Display.DrawHLine(DrawingEndY - sub, DrawingEndY, i);
}
Display.SetCoursor(0, 0);
Display.PrintFixedDigitsNumber2(scanDelay, 0);
Display.SetCoursor(6, 0);
Display.PrintFixedDigitsNumber2(currentFreq);
Display.SetCoursor(6, 8 * 2 + 10 * 7);
Display.PrintFixedDigitsNumber2(highestPeakF);
}
inline void DrawTicks() {
u32 f = modulo(FStart, 1_MHz);
for (u8 i = 0; i < 128; ++i, f += 12500_Hz) {
u8 barValue = 0b00001000;
modulo(f, 100_KHz) || (barValue |= 0b00010000);
modulo(f, 500_KHz) || (barValue |= 0b00100000);
modulo(f, 1_MHz) || (barValue |= 0b11000000);
*(FwData.pDisplayBuffer + BarPos + i) |= barValue;
}
// center
*(FwData.pDisplayBuffer + BarPos + 64) |= 0b10101010;
}
inline void DrawArrow(u8 x) {
u8 *peakPos = FwData.pDisplayBuffer + BarPos + x;
x > 1 && (*(peakPos - 2) |= 0b01000000);
x > 0 && (*(peakPos - 1) |= 0b01100000);
(*(peakPos) |= 0b01110000);
x < 127 && (*(peakPos + 1) |= 0b01100000);
x < 128 && (*(peakPos + 2) |= 0b01000000);
}
void HandleUserInput() {
switch (u8LastBtnPressed) {
case 1:
UpdateScanDelay(50);
break;
case 7:
UpdateScanDelay(-50);
break;
case 11: // up
UpdateCurrentFreq(100_KHz);
break;
case 12: // down
UpdateCurrentFreq(-100_KHz);
break;
default:
isUserInput = false;
}
}
void Render() {
DrawTicks();
DrawArrow(highestPeakX);
DrawSpectrum();
}
void Update() {
if (bDisplayCleared) {
currentFreq = GetFrequency();
OnUserInput();
u16OldAfSettings = Fw.BK4819Read(0x47);
Fw.BK4819Write(0x47, 0); // mute AF during scan
}
bDisplayCleared = false;
HandleUserInput();
Measure();
}
void UpdateScanDelay(short diff) {
scanDelay += diff;
scanDelay = clamp(scanDelay, 100, 2000);
OnUserInput();
}
void UpdateCurrentFreq(long long diff) {
currentFreq += diff;
currentFreq = clamp(currentFreq, 18_MHz, 1300_MHz);
OnUserInput();
}
inline void OnUserInput() {
isUserInput = true;
FStart = currentFreq - (u32ScanRange >> 1);
// reset peak
highestPeakT = 0;
highestPeakRssi = 0;
highestPeakX = 0;
highestPeakF = 0;
}
void Handle() {
if (!(GPIOC->DATA & 0b1)) {
return;
}
if (!FreeToDraw()) {
RestoreParams();
return;
}
Update();
DisplayBuff.ClearAll();
Render();
Fw.FlushFramebufferToScreen();
}
private:
void RestoreParams() {
if (!bDisplayCleared) {
bDisplayCleared = true;
DisplayBuff.ClearAll();
Fw.FlushFramebufferToScreen();
SetFrequency(currentFreq);
Fw.BK4819Write(0x47, u16OldAfSettings); // set previous AF settings
}
}
void SetFrequency(unsigned int u32Freq) {
Fw.BK4819Write(0x39, ((u32Freq >> 16) & 0xFFFF));
Fw.BK4819Write(0x38, (u32Freq & 0xFFFF));
Fw.BK4819Write(0x30, 0);
Fw.BK4819Write(0x30, 0xbff1);
}
u8 GetRssi(u32 f, u16 delay = 800) {
SetFrequency(f);
Fw.DelayUs(delay);
return Fw.BK4819Read(0x67);
}
u32 GetFrequency() {
return ((Fw.BK4819Read(0x39) << 16) | Fw.BK4819Read(0x38));
}
bool FreeToDraw() {
bool bFlashlight = (GPIOC->DATA & GPIO_PIN_3);
if (bFlashlight) {
working = true;
GPIOC->DATA &= ~GPIO_PIN_3;
*FwData.p8FlashLightStatus = 3;
}
if (working) {
u8LastBtnPressed = Fw.PollKeyboard();
}
bool bPtt = !(GPIOC->DATA & GPIO_PIN_5);
if (bPtt || u8LastBtnPressed == EnableKey) {
working = false;
}
return working;
}
unsigned clamp(unsigned v, unsigned min, unsigned max) {
if (v < min)
return min;
if (v > max)
return max;
return v;
}
unsigned modulo(unsigned num, unsigned div) {
while (num >= div)
num -= div;
return num;
}
TUV_K5Display DisplayBuff;
const TUV_K5SmallNumbers FontSmallNr;
CDisplay<const TUV_K5Display> Display;
bool bDisplayCleared;
u32 u32ScanRange;
u32 currentFreq;
u16 u16OldAfSettings;
u8 u8LastBtnPressed;
bool working;
u16 scanDelay;
bool isUserInput;
};