From 8f9502cade97224c626bcd2d18aac94e2ca33091 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Sun, 29 Sep 2024 17:17:16 +0200 Subject: [PATCH] MDUV3x0: updated radio driver --- openrtx/src/rtx/OpMode_FM.cpp | 6 +-- platform/drivers/baseband/radio_UV3x0.cpp | 7 +++- platform/targets/MD-UV3x0/hwconfig.c | 47 +++++++++++++++++++++++ platform/targets/MD-UV3x0/hwconfig.h | 7 ++++ platform/targets/MD-UV3x0/pinmap.h | 2 +- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/openrtx/src/rtx/OpMode_FM.cpp b/openrtx/src/rtx/OpMode_FM.cpp index d4b19638..0eec9244 100644 --- a/openrtx/src/rtx/OpMode_FM.cpp +++ b/openrtx/src/rtx/OpMode_FM.cpp @@ -24,9 +24,7 @@ #include #include -#if defined(PLATFORM_MDUV3x0) -#include "../../../drivers/baseband/HR_C6000.h" -#elif defined(PLATFORM_TTWRPLUS) +#if defined(PLATFORM_TTWRPLUS) #include "AT1846S.h" #endif @@ -50,7 +48,7 @@ void _setVolume() #if defined(PLATFORM_MDUV3x0) // Apply new volume level, map 0 - 255 range into -31 to 31 int8_t gain = ((int8_t) (volume / 4)) - 31; - HR_C6000::instance().setDacGain(gain); + C6000.setDacGain(gain); #elif defined(PLATFORM_TTWRPLUS) // AT1846S volume control is 4 bit AT1846S::instance().setRxAudioGain(volume / 16, volume / 16); diff --git a/platform/drivers/baseband/radio_UV3x0.cpp b/platform/drivers/baseband/radio_UV3x0.cpp index 3de4aaa3..9ea77403 100644 --- a/platform/drivers/baseband/radio_UV3x0.cpp +++ b/platform/drivers/baseband/radio_UV3x0.cpp @@ -43,7 +43,7 @@ static uint8_t txModBias = 0; // VCXO bias for TX static enum opstatus radioStatus; // Current operating status -static HR_C6000& C6000 = HR_C6000::instance(); // HR_C5000 driver +HR_C6000 C6000((const struct spiDevice *) &c6000_spi, { DMR_CS }); // HR_C6000 driver static AT1846S& at1846s = AT1846S::instance(); // AT1846S driver void radio_init(const rtxStatus_t *rtxState) @@ -87,6 +87,11 @@ void radio_init(const rtxStatus_t *rtxState) /* * Configure AT1846S and HR_C6000, keep AF output disabled at power on. */ + gpio_setMode(DMR_CLK, OUTPUT); + gpio_setMode(DMR_MOSI, OUTPUT); + gpio_setMode(DMR_MISO, INPUT); + spi_init((const struct spiDevice *) &c6000_spi); + at1846s.init(); C6000.init(); radio_disableAfOutput(); diff --git a/platform/targets/MD-UV3x0/hwconfig.c b/platform/targets/MD-UV3x0/hwconfig.c index d956b831..c916d01e 100644 --- a/platform/targets/MD-UV3x0/hwconfig.c +++ b/platform/targets/MD-UV3x0/hwconfig.c @@ -18,7 +18,54 @@ * along with this program; if not, see * ***************************************************************************/ +#include +#include #include +#include #include +/** + * SPI bitbang function for HR_C6000 command interface (U_SPI). + * + * Hand-tuned to be as fast as possible, gives the following clock performance + * when compiled with -Os and run on STM32F405 at 168MHz: + * + * - Freq 6.46MHz + * - Pos. width 71ns + * - Neg. with 83ns + */ +static uint8_t spiC6000_func(const void *priv, uint8_t value) +{ + (void) priv; + uint8_t incoming = 0; + + __disable_irq(); + + for(uint8_t cnt = 0; cnt < 8; cnt++) + { + GPIOE->BSRR = (1 << 3); // Set PE3 (CLK) + + if(value & (0x80 >> cnt)) + GPIOE->BSRR = 1 << 4; // Set PE4 (MOSI) + else + GPIOE->BSRR = 1 << 20; // Clear PE4 (MOSI) + + // ~70ns delay + asm volatile(" mov r1, #1 \n" + "___loop_1: cmp r1, #0 \n" + " itt ne \n" + " subne r1, r1, #1 \n" + " bne ___loop_1 \n":::"r1"); + + incoming <<= 1; + GPIOE->BSRR = (1 << 19); // Clear PE3 (CLK) + incoming |= (GPIOE->IDR >> 5) & 0x01; // Read PE5 (MISO) + } + + __enable_irq(); + + return incoming; +} + +SPI_CUSTOM_DEVICE_DEFINE(c6000_spi, spiC6000_func, NULL, NULL) SPI_STM32_DEVICE_DEFINE(nvm_spi, SPI1, NULL) diff --git a/platform/targets/MD-UV3x0/hwconfig.h b/platform/targets/MD-UV3x0/hwconfig.h index a3f7a707..d016fa57 100644 --- a/platform/targets/MD-UV3x0/hwconfig.h +++ b/platform/targets/MD-UV3x0/hwconfig.h @@ -24,9 +24,16 @@ #include "pinmap.h" #ifdef __cplusplus + +// Export the HR_C6000 driver only for C++ sources +#include + +extern HR_C6000 C6000; + extern "C" { #endif +extern const struct spiCustomDevice c6000_spi; extern const struct spiDevice nvm_spi; /* Device has a working real time clock */ diff --git a/platform/targets/MD-UV3x0/pinmap.h b/platform/targets/MD-UV3x0/pinmap.h index 7be31347..7940b8b8 100644 --- a/platform/targets/MD-UV3x0/pinmap.h +++ b/platform/targets/MD-UV3x0/pinmap.h @@ -108,7 +108,7 @@ /* HR_C6000 control interface */ #define DMR_SLEEP GPIOE,6 -#define DMR_CS GPIOE,2 +#define DMR_CS &GpioE,2 #define DMR_CLK GPIOE,3 #define DMR_MOSI GPIOE,4 #define DMR_MISO GPIOE,5