first commit

This commit is contained in:
2022-11-08 16:13:55 +01:00
commit f838fa66c4
2500 changed files with 2237507 additions and 0 deletions
@@ -0,0 +1,14 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_RF_MCHF_CONFIG_H
#define __UHSDR_RF_MCHF_CONFIG_H
#endif // __UHSDR_RF_MCHF_CONFIG_H
@@ -0,0 +1,15 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_RF_OVI40_CONFIG_H
#define __UHSDR_RF_OVI40_CONFIG_H
#endif // __UHSDR_RF_OVI40_CONFIG_H
@@ -0,0 +1,342 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_UI_MCHF_CONFIG_H
#define __UHSDR_UI_MCHF_CONFIG_H
#if defined(CORTEX_M4)
#include "stm32f4xx.h"
#include "core_cm4.h"
#else
#error McHF boards support only CORTEX_M4 MCU!
#endif
// place tagged elements in CCM 64k extra RAM (no DMA)
#define __MCHF_SPECIALMEM __attribute__ ((section (".ccm")))
// NOT USED ON F4 based mcHF boards (defined as "no-op")
// if used place tagged elements in an memory to peripheral DMA-able memory region
// with the correct cache strategy set
#define __UHSDR_DMAMEM
#ifndef TRX_NAME
#define TRX_NAME "mcHF QRP"
#endif // TRX_NAME
#ifndef TRX_ID
#define TRX_ID "mchf"
#endif // TRX_ID
#ifndef TRX_HW_LIC
#define TRX_HW_LIC "CC BY-NC-SA 3.0"
#define TRX_HW_CREATOR "K. Atanassov, M0NKA, www.m0nka.co.uk"
#endif
#define SI570_I2C (&hi2c1)
#define SI5351A_I2C (&hi2c1)
#define MCP_I2C (&hi2c1)
#define CODEC_I2C (&hi2c2)
#define CODEC_ANA_I2C (&hi2c2)
#define CODEC_IQ_I2C (&hi2c2)
#define CODEC_NUM (1)
#define SERIALEEPROM_I2C (&hi2c2)
// -----------------------------------------------------------------------------
// PORT PINS ALLOCATION
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// ---- PORT A ----
// -----------------------------------------------------------------------------
// pin 0
#define ENC_THREE_CH1 GPIO_PIN_0
#define ENC_THREE_CH1_PIO GPIOA
// pin 1
#define ENC_THREE_CH2 GPIO_PIN_1
#define ENC_THREE_CH2_PIO GPIOA
// pin 2
#define ADC3_FWD GPIO_PIN_2
#define ADC3_FWD_PIO GPIOA
// pin 3
#define ADC2_RET GPIO_PIN_3
#define ADC2_RET_PIO GPIOA
// pin 4
#ifdef MCHF_BOARD_0P5
#define TP_IRQ GPIO_PIN_14
#else
#define TP_IRQ GPIO_PIN_4
#endif
#define TP_IRQ_PIO GPIOA
#define DAC0 GPIO_PIN_4
#define DAC0_PIO GPIOA
// pin 5
//#define DAC1 GPIO_PIN_5
//#define DAC1_SOURCE GPIO_PinSource5
//#define DAC1_PIO GPIOA
// pin 6
#define ADC1_PWR GPIO_PIN_6
#define ADC1_PWR_PIO GPIOA
// pin 7
#define BAND0 GPIO_PIN_7
#define BAND0_PIO GPIOA
// pin 8
#define BAND1 GPIO_PIN_8
#define BAND1_PIO GPIOA
// pin 9
#define DEBUG_PRINT GPIO_PIN_9
#define DEBUG_PRINT_PIO GPIOA
#ifdef MCHF_BOARD_0P5
#define TP_CS GPIO_PIN_13
#else
#define TP_CS GPIO_PIN_9
#endif
#define TP_CS_PIO GPIOA
// pin 10
#define BAND2 GPIO_PIN_10
#define BAND2_PIO GPIOA
// pin 11
// USB DFU
//
// pin 12
// USB DFU
//
//
// pin 13
// SWDIO
// pin 14
// SWCLK
//
//
// pin 15
#define CODEC_I2S_WS GPIO_PIN_15
#define CODEC_I2S_WS_PIO GPIOA
//
// -----------------------------------------------------------------------------
// ---- PORT B ----
// -----------------------------------------------------------------------------
// pin 0
#define BUTTON_BNDM GPIO_PIN_0
#define BUTTON_BNDM_PIO GPIOB
// pin 1
#define TXRX_CNTR GPIO_PIN_1
#define TXRX_CNTR_PIO GPIOB
// pin 2
#define BUTTON_BNDP GPIO_PIN_2
#define BUTTON_BNDP_PIO GPIOB
// pin 3
#define BUTTON_M2 GPIO_PIN_3
#define BUTTON_M2_PIO GPIOB
// pin 4
#define ENC_ONE_CH1 GPIO_PIN_4
#define ENC_ONE_CH1_PIO GPIOB
// pin 5
#define ENC_ONE_CH2 GPIO_PIN_5
#define ENC_ONE_CH2_PIO GPIOB
// pin 6
#define I2C1_SCL_PIN GPIO_PIN_6
#define I2C1_SCL_GPIO GPIOB
// pin 7
#define I2C1_SDA_PIN GPIO_PIN_7
#define I2C1_SDA_GPIO GPIOB
// pin 8
#define BUTTON_G2 GPIO_PIN_8
#define BUTTON_G2_PIO GPIOB
// pin 9
#define GREEN_LED GPIO_PIN_9
#define GREEN_LED_PIO GPIOB
// pin 10
#define I2C2_SCL_PIN GPIO_PIN_10
#define I2C2_SCL_GPIO GPIOB
// pin 11
#define I2C2_SDA_PIN GPIO_PIN_11
#define I2C2_SDA_GPIO GPIOB
// pin 12
#define RED_LED GPIO_PIN_12
#define RED_LED_PIO GPIOB
// pin 13
#define LCD_SCK GPIO_PIN_13
#define LCD_SCK_PIO GPIOB
// pin 14
// USB HOST
//
// pin 15
// USB HOST
//
//
// -----------------------------------------------------------------------------
// ---- PORT C ----
// -----------------------------------------------------------------------------
// pin 0
#define BUTTON_G4 GPIO_PIN_0
#define BUTTON_G4_PIO GPIOC
// pin 1
#define BUTTON_M3 GPIO_PIN_1
#define BUTTON_M3_PIO GPIOC
// pin 2
#define LCD_MISO GPIO_PIN_2
#define LCD_MISO_PIO GPIOC
// pin 3
#define LCD_MOSI GPIO_PIN_3
#define LCD_MOSI_PIO GPIOC
// pin 4
#define BUTTON_STEPM GPIO_PIN_4
#define BUTTON_STEPM_PIO GPIOC
// pin 5
#define BUTTON_STEPP GPIO_PIN_5
#define BUTTON_STEPP_PIO GPIOC
// pin 6
#define FREQ_ENC_CH1 GPIO_PIN_6
#define FREQ_ENC_CH1_PIO GPIOC
// pin 7
#define FREQ_ENC_CH2 GPIO_PIN_7
#define FREQ_ENC_CH2_PIO GPIOC
// pin 8
#define POWER_DOWN GPIO_PIN_8
#define POWER_DOWN_PIO GPIOC
// pin 9
#define CODEC_CLOCK GPIO_PIN_9
#define CODEC_CLOCK_PIO GPIOC
// pin 10
#define CODEC_I2S_SCK GPIO_PIN_10
#define CODEC_I2S_SCK_PIO GPIOC
// pin 11
#define CODEC_I2S_SDI GPIO_PIN_11
#define CODEC_I2S_SDI_PIO GPIOC
// pin 12
#define CODEC_I2S_SDO GPIO_PIN_12
#define CODEC_I2S_SDO_PIO GPIOC
// pin 13
#define BUTTON_PWR GPIO_PIN_13
#define BUTTON_PWR_PIO GPIOC
// pin 14
#define BUTTON_M1 GPIO_PIN_14
#define BUTTON_M1_PIO GPIOC
// pin 15
#define BUTTON_F3 GPIO_PIN_15
#define BUTTON_F3_PIO GPIOC
#define BUTTON_M1_RTC GPIO_PIN_14
#define BUTTON_M1_PIO_RTC GPIOD
// pin 15
#define BUTTON_F3_RTC GPIO_PIN_15
#define BUTTON_F3_PIO_RTC GPIOD
//
// -----------------------------------------------------------------------------
// ---- PORT D ----
// -----------------------------------------------------------------------------
// pin 0
#define LCD_D2 GPIO_PIN_0
#define LCD_D2_PIO GPIOD
// pin 1
#define LCD_D3 GPIO_PIN_1
#define LCD_D3_PIO GPIOD
// pin 2
#define LCD_BACKLIGHT GPIO_PIN_2
#define LCD_BACKLIGHT_PIO GPIOD
// pin 3
#define LCD_RESET GPIO_PIN_3
#define LCD_RESET_PIO GPIOD
// pin 4
#define LCD_RD GPIO_PIN_4
#define LCD_RD_PIO GPIOD
// pin 5
#define LCD_WR GPIO_PIN_5
#define LCD_WR_PIO GPIOD
// pin 6
#define BUTTON_F1 GPIO_PIN_6
#define BUTTON_F1_PIO GPIOD
// pin 7
#define LCD_CSA GPIO_PIN_7
#define LCD_CSA_PIO GPIOD
// pin 8
#define LCD_D15 GPIO_PIN_8
#define LCD_D15_PIO GPIOD
// pin 9
#define LCD_D16 GPIO_PIN_9
#define LCD_D16_PIO GPIOD
// pin 10
#define LCD_D17 GPIO_PIN_10
#define LCD_D17_PIO GPIOD
// pin 11
#define LCD_RS GPIO_PIN_11
#define LCD_RS_PIO GPIOD
// pin 12
#define ENC_TWO_CH1 GPIO_PIN_12
#define ENC_TWO_CH1_PIO GPIOD
// pin 13
#define ENC_TWO_CH2 GPIO_PIN_13
#define ENC_TWO_CH2_PIO GPIOD
// pin 14
#define LCD_D0 GPIO_PIN_14
#define LCD_D0_PIO GPIOD
// pin 15
#define LCD_D1 GPIO_PIN_15
#define LCD_D1_PIO GPIOD
//
// -----------------------------------------------------------------------------
// ---- PORT E ----
// -----------------------------------------------------------------------------
// pin 0
#define PADDLE_DAH GPIO_PIN_0
#define PADDLE_DAH_PIO GPIOE
// pin 1
#define PADDLE_DIT GPIO_PIN_1
#define PADDLE_DIT_PIO GPIOE
// pin 2
#define BUTTON_F2 GPIO_PIN_2
#define BUTTON_F2_PIO GPIOE
// pin 3
#define BUTTON_F4 GPIO_PIN_3
#define BUTTON_F4_PIO GPIOE
// pin 4
#define BUTTON_G3 GPIO_PIN_4
#define BUTTON_G3_PIO GPIOE
// pin 5
#define BUTTON_F5 GPIO_PIN_5
#define BUTTON_F5_PIO GPIOE
// pin 6
#define BUTTON_G1 GPIO_PIN_6
#define BUTTON_G1_PIO GPIOE
// pin 7
#define LCD_D4 GPIO_PIN_7
#define LCD_D4_PIO GPIOE
// pin 8
#define LCD_D5 GPIO_PIN_8
#define LCD_D5_PIO GPIOE
// pin 9
#define LCD_D6 GPIO_PIN_9
#define LCD_D6_PIO GPIOE
// pin 10
#define LCD_D7 GPIO_PIN_10
#define LCD_D7_PIO GPIOE
// pin 11
#define LCD_D10 GPIO_PIN_11
#define LCD_D10_PIO GPIOE
// pin 12
#define LCD_D11 GPIO_PIN_12
#define LCD_D11_PIO GPIOE
// pin 13
#define LCD_D12 GPIO_PIN_13
#define LCD_D12_PIO GPIOE
// pin 14
#define LCD_D13 GPIO_PIN_14
#define LCD_D13_PIO GPIOE
// pin 15
#define LCD_D14 GPIO_PIN_15
#define LCD_D14_PIO GPIOE
#endif // __UHSDR_UI_MCHF_CONFIG_H
@@ -0,0 +1,435 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_UI_OVI40_CONFIG_H
#define __UHSDR_UI_OVI40_CONFIG_H
#if defined(CORTEX_M7)
#if defined(STM32H743xx)
#include "stm32h7xx.h"
#include "core_cm7.h"
#elif defined(STM32F767xx)
#include "stm32f7xx.h"
#include "core_cm7.h"
#else
#error Not supported CORTEX_M7 MCU specified.
#endif
#else
#error OVI40 boards support only CORTEX_M7 MCU!
#endif //CORTEX_M7
// NOT USED on OVI40 F7/H7 boards (defined as no-op)
// compiler places tagged elements by its default rules
#define __MCHF_SPECIALMEM
// place tagged elements in a memory to peripheral DMA-able memory region
// with the correct cache strategy set
#if defined(STM32H7)
#define __UHSDR_DMAMEM __attribute__ ((section (".dmamem")))
#else
#define __UHSDR_DMAMEM
#endif // STM32H7
#if defined(STM32H7)
#define hdac hdac1
#endif // STM32H7
#define USE_TWO_CHANNEL_AUDIO
#ifndef SDR_AMBER
#define USE_HMC1023
#endif
#if defined(STM32F7)
#ifndef TRX_NAME
#define TRX_NAME "OVI40 F7"
#endif
#ifndef TRX_ID
#define TRX_ID "40sdr"
#endif
#elif defined(STM32H7)
#ifndef TRX_NAME
#define TRX_NAME "OVI40 H7"
#endif
#ifndef TRX_ID
#define TRX_ID "ovi40"
#endif
#endif
#ifndef TRX_HW_LIC
// #define TRX_HW_LIC "???"
// #define TRX_HW_CREATOR "???"
#endif // TRX_HW_LIC
#define SI570_I2C (&hi2c1)
#define SI5351A_I2C (&hi2c1)
#define MCP_I2C (&hi2c1)
#define CODEC_ANA_I2C (&hi2c2)
#define CODEC_ANA_SAI SAI1
#define CODEC_IQ_I2C (&hi2c4)
#define CODEC_IQ_SAI SAI2
#define CODEC_NUM 2
#define SERIALEEPROM_I2C (&hi2c2)
// -----------------------------------------------------------------------------
// PORT PINS ALLOCATION
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// ---- PORT A ----
// -----------------------------------------------------------------------------
// pin 0
#define ENC_THREE_CH1 GPIO_PIN_0
#define ENC_THREE_CH1_PIO GPIOA
// pin 1
#define ENC_THREE_CH2 GPIO_PIN_1
#define ENC_THREE_CH2_PIO GPIOA
// pin 2
#define XADC3_FWD GPIO_PIN_2
#define XXADC3_FWD_PIO GPIOA
// pin 3
#define ADC2_RET GPIO_PIN_3
#define ADC2_RET_PIO GPIOA
// pin 4
#define DAC_CH1 GPIO_PIN_4
#define DAC_CH1_PIO GPIOA
// pin 5
#define DAC_CH2 GPIO_PIN_5
#define DAC_CH2_PIO GPIOA
// pin 6
#define ADC1_PWR GPIO_PIN_6
#define ADC1_PWR_PIO GPIOA
// pin 7
// pin 8
#define BAND1 GPIO_PIN_8
#define BAND1_PIO GPIOA
// pin 9
#define TP_CS GPIO_PIN_9
#define TP_CS_PIO GPIOA
// pin 10
#define BAND2 GPIO_PIN_10
#define BAND2_PIO GPIOA
// pin 11
// USB DFU
//
// pin 12
// USB DFU
//
//
// pin 13
// SWDIO
// pin 14
// SWCLK
//
//
// pin 15
#define BUTTON_F1 GPIO_PIN_15
#define BUTTON_F1_PIO GPIOA
//
// -----------------------------------------------------------------------------
// ---- PORT B ----
// -----------------------------------------------------------------------------
// pin 0
#define BUTTON_BNDM GPIO_PIN_0
#define BUTTON_BNDM_PIO GPIOB
// pin 1
#define TXRX_CNTR GPIO_PIN_1
#define TXRX_CNTR_PIO GPIOB
// pin 2
#define BUTTON_BNDP GPIO_PIN_2
#define BUTTON_BNDP_PIO GPIOB
// pin 3
#define BUTTON_M2 GPIO_PIN_3
#define BUTTON_M2_PIO GPIOB
// pin 4
#define ENC_ONE_CH1 GPIO_PIN_4
#define ENC_ONE_CH1_PIO GPIOB
// pin 5
#define ENC_ONE_CH2 GPIO_PIN_5
#define ENC_ONE_CH2_PIO GPIOB
// pin 6
#define I2C1_SCL_PIN GPIO_PIN_6
#define I2C1_SCL_GPIO GPIOB
// pin 7
#define I2C1_SDA_PIN GPIO_PIN_7
#define I2C1_SDA_GPIO GPIOB
// pin 8
#define BUTTON_G2 GPIO_PIN_8
#define BUTTON_G2_PIO GPIOB
// pin 9
#define GREEN_LED GPIO_PIN_9
#define GREEN_LED_PIO GPIOB
// pin 10
#define I2C2_SCL_PIN GPIO_PIN_10
#define I2C2_SCL_GPIO GPIOB
// pin 11
#define I2C2_SDA_PIN GPIO_PIN_11
#define I2C2_SDA_GPIO GPIOB
// pin 12
#define RED_LED GPIO_PIN_12
#define RED_LED_PIO GPIOB
// pin 13
#define LCD_SCK GPIO_PIN_13
#define LCD_SCK_PIO GPIOB
// pin 14
// USB HOST
//
// pin 15
// USB HOST
//
//
// -----------------------------------------------------------------------------
// ---- PORT C ----
// -----------------------------------------------------------------------------
// pin 0
#define XBUTTON_G4 GPIO_PIN_0
#define XBUTTON_G4_PIO GPIOC
// pin 1
#define BUTTON_M3 GPIO_PIN_1
#define BUTTON_M3_PIO GPIOC
// pin 2
#define LCD_MISO GPIO_PIN_2
#define LCD_MISO_PIO GPIOC
// pin 3
#define LCD_MOSI GPIO_PIN_3
#define LCD_MOSI_PIO GPIOC
// pin 4
#define BUTTON_STEPM GPIO_PIN_4
#define BUTTON_STEPM_PIO GPIOC
// pin 5
#define BUTTON_STEPP GPIO_PIN_5
#define BUTTON_STEPP_PIO GPIOC
// pin 6
#define FREQ_ENC_CH1 GPIO_PIN_6
#define FREQ_ENC_CH1_PIO GPIOC
// pin 7
#define FREQ_ENC_CH2 GPIO_PIN_7
#define FREQ_ENC_CH2_PIO GPIOC
// pin 8
#define POWER_DOWN GPIO_PIN_8
#define POWER_DOWN_PIO GPIOC
// pin 9
#define IQ_CLOCK_DIV4_SIG GPIO_PIN_9
#define IQ_CLOCK_DIV4_SIG_PIO GPIOC
// pin 10
#define CODEC_I2S_SCK GPIO_PIN_10
#define CODEC_I2S_SCK_PIO GPIOC
// pin 11
#define CODEC_I2S_SDI GPIO_PIN_11
#define CODEC_I2S_SDI_PIO GPIOC
// pin 12
#define CODEC_I2S_SDO GPIO_PIN_12
#define CODEC_I2S_SDO_PIO GPIOC
// pin 13
#define XBUTTON_PWR GPIO_PIN_13
#define XBUTTON_PWR_PIO GPIOC
// pin 14
#define XBUTTON_M1 GPIO_PIN_14
#define XBUTTON_M1_PIO GPIOC
// pin 15
#define XBUTTON_F3 GPIO_PIN_15
#define XBUTTON_F3_PIO GPIOC
// pin 15
//
// -----------------------------------------------------------------------------
// ---- PORT D ----
// -----------------------------------------------------------------------------
// pin 0
#define LCD_D2 GPIO_PIN_0
#define LCD_D2_PIO GPIOD
// pin 1
#define LCD_D3 GPIO_PIN_1
#define LCD_D3_PIO GPIOD
// pin 2
#define LCD_BACKLIGHT GPIO_PIN_2
#define LCD_BACKLIGHT_PIO GPIOD
// pin 3
#define LCD_RESET GPIO_PIN_3
#define LCD_RESET_PIO GPIOD
// pin 4
#define LCD_RD GPIO_PIN_4
#define LCD_RD_PIO GPIOD
// pin 5
#define LCD_WR GPIO_PIN_5
#define LCD_WR_PIO GPIOD
// pin 6
#define XBUTTON_F1 GPIO_PIN_6
#define XBUTTON_F1_PIO GPIOD
// pin 7
#define LCD_CSA GPIO_PIN_7
#define LCD_CSA_PIO GPIOD
// pin 8
#define LCD_D13 GPIO_PIN_8
#define LCD_D13_PIO GPIOD
// pin 9
#define LCD_D14 GPIO_PIN_9
#define LCD_D14_PIO GPIOD
// pin 10
#define LCD_D15 GPIO_PIN_10
#define LCD_D15_PIO GPIOD
// pin 11
//SAI INTERFACE: SAI2_SD_A
// pin 12
#define ENC_TWO_CH1 GPIO_PIN_12
#define ENC_TWO_CH1_PIO GPIOD
// pin 13
#define ENC_TWO_CH2 GPIO_PIN_13
#define ENC_TWO_CH2_PIO GPIOD
// pin 14
#define LCD_D0 GPIO_PIN_14
#define LCD_D0_PIO GPIOD
// pin 15
#define LCD_D1 GPIO_PIN_15
#define LCD_D1_PIO GPIOD
//
// -----------------------------------------------------------------------------
// ---- PORT E ----
// -----------------------------------------------------------------------------
// pin 0
#define PADDLE_DAH GPIO_PIN_0
#define PADDLE_DAH_PIO GPIOE
// pin 1
#define PADDLE_DIT GPIO_PIN_1
#define PADDLE_DIT_PIO GPIOE
// pin 2
#define BUTTON_F2 GPIO_PIN_2
#define BUTTON_F2_PIO GPIOE
// pin 3
#define BUTTON_F4 GPIO_PIN_3
#define BUTTON_F4_PIO GPIOE
// pin 4
#define BUTTON_G3 GPIO_PIN_4
#define BUTTON_G3_PIO GPIOE
// pin 5
#define BUTTON_F5 GPIO_PIN_5
#define BUTTON_F5_PIO GPIOE
// pin 6
#define XBUTTON_G1 GPIO_PIN_6
#define XBUTTON_G1_PIO GPIOE
// pin 7
#define LCD_D4 GPIO_PIN_7
#define LCD_D4_PIO GPIOE
// pin 8
#define LCD_D5 GPIO_PIN_8
#define LCD_D5_PIO GPIOE
// pin 9
#define LCD_D6 GPIO_PIN_9
#define LCD_D6_PIO GPIOE
// pin 10
#define LCD_D7 GPIO_PIN_10
#define LCD_D7_PIO GPIOE
// pin 11
#define LCD_D8 GPIO_PIN_11
#define LCD_D8_PIO GPIOE
// pin 12
#define LCD_D9 GPIO_PIN_12
#define LCD_D9_PIO GPIOE
// pin 13
#define LCD_D10 GPIO_PIN_13
#define LCD_D10_PIO GPIOE
// pin 14
#define LCD_D11 GPIO_PIN_14
#define LCD_D11_PIO GPIOE
// pin 15
#define LCD_D12 GPIO_PIN_15
#define LCD_D12_PIO GPIOE
// -----------------------------------------------------------------------------
// ---- PORT F ----
// -----------------------------------------------------------------------------
// pin 0
#define BUTTON_M1 GPIO_PIN_0
#define BUTTON_M1_PIO GPIOF
// pin 1
// pin 2
#define ADC3_FWD GPIO_PIN_3
#define ADC3_FWD_PIO GPIOF
// pin 3
// pin 4
// pin 5
#define BUTTON_E2 GPIO_PIN_5
#define BUTTON_E2_PIO GPIOF
// pin 6
// pin 7
// pin 8
// pin 9
// pin 10
#define BUTTON_E3 GPIO_PIN_10
#define BUTTON_E3_PIO GPIOF
// pin 11
#define BUTTON_S19 GPIO_PIN_11
#define BUTTON_S19_PIO GPIOF
// pin 12
#define BLUE_LED GPIO_PIN_12
#define BLUE_LED_PIO GPIOF
// pin 13
#define BUTTON_E1 GPIO_PIN_13
#define BUTTON_E1_PIO GPIOF
// pin 14
// pin 15
#define BUTTON_F3 GPIO_PIN_15
#define BUTTON_F3_PIO GPIOG
#define BUTTON_F3_RTC GPIO_PIN_15
#define BUTTON_F3_PIO_RTC GPIOG
// -----------------------------------------------------------------------------
// ---- PORT G ----
// -----------------------------------------------------------------------------
// pin 0
#define BAND0 GPIO_PIN_0
#define BAND0_PIO GPIOG
// pin 1
#define BAND3 GPIO_PIN_1
#define BAND3_PIO GPIOG
// pin 2
#define BUTTON_PWR GPIO_PIN_2
#define BUTTON_PWR_PIO GPIOG
// pin 3
#define LCD_RS GPIO_PIN_3
#define LCD_RS_PIO GPIOG
// pin 4
#define TP_IRQ GPIO_PIN_4
#define TP_IRQ_PIO GPIOG
// pin 5
#define AUDIO_PA_EN GPIO_PIN_5
#define AUDIO_PA_EN_PIO GPIOG
// pin 6
#define BUTTON_G1 GPIO_PIN_6
#define BUTTON_G1_PIO GPIOG
// pin 7
#define BUTTON_E4 GPIO_PIN_7
#define BUTTON_E4_PIO GPIOG
// pin 8
#define AUDIO_MIC_BIAS GPIO_PIN_8
#define AUDIO_MIC_BIAS_PIO GPIOG
// pin 9
// pin 10
// pin 11
#define BUTTON_G4 GPIO_PIN_11
#define BUTTON_G4_PIO GPIOG
// pin 12
// pin 13
// pin 14
// pin 15
// PORT H
// pin1
#define BUTTON_S18 GPIO_PIN_1
#define BUTTON_S18_PIO GPIOH
#endif // __UHSDR_UI_OVI40_CONFIG_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,294 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**--------------------------------------------------------------------------------**
** **
** Description: Please provide one **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_BOARD_CONFIG_H
#define __UHSDR_BOARD_CONFIG_H
#if defined(UI_BRD_MCHF) && defined(UI_BRD_OVI40)
#error Only one ui board can be selected: UI_BRD_MCHF, UI_BRD_OVI40
#elif defined(UI_BRD_OVI40)
#include "UHSDR_UI_ovi40_config.h"
#elif defined(UI_BRD_MCHF)
#include "UHSDR_UI_mchf_config.h"
#else
#error One ui board has to be selected: UI_BRD_MCHF, UI_BRD_OVI40
#endif
#if !defined(BOOTLOADER_BUILD)
// The rf boards we want to support, but the bootloader should compile for all if possible.
// so we don't tell the bootloader which one we have
#if !defined(RF_BRD_OVI40) && !defined(RF_BRD_MCHF) && !defined(RF_BRD_LAPWING)
#error At least one rf board must be selected: RF_BRD_MCHF, RF_BRD_OVI40, RF_BRD_LAPWING
#else
#if defined(RF_BRD_OVI40)
#include "UHSDR_RF_ovi40_config.h"
#endif
#if defined(RF_BRD_MCHF)
#include "UHSDR_RF_mchf_config.h"
#endif
#endif
#endif
#include "uhsdr_types.h"
//************DEFAULT_VALUES_IF_NOT_SET_IN_BOARD_CONFIG_FILES**********//
#if !defined(TRX_NAME)
#define TRX_NAME "mcHF QRP"
#endif //TRX_NAME
#if !defined(TRX_ID)
#define TRX_ID "mchf"
#endif // TRX_ID
#if !defined(TRX_HW_LIC)
#define TRX_HW_LIC "CC BY-NC-SA 3.0"
#define TRX_HW_CREATOR "K. Atanassov, M0NKA, www.m0nka.co.uk"
#endif // TRX_HW_LIC
#if !defined(__MCHF_SPECIALMEM)
#define __MCHF_SPECIALMEM
#endif
#if !defined(__UHSDR_DMAMEM)
#define __UHSDR_DMAMEM
#endif
#if !defined(DEVICE_STRING)
#define DEVICE_STRING TRX_NAME " Transceiver"
#endif
/***
* Please document all switches/parameters with what they are supposed to do and what values they can have.
* Please use proper naming:
* For capabilities of the software which can be enabled and disabled
* use USE_<CAPABILITY/FEATURENAME>
*
* These should be defined using #define USE_CAPABILITY
* or left undefined if not enabled so that these can be checked using #ifdef
*
* For related parameters DON'T USE USE_...
*
* In an ideal world please use PAR_<CAPABILITY/FEATURE>_<PARAMETERNAME> (we haven't done that yet)
* Please don't define constant or local parameters here, only those a user (!) is supposed to change as part of
* configuring a specific build variant.
*
*/
// Fast convolution filtering
// experimental at the moment DD4WH, 2018_08_18
//#define USE_CONVOLUTION
// old LMS noise reduction
// will probably never used any more
//#define OBSOLETE_NR
// this switches on the autonotch filter based on LMS algorithm
// leave this switched on, until we have a new autonotch filter approach
#define USE_LMS_AUTONOTCH
// save processor time for the STM32F4
// changes lowpass decimation filters to 89 taps instead of 199 taps
// because they run at 48ksps, this is a considerable decrease in processing power
#ifdef STM32F4
//#define USE_SMALL_HILBERT_DECIMATION_FILTERS
#endif
// save processor time for the STM32F4
// changes lowpass decimation filters to 89 taps instead of 199 taps
// because they run at 48ksps, this is a considerable decrease in processing power
// this is ONLY relevant for STM32F4 which has SPI !
// in those machines when enabling NR and other features, ui slows down . . .
// thus we should enable the small decimation filter in those machines
/**
* This parameter disables certain features / capabilites in order to achieve a minimum build size for
* the 192k ram / 512k flash STM32F4 machines. Unless you have such a machine, leave this disabled.
*/
//#define IS_SMALL_BUILD // ********************************** Small build (512k) Var. 1 (not good)
#define R928_PLUS // ********************************** For R928 ets with Si5351a alone synthesizer
//#define OPEN_TX_OUTBAND // Open TX out of band (by Menu option) - not in use now
//#define GREY_STYLE // ********************************** Monochrome display style
//#define SEPIA_STYLE // ********************************** Monochrome display style
//#define SDR_AMBER // ********************************** Russian replica from UB8JDC (SDR)
//#define SDR_AMBER_480_320 // ********************************** Display 480x320 (3.5")
//#define SDR_AMBER_4INCH // ********************************** Display 480x320 (4.0")
//#define SDR_AMBER_PTT_ALT // ********************************** Work CW with pedal is ON - Amber only for F7 and H7!!!
//#define DDC_AXIS // ********************************** Russian replica from UB8JDC (DDC/DUC)
//#define OVI40_DISP_320_240 // ********************************** UHSDR don't love displays 320*240 now. Why?
//#define OVI40_MOD_480_320 // ********************************** Interface like Amber 480x320
#define FAST_FREQ_ENC // ********************************** The freq encoder is polled more often than 10ms.
//#define HELP_MENU // ********************************** Show help for system menu - need a lot of RAM
#if !defined(IS_SMALL_BUILD)
#define USE_8bit_FONT
#define USE_PREDEFINED_WINDOW_DATA
// OPTION with IS_SMALL_BUILD we are not automatically including USE_FREEDV as it uses lot of memory, both RAM and flash
#define USE_FREEDV // ********************************** Small build (512k) Var. 2
#endif // IS_SMALL_BUILD
#ifdef SDR_AMBER
#define DAC_5MW 0
#define DAC_05W 208
#define DAC_1W 298
#define DAC_2W 438
#define DAC_4W 758
#define DAC_5W 2048
#endif
// some special switches
//#define DEBUG_BUILD
//#define DEBUG_FREEDV
// if enabled the alternate (read new and better) noise reduction is active
// this is the standard NR now (Febr 2018)
#define USE_ALTERNATE_NR
#define USE_LEAKY_LMS // Named in interface as ANR
// you may optionally define the list of supported GFX drivers externally
// if you just define EXTERNAL_USE_GFX_CONFIG and no USE_GFX_...
// you will get a headless system using a dummy display driver
#ifndef EXTERNAL_USE_GFX_CONFIG
#define USE_GFX_ILI932x
#define USE_GFX_ILI9486
#define USE_GFX_ST7796
// #define USE_GFX_ILI9341
// SSD1289 support is not yet working, also requires USE_GFX_ILI932x to be enabled for now.
// #define USE_GFX_SSD1289
#define USE_DISP_480_320
#if defined(STM32F7) || defined(STM32H7)
#define USE_GFX_RA8875
#endif
#endif
#define USE_FFT_1024
// OPTION
#define USE_RTTY_PROCESSOR
// OPTION
#define USE_USBHOST
#ifdef USE_USBHOST
// define additional USBHOST related "switches" only here!
// #define USE_USBDRIVE
#define USE_USBKEYBOARD
#endif
// use the STM32 internal RTC with an external quartz and
// M1 and F3 connected to PD14 and PD15 (D0 and D1 of LCD) instead of PC14 and PC15 (to which the 32768 Hz quartz has to be connected)
#define USE_RTC_LSE
// multiple oscillators may be enabled, but only the first detected oscillator is issued
// i.e. there is currently only support for a single oscillator in a TRX.
// Support for LO based on SI570
#define USE_OSC_SI570
// Support for LO based on SI5351
#define USE_OSC_SI5351A
// Support for DUC/DDC board
#define USE_OSC_DUCDDC
// OPTION TO USE FLASH BASED CONFIGURATION STORAGE
#define USE_CONFIGSTORAGE_FLASH
// Option: If defined, high priority tasks are executed in the context of an PendSV interrupt
// which gives finishing these tasks a priority over "normal", less real-time critical longer running user control tasks
// such as display redraw.
// In general this should be defined but in case of issues one may want to execute High Prio tasks not concurrently
// to normal tasks, comment this in this case and see if the issue goes away. But this may cause other problems
// of course.
#define USE_PENDSV_FOR_HIGHPRIO_TASKS
// OPTION: Enable handling of TX/RX switching in an interrupt. Provides very low latency switching
// EXPERIMENTAL !!!
#define USE_HIGH_PRIO_PTT
// OPTION: IQ signal path now use 24bit samples from/to the codecs instead of the default 16bit. Slightly increases RAM usage (+0.5 - 1k).
// will finally work both on single and dual codec configurations.
#define USE_32_IQ_BITS
#define USE_32_AUDIO_BITS
// OPTION: Instead of band names for memories and enabling only band memories which are supported
// by the current RF board, use all available memories
// this changes the displayed memory name to Mem<Num> instead of Bnd<Wavelength>
#ifdef RF_BRD_LAPWING
#define USE_MEMORY_MODE
#define DEFAULT_MEMORY_FREQ (1240000000)
#endif
// for now: These are fixed.
#define IQ_SAMPLE_RATE (48000)
#define AUDIO_SAMPLE_RATE (48000)
// a lot of code pieces assume that this frequency
// is 1500 Hz, so don't change
#define IQ_INTERRUPT_FREQ (1500)
// we process one dma block of samples at once
// block sizes should be a power of two
// a lot of code process information in these blocks
#define IQ_BLOCK_SIZE (IQ_SAMPLE_RATE/IQ_INTERRUPT_FREQ)
#define AUDIO_BLOCK_SIZE (AUDIO_SAMPLE_RATE/IQ_INTERRUPT_FREQ)
// use for clocking based on DMA IRQ
#define SAMPLES_PER_DMA_CYCLE (IQ_BLOCK_SIZE)
#define SAMPLES_PER_CENTISECOND (IQ_SAMPLE_RATE/100)
#ifdef STM32F4
#define USE_SIMPLE_FREEDV_FILTERS
#define USE_FREEDV_1600
#else
#define USE_FREEDV_700D
#endif
#if (IQ_SAMPLE_RATE) != 48000
#error Only 48k sample frequency supported (yet).
#endif
#if (IQ_BLOCK_SIZE * 1500) != IQ_SAMPLE_RATE
#error Audio Interrupt Frequency must be 1500.
#endif
#if (IQ_SAMPLE_RATE/IQ_BLOCK_SIZE) != (AUDIO_SAMPLE_RATE/AUDIO_BLOCK_SIZE)
#error IQ Interrupt frequency must be idential to Audio Interrupt Frequency
#endif
//******************************CONFIGURATION_LOGIC_CHECKS************************************//
//#if !defined(USE_OSC_SI570) && !defined(USE_OSC_SI5351A)
#if !defined(USE_OSC_SI570) && !defined(USE_OSC_SI5351A) && !defined(USE_OSC_DUCDDC)
#error At least one of supported oscillators should be enabled.
#endif
#if !defined(USE_PENDSV_FOR_HIGHPRIO_TASKS) && defined(USE_HIGH_PRIO_PTT)
#error USE_HIGH_PRIO_PTT requires USE_PENDSV_FOR_HIGHPRIO_TASKS
#endif
#if defined(USE_32_IQ_BITS) && CODEC_NUM == 1
#define USE_32_AUDIO_BITS
#endif
#if !defined(USE_GFX_ILI932x) && !defined(USE_GFX_ILI9486)
#warning Both USE_GFX_ILI932x and USE_GFX_ILI9486 are disabled, no display driver will be available!
#endif
#if defined(UI_BRD_MCHF) && defined(USE_TWO_CHANNEL_AUDIO)
#error UI_BRD_MCHF does not permit USE_TWO_CHANNEL_AUDIO
#endif
#if CODEC_NUM == 1 && (defined(USE_32_IQ_BITS) && !defined(USE_32_AUDIO_BITS)) || (!defined(USE_32_IQ_BITS) && defined(USE_32_AUDIO_BITS))
#error With only one codec bit width of iq and audio must match, either define both USE_32_IQ_BITS and USE_32_AUDIO_BITS or none
#endif
#endif
@@ -0,0 +1,303 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#include "uhsdr_board.h"
#include "uhsdr_hmc1023.h"
HMC1023_t hmc1023;
#ifdef USE_HMC1023
#define HMC1023_CS_PIN GPIO_PIN_9
#define HMC1023_CS_PORT GPIOG
#define hspiHmc1023 (hspi6)
#include <spi.h>
#define HMC1023_REG3_FINE_LIMIT (11)
#define HMC1023_REG2_OPAMP_LIMIT (3)
#define HMC1023_REG2_OPAMP_SHIFT (0)
#define HMC1023_REG2_OPAMP_MASK (0x03)
#define HMC1023_REG2_DRVR_LIMIT (3)
#define HMC1023_REG2_DRVR_SHIFT (2)
#define HMC1023_REG2_DRVR_MASK (0x03)
#define HMC1023_REG2_GAIN_LIMIT (1)
#define HMC1023_REG2_GAIN_SHIFT (4)
#define HMC1023_REG2_GAIN_MASK (0x01)
#define HMC1023_REG2_BYPASS_LIMIT (1)
#define HMC1023_REG2_BYPASS_SHIFT (5)
#define HMC1023_REG2_BYPASS_MASK (0x01)
#define HMC1023_REG2_COARSE_LIMIT (8)
#define HMC1023_REG2_COARSE_SHIFT (6)
#define HMC1023_REG2_COARSE_MASK (0x0f)
#define HMC1023_REG1_USE_SPI_SETTINGS (1 << 1)
#define HMC1023_REG1_FORCE_CAL_CODE (1 << 4)
/**
* Switch hardware SPI settings from tx to rx mode and vice versa. Also provides necessary delay between
* tx and rx.
* HMC1023LP5E needs phase == 1EDGE for transmit by STM and 2EDGE for RX sampling by STM. Who designs such an SPI protocol?
* @param is_tx true -> configure for tx mode, false -> for rx mode
*/
static void hmc1023_ll_spi_tx(bool is_tx)
{
hspiHmc1023.Init.CLKPhase = is_tx == true? SPI_PHASE_1EDGE : SPI_PHASE_2EDGE;
if (HAL_SPI_Init(&hspi6) != HAL_OK)
{
Error_Handler();
}
__HAL_SPI_ENABLE(&hspi6);
}
/**
* Control selection of HMC1023LP5E. Please note, output of SDO does not go tristate if deselected!
* @param on true -> chip is selected (HMC1023LP5E input EN == LOW), false -> not selected
*/
static void hmc1023_ll_cs(bool on)
{
if (on)
{
GPIO_ResetBits(HMC1023_CS_PORT,HMC1023_CS_PIN);
}
else
{
GPIO_SetBits(HMC1023_CS_PORT,HMC1023_CS_PIN);
}
}
/**
* Write register value into the HMC1023LP5E. It is not checked if the value was received correctly!
* @param regaddr which register to write to, not range checked!
* @param value 24 bit value
* @return HMC1023_ERROR if failed, HMC1023_OK otherwise.
*/
static uint32_t hmc1023_ll_write(uint32_t regaddr, uint32_t value)
{
uint8_t tx_data[4];
uint32_t retval = HMC1023_ERROR;
tx_data[0] = value >> 16;
tx_data[1] = value >> 8;
tx_data[2] = value;
tx_data[3] = 0x5 | (regaddr << 3); // chip id & register to write;
hmc1023_ll_cs(true);
if (HAL_SPI_Transmit(&hspi6,tx_data,4,100) == HAL_OK)
{
retval = HMC1023_OK;
}
hmc1023_ll_cs(false);
return retval;
}
/**
*
* @param regaddr which register to read, not range checked!
* @return 24 bit value in case of success, HMC1023_ERROR otherwise
*/
static uint32_t hmc1023_ll_read(uint32_t regaddr)
{
uint32_t retval = HMC1023_ERROR;
// write register address to read to register 0
if (hmc1023_ll_write(0,regaddr) == HAL_OK)
{
uint8_t tx_data[4] = { 0, 0, 0, 0};
uint8_t rx_data[4];
hmc1023_ll_spi_tx(false);
// reconfig through HAL should cause enough delay
hmc1023_ll_cs(true);
// now all tx_data is zero and we try to read using
// the rx spi config
if (HAL_SPI_TransmitReceive(&hspi6,tx_data,rx_data, 4,100) == HAL_OK)
{
if (( rx_data[3] & 0x07) == 5) // we found the correct "chip id"
{
retval = rx_data[0] << 16 | rx_data[1] << 8 | rx_data[2];
}
}
hmc1023_ll_cs(false);
hmc1023_ll_spi_tx(true);
}
return retval;
}
/**
*
* @return true if HMC1023LP5E was detected by reading the correct id
*/
static bool hmc1023_ll_presence(void)
{
uint32_t value = hmc1023_ll_read(0);
return (value == 0x114080);
}
/**
* Set bits in register 2
* @param bits actual bits to set (zero based, bits will be later shifted)
* @param limit maximum permitted value for bits (0...limit) is permitted range
* @param mask bit mask for bits (zero based, bits will be later shifted)
* @param shift position of mask (how many bits to shift left for final position)
*/
static void hmc1023_set_reg2_bits(uint8_t bits,uint8_t limit, uint32_t mask, uint8_t shift)
{
if (bits <= limit)
{
const uint32_t shifted_mask = (mask << shift);
const uint32_t shifted_bits = (bits << shift);
if ( (hmc1023.reg2 & shifted_mask) != shifted_bits)
{
MODIFY_REG(hmc1023.reg2,shifted_mask,shifted_bits);
hmc1023_ll_write(2,hmc1023.reg2);
}
}
}
/**
* Sets the coarse bandwidth from about 5 / 7 / 10 / 14 / 20 / 28 / 40 / 50 / 72
* Note +/-20% variation if not calibrated!
* @param coarse 0 - 8
*/
void hmc1023_set_coarse(uint8_t value)
{
hmc1023_set_reg2_bits(value,HMC1023_REG2_COARSE_LIMIT,HMC1023_REG2_COARSE_MASK, HMC1023_REG2_COARSE_SHIFT);
}
/**
* Control HMC1023LP5E opamp bias
* @param value: 0 - 3 (higher value, higher bias)
*/
void hmc1023_set_bias_opamp(uint8_t value)
{
hmc1023_set_reg2_bits(value,HMC1023_REG2_OPAMP_LIMIT,HMC1023_REG2_OPAMP_MASK, HMC1023_REG2_OPAMP_SHIFT);
}
/**
* Control HMC1023LP5E driver bias
* @param value: 0 - 3 (higher value, higher bias)
*/
void hmc1023_set_bias_drvr(uint8_t value)
{
hmc1023_set_reg2_bits(value,HMC1023_REG2_DRVR_LIMIT,HMC1023_REG2_DRVR_MASK, HMC1023_REG2_DRVR_SHIFT);
}
/**
* Sets the 10db amplifier on or off
* @param on true on / false off
*/
void hmc1023_set_gain(bool on)
{
hmc1023_set_reg2_bits(on?1:0,HMC1023_REG2_GAIN_LIMIT,HMC1023_REG2_GAIN_MASK, HMC1023_REG2_GAIN_SHIFT);
}
/**
* Sets the LPF bypass on or off
* @param on true on / false off
*/
void hmc1023_set_bypass(bool on)
{
hmc1023_set_reg2_bits(on?1:0,HMC1023_REG2_BYPASS_LIMIT,HMC1023_REG2_BYPASS_MASK, HMC1023_REG2_BYPASS_SHIFT);
}
/**
* adjusts the lpf bandwidth from about 0.803 to about 1.183 of the coarse frequency
* Note +/-20% variation if not calibrated!
* @param fine 0 - 11
*/
void hmc1023_set_fine(uint8_t fine)
{
if (fine < HMC1023_REG3_FINE_LIMIT)
{
if ( (hmc1023.reg3) != fine )
{
hmc1023.reg3 = fine;
hmc1023_ll_write(3,hmc1023.reg3);
}
}
}
/**
* use HMC1023LP5E register settings for coarse and fine LPF bandwidth control
* please note that this enables both coarse and fine bandwidth from SPI, this is incompatible with
* automatic calibration as discussed in data sheet.
* @param on true -> use bandwidth settings in reg2/reg3, false -> use internal defaults
*/
void hmc1023_use_spi_settings(bool on)
{
const uint32_t target_bits = on == true ? (HMC1023_REG1_USE_SPI_SETTINGS | HMC1023_REG1_FORCE_CAL_CODE) : 0;
const uint32_t target_mask = (HMC1023_REG1_USE_SPI_SETTINGS | HMC1023_REG1_FORCE_CAL_CODE);
if ((hmc1023.reg1 & target_mask) != target_bits)
{
MODIFY_REG(hmc1023.reg1, target_mask, target_bits);
hmc1023_ll_write(1,hmc1023.reg1);
}
}
/**
* Configures SPI bus 6 AND CS GPIO PG9 to detect and control an HMC1023LP5E LPF
* presence of an LPF is return via hmc1023.present
* Does not return hardware configuration to original state, even if LPF is not detected!
*/
void hmc1023_init()
{
// TODO: Move to HAL Config
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(HMC1023_CS_PORT, HMC1023_CS_PIN, GPIO_PIN_SET);
GPIO_InitTypeDef GPIO_InitStruct;
/*Configure GPIO pins : PFPin PFPin PFPin */
GPIO_InitStruct.Pin = HMC1023_CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(HMC1023_CS_PORT, &GPIO_InitStruct);
// setup SPI with correct data
hspiHmc1023.Init.Mode = SPI_MODE_MASTER;
hspiHmc1023.Init.Direction = SPI_DIRECTION_2LINES;
hspiHmc1023.Init.DataSize = SPI_DATASIZE_8BIT;
hspiHmc1023.Init.CLKPolarity = SPI_POLARITY_LOW;
hspiHmc1023.Init.CLKPhase = SPI_PHASE_1EDGE;
hspiHmc1023.Init.NSS = SPI_NSS_SOFT;
hspiHmc1023.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspiHmc1023.Init.FirstBit = SPI_FIRSTBIT_MSB;
hmc1023_ll_spi_tx(true);
// make sure we are in right config for TX,
// which is assumed by the read/write code
hmc1023.present = hmc1023_ll_presence();
if (hmc1023.present)
{
hmc1023.reg1 = hmc1023_ll_read(1);
hmc1023.reg2 = hmc1023_ll_read(2);
hmc1023.reg2 = hmc1023_ll_read(3);
hmc1023_use_spi_settings(true);
hmc1023_set_bias_opamp(1);
hmc1023_set_bias_opamp(0);
}
}
#endif // UI_BRD_OVI40
@@ -0,0 +1,52 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_HMC1023_H
#define __UHSDR_HMC1023_H
#include "uhsdr_board.h"
#define HMC1023_OK (HAL_OK)
#define HMC1023_ERROR (0xffffffff)
typedef struct
{
bool present;
#ifdef USE_HMC1023
uint32_t reg1;
uint32_t reg2;
uint32_t reg3;
// we use these to track the configration settings
uint8_t coarse;
uint8_t fine;
uint8_t opamp;
uint8_t drvr;
bool gain;
bool bypass;
#endif
} HMC1023_t;
extern HMC1023_t hmc1023;
#ifdef USE_HMC1023
void hmc1023_init(void);
void hmc1023_use_spi_settings();
void hmc1023_set_coarse(uint8_t coarse);
void hmc1023_set_fine(uint8_t fine);
void hmc1023_set_gain(bool on);
void hmc1023_set_bypass(bool on);
void hmc1023_set_bias_opamp(uint8_t value);
void hmc1023_set_bias_drvr(uint8_t value);
#endif
#endif
@@ -0,0 +1,84 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** File name: **
** Description: **
** Last Modified: **
** Licence: GNU GPLv3 **
************************************************************************************/
// Common
#include "uhsdr_board.h"
#include "uhsdr_hw_i2c.h"
#include "i2c.h"
uint16_t UhsdrHw_I2C_DeviceReady(I2C_HandleTypeDef* hi2c, uchar I2CAddr)
{
return HAL_I2C_IsDeviceReady(hi2c, I2CAddr,100,100);
}
uint16_t UhsdrHw_I2C_WriteRegister(I2C_HandleTypeDef* hi2c, uchar I2CAddr,uint16_t addr,uint16_t addr_size, uchar RegisterValue)
{
HAL_StatusTypeDef i2cRet = HAL_I2C_Mem_Write(hi2c,I2CAddr,addr,addr_size,&RegisterValue,1,100);
return i2cRet != HAL_OK?0xFF00:0;
}
uint16_t UhsdrHw_I2C_WriteBlock(I2C_HandleTypeDef* hi2c, uchar I2CAddr, uint16_t addr, uint16_t addr_size, const uint8_t* data, uint32_t size)
{
HAL_StatusTypeDef i2cRet = HAL_I2C_Mem_Write(hi2c,I2CAddr,addr,addr_size,(uint8_t*)data,size,100);
return i2cRet != HAL_OK?0xFF00:0;
}
uint16_t UhsdrHw_I2C_ReadRegister(I2C_HandleTypeDef* hi2c, uchar I2CAddr, uint16_t addr, uint16_t addr_size, uint8_t *RegisterValue)
{
HAL_StatusTypeDef i2cRet = HAL_I2C_Mem_Read(hi2c,I2CAddr,addr,addr_size,RegisterValue,1,100);
return i2cRet != HAL_OK?0xFF00:0;
}
uint16_t UhsdrHw_I2C_ReadBlock(I2C_HandleTypeDef* hi2c, uchar I2CAddr,uint16_t addr, uint16_t addr_size, uint8_t *data, uint32_t size)
{
HAL_StatusTypeDef i2cRet = HAL_I2C_Mem_Read(hi2c,I2CAddr,addr,addr_size,data,size,100);
return i2cRet != HAL_OK?0xFF00:0;
}
#ifdef STM32F4
/**
* @brief init I2C
* @param speed in Hertz !!!
*/
void UhsdrHw_I2C_ChangeSpeed(I2C_HandleTypeDef* hi2c)
{
/// FIXME: Support for more than I2C1 und I2C2
uint8_t speedIdx;
if (hi2c->Instance == I2C1)
{
speedIdx = I2C_BUS_1;
}
else
{
speedIdx = I2C_BUS_2;
}
HAL_I2C_DeInit(hi2c);
// FIXME: F7PORT: I2C Clock Timing works differently on the F7, we need to supply correct register values instead of a simple speed value
hi2c->Init.ClockSpeed = ts.i2c_speed[speedIdx] * I2C_BUS_SPEED_MULT;
HAL_I2C_Init(hi2c);
}
#endif
@@ -0,0 +1,65 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** File name: **
** Description: **
** Last Modified: **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __MCHF_HW_I2C_H
#define __MCHF_HW_I2C_H
#include "i2c.h"
#define I2C_BUS_SPEED_MULT 20000 // 20kHz is multiplier for config var
#define I2C1_SPEED_DEFAULT (100000/I2C_BUS_SPEED_MULT) // 20 * 20kHz == 200kHz 400000 does not work, may need resistor mod (now reduced to 100KHz)
#define I2C2_SPEED_DEFAULT (100000/I2C_BUS_SPEED_MULT) // 10 * 20kHz == 100kHz, was 25000, 400000 does not work, , may need resistor mod
// Generic Functions for Handling I2C Busses in MCHF
uint16_t UhsdrHw_I2C_WriteRegister(I2C_HandleTypeDef* i2c, uchar I2CAddr,uint16_t addr,uint16_t addr_size, uchar RegisterValue);
uint16_t UhsdrHw_I2C_WriteBlock(I2C_HandleTypeDef* i2c, uchar I2CAddr, uint16_t addr, uint16_t addr_size, const uint8_t* data, uint32_t size);
uint16_t UhsdrHw_I2C_ReadRegister(I2C_HandleTypeDef* i2c, uchar I2CAddr, uint16_t addr, uint16_t addr_size, uint8_t *RegisterValue);
uint16_t UhsdrHw_I2C_ReadBlock(I2C_HandleTypeDef* i2c, uchar I2CAddr,uint16_t addr, uint16_t addr_size, uint8_t *data, uint32_t size);
uint16_t UhsdrHw_I2C_DeviceReady(I2C_HandleTypeDef* hi2c, uchar I2CAddr);
#ifdef STM32F4
// Special init and wrapper functions for I2C Bus 1
void UhsdrHw_I2C_ChangeSpeed(I2C_HandleTypeDef* hi2c);
#endif
// Flags do not really need a timeout according to my testing.
#define MCHF_I2C_FLAG_TIMEOUT ((uint32_t)1)
// Event timeout according to testing is depending on the actual speed of the bus
// 200 kHz Bus -> 100 would be sufficient
// 100 kHz Bus -> 200, 50kHz -> 400, 25kHz -> 800
// other place I saw 20000 used as timeout
#define MCHF_I2C_LONG_TIMEOUT ((uint32_t)1000)
// extern uint32_t i2c_flag_timeout_max; // lower values, higher timeout!
extern uint32_t i2c_event_timeout_max; // lower values, higher timeout!
#define I2C_FlagStatusOrReturn(BUS, FLAG, RETURN) { \
uint32_t timeout = MCHF_I2C_FLAG_TIMEOUT;\
while(I2C_GetFlagStatus((BUS), (FLAG)))\
{ if ((timeout--) == 0) { return (RETURN); } } \
/* if (timeout < i2c_flag_timeout_max){ i2c_flag_timeout_max = timeout; }*/ \
}
#define I2C_EventCompleteOrReturn(BUS,EVENT, RETURN) { \
uint32_t timeout = MCHF_I2C_LONG_TIMEOUT;\
while(!I2C_CheckEvent((BUS), (EVENT)))\
{ if ((timeout--) == 0) { return (RETURN); } } \
if (timeout < i2c_event_timeout_max){ i2c_event_timeout_max = timeout; } }
#endif
@@ -0,0 +1,251 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#include <assert.h>
#include "uhsdr_board_config.h"
#include "uhsdr_keypad.h"
#include "gpio.h"
// Key map structure
// represents a physical key which can be pressed (via GPIO)
typedef struct
{
GPIO_TypeDef* keyPort;
uint16_t keyPin;
uint16_t button_id;
const char* label;
} Keypad_KeyPhys_t;
// represents a logical button
typedef struct
{
uint16_t button_id;
const char* label;
} UhsdrButtonLogical_t;
typedef struct
{
const Keypad_KeyPhys_t* map;
uint32_t num;
} UhsdrHwKey_t;
const Keypad_KeyPhys_t* bm_set_normal;
#ifdef UI_BRD_MCHF
const Keypad_KeyPhys_t* bm_set_rtc;
#endif
// -------------------------------------------------------
// Constant declaration of the buttons map across ports
// - update if moving buttons around !!!
// the order in this array is not relevant for functional aspects
const Keypad_KeyPhys_t bm_set_normal_arr[] =
{
{BUTTON_M2_PIO, BUTTON_M2, BUTTON_M2_PRESSED, "S3"},
{BUTTON_G3_PIO, BUTTON_G3, BUTTON_G3_PRESSED, "S2"},
{BUTTON_G2_PIO, BUTTON_G2, BUTTON_G2_PRESSED, "S1"},
{BUTTON_BNDM_PIO, BUTTON_BNDM, BUTTON_BNDM_PRESSED, "S4"},
{BUTTON_G4_PIO, BUTTON_G4, BUTTON_G4_PRESSED, "S5"},
{BUTTON_M3_PIO, BUTTON_M3, BUTTON_M3_PRESSED, "S6"},
{BUTTON_STEPM_PIO, BUTTON_STEPM, BUTTON_STEPM_PRESSED, "S7"},
{BUTTON_STEPP_PIO, BUTTON_STEPP, BUTTON_STEPP_PRESSED, "S8"},
{BUTTON_M1_PIO, BUTTON_M1, BUTTON_M1_PRESSED, "S9"},
{BUTTON_F3_PIO, BUTTON_F3, BUTTON_F3_PRESSED, "S10"},
{BUTTON_F1_PIO, BUTTON_F1, BUTTON_F1_PRESSED, "S11"},
{BUTTON_F2_PIO, BUTTON_F2, BUTTON_F2_PRESSED, "S12"},
{BUTTON_F4_PIO, BUTTON_F4, BUTTON_F4_PRESSED, "S13"},
{BUTTON_BNDP_PIO, BUTTON_BNDP, BUTTON_BNDP_PRESSED, "S14"},
{BUTTON_F5_PIO, BUTTON_F5, BUTTON_F5_PRESSED, "S15"},
{BUTTON_G1_PIO, BUTTON_G1, BUTTON_G1_PRESSED, "S16"},
{BUTTON_PWR_PIO, BUTTON_PWR, BUTTON_PWR_PRESSED, "S17"},
{TP_IRQ_PIO, TP_IRQ, TOUCHSCREEN_ACTIVE, "TPIRQ"},
#ifdef UI_BRD_OVI40
{BUTTON_E1_PIO, BUTTON_E1, BUTTON_E1_PRESSED, "E1"},
{BUTTON_E2_PIO, BUTTON_E2, BUTTON_E2_PRESSED, "E2"},
{BUTTON_E3_PIO, BUTTON_E3, BUTTON_E3_PRESSED, "E3"},
{BUTTON_E4_PIO, BUTTON_E4, BUTTON_E4_PRESSED, "E4"},
{BUTTON_S18_PIO, BUTTON_S18, BUTTON_L1_PRESSED, "S18"},
{BUTTON_S19_PIO, BUTTON_S19, BUTTON_F6_PRESSED, "S19"},
#endif
// this must be the last entry
{NULL, 0, 0, NULL}
};
const Keypad_KeyPhys_t* bm_set_normal = &bm_set_normal_arr[0];
#ifdef UI_BRD_MCHF
const Keypad_KeyPhys_t bm_set_rtc_arr[] =
{
// alternative mapping for RTC Modification
{BUTTON_M2_PIO, BUTTON_M2, BUTTON_M2_PRESSED, "S3"},
{BUTTON_G3_PIO, BUTTON_G3, BUTTON_G3_PRESSED, "S2"},
{BUTTON_G2_PIO, BUTTON_G2, BUTTON_G2_PRESSED, "S1"},
{BUTTON_BNDM_PIO, BUTTON_BNDM, BUTTON_BNDM_PRESSED, "S4"},
{BUTTON_G4_PIO, BUTTON_G4, BUTTON_G4_PRESSED, "S5"},
{BUTTON_M3_PIO, BUTTON_M3, BUTTON_M3_PRESSED, "S6"},
{BUTTON_STEPM_PIO, BUTTON_STEPM, BUTTON_STEPM_PRESSED, "S7"},
{BUTTON_STEPP_PIO, BUTTON_STEPP, BUTTON_STEPP_PRESSED, "S8"},
{BUTTON_M1_PIO_RTC, BUTTON_M1_RTC, BUTTON_M1_PRESSED, "S9"},
{BUTTON_F3_PIO_RTC, BUTTON_F3_RTC, BUTTON_F3_PRESSED, "S10"},
{BUTTON_F1_PIO, BUTTON_F1, BUTTON_F1_PRESSED, "S11"},
{BUTTON_F2_PIO, BUTTON_F2, BUTTON_F2_PRESSED, "S12"},
{BUTTON_F4_PIO, BUTTON_F4, BUTTON_F4_PRESSED, "S13"},
{BUTTON_BNDP_PIO, BUTTON_BNDP, BUTTON_BNDP_PRESSED, "S14"},
{BUTTON_F5_PIO, BUTTON_F5, BUTTON_F5_PRESSED, "S15"},
{BUTTON_G1_PIO, BUTTON_G1, BUTTON_G1_PRESSED, "S16"},
{BUTTON_PWR_PIO, BUTTON_PWR, BUTTON_PWR_PRESSED, "S17"},
{TP_IRQ_PIO, TP_IRQ, TOUCHSCREEN_ACTIVE, "TPIRQ"},
// this must be the last entry
{NULL, 0, 0, NULL},
};
const Keypad_KeyPhys_t* bm_set_rtc = &bm_set_rtc_arr[0];
#endif
// all supported logical buttons
// the order in this list must be identical to the order
// in the enum
const UhsdrButtonLogical_t buttons[BUTTON_NUM] =
{
{BUTTON_M2_PRESSED, "M2"}, // 0 / S3
{BUTTON_G3_PRESSED, "G3"}, // 1 / S2
{BUTTON_G2_PRESSED, "G2"}, // 2 / S1
{BUTTON_BNDM_PRESSED, "Band-"}, // 3 / S4
{BUTTON_G4_PRESSED, "G4"}, // 4 / S5
{BUTTON_M3_PRESSED, "M3"}, // 5 / S6
{BUTTON_STEPM_PRESSED, "Step-"}, // 6 / S7
{BUTTON_STEPP_PRESSED, "Step+"}, // 7 / S8
{BUTTON_M1_PRESSED, "M1"}, // 8 / S9
{BUTTON_F3_PRESSED, "F3"}, // 9 / S10
{BUTTON_F1_PRESSED, "F1"}, // 10 / S11
{BUTTON_F2_PRESSED, "F2"}, // 11 / S12
{BUTTON_F4_PRESSED, "F4"}, // 12 / S13
{BUTTON_BNDP_PRESSED, "Band+"}, // 13 / S14
{BUTTON_F5_PRESSED, "F5"}, // 14 / S15
{BUTTON_G1_PRESSED, "G1"}, // 15 / S16
{BUTTON_PWR_PRESSED, "Power"}, // 16 / S17 Power Button
{TOUCHSCREEN_ACTIVE, "Touch"}, // 17 TP "Button"
#ifdef UI_BRD_OVI40
{BUTTON_E1_PRESSED, "E1" },
{BUTTON_E2_PRESSED, "E2" },
{BUTTON_E3_PRESSED, "E3" },
{BUTTON_E4_PRESSED, "E4" },
#ifndef SDR_AMBER
{BUTTON_L1_PRESSED, "L1" },
{BUTTON_F6_PRESSED, "F6" },
#else // Too lazy to correct the topology of the Amber-UI board (there is an error in the OVI40-UI schematic diagram).
{BUTTON_L1_PRESSED, "F6" },
{BUTTON_F6_PRESSED, "PTT_Alt" },
#endif
#endif
};
// the initial button map is the default one
UhsdrHwKey_t hwKeys = { .map = &bm_set_normal_arr[0], .num = 0 };
// FIXME? Do we change state of these in IRQ? Maybe more save mark them as volatile?
uint32_t buttonStates; // logical buttons
uint32_t keyStates; // hw scan keys
#ifdef UI_BRD_MCHF
// this function invoked only on the UI_MCHF_BRD with RTC as they have different buttons layout
inline void Keypad_SetLayoutRTC_MCHF()
{
hwKeys.map = &bm_set_rtc[0];
}
#endif
bool Keypad_IsButtonPressed(uint32_t button_num)
{
return ((1 << button_num) & buttonStates) != 0;
}
bool Keypad_IsAnyButtonPressed()
{
return buttonStates != 0;
}
bool Keypad_IsKeyPressed(uint32_t key_num)
{
return ((1 << key_num) & keyStates) != 0;
}
bool Keypad_IsAnyKeyPressed()
{
return keyStates != 0;
}
uint32_t Keypad_KeyStates()
{
return keyStates;
}
uint32_t Keypad_ButtonStates()
{
return buttonStates;
}
/*
* @brief keypad hardware initialization based on the given keyMap
*
*/
void Keypad_KeypadInit()
{
UhsdrHwKey_t* keyMap = &hwKeys;
GPIO_InitTypeDef GPIO_InitStructure;
// Common init
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pull = GPIO_PULLUP;
// Init all hw gpio from public struct declaration
for(keyMap->num = 0; keyMap->map[keyMap->num].keyPort != NULL; keyMap->num++)
{
GPIO_InitStructure.Pin = keyMap->map[keyMap->num].keyPin;
HAL_GPIO_Init(keyMap->map[keyMap->num].keyPort, &GPIO_InitStructure);
}
}
/*
* @brief Keypad direct HW access reading returning if a key is pressed (or not)
*/
static bool Keypad_GetKeyGPIOState(const Keypad_KeyPhys_t* key)
{
return HAL_GPIO_ReadPin(key->keyPort, key->keyPin) == 0;
}
/*
* We scan all known physical buttons and map them to the logical button states
* has to be called before processing key presses.
*/
void Keypad_Scan()
{
for (uint32_t key_num = 0; key_num < hwKeys.num; key_num++)
{
if (Keypad_GetKeyGPIOState(&hwKeys.map[key_num]))
{
// in normal mode - return key value
SET_BIT( buttonStates, ( 1 << hwKeys.map[key_num].button_id ));
SET_BIT( keyStates, ( 1 << key_num ));
}
else
{
CLEAR_BIT( buttonStates, ( 1 << hwKeys.map[key_num].button_id ));
CLEAR_BIT( keyStates, ( 1 << key_num ));
}
}
}
inline const char* Keypad_GetLabelOfButton( uint32_t id_button )
{
assert( id_button < sizeof( buttons ) / sizeof( UhsdrButtonLogical_t ));
return buttons[ id_button ].label;
}
@@ -0,0 +1,66 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** UHSDR **
** a powerful firmware for STM32 based SDR transceivers **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __UHSDR_KEYPAD_H
#define __UHSDR_KEYPAD_H
// Logical Button definitions
enum
{
BUTTON_M2_PRESSED = 0, // 0
BUTTON_G3_PRESSED, // 1
BUTTON_G2_PRESSED, // 2
BUTTON_BNDM_PRESSED, // 3
BUTTON_G4_PRESSED, // 4
BUTTON_M3_PRESSED, // 5
BUTTON_STEPM_PRESSED, // 6
BUTTON_STEPP_PRESSED, // 7
BUTTON_M1_PRESSED, // 8
BUTTON_F3_PRESSED, // 9 - Press and release handled in UiDriverProcessFunctionKeyClick()
BUTTON_F1_PRESSED, // 10 - Press and release handled in UiDriverProcessFunctionKeyClick()
BUTTON_F2_PRESSED, // 11 - Press and release handled in UiDriverProcessFunctionKeyClick()
BUTTON_F4_PRESSED, // 12 - Press and release handled in UiDriverProcessFunctionKeyClick()
BUTTON_BNDP_PRESSED, // 13
BUTTON_F5_PRESSED, // 14 - Press and release handled in UiDriverProcessFunctionKeyClick()
BUTTON_G1_PRESSED, // 15
BUTTON_PWR_PRESSED, // 16 - Used for press and release
TOUCHSCREEN_ACTIVE, // 17 - Touchscreen touched, needs to last entry before BUTTON_NUM,
#ifdef UI_BRD_OVI40
BUTTON_E1_PRESSED, // encoder 1 click
BUTTON_E2_PRESSED, // encoder 2 click
BUTTON_E3_PRESSED, // encoder 3 click
BUTTON_E4_PRESSED, // encoder 4 click
BUTTON_L1_PRESSED, // one more button
BUTTON_F6_PRESSED, // one more function button
#endif
// init code relies on this
BUTTON_NUM, // How many buttons we have defined
BUTTON_NOP // used for buttons with no function
};
void Keypad_KeypadInit(void);
#ifdef UI_BRD_MCHF
// this function invoked only on the MCHF with RTC as they have different buttons layout
void Keypad_SetLayoutRTC_MCHF(void);
#endif
bool Keypad_IsButtonPressed( uint32_t button_num );
bool Keypad_IsAnyButtonPressed(void);
bool Keypad_IsKeyPressed( uint32_t key_num );
bool Keypad_IsAnyKeyPressed(void);
void Keypad_Scan(void);
uint32_t Keypad_KeyStates(void);
uint32_t Keypad_ButtonStates(void);
const char* Keypad_GetLabelOfButton( uint32_t id_button );
#endif
@@ -0,0 +1,63 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** File name: **
** Description: **
** Last Modified: **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __MCHF_MCU_H
#define __MCHF_MCU_H
#include "uhsdr_board_config.h"
typedef enum {
CPU_NONE = 0,
CPU_STM32F4 = 1,
CPU_STM32F7 = 2,
CPU_STM32H7 = 3,
} mchf_cpu_t;
inline mchf_cpu_t MchfHW_Cpu(void)
{
mchf_cpu_t retval = CPU_NONE;
#if defined(STM32F4)
retval = CPU_STM32F4;
#elif defined(STM32F7)
retval = CPU_STM32F7;
#elif defined(STM32H7)
retval = CPU_STM32H7;
#endif
return retval;
}
#define STM32_GetRevision() (*(uint16_t *) (UID_BASE + 2))
#define STM32_GetSignature() ((*(uint16_t *) (DBGMCU_BASE)) & 0x0FFF)
#define STM32_UUID ((uint32_t *)UID_BASE)
#if defined(STM32F4) || defined(STM32F7)
#define STM32_GetFlashSize() (*(uint16_t *) (FLASHSIZE_BASE))
#elif defined(STM32H7)
#define STM32_GetFlashSize() (FLASH_SIZE/1024)
#define FLASHSIZE_BASE 0x1FF1E880
#define SRAM2_BASE 0x38000000
#endif
#if defined(STM32H7)
#define GPIO_SetBits(PORT,PINS) { (PORT)->BSRRL = (PINS); }
#define GPIO_ResetBits(PORT,PINS) { (PORT)->BSRRH = (PINS); }
#elif defined(STM32F7) || defined(STM32F4)
#define GPIO_SetBits(PORT,PINS) { (PORT)->BSRR = (PINS); }
#define GPIO_ResetBits(PORT,PINS) { (PORT)->BSRR = (PINS) << 16U; }
#endif
#define GPIO_ToggleBits(PORT,PINS) { (PORT)->ODR ^= (PINS); }
#define GPIO_ReadInputDataBit(PORT,PINS) { ((PORT)->IDR = (PINS); }
#endif
@@ -0,0 +1,254 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#include "uhsdr_board.h"
#include "uhsdr_rtc.h"
#ifdef STM32F4
#include "stm32f4xx_hal_rtc.h"
#include "stm32f4xx_hal_rtc_ex.h"
#include "stm32f4xx_hal_rcc.h"
#elif defined(STM32H7)
#include "stm32h7xx_hal_rtc.h"
#include "stm32h7xx_hal_rtc_ex.h"
#include "stm32h7xx_hal_rcc.h"
#elif defined(STM32F7)
#include "stm32f7xx_hal_rtc.h"
#include "stm32f7xx_hal_rtc_ex.h"
#include "stm32f7xx_hal_rcc.h"
#endif
#include "rtc.h"
/* Private macros */
/* Internal status registers for RTC */
#define RTC_PRESENCE_REG RTC_BKP_DR1
// previously we used DR0 which is also used by the HAL Layer, so we move to DR1
#define RTC_PRESENCE_INIT_VAL 0x0001 // if we find this value after power on, we assume battery is available
#define RTC_PRESENCE_OK_VAL 0x0002 // then we set this value to rembember a clock is present
//#define RTC_PRESENCE_ACK_VAL 0x0003 // if we find this value after power on, we assume user enabled RTC
//#define RTC_PRESENCE_NACK_VAL 0x0004 // if we find this value after power on, we assume user decided against using RTC
#ifdef USE_RTC_LSE
static void RTC_LSE_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
__HAL_RCC_RTC_ENABLE();
HAL_RTCEx_BKUPWrite(&hrtc,RTC_PRESENCE_REG,RTC_PRESENCE_OK_VAL);
}
void Rtc_FullReset() {
__HAL_RCC_BACKUPRESET_FORCE();
}
#if 0
static void RTC_LSI_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
__HAL_RCC_RTC_ENABLE();
HAL_RTCEx_BKUPWrite(&hrtc,RTC_PRESENCE_REG,RTC_PRESENCE_OK_VAL);
}
#endif
static void Rtc_StartInternal(bool doClock)
{
if (doClock)
{
// ok, there is a battery, so let us now start the oscillator
RTC_LSE_Config();
}
// very first start of rtc
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_RTC_Init(&hrtc);
}
void Rtc_Start()
{
Rtc_StartInternal(true);
}
#endif
bool Rtc_isEnabled()
{
bool retval = false;
#ifdef USE_RTC_LSE
// FIXME: H7 Port
#ifndef STM32H7
__HAL_RCC_PWR_CLK_ENABLE();
#else
__HAL_RCC_RTC_CLK_ENABLE();
#endif
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_RTC_ENABLE();
if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
{
// we detected most likely a running RTC or a system capable of running an RTC since the external oscillator is running;
retval = true;
}
switch(HAL_RTCEx_BKUPRead(&hrtc,RTC_PRESENCE_REG))
{
case 0:
// 0 -> cleared backup ram -> no battery or reset
// if we find the RTC_PRESENCE_INIT_VAL in the backup register next time we boot
// we know there is a battery present.
HAL_RTCEx_BKUPWrite(&hrtc,RTC_PRESENCE_REG,RTC_PRESENCE_INIT_VAL);
break;
case RTC_PRESENCE_OK_VAL:
retval = true;
ts.vbat_present = true;
break;
case RTC_PRESENCE_INIT_VAL:
ts.vbat_present = true;
break;
default:
// TODO: Anything else is a problem, since who wrote a different value? Not this code!
break;
}
#endif
return retval;
}
bool Rtc_SetPpm(int16_t ppm)
{
bool retval = false;
if (ppm >= RTC_CALIB_PPM_MIN && ppm <= RTC_CALIB_PPM_MAX)
{
uint32_t calm;
uint32_t calp;
float64_t ppm2pulses = rint((float64_t)ppm * 1.048576); // = (32 * 32768) / 1000.0000
if (ppm2pulses <= 0.0) // important, we must make sure to not set calp if 0ppm
{
calm = - ppm2pulses;
calp = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
}
else
{
calm = 512 - ppm2pulses;
if (calm > 512)
{
calm = 0;
}
calp = RTC_SMOOTHCALIB_PLUSPULSES_SET;
}
HAL_RTCEx_SetSmoothCalib(&hrtc,RTC_SMOOTHCALIB_PERIOD_32SEC,calp,calm);
retval = true;
}
return retval;
}
/**
* @brief Gets RTC current time. THIS A replacement for the not working HAL_RTC_GetTime() function/
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param sTime: Pointer to Time structure
* @param Format: Specifies the format of the entered parameters.
* This parameter can be one of the following values:
* @arg RTC_FORMAT_BIN: Binary data format
* @arg RTC_FORMAT_BCD: BCD data format
* @note You cannot use SubSeconds etc since these are not read due to an apparent bug in some STM32F407 silicon.
* On my STM32F407 reading the SSR will for sure stop the RTC shadow registers and cause also other troubles.
* Probably different hardware does not have this problem but we don't need subseconds anyway.
* @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values
* in the higher-order calendar shadow registers to ensure consistency between the time and date values.
* Reading RTC current time locks the values in calendar shadow registers until current date is read.
* @retval HAL status
*/
// we need this to keep the compiler happy and keep the read of the DR
static volatile uint32_t dr_dummy ;
void Rtc_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
{
uint32_t tmpreg = 0U;
/* Check the parameters */
assert_param(IS_RTC_FORMAT(Format));
/* Get subseconds structure field from the corresponding register */
// See above:
sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR);
//sTime->SubSeconds = 0;
/* Get SecondFraction structure field from the corresponding register field*/
sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S);
// sTime->SecondFraction = 0;
/* Get the TR register */
tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);
dr_dummy = (uint32_t)hrtc->Instance->DR;
/* Fill the structure fields with the read parameters */
sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16U);
sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8U);
sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16U);
/* Check the input parameters format */
if(Format == RTC_FORMAT_BIN)
{
/* Convert the time structure parameters to Binary format */
sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours);
sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes);
sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds);
}
}
@@ -0,0 +1,27 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef HARDWARE_MCHF_RTC_H_
#define HARDWARE_MCHF_RTC_H_
#define RTC_CALIB_PPM_MAX 488
#define RTC_CALIB_PPM_MIN -487
#define RTC_CALIB_PPM_DEFAULT 0
#include "rtc.h"
bool Rtc_isEnabled(void);
void Rtc_FullReset(void);
void Rtc_Start(void);
bool Rtc_SetPpm(int16_t ppm);
void Rtc_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
#endif /* HARDWARE_MCHF_RTC_H_ */
@@ -0,0 +1,63 @@
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
/************************************************************************************
** **
** mcHF QRP Transceiver **
** K Atanassov - M0NKA 2014 **
** **
**---------------------------------------------------------------------------------**
** **
** File name: **
** Description: **
** Last Modified: **
** Licence: GNU GPLv3 **
************************************************************************************/
#ifndef __MCHF_TYPES_H
#define __MCHF_TYPES_H
#include <stdint.h>
#include "arm_math.h"
// defines float32_t
#ifndef uchar
typedef unsigned char uchar;
#endif
#ifndef ushort
typedef unsigned short ushort;
#endif
#ifndef uint
typedef unsigned int uint;
#endif
#ifndef ulong
typedef unsigned long ulong;
#endif
#ifndef bool
typedef int bool;
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
typedef struct {
float32_t i;
float32_t q;
} iq_float_t;
typedef enum {
IQ_TRANS_OFF = 0,
IQ_TRANS_ON,
IQ_TRANS_NUM
} iq_trans_idx_t;
#endif