kopia lustrzana https://github.com/mobilinkd/tnc3-firmware
Regulatory testing mode. Disable the BT module, enable demodulator, and transmit a test beacon at regular intervals.
rodzic
c75b20e9c1
commit
1be6b066bc
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue