1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00
LibrePilot/flight/PipXtreme/main.c
stac 841b0d3d6d hwinit: Convert COM and USART to dynamic init
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2771 ebee16cc-31ac-478f-84a7-5cbb03baadba
2011-02-12 22:19:43 +00:00

1035 lines
32 KiB
C
Raw Blame History

/**
******************************************************************************
*
* @file main.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Main modem functions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// *****************************************************************************
#define USE_WATCHDOG // comment this out if you don't want to use the watchdog
// *****************************************************************************
// OpenPilot Includes
#include <string.h>
#include "crc.h"
#include "aes.h"
#include "rfm22b.h"
#include "packet_handler.h"
#include "stream.h"
#include "scan_spectrum.h"
#include "ppm.h"
#include "transparent_comms.h"
//#include "api_comms.h"
#include "api_config.h"
#include "gpio_in.h"
#include "stopwatch.h"
#include "watchdog.h"
#include "saved_settings.h"
#include "main.h"
/* Prototype of PIOS_Board_Init() function */
extern void PIOS_Board_Init(void);
// *****************************************************************************
// ADC data
#define ADC_REF 3.3f // ADC reference voltage
#define ADC_FULL_RANGE 4096 // 12 bit ADC
#define ADC_PSU_RESISTOR_TOP 10000.0f // 10k upper resistor
#define ADC_PSU_RESISTOR_BOTTOM 2700.0f // 2k7 lower resistor
#define ADC_PSU_RATIO (ADC_PSU_RESISTOR_BOTTOM / (ADC_PSU_RESISTOR_TOP + ADC_PSU_RESISTOR_BOTTOM))
#define ADC_PSU_mV_SCALE ((ADC_REF * 1000) / (ADC_FULL_RANGE * ADC_PSU_RATIO))
// *****************************************************************************
// Global Variables
uint32_t flash_size;
char serial_number_str[25];
uint32_t serial_number_crc32;
uint32_t reset_addr;
bool API_Mode;
bool booting;
volatile uint32_t random32;
// *****************************************************************************
// Local Variables
#if defined(USE_WATCHDOG)
volatile uint16_t watchdog_timer;
uint16_t watchdog_delay;
#endif
volatile bool inside_timer_int;
volatile uint32_t uptime_ms;
volatile uint16_t second_tick_timer;
volatile bool second_tick;
//volatile int32_t temp_adc;
//volatile int32_t psu_adc;
// *****************************************************************************
#if defined(USE_WATCHDOG)
void processWatchdog(void)
{
// random32 = UpdateCRC32(random32, IWDG->SR);
if (watchdog_timer < watchdog_delay)
return;
// the watchdog needs resetting
watchdog_timer = 0;
watchdog_Clear();
}
void enableWatchdog(void)
{ // enable a watchdog
watchdog_timer = 0;
watchdog_delay = watchdog_Init(1000); // 1 second watchdog timeout
}
#endif
// *****************************************************************************
/*
void WWDG_IRQHandler(void)
{
// Update WWDG counter
WWDG_SetCounter(0x7F);
// Clear EWI flag
WWDG_ClearFlag();
}
void enableWatchdog(void)
{
// Enable WWDG clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
// On Value line devices, WWDG clock counter = (PCLK1 (24MHz)/4096)/8 = 732 Hz (~1366 <20>s)
// On other devices, WWDG clock counter = (PCLK1(36MHz)/4096)/8 = 1099 Hz (~910 <20>s)
WWDG_SetPrescaler(WWDG_Prescaler_8);
// Set Window value to 65
WWDG_SetWindowValue(65);
// On Value line devices, Enable WWDG and set counter value to 127, WWDG timeout = ~1366 <20>s * 64 = 87.42 ms
// On other devices, Enable WWDG and set counter value to 127, WWDG timeout = ~910 <20>s * 64 = 58.25 ms
WWDG_Enable(127);
// Clear EWI flag
WWDG_ClearFlag();
// Enable EW interrupt
WWDG_EnableIT();
}
*/
// *****************************************************************************
void sequenceLEDs(void)
{
for (int i = 0; i < 2; i++)
{
USB_LED_ON;
PIOS_DELAY_WaitmS(80);
USB_LED_OFF;
LINK_LED_ON;
PIOS_DELAY_WaitmS(80);
LINK_LED_OFF;
RX_LED_ON;
PIOS_DELAY_WaitmS(80);
RX_LED_OFF;
TX_LED_ON;
PIOS_DELAY_WaitmS(80);
TX_LED_OFF;
#if defined(USE_WATCHDOG)
processWatchdog(); // process the watchdog
#endif
}
}
// *****************************************************************************
/*
void setup_SPI(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master,
// SPI_InitStructure.SPI_Mode = SPI_Mode_Slave,
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex,
// SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly,
// SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx,
// SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx,
// SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b,
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b,
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft,
// SPI_InitStructure.SPI_NSS = SPI_NSS_Hard,
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB,
// SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB,
SPI_InitStructure.SPI_CRCPolynomial = 7,
// SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low,
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High,
// SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge,
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2, // fastest SCLK
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64,
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128,
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256, // slowest SCLK
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
*/
// *****************************************************************************
// timer interrupt
void TIMER_INT_FUNC(void)
{
inside_timer_int = TRUE;
if (TIM_GetITStatus(TIMER_INT_TIMER, TIM_IT_Update) != RESET)
{
// Clear timer interrupt pending bit
TIM_ClearITPendingBit(TIMER_INT_TIMER, TIM_IT_Update);
// random32 = UpdateCRC32(random32, PIOS_DELAY_TIMER->CNT >> 8);
// random32 = UpdateCRC32(random32, PIOS_DELAY_TIMER->CNT);
uptime_ms++;
#if defined(USE_WATCHDOG)
watchdog_timer++;
#endif
// ***********
if (!booting)
{
// ***********
if (++second_tick_timer >= 1000)
{
second_tick_timer -= 1000;
second_tick = TRUE;
}
// ***********
// read the chip temperature
// temp_adc = PIOS_ADC_PinGet(0);
// read the psu voltage
// psu_adc = PIOS_ADC_PinGet(1);
// ***********
uint8_t mode = saved_settings.mode;
// modeTxBlankCarrierTest, // blank carrier Tx mode (for calibrating the carrier frequency say)
// modeTxSpectrumTest // pseudo random Tx data mode (for checking the Tx carrier spectrum)
rfm22_1ms_tick(); // rf module tick
if (mode == MODE_NORMAL)
ph_1ms_tick(); // packet handler tick
if (mode == MODE_STREAM_TX || mode == MODE_STREAM_RX)
stream_1ms_tick(); // continuous data stream tick
if (mode == MODE_SCAN_SPECTRUM)
ss_1ms_tick(); // spectrum scan tick
if (mode == MODE_PPM_TX || mode == MODE_PPM_RX)
ppm_1ms_tick(); // ppm tick
if (!API_Mode)
trans_1ms_tick(); // transparent communications tick
else
// api_1ms_tick(); // api communications tick
apiconfig_1ms_tick(); // api communications tick
// ***********
}
}
inside_timer_int = FALSE;
}
void setup_TimerInt(uint16_t Hz)
{ // setup the timer interrupt
// enable timer clock
switch ((uint32_t)TIMER_INT_TIMER)
{
case (uint32_t)TIM1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); break;
case (uint32_t)TIM2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); break;
case (uint32_t)TIM3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); break;
case (uint32_t)TIM4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); break;
#ifdef STM32F10X_HD
case (uint32_t)TIM5: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); break;
case (uint32_t)TIM6: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); break;
case (uint32_t)TIM7: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); break;
case (uint32_t)TIM8: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); break;
#endif
}
// enable timer interrupt
NVIC_InitTypeDef NVIC_InitStructure;
switch ((uint32_t)TIMER_INT_TIMER)
{
// case (uint32_t)TIM1: NVIC_InitStructure.NVIC_IRQChannel = TIM1_IRQn; break;
case (uint32_t)TIM2: NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; break;
case (uint32_t)TIM3: NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; break;
case (uint32_t)TIM4: NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; break;
#ifdef STM32F10X_HD
case (uint32_t)TIM5: NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; break;
case (uint32_t)TIM6: NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; break;
case (uint32_t)TIM7: NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; break;
// case (uint32_t)TIM8: NVIC_InitStructure.NVIC_IRQChannel = TIM8_IRQn; break;
#endif
}
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMER_INT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Time base configuration
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = ((1000000 / Hz) - 1);
TIM_TimeBaseStructure.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1; // For 1 uS accuracy
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIMER_INT_TIMER, &TIM_TimeBaseStructure);
// Enable the CC2 Interrupt Request
TIM_ITConfig(TIMER_INT_TIMER, TIM_IT_Update, ENABLE);
// Clear update pending flag
TIM_ClearFlag(TIMER_INT_TIMER, TIM_FLAG_Update);
// Enable counter
TIM_Cmd(TIMER_INT_TIMER, ENABLE);
}
// *****************************************************************************
// read the CPU's flash and ram sizes
void get_CPUDetails(void)
{
// read the flash size
flash_size = (uint32_t)mem16(0x1FFFF7E0) * 1024;
int j = 0;
// read the CPU electronic signature (12-bytes)
serial_number_str[j] = 0;
for (int i = 0; i < 12; i++)
{
uint8_t ms_nibble = mem8(0x1ffff7e8 + i) >> 4;
uint8_t ls_nibble = mem8(0x1ffff7e8 + i) & 0x0f;
if (j > sizeof(serial_number_str) - 3) break;
serial_number_str[j++] = ((ms_nibble > 9) ? ('A' - 10) : '0') + ms_nibble;
serial_number_str[j++] = ((ls_nibble > 9) ? ('A' - 10) : '0') + ls_nibble;
serial_number_str[j] = 0;
}
// create a 32-bit crc from the serial number hex string
serial_number_crc32 = updateCRC32Data(0xffffffff, serial_number_str, j);
serial_number_crc32 = updateCRC32(serial_number_crc32, j);
// reset_addr = (uint32_t)&Reset_Handler;
}
// *****************************************************************************
void init_RF_module(void)
{
int i = -100;
switch (saved_settings.frequency_band)
{
case FREQBAND_434MHz:
case FREQBAND_868MHz:
case FREQBAND_915MHz:
i = rfm22_init(saved_settings.min_frequency_Hz, saved_settings.max_frequency_Hz, 50000);
break;
default:
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("UNKNOWN BAND ERROR\r\n", i);
#endif
for (int j = 0; j < 8; j++)
{
USB_LED_ON;
LINK_LED_OFF;
RX_LED_ON;
TX_LED_OFF;
PIOS_DELAY_WaitmS(200);
USB_LED_OFF;
LINK_LED_ON;
RX_LED_OFF;
TX_LED_ON;
PIOS_DELAY_WaitmS(200);
#if defined(USE_WATCHDOG)
processWatchdog();
#endif
}
PIOS_DELAY_WaitmS(1000);
PIOS_SYS_Reset();
while (1);
break;
}
if (i < 0)
{ // RF module error .. flash the LED's
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("RF ERROR res: %d\r\n", i);
#endif
for (int j = 0; j < 6; j++)
{
USB_LED_ON;
LINK_LED_ON;
RX_LED_OFF;
TX_LED_OFF;
PIOS_DELAY_WaitmS(200);
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_ON;
TX_LED_ON;
PIOS_DELAY_WaitmS(200);
#if defined(USE_WATCHDOG)
processWatchdog();
#endif
}
PIOS_DELAY_WaitmS(1000);
PIOS_SYS_Reset();
while (1);
}
rfm22_setFreqCalibration(saved_settings.rf_xtal_cap);
ph_setNominalCarrierFrequency(saved_settings.frequency_Hz);
ph_setDatarate(saved_settings.max_rf_bandwidth);
ph_setTxPower(saved_settings.max_tx_power);
}
// *****************************************************************************
// find out what caused our reset and act on it
void processReset(void)
{
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{ // Independant Watchdog Reset
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\nINDEPENDANT WATCHDOG CAUSED A RESET\r\n");
#endif
// all led's ON
USB_LED_ON;
LINK_LED_ON;
RX_LED_ON;
TX_LED_ON;
PIOS_DELAY_WaitmS(500); // delay a bit
// all led's OFF
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_OFF;
TX_LED_OFF;
}
/*
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
{ // Window Watchdog Reset
DEBUG_PRINTF("\r\nWINDOW WATCHDOG CAUSED A REBOOT\r\n");
// all led's ON
USB_LED_ON;
LINK_LED_ON;
RX_LED_ON;
TX_LED_ON;
PIOS_DELAY_WaitmS(500); // delay a bit
// all led's OFF
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_OFF;
TX_LED_OFF;
}
*/
if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
{ // Power-On Reset
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\nPOWER-ON-RESET\r\n");
#endif
}
if (RCC_GetFlagStatus(RCC_FLAG_SFTRST) != RESET)
{ // Software Reset
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\nSOFTWARE RESET\r\n");
#endif
}
if (RCC_GetFlagStatus(RCC_FLAG_LPWRRST) != RESET)
{ // Low-Power Reset
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\nLOW POWER RESET\r\n");
#endif
}
if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
{ // Pin Reset
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\nPIN RESET\r\n");
#endif
}
// Clear reset flags
RCC_ClearFlag();
}
// *****************************************************************************
// Main function
int main()
{
// *************
// init various variables
booting = TRUE;
inside_timer_int = FALSE;
uptime_ms = 0;
flash_size = 0;
serial_number_str[0] = 0;
serial_number_crc32 = 0;
reset_addr = 0;
// temp_adc = -1;
// psu_adc = -1;
// API_Mode = FALSE;
API_Mode = TRUE; // TEST ONLY
second_tick_timer = 0;
second_tick = FALSE;
saved_settings.frequency_band = FREQBAND_UNKNOWN;
// *************
PIOS_Board_Init();
CRC_init();
// read the CPU details
get_CPUDetails();
// setup the GPIO input pins
GPIO_IN_Init();
// *************
// set various GPIO pin states
// uart serial RTS line high
SERIAL_RTS_ENABLE;
SERIAL_RTS_SET;
// RF module chip-select line high
RF_CS_ENABLE;
RF_CS_HIGH;
// EEPROM chip-select line high
EE_CS_ENABLE;
EE_CS_HIGH;
// *************
random32 ^= serial_number_crc32; // try to randomize the random number
// random32 ^= serial_number_crc32 ^ CRC_IDR; // try to randomize the random number
ph_init(serial_number_crc32, 128000, 0); // initialise the packet handler
trans_init(); // initialise the tranparent communications module
// api_init(); // initialise the API communications module
apiconfig_init(); // initialise the API communications module
setup_TimerInt(1000); // setup a 1kHz timer interrupt
#if defined(USE_WATCHDOG)
enableWatchdog(); // enable the watchdog
#endif
// *************
// do a simple LED flash test sequence so the user knows all the led's are working and that we have booted
PIOS_DELAY_WaitmS(100);
// turn all the leds off
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_OFF;
TX_LED_OFF;
PIOS_DELAY_WaitmS(200);
sequenceLEDs();
// turn all the leds off
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_OFF;
TX_LED_OFF;
// *************
// debug stuff
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\n");
DEBUG_PRINTF("PipXtreme v%u.%u rebooted\r\n", VERSION_MAJOR, VERSION_MINOR);
#endif
// *************
// initialize the saved settings module
saved_settings_init();
#if !defined(PIOS_COM_DEBUG)
if (saved_settings.serial_baudrate != 0xffffffff)
PIOS_COM_ChangeBaud(PIOS_COM_SERIAL, saved_settings.serial_baudrate);
#endif
// *************
// read the API mode pin
if (!GPIO_IN(API_MODE_PIN))
API_Mode = TRUE;
// *************
// read the 434/868/915 jumper options
if (!GPIO_IN(_868MHz_PIN) && !GPIO_IN(_915MHz_PIN)) saved_settings.frequency_band = FREQBAND_434MHz; // 434MHz band
else
if (!GPIO_IN(_868MHz_PIN) && GPIO_IN(_915MHz_PIN)) saved_settings.frequency_band = FREQBAND_868MHz; // 868MHz band
else
if ( GPIO_IN(_868MHz_PIN) && !GPIO_IN(_915MHz_PIN)) saved_settings.frequency_band = FREQBAND_915MHz; // 915MHz band
if (saved_settings.mode == 0xff ||
saved_settings.mode == MODE_TX_BLANK_CARRIER_TEST ||
saved_settings.mode == MODE_TX_SPECTRUM_TEST ||
saved_settings.mode == MODE_SCAN_SPECTRUM)
saved_settings.mode = MODE_NORMAL;
// set some defaults if they are not set
switch (saved_settings.frequency_band)
{
case FREQBAND_434MHz:
if (saved_settings.min_frequency_Hz == 0xffffffff)
{
saved_settings.frequency_Hz = 434000000;
saved_settings.min_frequency_Hz = saved_settings.frequency_Hz - 2000000;
saved_settings.max_frequency_Hz = saved_settings.frequency_Hz + 2000000;
}
if (saved_settings.max_rf_bandwidth == 0xffffffff)
{
// saved_settings.max_rf_bandwidth = 500;
// saved_settings.max_rf_bandwidth = 1000;
// saved_settings.max_rf_bandwidth = 2000;
// saved_settings.max_rf_bandwidth = 4000;
// saved_settings.max_rf_bandwidth = 8000;
// saved_settings.max_rf_bandwidth = 9600;
// saved_settings.max_rf_bandwidth = 16000;
// saved_settings.max_rf_bandwidth = 19200;
// saved_settings.max_rf_bandwidth = 24000;
// saved_settings.max_rf_bandwidth = 32000;
// saved_settings.max_rf_bandwidth = 64000;
saved_settings.max_rf_bandwidth = 128000;
// saved_settings.max_rf_bandwidth = 192000;
}
if (saved_settings.max_tx_power == 0xff)
{
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_0; // +1dBm ... 1.25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_1; // +2dBm ... 1.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_2; // +5dBm ... 3.16mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_3; // +8dBm ... 6.3mW
saved_settings.max_tx_power = RFM22_tx_pwr_txpow_4; // +11dBm .. 12.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_5; // +14dBm .. 25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_6; // +17dBm .. 50mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_7; // +20dBm .. 100mW
}
break;
case FREQBAND_868MHz:
if (saved_settings.min_frequency_Hz == 0xffffffff)
{
saved_settings.frequency_Hz = 868000000;
saved_settings.min_frequency_Hz = saved_settings.frequency_Hz - 10000000;
saved_settings.max_frequency_Hz = saved_settings.frequency_Hz + 10000000;
}
if (saved_settings.max_rf_bandwidth == 0xffffffff)
{
// saved_settings.max_rf_bandwidth = 500;
// saved_settings.max_rf_bandwidth = 1000;
// saved_settings.max_rf_bandwidth = 2000;
// saved_settings.max_rf_bandwidth = 4000;
// saved_settings.max_rf_bandwidth = 8000;
// saved_settings.max_rf_bandwidth = 9600;
// saved_settings.max_rf_bandwidth = 16000;
// saved_settings.max_rf_bandwidth = 19200;
// saved_settings.max_rf_bandwidth = 24000;
// saved_settings.max_rf_bandwidth = 32000;
// saved_settings.max_rf_bandwidth = 64000;
saved_settings.max_rf_bandwidth = 128000;
// saved_settings.max_rf_bandwidth = 192000;
}
if (saved_settings.max_tx_power == 0xff)
{
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_0; // +1dBm ... 1.25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_1; // +2dBm ... 1.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_2; // +5dBm ... 3.16mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_3; // +8dBm ... 6.3mW
saved_settings.max_tx_power = RFM22_tx_pwr_txpow_4; // +11dBm .. 12.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_5; // +14dBm .. 25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_6; // +17dBm .. 50mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_7; // +20dBm .. 100mW
}
break;
case FREQBAND_915MHz:
if (saved_settings.min_frequency_Hz == 0xffffffff)
{
saved_settings.frequency_Hz = 915000000;
saved_settings.min_frequency_Hz = saved_settings.frequency_Hz - 13000000;
saved_settings.max_frequency_Hz = saved_settings.frequency_Hz + 13000000;
}
if (saved_settings.max_rf_bandwidth == 0xffffffff)
{
// saved_settings.max_rf_bandwidth = 500;
// saved_settings.max_rf_bandwidth = 1000;
// saved_settings.max_rf_bandwidth = 2000;
// saved_settings.max_rf_bandwidth = 4000;
// saved_settings.max_rf_bandwidth = 8000;
// saved_settings.max_rf_bandwidth = 9600;
// saved_settings.max_rf_bandwidth = 16000;
// saved_settings.max_rf_bandwidth = 19200;
// saved_settings.max_rf_bandwidth = 24000;
// saved_settings.max_rf_bandwidth = 32000;
// saved_settings.max_rf_bandwidth = 64000;
saved_settings.max_rf_bandwidth = 128000;
// saved_settings.max_rf_bandwidth = 192000;
}
if (saved_settings.max_tx_power == 0xff)
{
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_0; // +1dBm ... 1.25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_1; // +2dBm ... 1.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_2; // +5dBm ... 3.16mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_3; // +8dBm ... 6.3mW
saved_settings.max_tx_power = RFM22_tx_pwr_txpow_4; // +11dBm .. 12.6mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_5; // +14dBm .. 25mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_6; // +17dBm .. 50mW
// saved_settings.max_tx_power = RFM22_tx_pwr_txpow_7; // +20dBm .. 100mW
}
break;
default:
break;
}
// if (serial_number_crc32 == 0x176C1EC6) saved_settings.destination_id = 0xA524A3B0; // modem 1, open a connection to modem 2
// else
// if (serial_number_crc32 == 0xA524A3B0) saved_settings.destination_id = 0x176C1EC6; // modem 2, open a connection to modem 1
// *************
processReset(); // Determine what caused the reset/reboot
// *************
// debug stuff
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\n");
DEBUG_PRINTF("CPU flash size: %u\r\n", flash_size);
DEBUG_PRINTF("CPU serial number: %s %08X\r\n", serial_number_str, serial_number_crc32);
// DEBUG_PRINTF("Reset address: %08X\r\n", reset_addr);
if (!API_Mode)
DEBUG_PRINTF("TRANSPARENT mode\r\n");
else
DEBUG_PRINTF("API mode\r\n");
switch (saved_settings.frequency_band)
{
case FREQBAND_UNKNOWN: DEBUG_PRINTF("UNKNOWN band\r\n"); break;
case FREQBAND_434MHz: DEBUG_PRINTF("434MHz band\r\n"); break;
case FREQBAND_868MHz: DEBUG_PRINTF("868MHz band\r\n"); break;
case FREQBAND_915MHz: DEBUG_PRINTF("915MHz band\r\n"); break;
}
#endif
// *************
init_RF_module(); // initialise the RF module
stream_init(); // initialise the continuous packet stream module
ppm_init(); // initialise the ppm module
ss_init(); // initialise the spectrum scanning module
// *************
saved_settings_save();
booting = FALSE;
// *************
// Main executive loop
#if defined(PIOS_COM_DEBUG)
DEBUG_PRINTF("\r\n");
DEBUG_PRINTF("RF datarate: %dbps\r\n", ph_getDatarate());
DEBUG_PRINTF("RF frequency: %dHz\r\n", rfm22_getNominalCarrierFrequency());
DEBUG_PRINTF("RF TX power: %d\r\n", ph_getTxPower());
#endif
// start a remote connection going
ph_set_remote_encryption(0, saved_settings.aes_enable, (const void *)saved_settings.aes_key);
ph_set_remote_serial_number(0, saved_settings.destination_id);
for (;;)
{
random32 = updateCRC32(random32, PIOS_DELAY_TIMER->CNT >> 8);
random32 = updateCRC32(random32, PIOS_DELAY_TIMER->CNT);
if (second_tick)
{
second_tick = FALSE;
// *************************
// display the up-time .. HH:MM:SS
// #if defined(PIOS_COM_DEBUG)
// int32_t _uptime_ms = uptime_ms;
// uint32_t _uptime_sec = _uptime_ms / 1000;
// DEBUG_PRINTF("Uptime: %02d:%02d:%02d.%03d\r\n", _uptime_sec / 3600, (_uptime_sec / 60) % 60, _uptime_sec % 60, _uptime_ms % 1000);
// #endif
// *************************
// process the Temperature
// if (temp_adc >= 0)
// {
// int32_t degress_C = temp_adc;
//
// #if defined(PIOS_COM_DEBUG)
// DEBUG_PRINTF("TEMP: %d %d\r\n", temp_adc, degress_C);
// #endif
// }
// *************************
// process the PSU voltage level
// if (psu_adc >= 0)
// {
// int32_t psu_mV = psu_adc * ADC_PSU_mV_SCALE;
//
// #if defined(PIOS_COM_DEBUG)
// DEBUG_PRINTF("PSU: %d, %dmV\r\n", psu_adc, psu_mV);
// #endif
// }
// *************************
// rfm22_setTxCarrierMode(); // TEST ONLY
}
rfm22_process(); // rf hardware layer processing
uint8_t mode = saved_settings.mode;
// modeTxBlankCarrierTest, // blank carrier Tx mode (for calibrating the carrier frequency say)
// modeTxSpectrumTest // pseudo random Tx data mode (for checking the Tx carrier spectrum)
if (mode == MODE_NORMAL)
ph_process(); // packet handler processing
if (mode == MODE_STREAM_TX || mode == MODE_STREAM_RX)
stream_process(); // continuous data stream processing
if (mode == MODE_SCAN_SPECTRUM)
ss_process(); // spectrum scan processing
if (mode == MODE_PPM_TX || mode == MODE_PPM_RX)
ppm_process(); // ppm processing
if (!API_Mode)
trans_process(); // tranparent local communication processing (serial port and usb port)
else
// api_process(); // API local communication processing (serial port and usb port)
apiconfig_process(); // API local communication processing (serial port and usb port)
// ******************
// TEST ONLY ... get/put data over the radio link .. speed testing .. comment out trans_process() and api_process() if testing with this
/*
int connection_index = 0;
if (ph_connected(connection_index))
{ // we have a connection to a remote modem
uint8_t buffer[128];
uint16_t num = ph_getData_used(connection_index); // number of bytes waiting for us to get
if (num > 0)
{ // their is data in the received buffer - fetch it
if (num > sizeof(buffer)) num = sizeof(buffer);
num = ph_getData(connection_index, buffer, num); // fetch the received data
}
// keep the tx buffer topped up
num = ph_putData_free(connection_index);
if (num > 0)
{ // their is space available in the transmit buffer - top it up
if (num > sizeof(buffer)) num = sizeof(buffer);
for (int16_t i = 0; i < num; i++) buffer[i] = i;
num = ph_putData(connection_index, buffer, num);
}
}
*/
// ******************
#if defined(USE_WATCHDOG)
processWatchdog(); // process the watchdog
#endif
}
// *************
// we should never arrive here
// disable all interrupts
PIOS_IRQ_Disable();
// turn off all leds
USB_LED_OFF;
LINK_LED_OFF;
RX_LED_OFF;
TX_LED_OFF;
PIOS_SYS_Reset();
while (1);
return 0;
}
// *****************************************************************************