Regulatory testing mode. Disable the BT module, enable demodulator, and transmit a test beacon at regular intervals.

cert
Rob Riggs 2018-11-14 16:57:01 -06:00
rodzic c75b20e9c1
commit 1be6b066bc
6 zmienionych plików z 170 dodań i 8 usunięć

Wyświetl plik

@ -4,6 +4,12 @@
#include "Digipeater.hpp"
#include "Digipeater.h"
#include "IOEventTask.h"
#include "HdlcFrame.hpp"
#include <algorithm>
#include <iterator>
extern osMessageQId hdlcOutputQueueHandle;
/*
* APRS Digipeater implementation.
@ -51,9 +57,35 @@ void startDigipeaterTask(void* arg)
}
}
const uint8_t test_beacon[] = {
0x82, 0xa0, 0xb0, 0x64, 0x60, 0x70, 0x60, 0xae,
0xb0, 0x72, 0x9e, 0x40, 0x40, 0x66, 0xae, 0x92,
0x88, 0x8a, 0x64, 0x40, 0x63, 0x03, 0xf0, 0x3d,
0x34, 0x31, 0x35, 0x34, 0x2e, 0x37, 0x20, 0x4e,
0x2f, 0x30, 0x38, 0x37, 0x34, 0x31, 0x2e, 0x32,
0x20, 0x57, 0x33, 0x50, 0x48, 0x47, 0x33, 0x32,
0x36, 0x30, 0x2d, 0x4d, 0x6f, 0x62, 0x69, 0x6c,
0x69, 0x6e, 0x6b, 0x64, 0x20, 0x50, 0x72, 0x6f,
0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x42,
0x4c, 0x45, 0x20, 0x54, 0x4e, 0x43, 0x0d
};
void beacon(void* arg)
{
using namespace mobilinkd::tnc;
auto frame = hdlc::acquire_wait();
std::copy(test_beacon, test_beacon + sizeof(test_beacon),
std::back_inserter(*frame));
if (osMessagePut(hdlcOutputQueueHandle,
reinterpret_cast<uint32_t>(frame),
osWaitForever) != osOK)
{
ERROR("Failed to write frame to TX queue");
hdlc::release(frame);
}
}
namespace mobilinkd { namespace tnc {

Wyświetl plik

@ -71,11 +71,13 @@ struct Digipeater
*/
const kiss::Alias* can_repeat(hdlc::IoFrame* frame)
{
(void) frame;
return nullptr;
}
hdlc::IoFrame* rewrite_frame(hdlc::IoFrame* frame)
{
(void) frame;
frame->source(hdlc::IoFrame::DIGI_DATA);
return frame;
}

Wyświetl plik

@ -33,6 +33,7 @@ class Frame : public list_base_hook<>
public:
typedef POOL pool_type;
typedef buffer::SegmentedBuffer<POOL, allocator> data_type;
typedef typename data_type::value_type value_type;
typedef typename data_type::iterator iterator;
enum Type {

Wyświetl plik

@ -27,6 +27,7 @@
extern osMessageQId hdlcOutputQueueHandle;
extern PCD_HandleTypeDef hpcd_USB_FS;
extern UART_HandleTypeDef huart3;
extern osTimerId beaconTimer1Handle;
extern "C" void stop2(void);
extern "C" void shutdown(void);
@ -41,6 +42,8 @@ void startIOEventTask(void const*)
{
using namespace mobilinkd::tnc;
static bool demod{false};
indicate_on();
print_startup_banner();
@ -129,8 +132,8 @@ void startIOEventTask(void const*)
stop2();
break;
} else {
HAL_PCD_MspDeInit(&hpcd_USB_FS);
HAL_GPIO_WritePin(USB_CE_GPIO_Port, USB_CE_Pin, GPIO_PIN_SET);
HAL_PCD_MspDeInit(&hpcd_USB_FS);
if (ioport != getUsbPort())
{
break;
@ -189,13 +192,37 @@ void startIOEventTask(void const*)
break;
case CMD_BOOT_BUTTON_DOWN:
DEBUG("BOOT Down");
// If the TNC has USB power, reboot. The boot pin is being
// held so it will boot into the bootloader. This is a bit
// of a hack, since we really should check if the port is a
// standard USB port and not just a charging port.
if (gpio::USB_POWER::get() and ioport == getNullPort())
// switch between demod and idle via boot pin.
if (ioport == getNullPort())
{
HAL_NVIC_SystemReset();
if (demod) {
osMessagePut(audioInputQueueHandle,
audio::IDLE, osWaitForever);
HAL_GPIO_WritePin(BT_SLEEP_GPIO_Port, BT_SLEEP_Pin,
GPIO_PIN_SET);
bm78_wait_until_ready();
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_UART_MspInit(&huart3);
indicate_waiting_to_connect();
demod = false;
} else {
osMessagePut(audioInputQueueHandle,
audio::DEMODULATOR, osWaitForever);
HAL_UART_MspDeInit(&huart3);
HAL_NVIC_DisableIRQ(EXTI4_IRQn);
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
HAL_GPIO_WritePin(BT_SLEEP_GPIO_Port, BT_SLEEP_Pin,
GPIO_PIN_RESET);
indicate_testing();
demod = true;
}
}
break;
case CMD_BOOT_BUTTON_UP:
@ -203,13 +230,16 @@ void startIOEventTask(void const*)
osMessagePut(audioInputQueueHandle,
audio::AUTO_ADJUST_INPUT_LEVEL,
osWaitForever);
if (ioport != getNullPort())
if (ioport != getNullPort() or demod)
{
osMessagePut(audioInputQueueHandle,
audio::DEMODULATOR, osWaitForever);
osTimerStart(beaconTimer1Handle, 60000);
}
else
{
osTimerStop(beaconTimer1Handle);
osMessagePut(audioInputQueueHandle,
audio::IDLE, osWaitForever);
}

Wyświetl plik

@ -360,6 +360,90 @@ struct USBConnection
}
};
/**
* Testing shows a low, medium breathing. Each breath inhale takes
* for 200ms, is held for 400ms, and exhaled in 300ms. This is repeated
* every 3 seconds. Maximum brightness is 20%.
*
* Each interrupt occurs at 10ms intervals.
*
* The sequence is:
* - ramp up 300ms(30)
* - hold 400ms (40)
* - ramp down 300ms (30)
* - wait 2000ms (200)
*
*
*/
struct Testing
{
enum STATE
{
RAMP_UP_1, WAIT_1, RAMP_DN_1, WAIT_2
};
int count { 0 };
int state { RAMP_UP_1 };
int operator()()
{
int result;
switch (state) {
case RAMP_UP_1:
result = count * 50;
if (count == 29)
{
count = 0;
state = WAIT_1;
}
else
{
++count;
}
break;
case WAIT_1:
result = 1500;
if (count == 39)
{
state = RAMP_DN_1;
count = 29;
}
else
{
++count;
}
break;
case RAMP_DN_1:
result = count * 50;
if (count == 0)
{
count = 0;
state = WAIT_2;
}
else
{
--count;
}
break;
case WAIT_2:
result = 0;
if (count == 200)
{
state = RAMP_UP_1;
count = 0;
}
else
{
++count;
}
break;
}
return result;
}
};
struct Flash
{
enum class STATE
@ -385,6 +469,7 @@ struct Flash
NoConnection noConnection;
BluetoothConnection btConnection;
USBConnection usbConnection;
Testing regulatoryTesting;
function_type blue_func { noConnection };
@ -501,6 +586,12 @@ struct Flash
blue_func = btConnection;
HAL_TIM_PWM_Start(&htim1, BLUE_CHANNEL);
}
void test()
{
blue_func = regulatoryTesting;
HAL_TIM_PWM_Start(&htim1, BLUE_CHANNEL);
}
};
Flash& flash()
@ -556,6 +647,11 @@ void indicate_connected_via_ble(void)
mobilinkd::tnc::flash().bt();
}
void indicate_testing(void)
{
mobilinkd::tnc::flash().test();
}
void tx_on(void)
{
mobilinkd::tnc::flash().tx_on();

Wyświetl plik

@ -15,6 +15,7 @@ void indicate_turning_off(void);
void indicate_waiting_to_connect(void);
void indicate_connected_via_usb(void);
void indicate_connected_via_ble(void);
void indicate_testing(void);
void tx_on(void);
void tx_off(void);
void rx_on(void);