From 793a2dcd52316bf6c3ea237da546a867d9007d53 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Fri, 13 Nov 2020 16:57:49 +0100 Subject: [PATCH] Adding build target for Tytera MD-390 radio --- meson.build | 33 +++- platform/drivers/ADC/ADC1_MDxx380.c | 4 +- platform/targets/{MD380 => MD-380}/hwconfig.h | 0 platform/targets/{MD380 => MD-380}/platform.c | 0 platform/targets/MD-390/hwconfig.h | 78 ++++++++ platform/targets/MD-390/platform.c | 171 ++++++++++++++++++ 6 files changed, 280 insertions(+), 6 deletions(-) rename platform/targets/{MD380 => MD-380}/hwconfig.h (100%) rename platform/targets/{MD380 => MD-380}/platform.c (100%) create mode 100644 platform/targets/MD-390/hwconfig.h create mode 100644 platform/targets/MD-390/platform.c diff --git a/meson.build b/meson.build index 7bad9a54..9441ddce 100644 --- a/meson.build +++ b/meson.build @@ -134,12 +134,24 @@ md380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDxx380.c', 'platform/drivers/keyboard/keyboard_MDxx380.c', 'platform/drivers/ADC/ADC1_MDxx380.c', 'platform/drivers/tones/toneGenerator_MDxx380.c', - 'platform/targets/MD380/platform.c', + 'platform/targets/MD-380/platform.c', 'openrtx/src/graphics/graphics_rgb565.c'] +md380_inc = inc + stm32f405_inc + ['platform/targets/MD-380'] md380_def = def + stm32f405_def -md380_inc = inc + stm32f405_inc + ['platform/targets/MD380'] + +## TYT MD390 +md390_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDxx380.c', + 'platform/drivers/keyboard/keyboard_MDxx380.c', + 'platform/drivers/ADC/ADC1_MDxx380.c', + 'platform/drivers/tones/toneGenerator_MDxx380.c', + 'platform/targets/MD-390/platform.c', + 'openrtx/src/graphics/graphics_rgb565.c'] + +md390_inc = inc + stm32f405_inc + ['platform/targets/MD-390'] +md390_def = def + stm32f405_def + ## TYT MD-UV380 @@ -149,9 +161,9 @@ mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDxx380.c' 'platform/targets/MD-UV380/platform.c', 'openrtx/src/graphics/graphics_rgb565.c'] +mduv380_inc = inc + stm32f405_inc + ['platform/targets/MD-UV380'] mduv380_def = def + stm32f405_def -mduv380_inc = inc + stm32f405_inc + ['platform/targets/MD-UV380'] ## ## Compilation defines @@ -182,6 +194,15 @@ foreach k, v : md380_def endif endforeach +md390_args = [] +foreach k, v : md390_def + if v == '' + md390_args += '-D@0@'.format(k) + else + md390_args += '-D@0@=@1@'.format(k, v) + endif +endforeach + mduv380_args = [] foreach k, v : mduv380_def if v == '' @@ -202,6 +223,10 @@ md380_opts = {'sources': md380_src, 'link_args' : '-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', 'include_directories': md380_inc} +md390_opts = {'sources': md390_src, + 'c_args': md390_args, + 'link_args' : '-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', + 'include_directories': md390_inc} mduv380_opts = {'sources': mduv380_src, 'c_args': mduv380_args, @@ -224,7 +249,7 @@ targets = [ 'load_addr': '0x0800C000'}, {'name': 'md390', - 'opts': md380_opts, + 'opts': md390_opts, 'flashable': true, 'wrap': 'MD390', 'load_addr': '0x0800C000'}, diff --git a/platform/drivers/ADC/ADC1_MDxx380.c b/platform/drivers/ADC/ADC1_MDxx380.c index 2d079a76..336c76d0 100644 --- a/platform/drivers/ADC/ADC1_MDxx380.c +++ b/platform/drivers/ADC/ADC1_MDxx380.c @@ -34,7 +34,7 @@ void adc1_init() * - PB0: RSSI level */ gpio_setMode(AIN_VBAT, INPUT_ANALOG); - #ifdef PLATFORM_MD380 + #if defined(PLATFORM_MD380) || defined(PLATFORM_MD390) gpio_setMode(AIN_VOLUME, INPUT_ANALOG); gpio_setMode(AIN_MIC, INPUT_ANALOG); gpio_setMode(AIN_RSSI, INPUT_ANALOG); @@ -64,7 +64,7 @@ void adc1_init() | ADC_CR2_ADON; /* Scan sequence config. */ - #ifdef PLATFORM_MD380 + #if defined(PLATFORM_MD380) || defined(PLATFORM_MD390) ADC1->SQR1 = 3 << 20; /* Four channels to be converted */ ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */ | (8 << 5) /* CH8, RSSI value on PB0 */ diff --git a/platform/targets/MD380/hwconfig.h b/platform/targets/MD-380/hwconfig.h similarity index 100% rename from platform/targets/MD380/hwconfig.h rename to platform/targets/MD-380/hwconfig.h diff --git a/platform/targets/MD380/platform.c b/platform/targets/MD-380/platform.c similarity index 100% rename from platform/targets/MD380/platform.c rename to platform/targets/MD-380/platform.c diff --git a/platform/targets/MD-390/hwconfig.h b/platform/targets/MD-390/hwconfig.h new file mode 100644 index 00000000..c3b9d19f --- /dev/null +++ b/platform/targets/MD-390/hwconfig.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * 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 + +#define PLATFORM_MD390 + +/* Screen dimensions */ +#define SCREEN_WIDTH 160 +#define SCREEN_HEIGHT 128 + +/* Display */ +#define LCD_D0 GPIOD,14 +#define LCD_D1 GPIOD,15 +#define LCD_D2 GPIOD,0 +#define LCD_D3 GPIOD,1 +#define LCD_D4 GPIOE,7 +#define LCD_D5 GPIOE,8 +#define LCD_D6 GPIOE,9 +#define LCD_D7 GPIOE,10 +#define LCD_WR GPIOD,5 +#define LCD_RD GPIOD,4 +#define LCD_CS GPIOD,6 +#define LCD_RS GPIOD,12 +#define LCD_RST GPIOD,13 +#define LCD_BKLIGHT GPIOC,6 + +/* Signalling LEDs */ +#define GREEN_LED GPIOE,0 +#define RED_LED GPIOE,1 + +/* Analog inputs */ +#define AIN_VOLUME GPIOA,0 +#define AIN_VBAT GPIOA,1 +#define AIN_MIC GPIOA,3 +#define AIN_RSSI GPIOB,0 + +/* 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 + +/* Push-to-talk switch */ +#define PTT_SW GPIOE,11 + +/* + * Keyboard. Here we define only rows, since coloumn lines are the same as + * LCD_Dx. See also: https://www.qsl.net/dl4yhf/RT3/md380_hw.html#keyboard + */ +#define KB_ROW1 GPIOA,6 /* K1 */ +#define KB_ROW2 GPIOD,2 /* K2 */ +#define KB_ROW3 GPIOD,3 /* K3 */ + +/* Tone generator */ +#define CTCSS_OUT GPIOC,7 /* System "beep" */ +#define BEEP_OUT GPIOC,8 /* CTCSS tone */ + +#endif diff --git a/platform/targets/MD-390/platform.c b/platform/targets/MD-390/platform.c new file mode 100644 index 00000000..aecc9bd7 --- /dev/null +++ b/platform/targets/MD-390/platform.c @@ -0,0 +1,171 @@ +/*************************************************************************** + * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * 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 "hwconfig.h" +#include "ADC1_MDxx380.h" + +void platform_init() +{ + /* Configure GPIOs */ + gpio_setMode(GREEN_LED, OUTPUT); + gpio_setMode(RED_LED, OUTPUT); + + gpio_setMode(LCD_BKLIGHT, ALTERNATE); + gpio_setAlternateFunction(LCD_BKLIGHT, 3); + + gpio_setMode(CH_SELECTOR_0, INPUT); + gpio_setMode(CH_SELECTOR_1, INPUT); + gpio_setMode(CH_SELECTOR_2, INPUT); + gpio_setMode(CH_SELECTOR_3, INPUT); + + gpio_setMode(PTT_SW, INPUT); + + /* + * Initialise ADC1, for vbat, RSSI, ... + * Configuration of corresponding GPIOs in analog input mode is done inside + * the driver. + */ + adc1_init(); + + /* + * Configure TIM8 for backlight PWM: Fpwm = 100kHz, 8 bit of resolution + * APB2 freq. is 84MHz, then: PSC = 327 to have Ftick = 256.097kHz + * With ARR = 256, Fpwm is 100kHz; + * Backlight pin is connected to TIM8 CR1. + */ + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + TIM8->ARR = 255; + TIM8->PSC = 327; + TIM8->CNT = 0; + TIM8->CR1 |= TIM_CR1_ARPE; /* LCD backlight is on PC6, TIM8-CH1 */ + TIM8->CCMR1 |= TIM_CCMR1_OC1M_2 + | TIM_CCMR1_OC1M_1 + | TIM_CCMR1_OC1PE; + TIM8->CCER |= TIM_CCER_CC1E; + TIM8->BDTR |= TIM_BDTR_MOE; + TIM8->CCR1 = 0; + TIM8->EGR = TIM_EGR_UG; /* Update registers */ + TIM8->CR1 |= TIM_CR1_CEN; /* Start timer */ +} + +void platform_terminate() +{ + /* Shut down backlight */ + gpio_setMode(LCD_BKLIGHT, OUTPUT); + gpio_clearPin(LCD_BKLIGHT); + + /* Shut down LEDs */ + gpio_clearPin(GREEN_LED); + gpio_clearPin(RED_LED); + + /* Shut down timer */ + RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + + /* Shut down ADC */ + adc1_terminate(); +} + +float platform_getVbat() +{ + /* + * Battery voltage is measured through an 1:3 voltage divider and + * adc1_getMeasurement returns a value in mV. Thus, to have effective + * battery voltage multiply by three and divide by 1000 + */ + return adc1_getMeasurement(0)*3.0f/1000.0f; +} + +float platform_getMicLevel() +{ + return adc1_getMeasurement(2); +} + +float platform_getVolumeLevel() +{ + return adc1_getMeasurement(3); +} + +uint8_t platform_getChSelector() +{ + static const uint8_t rsPositions[] = { 11, 14, 10, 15, 6, 3, 7, 2, 12, 13, + 9, 16, 5, 4, 8, 1 }; + int pos = gpio_readPin(CH_SELECTOR_0) + | (gpio_readPin(CH_SELECTOR_1) << 1) + | (gpio_readPin(CH_SELECTOR_2) << 2) + | (gpio_readPin(CH_SELECTOR_3) << 3); + return rsPositions[pos]; +} + +bool platform_getPttStatus() +{ + /* PTT line has a pullup resistor with PTT switch closing to ground */ + return (gpio_readPin(PTT_SW) == 0) ? true : false; +} + +void platform_ledOn(led_t led) +{ + switch(led) + { + case GREEN: + gpio_setPin(GREEN_LED); + break; + + case RED: + gpio_setPin(RED_LED); + break; + + default: + break; + } +} + +void platform_ledOff(led_t led) +{ + switch(led) + { + case GREEN: + gpio_clearPin(GREEN_LED); + break; + + case RED: + gpio_clearPin(RED_LED); + break; + + default: + break; + } +} + +void platform_beepStart(uint16_t freq) +{ + /* TODO */ + (void) freq; +} + +void platform_beepStop() +{ + /* TODO */ +} + +void platform_setBacklightLevel(uint8_t level) +{ + TIM8->CCR1 = level; +}