From 894d7b8b5714ea917d9a1268a7de16474ddd41c3 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 18 Oct 2024 20:20:57 +0200 Subject: [PATCH] Initial BSP for Connect Systems CS7000-PLUS --- meson.build | 52 ++++- .../mcu/STM32H7xx/linker_script_cs7000p.ld | 167 ++++++++++++++ platform/targets/CS7000-PLUS/hwconfig.c | 74 +++++++ platform/targets/CS7000-PLUS/hwconfig.h | 73 ++++++ platform/targets/CS7000-PLUS/pinmap.h | 173 +++++++++++++++ platform/targets/CS7000-PLUS/platform.c | 207 ++++++++++++++++++ 6 files changed, 745 insertions(+), 1 deletion(-) create mode 100644 platform/mcu/STM32H7xx/linker_script_cs7000p.ld create mode 100644 platform/targets/CS7000-PLUS/hwconfig.c create mode 100644 platform/targets/CS7000-PLUS/hwconfig.h create mode 100644 platform/targets/CS7000-PLUS/pinmap.h create mode 100644 platform/targets/CS7000-PLUS/platform.c diff --git a/meson.build b/meson.build index 48b44034..8f8ac86e 100644 --- a/meson.build +++ b/meson.build @@ -511,6 +511,30 @@ cs7000_src += openrtx_src + stm32f405_src + ui_src_default cs7000_inc += openrtx_inc + stm32f405_inc cs7000_def += openrtx_def + stm32f405_def +## +## Connect Systems CS70000-PLUS +## +cs7000p_src = ['platform/drivers/stubs/nvmem_stub.c', + 'platform/drivers/stubs/cps_io_stub.c', + 'platform/drivers/stubs/radio_stub.c', + 'platform/drivers/stubs/audio_stub.c', + 'platform/drivers/stubs/radio_stub.c', + 'platform/drivers/display/ST7735R_CS7000.c', + 'platform/drivers/keyboard/keyboard_CS7000.c', + 'platform/drivers/backlight/backlight_CS7000.c', + 'platform/drivers/GPIO/gpio_shiftReg.c', + 'platform/drivers/SPI/spi_custom.c', + 'platform/drivers/SPI/spi_bitbang.c', + 'platform/targets/CS7000-PLUS/hwconfig.c', + 'platform/targets/CS7000-PLUS/platform.c'] + +cs7000p_inc = ['platform/targets/CS7000-PLUS'] +cs7000p_def = {'PLATFORM_CS7000P': '', 'timegm': 'mktime'} + +cs7000p_src += openrtx_src + stm32h743_src + miosix_cm7_src + ui_src_default +cs7000p_inc += openrtx_inc + stm32h743_inc + miosix_cm7_inc +cs7000p_def += openrtx_def + stm32h743_def + miosix_cm7_def + ## ## -------------------------- Compilation arguments ---------------------------- ## @@ -615,6 +639,15 @@ foreach k, v : cs7000_def endif endforeach +cs7000p_args = [] +foreach k, v : cs7000p_def + if v == '' + cs7000p_args += '-D@0@'.format(k) + else + cs7000p_args += '-D@0@=@1@'.format(k, v) + endif +endforeach + linux_opts = { 'sources' : linux_default_src, 'include_directories': linux_inc, @@ -714,6 +747,16 @@ cs7000_opts = { 'link_args' : ['-Wl,-T../platform/mcu/STM32F4xx/stm32_1m+192k_rom.ld'] } +cs7000p_opts = { + 'sources' : cs7000p_src, + 'include_directories': cs7000p_inc, + 'dependencies' : [codec2_dep], + 'c_args' : cs7000p_args, + 'cpp_args' : cs7000p_args, + 'link_args' : ['-Wl,-T../platform/mcu/STM32H7xx/linker_script_cs7000p.ld', + '-Wl,--print-memory-usage'] +} + ## ## ---------------------------- Compilation targets ---------------------------- ## @@ -790,6 +833,13 @@ targets = [ 'wrap' : ' ', 'load_addr': '0x08000000' }, + { + 'name' : 'cs7000p', + 'opts' : cs7000p_opts, + 'flashable': true, + 'wrap' : ' ', + 'load_addr': '0x08100000' + }, ] if build_machine.system() == 'linux' @@ -919,7 +969,7 @@ foreach t : targets '-s', '0x08000000']) # For CS7000 'wrap' target prepares a .dfu file - elif name == 'openrtx_cs7000' + elif name == 'openrtx_cs7000' or name == 'openrtx_cs7000p' custom_target(name+'_wrap', output : name+'.dfu', diff --git a/platform/mcu/STM32H7xx/linker_script_cs7000p.ld b/platform/mcu/STM32H7xx/linker_script_cs7000p.ld new file mode 100644 index 00000000..7f686978 --- /dev/null +++ b/platform/mcu/STM32H7xx/linker_script_cs7000p.ld @@ -0,0 +1,167 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + * - the external ram (if available) is not used. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x24000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap */ +_heap_end = 0x24080000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08100000, LENGTH = 1M + + /* NOTE: for now wer support only the AXI SRAM */ + ram(wx) : ORIGIN = 0x24000200, LENGTH = 512K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/platform/targets/CS7000-PLUS/hwconfig.c b/platform/targets/CS7000-PLUS/hwconfig.c new file mode 100644 index 00000000..051b369e --- /dev/null +++ b/platform/targets/CS7000-PLUS/hwconfig.c @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +/** + * SPI bitbang function for SN74HC595 gpio extender. + * + * Hand-tuned to be as fast as possible, gives the following clock performance + * when compiled with -Os and run on STM32H743 at 400MHz: + * + * - Freq 7MHz + * - Pos. width 70ns + * - Neg. with 70ns + */ +static uint8_t spiSr_func(const void *priv, uint8_t value) +{ + (void) priv; + + for(uint8_t cnt = 0; cnt < 8; cnt++) + { + GPIOE->BSRR = (1 << 23); // Clear PE7 (CLK) + + if(value & (0x80 >> cnt)) + GPIOE->BSRR = 1 << 9; // Set PE9 (MOSI) + else + GPIOE->BSRR = 1 << 25; // Clear PE9 (MOSI) + + // ~70ns delay + asm volatile(" mov r1, #5 \n" + "___loop_2: cmp r1, #0 \n" + " itt ne \n" + " subne r1, r1, #1 \n" + " bne ___loop_2 \n":::"r1"); + + GPIOE->BSRR = (1 << 7); // Set PE7 (CLK) + + // ~70ns delay + asm volatile(" mov r1, #6 \n" + "___loop_3: cmp r1, #0 \n" + " itt ne \n" + " subne r1, r1, #1 \n" + " bne ___loop_3 \n":::"r1"); + } + + return 0; +} + +static const struct gpioPin shiftRegStrobe = { GPIOEXT_STR }; +static pthread_mutex_t adc1Mutex; + +SPI_CUSTOM_DEVICE_DEFINE(spiSr, spiSr_func, NULL, NULL) +GPIO_SHIFTREG_DEVICE_DEFINE(extGpio, (const struct spiDevice *) &spiSr, shiftRegStrobe, 24) +ADC_STM32_DEVICE_DEFINE(adc1, ADC1, &adc1Mutex, ADC_COUNTS_TO_UV(3300000, 16)) diff --git a/platform/targets/CS7000-PLUS/hwconfig.h b/platform/targets/CS7000-PLUS/hwconfig.h new file mode 100644 index 00000000..b8d03177 --- /dev/null +++ b/platform/targets/CS7000-PLUS/hwconfig.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef HWCONFIG_H +#define HWCONFIG_H + +#include +#include "pinmap.h" + +#ifdef __cplusplus + +// Export the HR_C6000 driver only for C++ sources +#include + +extern HR_C6000 C6000; + +extern "C" { +#endif + +enum AdcChannels +{ + ADC_VOL_CH = 8, /* PC5 */ + ADC_VBAT_CH = 3, /* PA6 */ + ADC_RTX_CH = 15, /* PA3 */ + ADC_RSSI_CH = 9, /* PB0 */ + ADC_MIC_CH = 7, /* PA7 */ + ADC_CTCSS_CH = 2, /* PA2 */ +}; + +extern const struct Adc adc1; +extern const struct spiCustomDevice spiSr; +extern const struct gpioDev extGpio; +extern const struct ak2365a detector; +extern const struct sky73210 pll; + +/* Screen dimensions */ +#define CONFIG_SCREEN_WIDTH 160 +#define CONFIG_SCREEN_HEIGHT 128 + +/* Screen pixel format */ +#define CONFIG_PIX_FMT_RGB565 + +/* Screen has adjustable brightness */ +#define CONFIG_SCREEN_BRIGHTNESS + +/* Battery type */ +#define CONFIG_BAT_LIPO_2S + +/* Device supports M17 mode */ +#define CONFIG_M17 + +/* Device has a GPS chip */ +// #define CONFIG_GPS + +#ifdef __cplusplus +} +#endif + +#endif /* HWCONFIG_H */ diff --git a/platform/targets/CS7000-PLUS/pinmap.h b/platform/targets/CS7000-PLUS/pinmap.h new file mode 100644 index 00000000..7459938b --- /dev/null +++ b/platform/targets/CS7000-PLUS/pinmap.h @@ -0,0 +1,173 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef PINMAP_H +#define PINMAP_H + +#include + +/* Power control */ +#define BAT_DETECT GPIOB,2 +#define MAIN_PWR_DET GPIOA,6 +#define MAIN_PWR_SW &extGpio,20 + +/* Display */ +#define LCD_D0 GPIOD,0 +#define LCD_D1 GPIOD,1 +#define LCD_D2 GPIOD,2 +#define LCD_D3 GPIOD,3 +#define LCD_D4 GPIOD,4 +#define LCD_D5 GPIOD,5 +#define LCD_D6 GPIOD,6 +#define LCD_D7 GPIOD,7 +#define LCD_WR GPIOD,13 +#define LCD_RD GPIOD,14 +#define LCD_DC GPIOD,12 +#define LCD_RST GPIOE,0 +#define LCD_CS GPIOE,1 +#define LCD_BKLIGHT GPIOC,9 + +/* + * Keyboard. Rows and columns, except for column 5, are shared with the LCD + * data lines. Commens reports the resistor number in the schematic for reference. + */ +#define KB_ROW1 LCD_D0 // R905 +#define KB_ROW2 LCD_D1 // R906 +#define KB_ROW3 LCD_D2 // R907 +#define KB_ROW4 LCD_D3 // R908 +#define KB_COL1 LCD_D7 // R902 +#define KB_COL2 LCD_D6 // R903 +#define KB_COL3 LCD_D5 // R904 +#define KB_COL4 LCD_D4 // R909 +#define KB_COL5 GPIOB,7 // R926 +#define KBD_BKLIGHT &extGpio,16 + +/* Push-to-talk and side keys */ +#define PTT_SW GPIOA,8 +#define PTT_EXT GPIOE,11 +#define SIDE_KEY1 GPIOD,15 +#define SIDE_KEY2 GPIOE,12 +#define SIDE_KEY3 GPIOE,13 +#define ALARM_KEY GPIOE,10 + +/* Channel selection rotary encoder */ +#define CH_SELECTOR_0 GPIOE,14 +#define CH_SELECTOR_1 GPIOE,15 +#define CH_SELECTOR_2 GPIOB,10 +#define CH_SELECTOR_3 GPIOB,11 + +/* LEDs */ +#define GREEN_LED &extGpio,12 +#define RED_LED &extGpio,13 + +/* Analog inputs */ +#define AIN_VOLUME GPIOC,5 +#define AIN_VBAT GPIOC,4 // BATT +#define AIN_MIC GPIOA,7 +#define AIN_RSSI GPIOB,0 +#define AIN_NOISE GPIOB,1 +#define AIN_RTX GPIOA,3 +#define AIN_CTCSS GPIOA,2 // QT_DQT_IN +#define AIN_TEMP GPIOA,7 // Batt. temp. + +/* Tone generator */ +#define CTCSS_OUT GPIOC,8 // CTCSS tone +#define BEEP_OUT GPIOA,5 // System "beep" + +/* External flash */ +#define FLASH_CS &GpioE,4 +#define FLASH_CLK GPIOE,2 +#define FLASH_SDO GPIOE,5 +#define FLASH_SDI GPIOE,6 + +/* PLL */ +#define PLL_CS &GpioD,9 +#define PLL_CLK GPIOD,10 +#define PLL_DAT GPIOD,8 +#define PLL_LD GPIOD,11 + +/* HR_C6000 */ +#define C6K_CS &GpioB,12 +#define C6K_CLK GPIOB,13 +#define C6K_MISO GPIOB,14 +#define C6K_MOSI GPIOB,15 +#define C6K_SLEEP &extGpio,7 + +#define VOC_CS GPIOB,6 +#define VOC_CLK GPIOB,3 +#define VOC_MOSI GPIOB,4 +#define VOC_MISO GPIOB,5 + +#define I2S_FS GPIOA,15 +#define I2S_CLK GPIOC,10 +#define I2S_RX GPIOC,11 +#define I2S_TX GPIOC,12 + +#define DMR_TS_INT GPIOC,0 +#define DMR_SYS_INT GPIOC,1 +#define DMR_TX_INT GPIOC,2 + +/* AK2365 */ +#define DET_PDN &extGpio,6 +#define DET_CS &extGpio,0 +#define DET_CLK GPIOE,3 +#define DET_DAT GPIOC,13 +#define DET_RST &GpioC,14 + +/* RTX control */ +#define RF_APC_SW &extGpio,3 +#define VCOVCC_SW &extGpio,8 +#define TX_PWR_EN &extGpio,9 +#define RX_PWR_EN &extGpio,15 +#define VCO_PWR_EN &extGpio,11 +#define CTCSS_AMP_EN &extGpio,22 +#define APC_TV GPIOA,4 + +/* Audio control */ +#define AUDIO_AMP_EN &extGpio,14 +#define INT_SPK_MUTE &extGpio,17 +#define EXT_SPK_MUTE &extGpio,19 +#define MIC_PWR_EN &extGpio,18 +#define INT_MIC_SEL &extGpio,10 +#define EXT_MIC_SEL &extGpio,5 +#define AF_MUTE &extGpio,23 +#define PHONE_DETECT GPIOA,13 + +/* GPS */ +#define GPS_TXD GPIOC,6 +#define GPS_RXD GPIOC,7 + +/* Accessory connector */ +#define PHONE_TXD GPIOA,0 +#define PHONE_RXD GPIOA,1 + +/* SN74HC595 gpio extenders */ +#define GPIOEXT_CLK GPIOE,7 +#define GPIOEXT_DAT GPIOE,9 +#define GPIOEXT_STR &GpioE,8 + +/* Bluetooth module */ +#define BLTH_DETECT GPIOA,14 +#define BLTH_PWR_EN &extGpio,4 +#define BLTH_RXD GPIOA,9 +#define BLTH_TXD GPIOA,10 + +/* ALPU-MP */ +#define ALPU_SDA GPIOB,9 +#define ALPU_SCL GPIOB,8 + +#endif /* PINMAP_H */ diff --git a/platform/targets/CS7000-PLUS/platform.c b/platform/targets/CS7000-PLUS/platform.c new file mode 100644 index 00000000..3f51ad6c --- /dev/null +++ b/platform/targets/CS7000-PLUS/platform.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const hwInfo_t hwInfo = +{ + .name = "CS7000P", + .hw_version = 0, + .vhf_band = 0, + .uhf_band = 1, + .vhf_minFreq = 0, + .vhf_maxFreq = 0, + .uhf_minFreq = 400, + .uhf_maxFreq = 527 +}; + + +void platform_init() +{ + gpio_setMode(PTT_SW, INPUT); + gpio_setMode(PTT_EXT, INPUT); + + gpio_setMode(MAIN_PWR_DET, ANALOG); + gpio_setMode(AIN_MIC, ANALOG); + gpio_setMode(AIN_VOLUME, ANALOG); + + gpio_setMode(GPIOEXT_CLK, OUTPUT); + gpio_setMode(GPIOEXT_DAT, OUTPUT); + + spi_init((const struct spiDevice *) &spiSr); + gpioShiftReg_init(&extGpio); + adcStm32_init(&adc1); + nvm_init(); + audio_init(); + + #ifndef RUNNING_TESTSUITE + gpioDev_set(MAIN_PWR_SW); + #endif +} + +void platform_terminate() +{ + adcStm32_terminate(&adc1); + + #ifndef RUNNING_TESTSUITE + gpioDev_clear(MAIN_PWR_SW); + #endif + + gpioShiftReg_terminate(&extGpio); +} + +uint16_t platform_getVbat() +{ + /* + * Battery voltage is measured through an 1:3.95 voltage divider and + * adc1_getMeasurement returns a value in uV. + */ + uint32_t vbat = adc_getVoltage(&adc1, ADC_VBAT_CH) * 395; + return vbat / 100000; +} + +uint8_t platform_getMicLevel() +{ + // ADC1 returns a 16-bit value: shift right by eight to get 0 - 255 + return adc_getRawSample(&adc1, ADC_MIC_CH) >> 8; +} + +uint8_t platform_getVolumeLevel() +{ + /* + * Volume level corresponds to an analog signal in the range 20 - 2520mV. + * Potentiometer has pseudo-logarithmic law, well described with two straight + * lines with a breakpoint around 410mV. + * Output value has range 0 - 255 with breakpoint at 139. + */ + uint16_t value = adc_getRawSample(&adc1, ADC_VOL_CH) >> 4; + uint32_t output; + + if(value <= 512) + { + // First line: offset zero, slope 0.271 + output = value; + output = (output * 271) / 1000; + } + else + { + // Second line: offset 512, slope 0.044 + output = value - 512; + output = (output * 44) / 1000; + output += 139; + } + + if(output > 255) + output = 255; + + return output; +} + +// int8_t platform_getChSelector() +// { +// return 0; // TODO +// } + +bool platform_getPttStatus() +{ + /* PTT line has a pullup resistor with PTT switch closing to ground */ + uint8_t intPttStatus = gpio_readPin(PTT_SW); + uint8_t extPttStatus = gpio_readPin(PTT_EXT); + return ((intPttStatus == 0) || (extPttStatus == 0)) ? true : false; +} + +bool platform_pwrButtonStatus() +{ + /* + * When power knob is set to off, battery voltage measurement returns 0V. + * Here we set the threshold to 1V since, with knob in off position, there + * is always a bit of noise in the ADC measurement making the returned + * voltage not to be exactly zero. + */ + uint16_t vbat = platform_getVbat(); + if(vbat < 1000) + return false; + + return true; +} + +void platform_ledOn(led_t led) +{ + switch(led) + { + case GREEN: + gpioDev_set(GREEN_LED); + break; + + case RED: + gpioDev_set(RED_LED); + break; + + case YELLOW: + gpioDev_set(GREEN_LED); + gpioDev_set(RED_LED); + break; + + default: + break; + } +} + +void platform_ledOff(led_t led) +{ + switch(led) + { + case GREEN: + gpioDev_clear(GREEN_LED); + break; + + case RED: + gpioDev_clear(RED_LED); + break; + + case YELLOW: + gpioDev_clear(GREEN_LED); + gpioDev_clear(RED_LED); + break; + + default: + break; + } +} + +void platform_beepStart(uint16_t freq) +{ + (void) freq; +} + +void platform_beepStop() +{ + +} + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +}