first commit
This commit is contained in:
@@ -0,0 +1,481 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include "dma.h"
|
||||
#include "spi.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#include "uhsdr_board.h"
|
||||
#include "flash_if.h"
|
||||
#include "uhsdr_boot_hw.h"
|
||||
#include "command.h"
|
||||
#include "fatfs.h"
|
||||
#include "usb_host.h"
|
||||
#include "bootloader_main.h"
|
||||
#include "ui_lcd_hy28.h"
|
||||
|
||||
|
||||
FATFS USBDISKFatFs; /* File system object for USB disk logical drive */
|
||||
FIL MyFile; /* File object */
|
||||
char USBDISKPath[4]; /* USB Host logical drive path */
|
||||
|
||||
bool boot_failed;
|
||||
static FIL fileR;
|
||||
extern USBH_HandleTypeDef hUsbHostHS;
|
||||
static uint8_t Bootloader_USBConnected(void)
|
||||
{
|
||||
return hUsbHostHS.device.is_connected;
|
||||
}
|
||||
|
||||
|
||||
static const char* bl_help[] =
|
||||
{
|
||||
TRX_NAME " Bootloader",
|
||||
"Firmware Name: " BASE_FILE,
|
||||
"USB Drive Mode",
|
||||
// "Release Band- to skip firmware update",
|
||||
"Release Band- to skip fw/config update",
|
||||
"",
|
||||
"DFU Update Mode",
|
||||
"Keep Power pressed until finish.",
|
||||
"Release Band+ to start DFU Mode.",
|
||||
"Screen may go white. This is ok.",
|
||||
"PC should recognize new USB device.",
|
||||
};
|
||||
|
||||
|
||||
static void Bootloader_DisplayInit(void)
|
||||
{
|
||||
MX_DMA_Init();
|
||||
MX_SPI2_Init();
|
||||
MX_GPIO_Init();
|
||||
|
||||
// we need to set the touch screen CS signal to high, otherwise SPI displays
|
||||
// will not be detectable
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pin = TP_CS;
|
||||
|
||||
HAL_GPIO_Init(TP_CS_PIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(TP_CS_PIO, TP_CS);
|
||||
|
||||
UiLcdHy28_Init();
|
||||
UiLcdHy28_LcdClear(Black);
|
||||
mchfBl_PinOn(BACKLIGHT);
|
||||
|
||||
}
|
||||
|
||||
// bin rw: 0 1 2 3 4
|
||||
// dfu 0 1 5 4 6 7 8 9
|
||||
|
||||
static void Bootloader_InfoScreen(void)
|
||||
{
|
||||
Bootloader_DisplayInit();
|
||||
Bootloader_PrintLine(bl_help[0]);
|
||||
Bootloader_PrintLine(bl_help[1]);
|
||||
Bootloader_PrintLine(bl_help[2]);
|
||||
Bootloader_PrintLine(bl_help[4]);
|
||||
Bootloader_PrintLine(bl_help[3]);
|
||||
Bootloader_PrintLine(bl_help[4]);
|
||||
}
|
||||
|
||||
static void Bootloader_InfoScreenDFU(void)
|
||||
{
|
||||
Bootloader_DisplayInit();
|
||||
Bootloader_PrintLine(bl_help[0]);
|
||||
Bootloader_PrintLine(bl_help[1]);
|
||||
Bootloader_PrintLine(bl_help[5]);
|
||||
Bootloader_PrintLine(bl_help[4]);
|
||||
Bootloader_PrintLine(bl_help[6]);
|
||||
Bootloader_PrintLine(bl_help[7]);
|
||||
Bootloader_PrintLine(bl_help[8]);
|
||||
Bootloader_PrintLine(bl_help[9]);
|
||||
}
|
||||
|
||||
static void Bootloader_UsbHost_Idle(void)
|
||||
{
|
||||
static bool power_was_up = false;
|
||||
static uint32_t tick;
|
||||
uint32_t now = HAL_GetTick();
|
||||
|
||||
if (now >= tick)
|
||||
{
|
||||
mchfBl_PinToggle(LEDGREEN);
|
||||
tick = now + 1024;
|
||||
}
|
||||
if(mchfBl_ButtonGetState(BUTTON_POWER) == 0)
|
||||
{
|
||||
// we only switch off, if power button was at least once seen as being released and pressed in the idle loop
|
||||
if (power_was_up == true)
|
||||
{
|
||||
mcHF_PowerOff();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay, power button is not pressed currently
|
||||
power_was_up = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int Bootloader_UsbMSCDevice_Application(void)
|
||||
{
|
||||
|
||||
Bootloader_PowerHoldOn(); // make sure we have uninterrupted power
|
||||
|
||||
Bootloader_PrintLine("USB Drive detected.");
|
||||
/* Register the file system object to the FatFs module */
|
||||
if(f_mount(&USBDISKFatFs, (TCHAR const*)USBDISKPath, 0) != FR_OK)
|
||||
{
|
||||
/* FatFs Initialization Error */
|
||||
FlashFail_Handler(BL_ERR_USBPROBLEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just before we start, we check the BANDM button.
|
||||
// If still pressed, we will also flash the memory afer reading it
|
||||
__IO uint32_t was_download = (mchfBl_ButtonGetState(BUTTON_BANDM) == 0);
|
||||
/* Reads all flash memory */
|
||||
if(was_download)
|
||||
{
|
||||
// Bootloader_PrintLine("Firmware will be updated...");
|
||||
Bootloader_PrintLine("Firmware/config will be updated...");
|
||||
}
|
||||
Bootloader_PrintLine("Saving Flash to \"" UPLOAD_FILE "\"...");
|
||||
COMMAND_UPLOAD();
|
||||
|
||||
Bootloader_PrintLine("Saving Flash to \"" UPLOAD_FILE_CONF "\"...");
|
||||
COMMAND_UPLOAD_CONF();
|
||||
|
||||
/* Check if BAND- Button was pressed */
|
||||
if (was_download)
|
||||
{
|
||||
/* Writes Flash memory */
|
||||
// Bootloader_PrintLine("Updating firmware using \"" DOWNLOAD_FILE "\"...");
|
||||
// COMMAND_DOWNLOAD();
|
||||
bool FilesAreHere = false;
|
||||
if (f_open(&fileR, DOWNLOAD_FILENAME, FA_READ) == FR_OK)
|
||||
{
|
||||
f_close (&fileR);
|
||||
FilesAreHere = true;
|
||||
Bootloader_PrintLine("Updating firmware using \"" DOWNLOAD_FILE "\"...");
|
||||
COMMAND_DOWNLOAD();
|
||||
}
|
||||
if (f_open(&fileR, DOWNLOAD_FILENAME_CONF, FA_READ) == FR_OK)
|
||||
{
|
||||
f_close (&fileR);
|
||||
FilesAreHere = true;
|
||||
Bootloader_PrintLine("Updating config using \"" DOWNLOAD_FILE_CONF "\"...");
|
||||
COMMAND_DOWNLOAD_CONF();
|
||||
}
|
||||
if(FilesAreHere == false)
|
||||
{
|
||||
Bootloader_PrintLine("No files for update.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bootloader_PrintLine("Skipping firmware update.");
|
||||
Bootloader_PrintLine("Skipping firmware/conf update.");
|
||||
}
|
||||
|
||||
Bootloader_PrintLine("");
|
||||
Bootloader_PrintLine("Finished.");
|
||||
Bootloader_PrintLine("");
|
||||
Bootloader_PrintLine("Remove drive or press Band- to reboot.");
|
||||
Bootloader_PrintLine("Press Power to switch off.");
|
||||
|
||||
// if we don't have a display, turn off backlight
|
||||
if (mchf_display.DeviceCode == 0x0000)
|
||||
{
|
||||
mchfBl_PinOff(BACKLIGHT);
|
||||
}
|
||||
|
||||
/* Waiting User Button Released */
|
||||
while ((mchfBl_ButtonGetState(BUTTON_BANDM) == 0))
|
||||
{}
|
||||
|
||||
/* Waiting User Button Pressed or usb drive removed. If drive is removed, we go straight to reboot */
|
||||
while ((mchfBl_ButtonGetState(BUTTON_BANDM) == 1) && Bootloader_USBConnected() != 0)
|
||||
{
|
||||
/* switch off if power button is pressed */
|
||||
if(mchfBl_ButtonGetState(BUTTON_POWER) == 0)
|
||||
{
|
||||
mcHF_PowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
/* Waiting User Button Released or usb drive removed. If drive is removed, we go straight to reboot */
|
||||
while ((mchfBl_ButtonGetState(BUTTON_BANDM) == 0) && Bootloader_USBConnected() != 0)
|
||||
{}
|
||||
|
||||
/* Jumps to user application code located in the internal Flash memory */
|
||||
COMMAND_ResetMCU(BOOT_REBOOT);
|
||||
}
|
||||
|
||||
// this below is a trick to get sbrk() linked in at the right time so that
|
||||
// we don't get a link error
|
||||
sbrk(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void BSP_Init(void)
|
||||
{
|
||||
// we assume that the clock for all required GPIO Ports has been turn on!!
|
||||
|
||||
/* Initialize LEDs and User_Button on mchf --------------------*/
|
||||
mchfBl_ButtonInit(BUTTON_BANDM, BUTTON_MODE_GPIO);
|
||||
mchfBl_ButtonInit(BUTTON_POWER, BUTTON_MODE_GPIO);
|
||||
mchfBl_ButtonInit(BUTTON_BANDP, BUTTON_MODE_GPIO);
|
||||
|
||||
mchfBl_LEDInit(LEDGREEN);
|
||||
mchfBl_LEDInit(LEDRED);
|
||||
mchfBl_LEDInit(PWR_HOLD);
|
||||
mchfBl_LEDInit(BACKLIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief jump to a STM32 Application by giving the start address of the ISR Vector structure of that application
|
||||
*/
|
||||
|
||||
// __attribute__ ( ( naked ) )
|
||||
extern const uint32_t* _linker_ram_start; // we get this from the linker script
|
||||
static const uint32_t linker_ram_start_addr = (uint32_t)&_linker_ram_start;
|
||||
|
||||
/**
|
||||
* We check whether the supplied address is pointing to a valid vector table
|
||||
* Checks are simple (right now we just look if the stack pointer points in the region of RAM)
|
||||
*
|
||||
* @param ApplicationAddress an 32 bit value pointing to the start of a vector table
|
||||
* @return true we should try to use this address
|
||||
*/
|
||||
bool uhsdrBl_IsValidApplication(uint32_t ApplicationAddress)
|
||||
{
|
||||
// TODO: Better checks
|
||||
// check if the stackpointer points into a likely ram area (normal RAM start + 1MB)
|
||||
uint32_t* const APPLICATION_PTR = (uint32_t*)ApplicationAddress;
|
||||
return APPLICATION_PTR[0] <= (linker_ram_start_addr + (1024 * 1024)) && ( APPLICATION_PTR[0] >= linker_ram_start_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Jumps to new code using a reset vector,
|
||||
* brings processor into the default state (almost like in reset state, except for peripherals and their clocks)
|
||||
* set stackpointer and then jumps to the specific address. This function normally never returns unless
|
||||
* the IsValidApplication check fails.
|
||||
*
|
||||
* @param ApplicationAddress the start address of the reset vector (not the start of the code itself!)
|
||||
*/
|
||||
void UhsdrBl_JumpToApplication(uint32_t ApplicationAddress)
|
||||
{
|
||||
|
||||
if (uhsdrBl_IsValidApplication(ApplicationAddress))
|
||||
{
|
||||
uint32_t* const APPLICATION_PTR = (uint32_t*)ApplicationAddress;
|
||||
|
||||
// disable all interrupts
|
||||
__disable_irq();
|
||||
|
||||
// disable systick irq
|
||||
HAL_SuspendTick();
|
||||
|
||||
// set clocks to default state
|
||||
HAL_RCC_DeInit();
|
||||
|
||||
// clear Interrupt Enable Register & Interrupt Pending Register
|
||||
const size_t icer_count = sizeof(NVIC->ICER)/sizeof(NVIC->ICER[0]);
|
||||
|
||||
for (size_t i = 0; i <icer_count; i++)
|
||||
{
|
||||
NVIC->ICER[i]=0xFFFFFFFF;
|
||||
NVIC->ICPR[i]=0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// enable all interrupts
|
||||
__enable_irq();
|
||||
|
||||
__set_MSP(APPLICATION_PTR[0]);
|
||||
/* Jump to user application */
|
||||
((pFunction) APPLICATION_PTR[1])();
|
||||
}
|
||||
}
|
||||
|
||||
int Bootloader_Main()
|
||||
{
|
||||
double i,border;
|
||||
/* prevention of erratical boot loop */
|
||||
if( *(__IO uint32_t*)(SRAM2_BASE) != BOOT_REBOOT)
|
||||
{
|
||||
border = 300000; // long delay if firmware was not running before or at powerdown
|
||||
}
|
||||
else
|
||||
{
|
||||
border = 10; // short delay if reboot is requested
|
||||
}
|
||||
for (i = 0; i < border; i++)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// #ifdef SBLA
|
||||
// *(uint32_t*)(SRAM2_BASE+5) = 0x29; // signature for DF8OE development features
|
||||
// #endif
|
||||
// #ifdef SBLS
|
||||
// *(uint32_t*)(SRAM2_BASE+10) = 0x29; // signature for special beta-testing features
|
||||
// #endif
|
||||
|
||||
/* initialization */
|
||||
BSP_Init();
|
||||
|
||||
//#if 0
|
||||
// mcHF_PowerHoldOff();
|
||||
//
|
||||
//
|
||||
// if( *(uint32_t*)(SRAM2_BASE) != 0x55) // no reboot requested?
|
||||
// {
|
||||
// // we wait for a longer time
|
||||
// HAL_Delay(300);
|
||||
// }
|
||||
//#else
|
||||
//#endif
|
||||
Bootloader_PowerHoldOn();
|
||||
HAL_Delay(50);
|
||||
|
||||
if (boot_failed == true)
|
||||
{
|
||||
BootFail_Handler(3);
|
||||
}
|
||||
else if (mchfBl_ButtonGetState(BUTTON_BANDP) == 0)
|
||||
{
|
||||
Bootloader_InfoScreenDFU();
|
||||
// BANDP pressed, DFU boot requested
|
||||
while (mchfBl_ButtonGetState(BUTTON_BANDP) == 0) {};
|
||||
COMMAND_ResetMCU(BOOT_DFU);
|
||||
}
|
||||
/* Test if BAND- button on mchf is NOT pressed */
|
||||
else if (mchfBl_ButtonGetState(BUTTON_BANDM) == 1)
|
||||
{
|
||||
/* Check Vector Table: Test if user code is programmed starting from address
|
||||
"APPLICATION_ADDRESS"
|
||||
We do that be reading the stack pointer value stored at APPLICATION_ADDRESS
|
||||
and roughly check if it points to a RAM SPACE address
|
||||
*/
|
||||
// we go through restart here to have all interrupts turned off and everything as
|
||||
// pristine as it gets after reset, avoids issues with enabled interrupts etc.
|
||||
// we had that and it is pain to debug, see #1610 in GitHub!
|
||||
if (uhsdrBl_IsValidApplication(APPLICATION_ADDRESS))
|
||||
{
|
||||
UhsdrBl_JumpToApplication(APPLICATION_ADDRESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
BootFail_Handler(2);
|
||||
}
|
||||
// never reached, is endless loop
|
||||
}
|
||||
|
||||
/* Init upgrade mode display */
|
||||
Bootloader_InfoScreen();
|
||||
mchfBl_PinOn(BACKLIGHT);
|
||||
// now give user a chance to let go off the BAND- button
|
||||
HAL_Delay(3000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern ApplicationTypeDef Appli_state;
|
||||
|
||||
void Bootloader_UsbHostApplication()
|
||||
{
|
||||
switch(Appli_state)
|
||||
{
|
||||
case APPLICATION_READY:
|
||||
Bootloader_UsbMSCDevice_Application();
|
||||
Appli_state = APPLICATION_IDLE;
|
||||
break;
|
||||
case APPLICATION_DISCONNECT:
|
||||
f_mount(NULL, (TCHAR const*)"", 0);
|
||||
Appli_state = APPLICATION_IDLE;
|
||||
break;
|
||||
case APPLICATION_IDLE:
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
Bootloader_UsbHost_Idle();
|
||||
}
|
||||
|
||||
/*
|
||||
* This does not work if data cache is enabled, since we then need to flush the SRAM2_BASE write
|
||||
* but here flash should not be enabled anyway!
|
||||
*/
|
||||
void Bootloader_CheckAndGoForBootTarget()
|
||||
{
|
||||
|
||||
if(*(uint32_t*)(SRAM2_BASE) == BOOT_DFU)
|
||||
{
|
||||
*(uint32_t*)(SRAM2_BASE) = BOOT_CLEARED;
|
||||
#if defined(STM32F4)
|
||||
__HAL_REMAPMEMORY_SYSTEMFLASH();
|
||||
|
||||
const uint32_t dfu_boot_start = 0x00000000;
|
||||
#elif defined(STM32F7)
|
||||
const uint32_t dfu_boot_start = 0x1FF00000;
|
||||
// if in dual boot mode (which is required for proper operation
|
||||
// we need to fix the setup
|
||||
#if defined (FLASH_OPTCR_nDBANK)
|
||||
if ((FLASH->OPTCR & (FLASH_OPTCR_nDBANK_Msk|FLASH_OPTCR_nDBOOT_Msk)) != FLASH_OPTCR_nDBOOT)
|
||||
{
|
||||
if (HAL_FLASH_OB_Unlock() == HAL_OK)
|
||||
{
|
||||
FLASH->OPTCR |= FLASH_OPTCR_nDBOOT; // set == disable dual boot
|
||||
FLASH->OPTCR &= ~FLASH_OPTCR_nDBANK; // unset == enabled dual bank mode
|
||||
HAL_FLASH_OB_Launch();
|
||||
HAL_FLASH_OB_Lock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#elif defined(STM32H7)
|
||||
const uint32_t dfu_boot_start = 0x1FF09800;
|
||||
#endif
|
||||
UhsdrBl_JumpToApplication(dfu_boot_start);
|
||||
// start the STM32Fxxx bootloader at address dfu_boot_start;
|
||||
}
|
||||
|
||||
if(*(uint32_t*)(SRAM2_BASE) == BOOT_FIRMWARE)
|
||||
{
|
||||
*(uint32_t*)(SRAM2_BASE) = BOOT_CLEARED;
|
||||
UhsdrBl_JumpToApplication(APPLICATION_ADDRESS);
|
||||
// start the STM32Fxxx bootloader at address dfu_boot_start;
|
||||
boot_failed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "uhsdr_board_config.h"
|
||||
|
||||
static uint8_t current_line;
|
||||
|
||||
void Bootloader_PrintLine(const char* txt)
|
||||
{
|
||||
UiLcdHy28_PrintText(4,4+current_line*16,txt,Yellow,Black,0);
|
||||
current_line++;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _BOOTLOADER_MAIN_H
|
||||
#define _BOOTLOADER_MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void Bootloader_UsbHostApplication(void);
|
||||
int Bootloader_Main(void);
|
||||
void Bootloader_CheckAndGoForBootTarget(void);
|
||||
void Bootloader_PrintLine(const char* txt);
|
||||
|
||||
enum
|
||||
{
|
||||
BOOT_CLEARED = 0,
|
||||
BOOT_REBOOT = 0x55, // this command can be issue also by the firmware indicate immediate start
|
||||
BOOT_DFU = 0x99,
|
||||
BOOT_FIRMWARE = 0x66993300,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BOOTLOADER_MAIN */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,394 @@
|
||||
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 28-October-2011
|
||||
* @brief This file provides all the IAP command functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "command.h"
|
||||
#include "uhsdr_mcu.h"
|
||||
#include "fatfs.h"
|
||||
#include "uhsdr_boot_hw.h"
|
||||
#include "bootloader_main.h"
|
||||
#include "ui_lcd_hy28.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
#define BUFFER_SIZE ((uint16_t)512*64)
|
||||
|
||||
// 64k flash are in use for bootloader and config memory
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static uint8_t RAM_Buf[BUFFER_SIZE] __attribute__ ((aligned (4)));
|
||||
|
||||
static FIL file;
|
||||
static FIL fileR;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
void Wait(int time)
|
||||
{
|
||||
HAL_Delay(time);
|
||||
// we show the error message until user presses power...
|
||||
if(mchfBl_ButtonGetState(BUTTON_POWER) == 0)
|
||||
{
|
||||
mcHF_PowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
static const char* error_help[] =
|
||||
{
|
||||
"No error",
|
||||
"USB problem",
|
||||
DOWNLOAD_FILE " not found",
|
||||
"Flash memory too small",
|
||||
"Problem writing " UPLOAD_FILE,
|
||||
"Problem reading" DOWNLOAD_FILE,
|
||||
"Flash programming problem",
|
||||
"Flash erase problem",
|
||||
"Flash write protected",
|
||||
};
|
||||
|
||||
// USB error handling
|
||||
void FlashFail_Handler(mchf_bootloader_error_t redCount)
|
||||
{
|
||||
mchfBl_PinOff(LEDGREEN);
|
||||
mchfBl_PinOff(LEDRED);
|
||||
|
||||
char txt[16] = "Error Code X";
|
||||
txt[12] = redCount + '0';
|
||||
|
||||
Bootloader_PrintLine("");
|
||||
Bootloader_PrintLine(txt);
|
||||
Bootloader_PrintLine(error_help[redCount]);
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (mchf_display.DeviceCode == 0x0000)
|
||||
{
|
||||
mchfBl_PinOff(BACKLIGHT);
|
||||
}
|
||||
Wait(600);
|
||||
for(int i = 0; i < redCount; i++)
|
||||
{
|
||||
mchfBl_PinOff(LEDRED);
|
||||
Wait(300);
|
||||
mchfBl_PinOn(LEDRED);
|
||||
Wait(300);
|
||||
mchfBl_PinOff(LEDRED);
|
||||
Wait(300);
|
||||
}
|
||||
Wait(600);
|
||||
mchfBl_PinOn(BACKLIGHT);
|
||||
Wait(900);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// USB error handling
|
||||
void BootFail_Handler(uint8_t count)
|
||||
{
|
||||
mchfBl_PinOff(BACKLIGHT);
|
||||
Wait(700);
|
||||
|
||||
while(1)
|
||||
{
|
||||
for(uint8_t i = 0; i < count; i++)
|
||||
{
|
||||
Wait(300);
|
||||
mchfBl_PinOn(BACKLIGHT);
|
||||
Wait(300);
|
||||
mchfBl_PinOff(BACKLIGHT);
|
||||
Wait(700);
|
||||
}
|
||||
Wait(700);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Programs the internal Flash memory
|
||||
*/
|
||||
//mchf_bootloader_error_t COMMAND_ProgramFlashMemory()
|
||||
mchf_bootloader_error_t COMMAND_ProgramFlashMemory(uint32_t LastPGAddress)
|
||||
{
|
||||
mchf_bootloader_error_t retval = BL_ERR_NONE;
|
||||
|
||||
uint8_t readflag = TRUE;
|
||||
// uint32_t LastPGAddress = APPLICATION_ADDRESS;
|
||||
|
||||
do
|
||||
{
|
||||
UINT BytesRead;
|
||||
|
||||
/* Read maximum 32 Kbyte from the selected file */
|
||||
if(f_read (&fileR, RAM_Buf, BUFFER_SIZE, &BytesRead) != FR_OK)
|
||||
{
|
||||
retval = BL_ERR_READDISK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The read data < "BUFFER_SIZE" Kbyte */
|
||||
if (BytesRead < BUFFER_SIZE)
|
||||
{
|
||||
readflag = FALSE;
|
||||
}
|
||||
|
||||
/* Program flash memory */
|
||||
for ( uint32_t programcounter = 0;
|
||||
programcounter < BytesRead;
|
||||
programcounter+=32,LastPGAddress += 32)
|
||||
{
|
||||
uint32_t* RAM_Address = (uint32_t*)&RAM_Buf[programcounter];
|
||||
|
||||
if (flashIf_Program256Bit(LastPGAddress, RAM_Address) != HAL_OK)
|
||||
{
|
||||
/* Flash programming error */
|
||||
retval = BL_ERR_FLASHPROG;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((readflag == TRUE) && retval == BL_ERR_NONE);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read flash and write to image on disk
|
||||
*/
|
||||
void COMMAND_UPLOAD(void)
|
||||
{
|
||||
|
||||
UINT bytesWritten;
|
||||
FRESULT res = FR_OK;
|
||||
|
||||
f_unlink(VERSION);
|
||||
f_unlink(AUTHOR);
|
||||
/* green LED on command upload */
|
||||
mchfBl_PinOn(LEDGREEN);
|
||||
/* Get the read out protection status */
|
||||
FlagStatus readoutstatus = flashIf_ReadOutProtectionStatus();
|
||||
if (readoutstatus == 0)
|
||||
{
|
||||
/* Remove UPLOAD file if exist on flash disk */
|
||||
f_unlink (UPLOAD_FILENAME);
|
||||
|
||||
/* Init written byte counter */
|
||||
uint32_t offset = 0;
|
||||
uint8_t* address = (uint8_t*)CONFIG_START_ADDRESS;//APPLICATION_ADDRESS;
|
||||
|
||||
|
||||
/* Open binary file to write on it */
|
||||
res = f_open(&file, UPLOAD_FILENAME, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res == FR_OK)
|
||||
{
|
||||
uint32_t counterread = 0;
|
||||
uint32_t fw_leight = flashIf_userFlashSize();
|
||||
/* Read flash memory */
|
||||
// while ((offset != flashIf_userFlashSize() && res == FR_OK))
|
||||
while ((offset != fw_leight && res == FR_OK))
|
||||
{
|
||||
// for (counterread = 0; counterread < BUFFER_SIZE && offset != flashIf_userFlashSize(); counterread++,offset++)
|
||||
for (counterread = 0; counterread < BUFFER_SIZE && offset != fw_leight; counterread++,offset++)
|
||||
{
|
||||
RAM_Buf[counterread] = address[offset];
|
||||
}
|
||||
/* Write buffer to file */
|
||||
res = f_write (&file, RAM_Buf, counterread, &bytesWritten);
|
||||
}
|
||||
/* Close file and filesystem */
|
||||
f_close (&file);
|
||||
}
|
||||
if (res != FR_OK)
|
||||
{
|
||||
FlashFail_Handler(BL_ERR_WRITEDISK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashFail_Handler(BL_ERR_FLASHPROTECT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read flash and write config on disk
|
||||
*/
|
||||
void COMMAND_UPLOAD_CONF(void)
|
||||
{
|
||||
|
||||
UINT bytesWritten;
|
||||
FRESULT res = FR_OK;
|
||||
|
||||
/* green LED on command upload */
|
||||
mchfBl_PinOn(LEDGREEN);
|
||||
/* Get the read out protection status */
|
||||
FlagStatus readoutstatus = flashIf_ReadOutProtectionStatus();
|
||||
if (readoutstatus == 0)
|
||||
{
|
||||
/* Remove UPLOAD file if exist on flash disk */
|
||||
f_unlink (UPLOAD_FILENAME_CONF);
|
||||
|
||||
/* Init written byte counter */
|
||||
uint32_t offset = 0;
|
||||
uint8_t* address = (uint8_t*)CONFIG_START_ADDRESS;
|
||||
|
||||
|
||||
/* Open binary file to write on it */
|
||||
res = f_open(&file, UPLOAD_FILENAME_CONF, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res == FR_OK)
|
||||
{
|
||||
uint32_t counterread = 0;
|
||||
/* Read flash memory */
|
||||
while ((offset != CONFIG_LEIGHT && res == FR_OK))
|
||||
{
|
||||
for (counterread = 0; counterread < BUFFER_SIZE && offset != CONFIG_LEIGHT; counterread++,offset++)
|
||||
{
|
||||
RAM_Buf[counterread] = address[offset];
|
||||
}
|
||||
/* Write buffer to file */
|
||||
res = f_write (&file, RAM_Buf, counterread, &bytesWritten);
|
||||
}
|
||||
/* Close file and filesystem */
|
||||
f_close (&file);
|
||||
}
|
||||
if (res != FR_OK)
|
||||
{
|
||||
Bootloader_PrintLine("Problem writing " UPLOAD_FILE_CONF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FlashFail_Handler(BL_ERR_FLASHPROTECT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read file and flash it
|
||||
*/
|
||||
void COMMAND_DOWNLOAD(void)
|
||||
{
|
||||
mchf_bootloader_error_t retval = BL_ERR_NONE;
|
||||
|
||||
/* Flash unlock */
|
||||
flashIf_FlashUnlock();
|
||||
|
||||
/* Reading for flash active: Red LED on */
|
||||
mchfBl_PinOn(LEDRED);
|
||||
|
||||
/* Open the binary file to be downloaded */
|
||||
if (f_open(&fileR, DOWNLOAD_FILENAME, FA_READ) == FR_OK)
|
||||
{
|
||||
/* Erase FLASH sectors to download image */
|
||||
if (f_size(&fileR) > flashIf_userFlashSize())
|
||||
{
|
||||
retval = BL_ERR_FLASHTOOSMALL;
|
||||
} else if ( flashIf_EraseSectors(APPLICATION_ADDRESS,f_size(&fileR)) != HAL_OK)
|
||||
{
|
||||
/* Flash erase error */
|
||||
retval = BL_ERR_FLASHERASE;
|
||||
} else
|
||||
{
|
||||
/* Program flash memory */
|
||||
// retval = COMMAND_ProgramFlashMemory();
|
||||
retval = COMMAND_ProgramFlashMemory(APPLICATION_ADDRESS);
|
||||
}
|
||||
|
||||
/* Close file and filesystem */
|
||||
f_close (&fileR);
|
||||
///f_mount(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the binary file is not available */
|
||||
retval = BL_ERR_NOIMAGE;
|
||||
}
|
||||
|
||||
flashIf_FlashLock();
|
||||
|
||||
if (retval != BL_ERR_NONE)
|
||||
{
|
||||
FlashFail_Handler(retval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief flash file
|
||||
*/
|
||||
void COMMAND_DOWNLOAD_CONF(void)
|
||||
{
|
||||
mchf_bootloader_error_t retval = BL_ERR_NONE;
|
||||
|
||||
/* Flash unlock */
|
||||
flashIf_FlashUnlock();
|
||||
|
||||
/* Reading for flash active: Red LED on */
|
||||
mchfBl_PinOn(LEDRED);
|
||||
|
||||
/* Open the binary file to be downloaded */
|
||||
if (f_open(&fileR, DOWNLOAD_FILENAME_CONF, FA_READ) == FR_OK)
|
||||
{
|
||||
/* Erase FLASH sectors to download image */
|
||||
if (f_size(&fileR) > CONFIG_LEIGHT)
|
||||
{
|
||||
retval = BL_ERR_FLASHTOOSMALL;
|
||||
} else if ( flashIf_EraseSectors(CONFIG_START_ADDRESS, CONFIG_LEIGHT) != HAL_OK)
|
||||
{
|
||||
/* Flash erase error */
|
||||
retval = BL_ERR_FLASHERASE;
|
||||
} else
|
||||
{
|
||||
/* Program flash memory */
|
||||
// retval = COMMAND_ProgramFlashMemory();
|
||||
retval = COMMAND_ProgramFlashMemory(CONFIG_START_ADDRESS);
|
||||
}
|
||||
|
||||
/* Close file and filesystem */
|
||||
f_close (&fileR);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the binary file is not available */
|
||||
retval = BL_ERR_NOIMAGE;
|
||||
}
|
||||
|
||||
flashIf_FlashLock();
|
||||
|
||||
if (retval != BL_ERR_NONE)
|
||||
{
|
||||
FlashFail_Handler(retval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reset to restart mchf
|
||||
*/
|
||||
void COMMAND_ResetMCU(uint32_t code)
|
||||
{
|
||||
*(__IO uint32_t*)(SRAM2_BASE) = code;
|
||||
__DSB();
|
||||
#if defined(STM32F7)
|
||||
// || defined(STM32H7) H7 crashes here if we would call SCB_CleanDCache since we do not enable it in the first place in main.c!
|
||||
SCB_CleanDCache();
|
||||
#endif
|
||||
/* Software reset */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 28-October-2011
|
||||
* @brief Header file for command.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _COMMAND_H
|
||||
#define _COMMAND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "gpio.h" // dummy include for HAL
|
||||
#include "flash_if.h"
|
||||
#include "uhsdr_version.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
BL_ERR_NONE = 0,
|
||||
BL_ERR_USBPROBLEM = 1,
|
||||
BL_ERR_NOIMAGE = 2,
|
||||
BL_ERR_FLASHTOOSMALL = 3,
|
||||
BL_ERR_WRITEDISK = 4,
|
||||
BL_ERR_READDISK = 5,
|
||||
BL_ERR_FLASHPROG = 6,
|
||||
BL_ERR_FLASHERASE = 7,
|
||||
BL_ERR_FLASHPROTECT = 8,
|
||||
} mchf_bootloader_error_t;
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
#define BASE_PREFIX "fw-"
|
||||
#define BASE_FILE BASE_PREFIX TRX_ID
|
||||
|
||||
#define UPLOAD_FILE BASE_FILE ".old"
|
||||
#define DOWNLOAD_FILE BASE_FILE ".bin"
|
||||
#define UPLOAD_FILENAME "0:" UPLOAD_FILE
|
||||
#define DOWNLOAD_FILENAME "0:" DOWNLOAD_FILE
|
||||
#define VERSION "Version: "UHSDR_BOOT_VER
|
||||
#define AUTHOR "Author: DF8OE"
|
||||
#define UPLOAD_FILE_CONF "cf-mchf.old"
|
||||
#define UPLOAD_FILENAME_CONF "0:" UPLOAD_FILE_CONF
|
||||
#define DOWNLOAD_FILE_CONF "cf-mchf.bin"
|
||||
#define DOWNLOAD_FILENAME_CONF "0:" DOWNLOAD_FILE_CONF
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#define CONFIG_START_ADDRESS ((uint32_t)0x08008000)
|
||||
#define CONFIG_LEIGHT ((uint32_t)0x00008000)
|
||||
#elif defined(STM32H7)
|
||||
#define CONFIG_START_ADDRESS ((uint32_t)0x08020000)
|
||||
#define CONFIG_LEIGHT ((uint32_t)0x00040000)
|
||||
#endif
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void COMMAND_UPLOAD(void);
|
||||
void COMMAND_UPLOAD_CONF(void);
|
||||
void COMMAND_DOWNLOAD(void);
|
||||
void COMMAND_DOWNLOAD_CONF(void);
|
||||
void COMMAND_ResetMCU(uint32_t code);
|
||||
|
||||
|
||||
|
||||
void BootFail_Handler(uint8_t count);
|
||||
void FlashFail_Handler(mchf_bootloader_error_t errcode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMMAND_H */
|
||||
@@ -0,0 +1,226 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
#include "uhsdr_board_config.h"
|
||||
|
||||
#if defined(STM32F7)
|
||||
#include "stm32f7xx_hal_flash.h"
|
||||
#elif defined(STM32H7)
|
||||
#include "stm32h7xx_hal_flash.h"
|
||||
#elif defined(STM32F4)
|
||||
#include "stm32f4xx_hal_flash.h"
|
||||
#else
|
||||
#error Unknown processor
|
||||
#endif
|
||||
|
||||
#include "flash_if.h"
|
||||
|
||||
|
||||
#define FLASH_NO_SECTOR (0xFFFFFFFF)
|
||||
|
||||
/* Base address of the Flash sectors */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t addr;
|
||||
} flash_sectorinfo_t;
|
||||
// this struct can be used to store more information
|
||||
// such as bank numbers, sector numbers etc. if flash layout gets more complex
|
||||
// right now not yet used
|
||||
|
||||
static const flash_sectorinfo_t flash_sector_addr[] = {
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
{ 0x08000000 }, /* Base @ of Sector 0, 16 Kbyte */
|
||||
{ 0x08004000 }, /* Base @ of Sector 1, 16 Kbyte */
|
||||
{ 0x08008000 }, /* Base @ of Sector 2, 16 Kbyte */
|
||||
{ 0x0800C000 }, /* Base @ of Sector 3, 16 Kbyte */
|
||||
{ 0x08010000 }, /* Base @ of Sector 4, 64 Kbyte */
|
||||
{ 0x08020000 }, /* Base @ of Sector 5, 128 Kbyte */
|
||||
{ 0x08040000 }, /* Base @ of Sector 6, 128 Kbyte */
|
||||
{ 0x08060000 }, /* Base @ of Sector 7, 128 Kbyte */
|
||||
{ 0x08080000 }, /* Base @ of Sector 8, 128 Kbyte */
|
||||
{ 0x080A0000 }, /* Base @ of Sector 9, 128 Kbyte */
|
||||
{ 0x080C0000 }, /* Base @ of Sector 10, 128 Kbyte */
|
||||
{ 0x080E0000 }, /* Base @ of Sector 11, 128 Kbyte */
|
||||
{ 0x08100000 }, /* Base @ of Sector 12, 128 Kbyte */
|
||||
{ 0x08104000 }, /* Base @ of Sector 13, 16 Kbyte */
|
||||
{ 0x08108000 }, /* Base @ of Sector 14, 16 Kbyte */
|
||||
{ 0x0810C000 }, /* Base @ of Sector 15, 16 Kbyte */
|
||||
{ 0x08110000 }, /* Base @ of Sector 16, 64 Kbyte */
|
||||
{ 0x08120000 }, /* Base @ of Sector 17, 128 Kbyte */
|
||||
{ 0x08140000 }, /* Base @ of Sector 18, 128 Kbyte */
|
||||
{ 0x08160000 }, /* Base @ of Sector 19, 128 Kbyte */
|
||||
{ 0x08180000 }, /* Base @ of Sector 20, 128 Kbyte */
|
||||
{ 0x081A0000 }, /* Base @ of Sector 21, 128 Kbyte */
|
||||
{ 0x081C0000 }, /* Base @ of Sector 22, 128 Kbyte */
|
||||
{ 0x081E0000 }, /* Base @ of Sector 23, 128 Kbyte */
|
||||
{ 0x08200000 }, /* End+1@ of Sector 23, 128 Kbyte */
|
||||
#elif defined(STM32H7)
|
||||
{ 0x08000000 }, /* Base @ of Sector 0, bank 1, 128 Kbyte */
|
||||
{ 0x08020000 }, /* Base @ of Sector 1, 128 Kbyte */
|
||||
{ 0x08040000 }, /* Base @ of Sector 2, 128 Kbyte */
|
||||
{ 0x08060000 }, /* Base @ of Sector 3, 128 Kbyte */
|
||||
{ 0x08080000 }, /* Base @ of Sector 4, 128 Kbyte */
|
||||
{ 0x080A0000 }, /* Base @ of Sector 5, 128 Kbyte */
|
||||
{ 0x080C0000 }, /* Base @ of Sector 6, 128 Kbyte */
|
||||
{ 0x080E0000 }, /* Base @ of Sector 7, 128 Kbyte */
|
||||
{ 0x08100000 }, /* Base @ of Sector 0, bank 2, 128 Kbyte */
|
||||
{ 0x08120000 }, /* Base @ of Sector 1, 128 Kbyte */
|
||||
{ 0x08140000 }, /* Base @ of Sector 2, 128 Kbyte */
|
||||
{ 0x08160000 }, /* Base @ of Sector 3, 128 Kbyte */
|
||||
{ 0x08180000 }, /* Base @ of Sector 4, 128 Kbyte */
|
||||
{ 0x081A0000 }, /* Base @ of Sector 5, 128 Kbyte */
|
||||
{ 0x081C0000 }, /* Base @ of Sector 6, 128 Kbyte */
|
||||
{ 0x081E0000 }, /* Base @ of Sector 7, 128 Kbyte */
|
||||
{ 0x08200000 }, /* End+1@ of Sector 7, 128 Kbyte */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static const uint32_t flash_sector_max = sizeof(flash_sector_addr)/sizeof(flash_sectorinfo_t)-1;
|
||||
// we have one extra entry at the end, hence we need to reduce number of sectors by one
|
||||
|
||||
#define RESET 0
|
||||
#define SET 1
|
||||
|
||||
/**
|
||||
* Return the Flash sector Number of the address
|
||||
* retval The Flash sector Number of the address
|
||||
*/
|
||||
static uint32_t flashIf_GetSectorInfoIndex(uint32_t Address)
|
||||
{
|
||||
uint32_t sector = FLASH_NO_SECTOR; // index of invalid sector, returned if address not in flash
|
||||
|
||||
for (int idx = 0; idx < flash_sector_max; idx++)
|
||||
{
|
||||
if (Address >= flash_sector_addr[idx].addr && Address < flash_sector_addr[idx+1].addr)
|
||||
{
|
||||
sector = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sector;
|
||||
}
|
||||
|
||||
static uint32_t flashIf_GetSectorNumber(uint32_t idx)
|
||||
{
|
||||
uint32_t retval = FLASH_NO_SECTOR;
|
||||
if (idx < flash_sector_max)
|
||||
{
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
retval = idx; // idx == sector number
|
||||
#elif defined(STM32H7)
|
||||
retval = idx % 8; // 2x8 sectors
|
||||
#endif
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#if defined(STM32H7)
|
||||
static uint32_t flashIf_GetSectorBank(uint32_t idx)
|
||||
{
|
||||
uint32_t retval = FLASH_NO_SECTOR;
|
||||
if (idx < flash_sector_max)
|
||||
{
|
||||
retval = idx < 8? FLASH_BANK_1:FLASH_BANK_2; // 2x8 sectors
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void flashIf_FlashUnlock()
|
||||
{
|
||||
HAL_FLASH_Unlock();
|
||||
}
|
||||
|
||||
void flashIf_FlashLock()
|
||||
{
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
|
||||
FlagStatus flashIf_ReadOutProtectionStatus()
|
||||
{
|
||||
FLASH_OBProgramInitTypeDef OBInit;
|
||||
|
||||
HAL_FLASHEx_OBGetConfig(&OBInit);
|
||||
FlagStatus readoutstatus = RESET;
|
||||
|
||||
if (OBInit.RDPLevel != OB_RDP_LEVEL0)
|
||||
{
|
||||
readoutstatus = SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
readoutstatus = RESET;
|
||||
}
|
||||
return readoutstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erases the required FLASH Sectors.
|
||||
* retval Sectors erase status:
|
||||
* HAL_OK: Erase sectors done with success
|
||||
* Anything else: Erase error
|
||||
*/
|
||||
uint32_t flashIf_EraseSectors(uint32_t Address, uint32_t Length)
|
||||
{
|
||||
FLASH_EraseInitTypeDef flashEraseOp;
|
||||
uint32_t sectorError = 0;
|
||||
uint32_t retval = HAL_ERROR;
|
||||
|
||||
/* Erase Flash sectors */
|
||||
uint32_t startsector = flashIf_GetSectorInfoIndex(Address);
|
||||
uint32_t endsector = flashIf_GetSectorInfoIndex(Address+Length-1);
|
||||
|
||||
if (startsector != FLASH_NO_SECTOR && endsector != FLASH_NO_SECTOR)
|
||||
|
||||
{
|
||||
retval = HAL_OK;
|
||||
|
||||
for (int idx = startsector; retval == HAL_OK && idx <= endsector; idx++)
|
||||
{
|
||||
/* Erase FLASH sectors to download image */
|
||||
flashEraseOp.Sector = flashIf_GetSectorNumber(idx);
|
||||
flashEraseOp.NbSectors = 1;
|
||||
flashEraseOp.VoltageRange = VOLTAGE_RANGE_3;
|
||||
flashEraseOp.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
#if defined(STM32H7)
|
||||
flashEraseOp.Banks = flashIf_GetSectorBank(idx);
|
||||
#endif
|
||||
retval = HAL_FLASHEx_Erase(&flashEraseOp, §orError);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Programs a word at a specified address.
|
||||
* Address: specifies the address to be programmed.
|
||||
* Data: specifies the data to be programmed.
|
||||
* retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
|
||||
* FLASH_ERROR_WRP, HAL_OK or FLASH_TIMEOUT.
|
||||
*/
|
||||
HAL_StatusTypeDef flashIf_Program256Bit(uint32_t Address, uint32_t Data[8])
|
||||
{
|
||||
HAL_StatusTypeDef retval = HAL_OK;
|
||||
#ifndef STM32H7
|
||||
for (int i=0; retval == HAL_OK && i < 8; i++)
|
||||
{
|
||||
retval = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,Address+(i*4), Data[i]);
|
||||
}
|
||||
#else
|
||||
retval = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,Address, (uint32_t)&Data[0]);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4; coding: utf-8 -*- */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 28-October-2011
|
||||
* @brief Header file for flash_layer.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _FLASH_ACCESS_LAYER_H
|
||||
#define _FLASH_ACCESS_LAYER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "uhsdr_mcu.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef void (*pFunction)(void);
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* extern const char* version;
|
||||
extern const char* author; */
|
||||
|
||||
#ifndef STM32H7
|
||||
/* Define the flash memory start address */
|
||||
#define USER_FLASH_STARTADDRESS ((uint32_t)0x08000000) /* Flash Start Address */
|
||||
|
||||
/* End of the Flash address for the largest device, dynamically sized down based on real processor flash */
|
||||
#define USER_FLASH_END_ADDRESS ((uint32_t)0x081FFFFF)
|
||||
|
||||
#define MCHF_FLASHRESERVED (64)
|
||||
#else
|
||||
/* Define the flash memory start address */
|
||||
#define USER_FLASH_STARTADDRESS ((uint32_t)0x08000000) /* Flash Start Address */
|
||||
|
||||
/* End of the Flash address for the largest device, dynamically sized down based on real processor flash */
|
||||
#define USER_FLASH_END_ADDRESS ((uint32_t)0x081FFFFF)
|
||||
|
||||
#define MCHF_FLASHRESERVED (384)
|
||||
#endif
|
||||
|
||||
/* Define the address from where user application will be loaded. */
|
||||
#define APPLICATION_ADDRESS (USER_FLASH_STARTADDRESS + (MCHF_FLASHRESERVED * 1024))
|
||||
|
||||
|
||||
/**
|
||||
* @brief real user flash size of microprocessor (flash size - bootloader/config flash size)
|
||||
* @returns size of user flash in bytes
|
||||
*/
|
||||
static inline uint32_t flashIf_userFlashSize() { return ((STM32_GetFlashSize() - MCHF_FLASHRESERVED)*1024); }
|
||||
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void flashIf_FlashUnlock(void);
|
||||
void flashIf_FlashLock(void);
|
||||
FlagStatus flashIf_ReadOutProtectionStatus(void);
|
||||
uint32_t flashIf_EraseSectors(uint32_t Address, uint32_t Length);
|
||||
HAL_StatusTypeDef flashIf_Program256Bit(uint32_t Address, uint32_t Data[8]);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FLASH_IF_H */
|
||||
|
||||
/*******************(C)COPYRIGHT 2011 STMicroelectronics *****END OF FILE******/
|
||||
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
#include "uhsdr_boot_hw.h"
|
||||
|
||||
|
||||
static GPIO_TypeDef* GPIO_PORT[LEDn] = {LEDGREEN_GPIO_PORT, LEDRED_GPIO_PORT, POWER_ON_GPIO_PORT, BACKLIGHT_ON_GPIO_PORT, TP_CS_PIO};
|
||||
static const uint16_t GPIO_PIN[LEDn] = {LEDGREEN_PIN, LEDRED_PIN, POWER_ON_PIN, BACKLIGHT_ON_PIN, TP_CS};
|
||||
|
||||
static GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {BANDM_BUTTON_GPIO_PORT,POWER_BUTTON_GPIO_PORT, BANDP_BUTTON_GPIO_PORT};
|
||||
|
||||
static const uint16_t BUTTON_PIN[BUTTONn] = {BANDM_BUTTON_PIN,POWER_BUTTON_PIN, BANDP_BUTTON_PIN};
|
||||
|
||||
static const uint8_t BUTTON_IRQn[BUTTONn] = {BANDM_BUTTON_EXTI_IRQn,POWER_BUTTON_EXTI_IRQn,BANDP_BUTTON_EXTI_IRQn};
|
||||
|
||||
void mchfBl_PortClock(uint32_t port)
|
||||
{
|
||||
|
||||
/* Enable the BUTTON Clock */
|
||||
switch(port)
|
||||
{
|
||||
case (uint32_t)GPIOA:
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOB:
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOC:
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOD:
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
break;
|
||||
#if 0
|
||||
case (uint32_t)GPIOE:
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOF:
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOG:
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOH:
|
||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||
break;
|
||||
case (uint32_t)GPIOI:
|
||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void mchfBl_LEDInit(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
mchfBl_PortClock((uint32_t)GPIO_PORT[Led]);
|
||||
/* Enable the GPIO_LED Clock */
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN[Led];
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(GPIO_PORT[Led], &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
void mchfBl_PinOn(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_SetBits(GPIO_PORT[Led],GPIO_PIN[Led])
|
||||
}
|
||||
|
||||
void mchfBl_PinOff(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_ResetBits(GPIO_PORT[Led],GPIO_PIN[Led])
|
||||
}
|
||||
|
||||
void mchfBl_PinToggle(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_PORT[Led]->ODR ^= GPIO_PIN[Led];
|
||||
}
|
||||
|
||||
void mchfBl_ButtonInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
mchfBl_PortClock((uint32_t)BUTTON_PORT[Button]);
|
||||
|
||||
/* Configure Button pin as input */
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Pin = BUTTON_PIN[Button];
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
if (Button_Mode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button EXTI line */
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_EVT_FALLING;
|
||||
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
HAL_NVIC_EnableIRQ(BUTTON_IRQn[Button]);
|
||||
HAL_NVIC_SetPriority(BUTTON_IRQn[Button],15,0);
|
||||
}
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
uint32_t mchfBl_ButtonGetState(Button_TypeDef Button)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
void mcHF_PowerOff()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN[PWR_HOLD];
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(GPIO_PORT[PWR_HOLD], &GPIO_InitStructure);
|
||||
|
||||
while(1) { asm("nop"); }
|
||||
// never reached
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __MCHF_H
|
||||
#define __MCHF_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "uhsdr_board_config.h"
|
||||
#include "uhsdr_board.h"
|
||||
#include "gpio.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LEDGREEN = 0,
|
||||
LEDRED = 1,
|
||||
PWR_HOLD = 2,
|
||||
BACKLIGHT = 3,
|
||||
TPCS_PIN = 4
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_BANDM = 0,
|
||||
BUTTON_POWER = 1,
|
||||
BUTTON_BANDP = 2
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 5
|
||||
|
||||
#define LEDGREEN_PIN GPIO_PIN_9
|
||||
#define LEDGREEN_GPIO_PORT GPIOB
|
||||
|
||||
#define LEDRED_PIN GPIO_PIN_12
|
||||
#define LEDRED_GPIO_PORT GPIOB
|
||||
|
||||
#define POWER_ON_PIN GPIO_PIN_8
|
||||
#define POWER_ON_GPIO_PORT GPIOC
|
||||
|
||||
#define BACKLIGHT_ON_PIN GPIO_PIN_2
|
||||
#define BACKLIGHT_ON_GPIO_PORT GPIOD
|
||||
|
||||
|
||||
#define BUTTONn 3
|
||||
|
||||
#define BANDM_BUTTON_PIN GPIO_PIN_0
|
||||
#define BANDM_BUTTON_GPIO_PORT GPIOB
|
||||
#define BANDM_BUTTON_EXTI_IRQn EXTI0_IRQn
|
||||
|
||||
#define BANDP_BUTTON_PIN GPIO_PIN_2
|
||||
#define BANDP_BUTTON_GPIO_PORT GPIOB
|
||||
#define BANDP_BUTTON_EXTI_IRQn EXTI0_IRQn
|
||||
|
||||
#if defined(UI_BRD_MCHF)
|
||||
#define POWER_BUTTON_PIN GPIO_PIN_13
|
||||
#define POWER_BUTTON_GPIO_PORT GPIOC
|
||||
#define POWER_BUTTON_EXTI_LINE EXTI_Line0
|
||||
#define POWER_BUTTON_EXTI_IRQn EXTI0_IRQn
|
||||
#elif defined(UI_BRD_OVI40)
|
||||
#define POWER_BUTTON_PIN GPIO_PIN_2
|
||||
#define POWER_BUTTON_GPIO_PORT GPIOG
|
||||
#define POWER_BUTTON_EXTI_LINE EXTI_Line0
|
||||
#define POWER_BUTTON_EXTI_IRQn EXTI0_IRQn
|
||||
#endif
|
||||
|
||||
void mchfBl_LEDInit(Led_TypeDef Led);
|
||||
void mchfBl_PinOn(Led_TypeDef Led);
|
||||
void mchfBl_PinOff(Led_TypeDef Led);
|
||||
void mchfBl_PinToggle(Led_TypeDef Led);
|
||||
void mchfBl_ButtonInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode);
|
||||
uint32_t mchfBl_ButtonGetState(Button_TypeDef Button);
|
||||
|
||||
void mcHF_PowerOff(void);
|
||||
|
||||
/*
|
||||
* Just toggles the PowerHold Pin, but does not stop execution
|
||||
*/
|
||||
static inline void Bootloader_PowerHoldOff(void)
|
||||
{
|
||||
mchfBl_PinOn(PWR_HOLD);
|
||||
}
|
||||
|
||||
static inline void Bootloader_PowerHoldOn(void)
|
||||
{
|
||||
mchfBl_PinOff(PWR_HOLD);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __MCHF_H */
|
||||
@@ -0,0 +1,555 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
// Common
|
||||
#include "uhsdr_board.h"
|
||||
#include <stdio.h>
|
||||
#include "uhsdr_rtc.h"
|
||||
#include "ui_spectrum.h"
|
||||
|
||||
#include "ui_configuration.h"
|
||||
#include "config_storage.h"
|
||||
|
||||
// serial EEPROM driver
|
||||
#include "uhsdr_hw_i2c.h"
|
||||
#include "uhsdr_hw_i2s.h"
|
||||
#include "uhsdr_hmc1023.h"
|
||||
|
||||
// Audio Driver
|
||||
#include "drivers/audio/audio_driver.h"
|
||||
#include "drivers/audio/audio_management.h"
|
||||
#include "drivers/audio/cw/cw_gen.h"
|
||||
#include "drivers/audio/freedv_uhsdr.h"
|
||||
#include "drivers/audio/audio_nr.h"
|
||||
|
||||
//cat
|
||||
#include "drivers/cat/cat_driver.h"
|
||||
|
||||
// UI Driver
|
||||
#include "drivers/ui/ui_driver.h"
|
||||
#include "drivers/ui/lcd/ui_lcd_hy28.h"
|
||||
#include "drivers/ui/menu/ui_menu.h"
|
||||
#include "drivers/ui/oscillator/osc_interface.h"
|
||||
#include "drivers/ui/oscillator/osc_si5351a.h"
|
||||
#include "drivers/ui/oscillator/osc_si570.h"
|
||||
#include "drivers/audio/codec/codec.h"
|
||||
#include "misc/profiling.h"
|
||||
#include "uhsdr_canary.h"
|
||||
#include "audio_agc.h"
|
||||
// Keyboard Driver
|
||||
// #include "keyb_driver.h"
|
||||
|
||||
// Misc
|
||||
#include "drivers/audio/softdds/softdds.h"
|
||||
|
||||
#include "uhsdr_flash.h" // only for EEPROM_START_ADDRESS
|
||||
#include "drivers/ui/radio_management.h"
|
||||
//
|
||||
|
||||
#include "misc/TestCPlusPlusInterface.h"
|
||||
|
||||
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
|
||||
{
|
||||
if (ts.paddles_active != false)
|
||||
{
|
||||
switch(GPIO_Pin)
|
||||
{
|
||||
case BUTTON_PWR:
|
||||
break;
|
||||
case PADDLE_DAH:
|
||||
// Call handler
|
||||
if (Board_PttDahLinePressed() && RadioManagement_IsTxDisabledBy(TX_DISABLE_RXMODE) == false)
|
||||
{ // was PTT line low? Is it not a RX only mode
|
||||
RadioManagement_Request_TxOn(); // yes - ONLY then do we activate PTT! (e.g. prevent hardware bug from keying PTT!)
|
||||
if(ts.dmod_mode == DEMOD_CW || is_demod_rtty() || is_demod_psk() || ts.cw_text_entry)
|
||||
{
|
||||
CwGen_DahIRQ(); // Yes - go to CW state machine
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PADDLE_DIT:
|
||||
if((ts.dmod_mode == DEMOD_CW || is_demod_rtty() || is_demod_psk() || ts.cw_text_entry) && Board_DitLinePressed())
|
||||
{
|
||||
if (ts.cw_keyer_mode != CW_KEYER_MODE_STRAIGHT)
|
||||
{
|
||||
RadioManagement_Request_TxOn();
|
||||
}
|
||||
CwGen_DitIRQ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if a special bootloader is used and configures some settings
|
||||
* Used for debugging and testing purposes only
|
||||
*/
|
||||
void Main_DetectSpecialBootloader()
|
||||
{
|
||||
// detection routine for special bootloader version strings which do enable debug or development functions
|
||||
char out[14];
|
||||
for(uint8_t* begin = (uint8_t*)0x8000000; begin < (uint8_t*)EEPROM_START_ADDRESS-8; begin++)
|
||||
{
|
||||
if (memcmp("Version: ",begin,9) == 0)
|
||||
{
|
||||
snprintf(out,13, "%s", &begin[9]);
|
||||
for (uint8_t i=1; i<13; i++)
|
||||
{
|
||||
if (out[i] == '\0')
|
||||
{
|
||||
if (out[i-1] == 'a')
|
||||
{
|
||||
ts.special_functions_enabled = 1;
|
||||
}
|
||||
if (out[i-1] == 's')
|
||||
{
|
||||
ts.special_functions_enabled = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All data inside the ts data structure which needs a non-zero value set at startup AND
|
||||
* is either used before the configuration has been loaded OR which is not loaded from the persistent configuration
|
||||
* should be initialized here.
|
||||
* Values which are initialized by other init functions before use should not be initialized here.
|
||||
* We try to initialize a single variable only once, to avoid confusion.
|
||||
*
|
||||
*/
|
||||
void TransceiverStateInit(void)
|
||||
{
|
||||
// Defaults always
|
||||
ts.txrx_mode = TRX_MODE_RX; // start in RX
|
||||
ts.samp_rate = IQ_SAMPLE_RATE; // set sampling rate
|
||||
|
||||
//CONFIG LOADED: ts.band = BAND_MODE_20; // band from eeprom
|
||||
ts.rx_temp_mute = false; // used in muting audio during band change
|
||||
ts.filter_band = FILTER_BAND_UNKNOWN; // used to indicate the bpf filter selection for power detector coefficient selection
|
||||
ts.dmod_mode = DEMOD_USB; // demodulator mode
|
||||
//CONFIG LOADED: ts.rx_gain[RX_AUDIO_SPKR].value = AUDIO_GAIN_DEFAULT;
|
||||
ts.rx_gain[RX_AUDIO_DIG].value = DIG_GAIN_DEFAULT;
|
||||
|
||||
//CONFIG LOADED:ts.rx_gain[RX_AUDIO_SPKR].max = MAX_VOLUME_DEFAULT; // Set max volume default
|
||||
ts.rx_gain[RX_AUDIO_DIG].max = DIG_GAIN_MAX; // Set max volume default
|
||||
|
||||
ts.rx_gain[RX_AUDIO_SPKR].active_value = 1; // this variable is used in the active RX audio processing function
|
||||
ts.rx_gain[RX_AUDIO_DIG].active_value = 1; // this variable is used in the active RX audio processing function
|
||||
//CONFIG LOADED:ts.lineout_gain = LINEOUT_GAIN_DEFAULT;
|
||||
//CONFIG LOADED:ts.rf_codec_gain = DEFAULT_RF_CODEC_GAIN_VAL; // Set default RF gain (0 = lowest, 8 = highest, 9 = "Auto")
|
||||
ts.rit_value = 0; // RIT value
|
||||
|
||||
//CONFIG LOADED:ts.cw_sidetone_gain = DEFAULT_SIDETONE_GAIN; // Sidetone gain
|
||||
|
||||
//CONFIG LOADED:ts.cw_keyer_mode = CW_KEYER_MODE_IAM_B; // CW keyer mode
|
||||
//CONFIG LOADED:ts.cw_keyer_speed = CW_KEYER_SPEED_DEFAULT; // CW keyer speed
|
||||
//CONFIG LOADED:ts.cw_sidetone_freq = CW_SIDETONE_FREQ_DEFAULT; // CW sidetone and TX offset frequency
|
||||
//CONFIG LOADED:ts.cw_paddle_reverse = 0; // Paddle defaults to NOT reversed
|
||||
//CONFIG LOADED:ts.cw_rx_delay = CW_TX2RX_DELAY_DEFAULT; // Delay of TX->RX turnaround
|
||||
//CONFIG LOADED:ts.cw_keyer_weight = CW_KEYER_WEIGHT_DEFAULT;
|
||||
|
||||
ts.audio_spkr_unmute_delay_count = VOICE_TX2RX_DELAY_DEFAULT; // TX->RX delay turnaround
|
||||
|
||||
ts.tune_freq = 0;
|
||||
|
||||
ts.menu_mode = 0; // menu mode
|
||||
ts.menu_item = 0; // menu item selection
|
||||
ts.menu_var = 0; // menu item change variable
|
||||
ts.menu_var_changed = 0; // TRUE if a menu variable was changed and that an EEPROM save should be done
|
||||
//NO INIT NEEDED? SET BEFORE USE? ts.tx_mic_boost = MIC_BOOST_DEFAULT; // no extra gain. electret element assumed
|
||||
|
||||
//CONFIG LOADED:ts.tx_audio_source = TX_AUDIO_MIC; // default source is microphone
|
||||
//NO INIT NEEDED, SET BEFORE USE: ts.tx_mic_gain_mult = MIC_GAIN_DEFAULT; // actual operating value for microphone gain
|
||||
|
||||
//CONFIG LOADED:ts.tx_gain[TX_AUDIO_MIC] = MIC_GAIN_DEFAULT; // default line gain
|
||||
//CONFIG LOADED:ts.tx_gain[TX_AUDIO_LINEIN_L] = LINE_GAIN_DEFAULT; // default line gain
|
||||
ts.tx_gain[TX_AUDIO_LINEIN_R] = LINE_GAIN_DEFAULT; // default line gain
|
||||
ts.tx_gain[TX_AUDIO_DIG] = LINE_GAIN_DEFAULT; // default line gain
|
||||
ts.tx_gain[TX_AUDIO_DIGIQ] = LINE_GAIN_DEFAULT; // default line gain
|
||||
|
||||
ts.tune = false; // reset tuning flag
|
||||
|
||||
//NO INIT NEEDED, SET BEFORE USE:ts.tx_power_factor = 0.50; // TX power factor
|
||||
|
||||
//CONFIG LOADED:ts.pa_bias = PA_BIAS_DEFAULT; // Use lowest possible voltage as default
|
||||
//CONFIG LOADED:ts.pa_cw_bias = PA_BIAS_DEFAULT; // Use lowest possible voltage as default (nonzero sets separate bias for CW mode)
|
||||
//CONFIG LOADED:ts.freq_cal = 0; // Initial setting for frequency calibration
|
||||
//CONFIG LOADED:ts.power_level = PA_LEVEL_DEFAULT; // See uhsdr_board.h for setting
|
||||
|
||||
ts.powering_down = 0; // TRUE if powering down
|
||||
|
||||
//CONFIG LOADED:ts.xverter_mode = 0; // TRUE if transverter mode is active (e.g. offset of display)
|
||||
//CONFIG LOADED:ts.xverter_offset = 0; // Frequency offset in transverter mode (added to frequency display)
|
||||
|
||||
// This is NOT reset by the LCD function, but must be enabled/disabled externally
|
||||
|
||||
//CONFIG LOADED:ts.demod_mode_disable = 0; // TRUE if a specific mode is to be disabled
|
||||
|
||||
//CONFIG LOADED:ts.tx_meter_mode = METER_SWR;
|
||||
|
||||
//CONFIG LOADED:ts.alc_decay = ALC_DECAY_DEFAULT; // ALC Decay (release) default value
|
||||
//NO INIT NEEDED, SET BEFORE USE:ts.alc_decay_var = ALC_DECAY_DEFAULT; // ALC Decay (release) default value
|
||||
//CONFIG LOADED:ts.alc_tx_postfilt_gain = ALC_POSTFILT_GAIN_DEFAULT; // Post-filter added gain default (used for speech processor/ALC)
|
||||
//NO INIT NEEDED, SET BEFORE USEts.alc_tx_postfilt_gain_var = ALC_POSTFILT_GAIN_DEFAULT; // Post-filter added gain default (used for speech processor/ALC)
|
||||
//CONFIG LOADED:ts.tx_comp_level = 0; // 0=Release Time/Pre-ALC gain manually adjusted, >=1: Value calculated by this parameter
|
||||
|
||||
ts.freq_step_config = 0; // disabled both marker line under frequency and swapping of STEP buttons
|
||||
|
||||
ts.lcd_backlight_brightness = 0; // = 0 full brightness
|
||||
ts.lcd_backlight_blanking = 0; // MSB = 1 for auto-off of backlight, lower nybble holds time for auto-off in seconds
|
||||
//CONFIG LOADED:ts.low_power_config = LOW_POWER_THRESHOLD_DEFAULT; // add LOW_POWER_THRESHOLD_OFFSET for voltage value
|
||||
|
||||
ts.tune_step = 0; // Used for press-and-hold step size changing mode
|
||||
ts.frequency_lock = 0; // TRUE if frequency knob is locked
|
||||
|
||||
//CONFIG LOADED:ts.tx_disable = TX_DISABLE_OFF; // > 0 if transmitter is to be disabled
|
||||
//CONFIG LOADED:ts.flags1 = 0; // Used to hold individual status flags, stored in EEPROM location "EEPROM_FLAGS1"
|
||||
//CONFIG LOADED:ts.flags2 = 0; // Used to hold individual status flags, stored in EEPROM location "EEPROM_FLAGS2"
|
||||
ts.sysclock = 0; // This counts up from zero when the unit is powered up at precisely 100 Hz over the long term. This
|
||||
|
||||
// is NEVER reset and is used for timing certain events.
|
||||
ts.version_number_release = 0; // version release - used to detect firmware change
|
||||
ts.version_number_major = 0; // version build - used to detect firmware change
|
||||
//CONFIG LOADED:ts.cw_offset_mode = CW_OFFSET_USB_RX; // CW offset mode (USB, LSB, etc.)
|
||||
ts.cw_lsb = false; // Flag that indicates CW operates in LSB mode when TRUE
|
||||
//CONFIG LOADED:ts.iq_freq_mode = FREQ_IQ_CONV_MODE_DEFAULT; // used to set/configure the I/Q frequency/conversion mode
|
||||
//CONFIG LOADED:ts.lsb_usb_auto_select = 0; // holds setting of LSB/USB auto-select above/below 10 MHz
|
||||
ts.last_tuning = 0; // this is a timer used to hold off updates of the spectrum scope when an SPI LCD display interface is used
|
||||
ts.lcd_blanking_time = 0; // this holds the system time after which the LCD is blanked - if blanking is enabled
|
||||
ts.lcd_blanking_flag = 0; // if TRUE, the LCD is blanked completely (e.g. backlight is off)
|
||||
ts.xvtr_adjust_flag = 0; // set TRUE if transverter offset adjustment is in process
|
||||
//CONFIG LOADED:ts.vfo_mem_mode = 0; // this is used to record the VFO/memory mode (0 = VFO "A" = backwards compatibility)
|
||||
//CONFIG LOADED:ts.voltmeter_calibrate = POWER_VOLTMETER_CALIBRATE_DEFAULT; // Voltmeter calibration constant
|
||||
|
||||
// spectrum general settings
|
||||
//CONFIG LOADED:ts.spectrum_filter = SPECTRUM_FILTER_DEFAULT; // default filter strength for spectrum scope
|
||||
//CONFIG LOADED:ts.spectrum_centre_line_colour = SPEC_COLOUR_GRID_DEFAULT; // color of center line of scope grid
|
||||
//CONFIG LOADED:ts.spectrum_freqscale_colour = SPEC_COLOUR_SCALE_DEFAULT; // default colour for the spectrum scope frequency scale at the bottom
|
||||
//CONFIG LOADED:ts.spectrum_db_scale = DB_DIV_10; // default to 10dB/division
|
||||
//CONFIG LOADED:ts.spectrum_size = SPECTRUM_SIZE_DEFAULT; // adjustment for waterfall size
|
||||
//CONFIG LOADED:ts.spectrum_agc_rate = SPECTRUM_SCOPE_AGC_DEFAULT; // load default spectrum scope AGC rate
|
||||
|
||||
// scope ui settings
|
||||
//CONFIG LOADED:ts.scope_trace_colour = SPEC_COLOUR_TRACE_DEFAULT; // default colour for the spectrum scope trace
|
||||
//CONFIG LOADED:ts.scope_grid_colour = SPEC_COLOUR_GRID_DEFAULT; // default colour for the spectrum scope grid
|
||||
//CONFIG LOADED:ts.scope_speed = SPECTRUM_SCOPE_SPEED_DEFAULT; // default rate of spectrum scope update
|
||||
ts.scope_scheduler = 0; // timer for scheduling the next update of the spectrum update
|
||||
|
||||
//CONFIG LOADED:ts.waterfall.speed = WATERFALL_SPEED_DEFAULT; // default speed of update of the waterfall
|
||||
//CONFIG LOADED:ts.waterfall.color_scheme = WATERFALL_COLOR_DEFAULT; // color scheme for waterfall display
|
||||
//CONFIG LOADED:ts.waterfall.vert_step_size = WATERFALL_STEP_SIZE_DEFAULT; // step size in waterfall display
|
||||
//CONFIG LOADED:ts.waterfall.contrast = WATERFALL_CONTRAST_DEFAULT; // contrast setting for waterfall display
|
||||
ts.waterfall.scheduler=0;
|
||||
|
||||
// ts.fft_window_type = FFT_WINDOW_DEFAULT; // FFT Windowing type
|
||||
ts.dvmode = false; // disable "DV" mode RX/TX functions by default
|
||||
|
||||
ts.txrx_switch_audio_muting_timing = 0; // timing value used for muting TX audio when keying PTT to suppress "click" or "thump"
|
||||
ts.audio_dac_muting_timer = 0; // timer used for muting TX audio when keying PTT to suppress "click" or "thump"
|
||||
ts.audio_dac_muting_flag = 0; // when TRUE, audio is to be muted after PTT/keyup
|
||||
|
||||
//CONFIG LOADED:ts.filter_disp_colour = FILTER_DISP_COLOUR_DEFAULT;
|
||||
ts.vfo_mem_flag = 0; // when TRUE, memory mode is enabled
|
||||
ts.mem_disp = 0; // when TRUE, memory list is enabled
|
||||
ts.xvtr_disp = false; // when TRUE, XVTR list is enabled
|
||||
//CONFIG LOADED:ts.fm_subaudible_tone_gen_select = 0; // lookup ("tone number") used to index the table generation (0 corresponds to "tone disabled")
|
||||
//CONFIG LOADED:ts.fm_tone_burst_mode = 0; // this is the setting for the tone burst generator
|
||||
ts.fm_tone_burst_timing = 0; // used to time the duration of the tone burst
|
||||
//CONFIG LOADED:ts.fm_sql_threshold = FM_SQUELCH_DEFAULT; // squelch threshold
|
||||
//CONFIG LOADED:ts.fm_subaudible_tone_det_select = 0; // lookup ("tone number") used to index the table for tone detection (0 corresponds to "tone disabled")
|
||||
|
||||
ts.ser_eeprom_type = 0; // serial eeprom not present
|
||||
ts.configstore_in_use = CONFIGSTORE_IN_USE_FLASH; // serial eeprom not in use
|
||||
|
||||
ts.tp = &mchf_touchscreen;
|
||||
ts.display = &mchf_display;
|
||||
|
||||
ts.show_debug_info = false; // dont show coordinates on LCD
|
||||
ts.show_wide_spectrum = false; // default mode of spectrum wide on screen
|
||||
//CONFIG LOADED:ts.tune_power_level = 0; // Tune with FULL POWER
|
||||
ts.power_scale_gen = 100; // power scale for Gen, %
|
||||
ts.power_scale_gen_full = 100; // power scale for Gen, FULL POWER, %
|
||||
//CONFIG LOADED:ts.xlat = 0; // 0 = report base frequency, 1 = report xlat-frequency;
|
||||
ts.audio_int_counter = 0; // test DL2FW
|
||||
ts.cat_band_index =255; // no CAT command arrived
|
||||
|
||||
|
||||
ts.s_meter = 1; // S-Meter configuration, 0 = old school, 1 = dBm-based, 2=dBm/Hz-based
|
||||
//CONFIG LOADED:ts.display_dbm = 0; // style of dBm display, 0=OFF, 1= dbm, 2= dbm/Hz
|
||||
// ts.dBm_count = 0; // timer start
|
||||
//CONFIG LOADED:ts.tx_filter = 0; // which TX filter has been chosen by the user
|
||||
//CONFIG LOADED: ts.iq_auto_correction = 1; // disable/enable automatic IQ correction
|
||||
|
||||
ts.twinpeaks_tested = TWINPEAKS_WAIT;
|
||||
|
||||
//CONFIG LOADED:ts.dbm_constant = 0;
|
||||
|
||||
ts.i2c_speed[I2C_BUS_1] = I2C1_SPEED_DEFAULT; // Si570, MCP9801
|
||||
ts.i2c_speed[I2C_BUS_2] = I2C2_SPEED_DEFAULT; // Codec, EEPROM
|
||||
|
||||
ts.keyer_mode.active = false;
|
||||
ts.keyer_mode.button_recording = KEYER_BUTTON_NONE;
|
||||
for (int idx = 0; idx<KEYER_BUTTONS; idx++)
|
||||
{
|
||||
|
||||
ts.keyer_mode.macro[idx][0] = '\0';
|
||||
// strcpy((char *) ts.keyer_mode.cap[idx], "BTN");
|
||||
strcpy((char *) ts.keyer_mode.cap[idx], "EMPTY");
|
||||
}
|
||||
// ts.buffered_tx = false;
|
||||
ts.keyer_mode_tx = 0;
|
||||
ts.keyer_cycled_tx_active = false;
|
||||
ts.keyer_cycled_tx_timer = 0;
|
||||
ts.keyer_cycled_tx_button = 1;
|
||||
ts.keyer_cycled_interval = 3; // 3 sec.
|
||||
ts.cw_beacon_interval = 18000; // 3 min
|
||||
ts.swbi = BEACON_INTERVAL_3M; // cw beacon interval numerator
|
||||
ts.peak_ind_tune = 3; // timer 0.75 sec
|
||||
ts.cw_text_entry = false;
|
||||
|
||||
ts.ExtFMenuActive = false;
|
||||
ts.XvtrFMenuActive = false;
|
||||
ts.MenuOfFMenusActive = false;
|
||||
|
||||
ts.debug_si5351a_pllreset = 2; //start with "reset on IQ Divider"
|
||||
|
||||
ts.debug_vswr_protection_threshold = 1; // OFF
|
||||
|
||||
//CONFIG LOADED:ts.expflags1 = 0; // Used to hold flags for options in Debug/Expert menu, stored in EEPROM location "EEPROM_EXPFLAGS1"
|
||||
|
||||
ts.lotx_dacs_present = false; // TX LO Supression DACs MCP4725 (x096/x097) is not present
|
||||
for (int idx = 0; idx < 15; idx++) // Band calibrated values for DACs MCP4725
|
||||
{
|
||||
ts.cal_lo_tx_supr0[idx] = 2048; // Half of +5V for each
|
||||
ts.cal_lo_tx_supr1[idx] = 2048; // Half of +5V for each
|
||||
}
|
||||
ts.band_index = 255; // Index of current band in table (by tune freq) - invalid for start
|
||||
ts.HereIsEnableCB26Mc = false; // Tune on enable CB band 26 Mc
|
||||
ts.HereIsEnableCB27Mc = false; // Tune on enable CB band 27 Mc
|
||||
ts.band_lo_tx_supr = 255; // Invalid band number (the band of currently selected frequency (CB band 27 MHz == 28 MHz))
|
||||
ts.band_lo_tx_supr_old = 255; // Invalid band number - old value bla-bla-bla
|
||||
|
||||
ts.band_effective = NULL; // this is an invalid band number, which will trigger a redisplay of the band name and the effective power
|
||||
//#ifdef SDR_AMBER
|
||||
ts.amber_input_state = 0; // Amber - state of RX input group, - PRE(amp)
|
||||
#ifdef SDR_AMBER
|
||||
ts.amber_io8_present = false; // I/Ox8 PCF8574A
|
||||
ts.amber_io8_state = 255;
|
||||
ts.amber_io4_present = false; // I/Ox4 PCA9536
|
||||
ts.amber_io4_state = 0;
|
||||
ts.amber_dac_pwr_tx_present = false; // DAC MCP4725 for TX PWR reg.
|
||||
ts.amber_dac_pwr_tx_state = 2048;
|
||||
ts.amber_pa_bandcode_mode = 0;
|
||||
#endif
|
||||
ts.box_colour = 2; // =Blue - screen boxes colour
|
||||
ts.txtline_colour = 9; // =Yellow - ticker colour
|
||||
ts.cw_smooth = 1; // smooth of CW signal edges == 5 ms
|
||||
ts.cw_smooth_len = 2; // duration of CW signal edges
|
||||
ts.cw_smooth_steps = 9; // duration steps of CW signal edges
|
||||
|
||||
ts.anr_n_taps = 64;
|
||||
ts.anr_delay = 12; //16;
|
||||
ts.anr_two_mu_int = 100;
|
||||
ts.anr_gamma_int = 100;
|
||||
ts.dummy = 0;
|
||||
ts.disabled_tp = false;
|
||||
#ifdef FAST_FREQ_ENC
|
||||
ts.freq_enc_timer = 0;
|
||||
#endif
|
||||
// ts.iq_freq_delta = 10;//0; //Hz
|
||||
ts.it_is_band = true;
|
||||
|
||||
#ifdef HELP_MENU
|
||||
ts.menu_selected_item = 280; // MENU_DEBUG_SHOW_GREETING, No comment
|
||||
ts.help_showing = false;
|
||||
#endif
|
||||
ts.maxi_pos_contest = 23;
|
||||
ts.maxi_pos_contesttry = 23;
|
||||
ts.cmem_colour = White;
|
||||
}
|
||||
|
||||
// #include "Trace.h"
|
||||
#if 0
|
||||
void timeTest1()
|
||||
{
|
||||
static uint32_t time = 0;
|
||||
if (time != RTC->TR)
|
||||
{
|
||||
Board_RedLed(LED_STATE_TOGGLE);
|
||||
time = RTC->TR;
|
||||
}
|
||||
}
|
||||
void timeTest()
|
||||
{
|
||||
MchfRtc_Start();
|
||||
while (1)
|
||||
{
|
||||
timeTest1();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Power on
|
||||
int mchfMain(void)
|
||||
{
|
||||
|
||||
///trace_puts("Hello mcHF World!");
|
||||
// trace_printf(" %u\n", 1u);
|
||||
|
||||
|
||||
// *(__IO uint32_t*)(SRAM2_BASE) = 0x0; // clearing delay prevent for bootloader
|
||||
|
||||
// Set default transceiver state
|
||||
TransceiverStateInit();
|
||||
|
||||
Board_RamSizeDetection();
|
||||
|
||||
#ifdef TESTCPLUSPLUS
|
||||
test_call_cpp();
|
||||
#endif
|
||||
|
||||
// HW init
|
||||
Board_InitMinimal();
|
||||
// Show logo & HW Info
|
||||
UiDriver_StartUpScreenInit(2000);
|
||||
|
||||
if (ts.display != DISPLAY_NONE)
|
||||
{
|
||||
// TODO: Better indication of non-detected display
|
||||
Board_GreenLed(LED_STATE_ON);
|
||||
}
|
||||
|
||||
Board_InitFull();
|
||||
|
||||
ConfigStorage_Init();
|
||||
|
||||
// init mchf_touchscreen to see if it is present
|
||||
// we don't care about the screen being reverse or not
|
||||
// here, so we simply set reverse to false
|
||||
UiLcdHy28_TouchscreenInit(0);
|
||||
|
||||
|
||||
Main_DetectSpecialBootloader();
|
||||
|
||||
UiDriver_Init();
|
||||
|
||||
|
||||
#ifdef STM32F4
|
||||
// we now re-init the I2C buses with the configured speed settings. Loading the EEPROM always uses the default speed!
|
||||
// we can do this only on the STM32F4 as we are not able to change
|
||||
// the speed on the STM32F7/H7 easily via HAL in a portable way
|
||||
UhsdrHw_I2C_ChangeSpeed(&hi2c1);
|
||||
UhsdrHw_I2C_ChangeSpeed(&hi2c2);
|
||||
#endif
|
||||
|
||||
profileTimedEventInit();
|
||||
|
||||
#ifdef USE_HMC1023
|
||||
hmc1023_init();
|
||||
#endif
|
||||
|
||||
// Audio Software Init
|
||||
AudioDriver_Init();
|
||||
|
||||
// Audio Driver Hardware Init
|
||||
ts.codecCS4270_present = false;
|
||||
ts.rf_gain_codecCS4270 = 1.0;
|
||||
ts.codec_present = Codec_Reset(ts.samp_rate) == HAL_OK;
|
||||
|
||||
#ifndef SDR_AMBER
|
||||
UiDriver_StartupScreen_LogIfProblem(ts.codec_present == false,
|
||||
"Audiocodec WM8731 NOT detected!");
|
||||
#else
|
||||
|
||||
#ifdef UI_BRD_MCHF
|
||||
UiDriver_StartupScreen_LogIfProblem(ts.codec_present == false,
|
||||
"Audiocodec WM8731 NOT detected!");
|
||||
#else // OVI40 or Amber
|
||||
UiDriver_StartupScreen_LogIfProblem(ts.codecWM8731_Audio_present == false,
|
||||
"Audio codec WM8731 NOT detected!");
|
||||
if(ts.codecCS4270_present)
|
||||
{
|
||||
// Amber-UI board
|
||||
}
|
||||
else if(!(ts.codec_present) && ts.codecWM8731_Audio_present)
|
||||
{
|
||||
UiDriver_StartupScreen_LogIfProblem(true,
|
||||
"IQ codec WM8731/AS4270 NOT detected!");
|
||||
}
|
||||
// Test
|
||||
GPIO_ResetBits(BAND1_PIO,BAND1);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
const char* bl_version = Board_BootloaderVersion();
|
||||
|
||||
UiDriver_StartupScreen_LogIfProblem(
|
||||
(bl_version[0] == '1' || bl_version[0] == '2' || bl_version[0] == '3' || bl_version[0] == '4') && bl_version[1] == '.',
|
||||
|
||||
"Upgrade bootloader to 5.0.1 or newer");
|
||||
|
||||
AudioFilter_SetDefaultMemories();
|
||||
|
||||
|
||||
ts.rx_gain[RX_AUDIO_SPKR].value_old = 0; // Force update of volume control
|
||||
|
||||
// TX LO Supression DACs MCP4725 (x096/x097) is present?
|
||||
ts.lotx_dacs_present = (UhsdrHw_I2C_DeviceReady(SERIALEEPROM_I2C,LO_TX_SUPR_DAC0_WRITE) == HAL_OK) && (UhsdrHw_I2C_DeviceReady(SERIALEEPROM_I2C,LO_TX_SUPR_DAC1_WRITE) == HAL_OK);
|
||||
#ifdef SDR_AMBER
|
||||
ts.amber_io8_present = UhsdrHw_I2C_DeviceReady(SERIALEEPROM_I2C,AMBER_IO8_WRITE) == HAL_OK;
|
||||
ts.amber_io4_present = UhsdrHw_I2C_DeviceReady(SERIALEEPROM_I2C,AMBER_IO4_WRITE) == HAL_OK;
|
||||
ts.amber_dac_pwr_tx_present = UhsdrHw_I2C_DeviceReady(SI5351A_I2C,AMBER_DAC_PWR_TX_WRITE) == HAL_OK;
|
||||
#endif
|
||||
#ifdef USE_FREEDV
|
||||
FreeDV_Init();
|
||||
// we now try to place a marker after last dynamically
|
||||
// allocated memory
|
||||
Canary_Create();
|
||||
#endif
|
||||
|
||||
UiDriver_StartUpScreenFinish(2000);
|
||||
|
||||
// We initialize the requested demodulation mode
|
||||
// and update the screen accordingly
|
||||
UiDriver_SetDemodMode(ts.dmod_mode);
|
||||
|
||||
// Finally, start DMA transfers to get everything going
|
||||
UhsdrHwI2s_Codec_StartDMA();
|
||||
|
||||
|
||||
// now enable paddles/ptt, i.e. external input
|
||||
ts.paddles_active = true;
|
||||
|
||||
Board_RedLed(LED_STATE_OFF);
|
||||
|
||||
// Eliminate sound blocking on boot in RX-slide mode
|
||||
if(ts.iq_freq_delta == 0)
|
||||
{
|
||||
ts.iq_freq_delta = 10; // Hz
|
||||
}
|
||||
|
||||
|
||||
// Transceiver main loop
|
||||
for(;;)
|
||||
{
|
||||
// UI events processing
|
||||
UiDriver_TaskHandler_MainTasks();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _MCHF_MAIN_H
|
||||
#define _MCHF_MAIN_H
|
||||
|
||||
#include "uhsdr_board.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int mchfMain(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MCHF_MAIN */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* -*- 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 **
|
||||
** **
|
||||
**---------------------------------------------------------------------------------**
|
||||
** **
|
||||
** File name: **
|
||||
** Description: **
|
||||
** Last Modified: **
|
||||
** Licence: GNU GPLv3 **
|
||||
************************************************************************************/
|
||||
|
||||
#define UHSDR_VER_MAJOR "2"
|
||||
#define UHSDR_VER_MINOR "12"
|
||||
#define UHSDR_VER_RELEASE "2m9"
|
||||
|
||||
|
||||
#define UHSDR_BOOT_VERS "5.0.4m"
|
||||
|
||||
|
||||
#ifdef SBLA // Bootloader enables additional rf bands PCB
|
||||
#define UHSDR_BOOT_VER UHSDR_BOOT_VERS"a"
|
||||
#elif SBLS // Bootloader enables special debug capabilities
|
||||
#define UHSDR_BOOT_VER UHSDR_BOOT_VERS"s"
|
||||
#else // Standard Bootloader
|
||||
#define UHSDR_BOOT_VER UHSDR_BOOT_VERS
|
||||
#endif
|
||||
|
||||
// trailing characters are needed for identifying version and building date+time in binary
|
||||
#define UHSDR_VERSION "fwv-"UHSDR_VER_MAJOR"."UHSDR_VER_MINOR"."UHSDR_VER_RELEASE
|
||||
#define UHSDR_BUILD_DAT "fwt-"__DATE__ " - " __TIME__
|
||||
#define UHSDR_LICENCE "GNU GPLv3"
|
||||
#define UHSDR_REPO "github.com/df8oe/UHSDR"
|
||||
Reference in New Issue
Block a user