kopia lustrzana https://github.com/DL7AD/pecanpico10
Multiple updates
- Trace out and shell. To get shell type any key. Trace is suspended. - Fixed bug where AX25 receive FIFO was left locked. - Improved trace message for AX25 packets with bad CRC. - Additions to config.c in preparation for adding fixed location beacon.pull/4/head
rodzic
f3f99aaaf4
commit
40042dc7c0
|
@ -0,0 +1 @@
|
|||
/pecanpico10-rescue.lib
|
|
@ -354,7 +354,7 @@ THD_FUNCTION(shellThread, p) {
|
|||
|
||||
chprintf(chp, SHELL_NEWLINE_STR);
|
||||
chprintf(chp, "ChibiOS/RT Shell" SHELL_NEWLINE_STR);
|
||||
while (true) {
|
||||
while (!chThdShouldTerminateX()) {
|
||||
chprintf(chp, SHELL_PROMPT_STR);
|
||||
if (shellGetLine(scfg, line, sizeof(line), shp)) {
|
||||
#if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_)
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
conf_t conf_sram;
|
||||
|
||||
const conf_t conf_flash_default = {
|
||||
// Primary position transmission thread
|
||||
// Primary position node
|
||||
.pos_pri = {
|
||||
.thread_conf = {
|
||||
.active = true,
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(60*30),
|
||||
.init_delay = TIME_S2I(30)
|
||||
},
|
||||
|
@ -21,16 +21,16 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x4F,
|
||||
},
|
||||
|
||||
// Node identity
|
||||
.call = "VK2GJ-12",
|
||||
.path = "WIDE2-1",
|
||||
.symbol = SYM_DIGIPEATER,
|
||||
.symbol = SYM_ANTENNA,
|
||||
.aprs_msg = true,
|
||||
|
||||
.tel_enc_cycle = TIME_S2I(10800)
|
||||
},
|
||||
|
||||
// Secondary position transmission thread
|
||||
// Secondary position node
|
||||
.pos_sec = {
|
||||
.thread_conf = {
|
||||
.active = false,
|
||||
|
@ -43,7 +43,7 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x4F
|
||||
},
|
||||
|
||||
// Node identity
|
||||
.call = "DL7AD-14",
|
||||
.path = "WIDE1-1",
|
||||
.symbol = SYM_BALLOON,
|
||||
|
@ -52,11 +52,11 @@ const conf_t conf_flash_default = {
|
|||
.tel_enc_cycle = TIME_S2I(10800)
|
||||
},
|
||||
|
||||
// Primary image transmission thread
|
||||
// Primary image node
|
||||
.img_pri = {
|
||||
.thread_conf = {
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(60*5),
|
||||
.cycle = TIME_S2I(60*10),
|
||||
.init_delay = TIME_S2I(60*5),
|
||||
.send_spacing = TIME_S2I(5)
|
||||
},
|
||||
|
@ -67,21 +67,21 @@ const conf_t conf_flash_default = {
|
|||
.rssi = 0x4F,
|
||||
.redundantTx = false
|
||||
},
|
||||
|
||||
// Node identity
|
||||
.call = "VK2GJ-15",
|
||||
.path = "",
|
||||
|
||||
.res = RES_VGA,
|
||||
.quality = 4,
|
||||
.buf_size = 64*1024
|
||||
.buf_size = 40*1024
|
||||
},
|
||||
|
||||
// Secondary image transmission thread
|
||||
// Secondary image node
|
||||
.img_sec = {
|
||||
.thread_conf = {
|
||||
.active = true,
|
||||
.cycle = TIME_S2I(300),
|
||||
.init_delay = TIME_S2I(60),
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(60*5),
|
||||
.init_delay = TIME_S2I(60*1),
|
||||
.send_spacing = TIME_S2I(30)
|
||||
},
|
||||
.radio_conf = {
|
||||
|
@ -90,16 +90,16 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x4F
|
||||
},
|
||||
|
||||
.call = "VK2GJ-15",
|
||||
// Node identity
|
||||
.call = "VK2GJ-14",
|
||||
.path = "",
|
||||
|
||||
.res = RES_QVGA,
|
||||
.quality = 4,
|
||||
.buf_size = 64*1024
|
||||
.buf_size = 15*1024
|
||||
},
|
||||
|
||||
// Log transmission thread
|
||||
// Log node
|
||||
.log = {
|
||||
.thread_conf = {
|
||||
.active = false,
|
||||
|
@ -112,13 +112,13 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x4F
|
||||
},
|
||||
|
||||
// Node identity
|
||||
.call = "VK2GJ-13",
|
||||
.path = "WIDE1-1",
|
||||
.density = 10
|
||||
},
|
||||
|
||||
// APRS system control
|
||||
// APRS node
|
||||
.aprs = {
|
||||
.thread_conf = {
|
||||
.active = true,
|
||||
|
@ -130,6 +130,7 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x3F
|
||||
},
|
||||
// Node rx identity
|
||||
.call = "VK2GJ-4"
|
||||
},
|
||||
.tx = { // The transmit identity for digipeat transmit and messages responses
|
||||
|
@ -139,6 +140,7 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.rssi = 0x4F
|
||||
},
|
||||
// Node tx identity
|
||||
.call = "VK2GJ-5",
|
||||
.path = "WIDE2-1",
|
||||
.symbol = SYM_DIGIPEATER,
|
||||
|
@ -147,7 +149,8 @@ const conf_t conf_flash_default = {
|
|||
.lon = 1511143478,
|
||||
.alt = 144
|
||||
},
|
||||
.base = { // The base station parameters - how and where tracker originated messages are sent
|
||||
.base = {
|
||||
// The base station identity - how and where tracker originated messages are sent
|
||||
.enabled = true,
|
||||
.call = "VK2GJ-7",
|
||||
.path = "WIDE2-1",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
|
||||
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
|
||||
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power. */
|
||||
#define ENABLE_EXTERNAL_I2C TRUE /* The external port can be used for bit bang I2C. */
|
||||
#define ENABLE_EXTERNAL_I2C FALSE /* The external port can be used for bit bang I2C. */
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
@ -18,5 +18,4 @@
|
|||
extern conf_t conf_sram;
|
||||
extern const conf_t conf_flash_default;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
||||
|
|
|
@ -6,60 +6,137 @@
|
|||
#include "pktconf.h"
|
||||
|
||||
static thread_t *shelltp;
|
||||
static bool usb_initialized;
|
||||
sdu_term_t sdu_chn_state;
|
||||
|
||||
event_listener_t shell_el;
|
||||
event_listener_t sdu1_el;
|
||||
|
||||
static const ShellConfig shell_cfg = {
|
||||
(BaseSequentialStream*)&SDU1,
|
||||
commands
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void startUSB(void) {
|
||||
if(usb_initialized)
|
||||
return; // Avoid duplicate initialization
|
||||
usbObjectInit(&USBD1);
|
||||
|
||||
/* Initialize USB. */
|
||||
sduObjectInit(&SDU1);
|
||||
usbStart(&USBD1, &usbcfg);
|
||||
|
||||
/* Currently does nothing. */
|
||||
usbDisconnectBus(serusbcfg.usbp);
|
||||
usbDisconnectBus(&USBD1);
|
||||
|
||||
chThdSleep(TIME_MS2I(100));
|
||||
|
||||
usbStart(serusbcfg.usbp, &usbcfg);
|
||||
|
||||
/* Currently does nothing. */
|
||||
usbConnectBus(serusbcfg.usbp);
|
||||
usbConnectBus(&USBD1);
|
||||
|
||||
sduStart(&SDU1, &serusbcfg);
|
||||
|
||||
// Initialize shell
|
||||
shelltp = NULL;
|
||||
shellInit();
|
||||
|
||||
usb_initialized = true;
|
||||
sdu_chn_state = TERM_SDU_INIT;
|
||||
}
|
||||
|
||||
void manageShell(void) {
|
||||
if(shelltp == NULL && isUSBactive()) {
|
||||
|
||||
shelltp = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(4*1024),
|
||||
"shell", NORMALPRIO + 1,
|
||||
shellThread,
|
||||
(void*)&shell_cfg);
|
||||
|
||||
|
||||
chEvtRegister(&shell_terminated, &shell_el, USB_SHELL_EVT);
|
||||
}
|
||||
chEvtWaitAnyTimeout(EVENT_MASK(USB_SHELL_EVT), TIME_S2I(1));
|
||||
if(chThdTerminatedX(shelltp)) {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
chEvtUnregister(&shell_terminated, &shell_el);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void startSDU(void) {
|
||||
if(sdu_chn_state != TERM_SDU_INIT)
|
||||
return;
|
||||
sduObjectInit(&SDU1);
|
||||
chEvtRegister(chnGetEventSource(&SDU1), &sdu1_el, USB_SDU1_EVT);
|
||||
sduStart(&SDU1, &serusbcfg);
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Manage trace output and shell on Serial Over USB.
|
||||
* @notes TRACE output is sent to USB serial.
|
||||
* @notes TRACE output is suspended when any key is pressed on terminal.
|
||||
* @notes A new shell is invoked and remains active until logout.
|
||||
* @notes TRACE output is then resotored.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void manageTraceAndShell(void) {
|
||||
|
||||
if(chEvtGetAndClearEvents(EVENT_MASK(USB_SDU1_EVT)) == 0)
|
||||
return;
|
||||
|
||||
BaseSequentialStream *chp = (BaseSequentialStream *)&SDU1;
|
||||
|
||||
eventflags_t evtf = chEvtGetAndClearFlags(&sdu1_el);
|
||||
|
||||
switch(sdu_chn_state) {
|
||||
case TERM_SDU_INIT:
|
||||
return;
|
||||
|
||||
case TERM_SDU_IDLE: {
|
||||
if(evtf == 0)
|
||||
return;
|
||||
if(evtf & CHN_CONNECTED) {
|
||||
sdu_chn_state = TERM_SDU_OUT;
|
||||
chprintf(chp, "\r\n*** Trace output enabled ***\r\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_IDLE */
|
||||
|
||||
case TERM_SDU_OUT: {
|
||||
if(evtf & CHN_DISCONNECTED) {
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
return;
|
||||
}
|
||||
if(evtf & CHN_INPUT_AVAILABLE) {
|
||||
/* Flush the input queue. */
|
||||
while(chnGetTimeout((SerialUSBDriver *)chp, TIME_MS2I(100)) != STM_TIMEOUT);
|
||||
chprintf(chp, "\r\n*** Trace suspended - type ^D or use the "
|
||||
"'exit' command to resume trace ***\r\n");
|
||||
shellInit();
|
||||
shelltp = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(4*1024),
|
||||
"shell", NORMALPRIO + 1,
|
||||
shellThread,
|
||||
(void*)&shell_cfg);
|
||||
if(shelltp == NULL) {
|
||||
chprintf(chp, "\r\n*** Failed to open shell ***\r\n");
|
||||
break;
|
||||
}
|
||||
sdu_chn_state = TERM_SDU_SHELL;
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_OUT */
|
||||
|
||||
case TERM_SDU_SHELL: {
|
||||
/* USB disconnect. */
|
||||
if(evtf & CHN_DISCONNECTED) {
|
||||
chThdTerminate(shelltp);
|
||||
sdu_chn_state = TERM_SDU_EXIT;
|
||||
break;
|
||||
}
|
||||
/* Was shell terminated from CLI? */
|
||||
if(chThdTerminatedX(shelltp)) {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
sdu_chn_state = TERM_SDU_OUT;
|
||||
chprintf(chp, "\r\n*** Trace resumed by user ***\r\n");
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_SHELL */
|
||||
|
||||
case TERM_SDU_EXIT: {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
break;
|
||||
} /* End case TERM_SDU_EXIT */
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* End switch. */
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
bool isSDUAvailable(void) {
|
||||
return usb_initialized;
|
||||
/* Return channel connection status of SDU. */
|
||||
return (bool)(sdu_chn_state == TERM_SDU_OUT);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,19 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
typedef enum sduTermStates {
|
||||
TERM_SDU_INIT = 0,
|
||||
TERM_SDU_IDLE,
|
||||
TERM_SDU_OUT,
|
||||
TERM_SDU_SHELL,
|
||||
TERM_SDU_EXIT
|
||||
} sdu_term_t;
|
||||
|
||||
#define isUSBactive() (SDU1.config->usbp->state == USB_ACTIVE)
|
||||
|
||||
void startUSB(void);
|
||||
void manageShell(void);
|
||||
void startSDU(void);
|
||||
void manageTraceAndShell(void);
|
||||
bool isSDUAvailable(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,344 +1,344 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Virtual serial port over USB.*/
|
||||
SerialUSBDriver SDU1;
|
||||
|
||||
/*
|
||||
* Endpoints to be used for USBD1.
|
||||
*/
|
||||
#define USBD1_DATA_REQUEST_EP 1
|
||||
#define USBD1_DATA_AVAILABLE_EP 1
|
||||
#define USBD1_INTERRUPT_REQUEST_EP 2
|
||||
|
||||
/*
|
||||
* USB Device Descriptor.
|
||||
*/
|
||||
static const uint8_t vcom_device_descriptor_data[18] = {
|
||||
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
|
||||
0x02, /* bDeviceClass (CDC). */
|
||||
0x00, /* bDeviceSubClass. */
|
||||
0x00, /* bDeviceProtocol. */
|
||||
0x40, /* bMaxPacketSize. */
|
||||
0x0483, /* idVendor (ST). */
|
||||
0x5740, /* idProduct. */
|
||||
0x0200, /* bcdDevice. */
|
||||
1, /* iManufacturer. */
|
||||
2, /* iProduct. */
|
||||
3, /* iSerialNumber. */
|
||||
1) /* bNumConfigurations. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_device_descriptor = {
|
||||
sizeof vcom_device_descriptor_data,
|
||||
vcom_device_descriptor_data
|
||||
};
|
||||
|
||||
/* Configuration Descriptor tree for a CDC.*/
|
||||
static const uint8_t vcom_configuration_descriptor_data[67] = {
|
||||
/* Configuration Descriptor.*/
|
||||
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
|
||||
0x02, /* bNumInterfaces. */
|
||||
0x01, /* bConfigurationValue. */
|
||||
0, /* iConfiguration. */
|
||||
0xC0, /* bmAttributes (self powered). */
|
||||
50), /* bMaxPower (100mA). */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x01, /* bNumEndpoints. */
|
||||
0x02, /* bInterfaceClass (Communications
|
||||
Interface Class, CDC section
|
||||
4.2). */
|
||||
0x02, /* bInterfaceSubClass (Abstract
|
||||
Control Model, CDC section 4.3). */
|
||||
0x01, /* bInterfaceProtocol (AT commands,
|
||||
CDC section 4.4). */
|
||||
0), /* iInterface. */
|
||||
/* Header Functional Descriptor (CDC section 5.2.3).*/
|
||||
USB_DESC_BYTE (5), /* bLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
|
||||
Functional Descriptor. */
|
||||
USB_DESC_BCD (0x0110), /* bcdCDC. */
|
||||
/* Call Management Functional Descriptor. */
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
|
||||
USB_DESC_BYTE (0x01), /* bDataInterface. */
|
||||
/* ACM Functional Descriptor.*/
|
||||
USB_DESC_BYTE (4), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
|
||||
Control Management Descriptor). */
|
||||
USB_DESC_BYTE (0x02), /* bmCapabilities. */
|
||||
/* Union Functional Descriptor.*/
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
|
||||
Class Interface). */
|
||||
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
|
||||
Interface). */
|
||||
/* Endpoint 2 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
|
||||
0x03, /* bmAttributes (Interrupt). */
|
||||
0x0008, /* wMaxPacketSize. */
|
||||
0xFF), /* bInterval. */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
0x0A, /* bInterfaceClass (Data Class
|
||||
Interface, CDC section 4.5). */
|
||||
0x00, /* bInterfaceSubClass (CDC section
|
||||
4.6). */
|
||||
0x00, /* bInterfaceProtocol (CDC section
|
||||
4.7). */
|
||||
0x00), /* iInterface. */
|
||||
/* Endpoint 3 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00), /* bInterval. */
|
||||
/* Endpoint 1 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00) /* bInterval. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_configuration_descriptor = {
|
||||
sizeof vcom_configuration_descriptor_data,
|
||||
vcom_configuration_descriptor_data
|
||||
};
|
||||
|
||||
/*
|
||||
* U.S. English language identifier.
|
||||
*/
|
||||
static const uint8_t vcom_string0[] = {
|
||||
USB_DESC_BYTE(4), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||
};
|
||||
|
||||
/*
|
||||
* Vendor string.
|
||||
*/
|
||||
static const uint8_t vcom_string1[] = {
|
||||
USB_DESC_BYTE(38), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
|
||||
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
|
||||
'c', 0, 's', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Description string.
|
||||
*/
|
||||
static const uint8_t vcom_string2[] = {
|
||||
USB_DESC_BYTE(56), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
|
||||
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
|
||||
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
|
||||
'o', 0, 'r', 0, 't', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial Number string.
|
||||
*/
|
||||
static const uint8_t vcom_string3[] = {
|
||||
USB_DESC_BYTE(8), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'0' + CH_KERNEL_MAJOR, 0,
|
||||
'0' + CH_KERNEL_MINOR, 0,
|
||||
'0' + CH_KERNEL_PATCH, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings wrappers array.
|
||||
*/
|
||||
static const USBDescriptor vcom_strings[] = {
|
||||
{sizeof vcom_string0, vcom_string0},
|
||||
{sizeof vcom_string1, vcom_string1},
|
||||
{sizeof vcom_string2, vcom_string2},
|
||||
{sizeof vcom_string3, vcom_string3}
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
|
||||
* handled here.
|
||||
*/
|
||||
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang) {
|
||||
|
||||
(void)usbp;
|
||||
(void)lang;
|
||||
switch (dtype) {
|
||||
case USB_DESCRIPTOR_DEVICE:
|
||||
return &vcom_device_descriptor;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
return &vcom_configuration_descriptor;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
if (dindex < 4)
|
||||
return &vcom_strings[dindex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IN EP1 state.
|
||||
*/
|
||||
static USBInEndpointState ep1instate;
|
||||
|
||||
/**
|
||||
* @brief OUT EP1 state.
|
||||
*/
|
||||
static USBOutEndpointState ep1outstate;
|
||||
|
||||
/**
|
||||
* @brief EP1 initialization structure (both IN and OUT).
|
||||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
USB_EP_MODE_TYPE_BULK,
|
||||
NULL,
|
||||
sduDataTransmitted,
|
||||
sduDataReceived,
|
||||
0x0040,
|
||||
0x0040,
|
||||
&ep1instate,
|
||||
&ep1outstate,
|
||||
2,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IN EP2 state.
|
||||
*/
|
||||
static USBInEndpointState ep2instate;
|
||||
|
||||
/**
|
||||
* @brief EP2 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
USB_EP_MODE_TYPE_INTR,
|
||||
NULL,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
0x0000,
|
||||
&ep2instate,
|
||||
NULL,
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||
extern SerialUSBDriver SDU1;
|
||||
|
||||
switch (event) {
|
||||
case USB_EVENT_ADDRESS:
|
||||
return;
|
||||
case USB_EVENT_CONFIGURED:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Enables the endpoints specified into the configuration.
|
||||
Note, this callback is invoked from an ISR so I-Class functions
|
||||
must be used.*/
|
||||
usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
|
||||
usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
|
||||
|
||||
/* Resetting the state of the CDC subsystem.*/
|
||||
sduConfigureHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_RESET:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_SUSPEND:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduSuspendHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_WAKEUP:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduWakeupHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_STALLED:
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void sof_handler(USBDriver *usbp) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
osalSysLockFromISR();
|
||||
sduSOFHookI(&SDU1);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
/*
|
||||
* USB driver configuration.
|
||||
*/
|
||||
const USBConfig usbcfg = {
|
||||
usb_event,
|
||||
get_descriptor,
|
||||
sduRequestsHook,
|
||||
sof_handler
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial over USB driver configuration.
|
||||
*/
|
||||
const SerialUSBConfig serusbcfg = {
|
||||
&USBD1,
|
||||
USBD1_DATA_REQUEST_EP,
|
||||
USBD1_DATA_AVAILABLE_EP,
|
||||
USBD1_INTERRUPT_REQUEST_EP
|
||||
};
|
||||
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Virtual serial port over USB.*/
|
||||
SerialUSBDriver SDU1;
|
||||
|
||||
/*
|
||||
* Endpoints to be used for USBD1.
|
||||
*/
|
||||
#define USBD1_DATA_REQUEST_EP 1
|
||||
#define USBD1_DATA_AVAILABLE_EP 1
|
||||
#define USBD1_INTERRUPT_REQUEST_EP 2
|
||||
|
||||
/*
|
||||
* USB Device Descriptor.
|
||||
*/
|
||||
static const uint8_t vcom_device_descriptor_data[18] = {
|
||||
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
|
||||
0x02, /* bDeviceClass (CDC). */
|
||||
0x00, /* bDeviceSubClass. */
|
||||
0x00, /* bDeviceProtocol. */
|
||||
0x40, /* bMaxPacketSize. */
|
||||
0x0483, /* idVendor (ST). */
|
||||
0x5740, /* idProduct. */
|
||||
0x0200, /* bcdDevice. */
|
||||
1, /* iManufacturer. */
|
||||
2, /* iProduct. */
|
||||
3, /* iSerialNumber. */
|
||||
1) /* bNumConfigurations. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_device_descriptor = {
|
||||
sizeof vcom_device_descriptor_data,
|
||||
vcom_device_descriptor_data
|
||||
};
|
||||
|
||||
/* Configuration Descriptor tree for a CDC.*/
|
||||
static const uint8_t vcom_configuration_descriptor_data[67] = {
|
||||
/* Configuration Descriptor.*/
|
||||
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
|
||||
0x02, /* bNumInterfaces. */
|
||||
0x01, /* bConfigurationValue. */
|
||||
0, /* iConfiguration. */
|
||||
0xC0, /* bmAttributes (self powered). */
|
||||
50), /* bMaxPower (100mA). */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x01, /* bNumEndpoints. */
|
||||
0x02, /* bInterfaceClass (Communications
|
||||
Interface Class, CDC section
|
||||
4.2). */
|
||||
0x02, /* bInterfaceSubClass (Abstract
|
||||
Control Model, CDC section 4.3). */
|
||||
0x01, /* bInterfaceProtocol (AT commands,
|
||||
CDC section 4.4). */
|
||||
0), /* iInterface. */
|
||||
/* Header Functional Descriptor (CDC section 5.2.3).*/
|
||||
USB_DESC_BYTE (5), /* bLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
|
||||
Functional Descriptor. */
|
||||
USB_DESC_BCD (0x0110), /* bcdCDC. */
|
||||
/* Call Management Functional Descriptor. */
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
|
||||
USB_DESC_BYTE (0x01), /* bDataInterface. */
|
||||
/* ACM Functional Descriptor.*/
|
||||
USB_DESC_BYTE (4), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
|
||||
Control Management Descriptor). */
|
||||
USB_DESC_BYTE (0x02), /* bmCapabilities. */
|
||||
/* Union Functional Descriptor.*/
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
|
||||
Class Interface). */
|
||||
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
|
||||
Interface). */
|
||||
/* Endpoint 2 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
|
||||
0x03, /* bmAttributes (Interrupt). */
|
||||
0x0008, /* wMaxPacketSize. */
|
||||
0xFF), /* bInterval. */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
0x0A, /* bInterfaceClass (Data Class
|
||||
Interface, CDC section 4.5). */
|
||||
0x00, /* bInterfaceSubClass (CDC section
|
||||
4.6). */
|
||||
0x00, /* bInterfaceProtocol (CDC section
|
||||
4.7). */
|
||||
0x00), /* iInterface. */
|
||||
/* Endpoint 3 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00), /* bInterval. */
|
||||
/* Endpoint 1 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00) /* bInterval. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_configuration_descriptor = {
|
||||
sizeof vcom_configuration_descriptor_data,
|
||||
vcom_configuration_descriptor_data
|
||||
};
|
||||
|
||||
/*
|
||||
* U.S. English language identifier.
|
||||
*/
|
||||
static const uint8_t vcom_string0[] = {
|
||||
USB_DESC_BYTE(4), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||
};
|
||||
|
||||
/*
|
||||
* Vendor string.
|
||||
*/
|
||||
static const uint8_t vcom_string1[] = {
|
||||
USB_DESC_BYTE(38), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
|
||||
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
|
||||
'c', 0, 's', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Description string.
|
||||
*/
|
||||
static const uint8_t vcom_string2[] = {
|
||||
USB_DESC_BYTE(56), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
|
||||
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
|
||||
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
|
||||
'o', 0, 'r', 0, 't', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial Number string.
|
||||
*/
|
||||
static const uint8_t vcom_string3[] = {
|
||||
USB_DESC_BYTE(8), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'0' + CH_KERNEL_MAJOR, 0,
|
||||
'0' + CH_KERNEL_MINOR, 0,
|
||||
'0' + CH_KERNEL_PATCH, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings wrappers array.
|
||||
*/
|
||||
static const USBDescriptor vcom_strings[] = {
|
||||
{sizeof vcom_string0, vcom_string0},
|
||||
{sizeof vcom_string1, vcom_string1},
|
||||
{sizeof vcom_string2, vcom_string2},
|
||||
{sizeof vcom_string3, vcom_string3}
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
|
||||
* handled here.
|
||||
*/
|
||||
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang) {
|
||||
|
||||
(void)usbp;
|
||||
(void)lang;
|
||||
switch (dtype) {
|
||||
case USB_DESCRIPTOR_DEVICE:
|
||||
return &vcom_device_descriptor;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
return &vcom_configuration_descriptor;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
if (dindex < 4)
|
||||
return &vcom_strings[dindex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IN EP1 state.
|
||||
*/
|
||||
static USBInEndpointState ep1instate;
|
||||
|
||||
/**
|
||||
* @brief OUT EP1 state.
|
||||
*/
|
||||
static USBOutEndpointState ep1outstate;
|
||||
|
||||
/**
|
||||
* @brief EP1 initialization structure (both IN and OUT).
|
||||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
USB_EP_MODE_TYPE_BULK,
|
||||
NULL,
|
||||
sduDataTransmitted,
|
||||
sduDataReceived,
|
||||
0x0040,
|
||||
0x0040,
|
||||
&ep1instate,
|
||||
&ep1outstate,
|
||||
2,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IN EP2 state.
|
||||
*/
|
||||
static USBInEndpointState ep2instate;
|
||||
|
||||
/**
|
||||
* @brief EP2 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
USB_EP_MODE_TYPE_INTR,
|
||||
NULL,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
0x0000,
|
||||
&ep2instate,
|
||||
NULL,
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||
extern SerialUSBDriver SDU1;
|
||||
|
||||
switch (event) {
|
||||
case USB_EVENT_ADDRESS:
|
||||
return;
|
||||
case USB_EVENT_CONFIGURED:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Enables the endpoints specified into the configuration.
|
||||
Note, this callback is invoked from an ISR so I-Class functions
|
||||
must be used.*/
|
||||
usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
|
||||
usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
|
||||
|
||||
/* Resetting the state of the CDC subsystem.*/
|
||||
sduConfigureHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_RESET:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_SUSPEND:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduSuspendHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_WAKEUP:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Wake up event.*/
|
||||
sduWakeupHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_STALLED:
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void sof_handler(USBDriver *usbp) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
osalSysLockFromISR();
|
||||
sduSOFHookI(&SDU1);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
/*
|
||||
* USB driver configuration.
|
||||
*/
|
||||
const USBConfig usbcfg = {
|
||||
usb_event,
|
||||
get_descriptor,
|
||||
sduRequestsHook,
|
||||
sof_handler
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial over USB driver configuration.
|
||||
*/
|
||||
const SerialUSBConfig serusbcfg = {
|
||||
&USBD1,
|
||||
USBD1_DATA_REQUEST_EP,
|
||||
USBD1_DATA_AVAILABLE_EP,
|
||||
USBD1_INTERRUPT_REQUEST_EP
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "padc.h"
|
||||
|
||||
/**
|
||||
* Main routine is starting up system, runs the software watchdog (module monitoring), controls LEDs
|
||||
|
@ -27,6 +26,9 @@ int main(void) {
|
|||
|
||||
chDbgAssert(pkt == true, "failed to init packet system");
|
||||
|
||||
/* Start Serial Over USB. */
|
||||
startSDU();
|
||||
|
||||
/* Start serial channels if selected. */
|
||||
pktSerialStart();
|
||||
|
||||
|
@ -37,10 +39,6 @@ int main(void) {
|
|||
pktEnableEventTrace();
|
||||
}
|
||||
|
||||
#if ACTIVATE_USB
|
||||
startUSB();
|
||||
#endif
|
||||
|
||||
TRACE_INFO("MAIN > Startup");
|
||||
|
||||
// Startup threads
|
||||
|
@ -48,15 +46,12 @@ int main(void) {
|
|||
start_user_threads(); // Startup optional modules (eg. POSITION, LOG, ...)
|
||||
|
||||
while(true) {
|
||||
#if ACTIVATE_USB
|
||||
if(isUSBactive()) {
|
||||
manageShell();
|
||||
pktTraceEvents();
|
||||
continue;
|
||||
}
|
||||
#endif /* ACTIVATE_USB */
|
||||
/* Wait in a loop if nothing to do. */
|
||||
chThdSleep(TIME_S2I(1));
|
||||
#if ACTIVATE_USB
|
||||
manageTraceAndShell();
|
||||
pktTraceEvents();
|
||||
#endif /* ACTIVATE_USB */
|
||||
/* Wait in a loop if nothing to do. */
|
||||
chThdSleep(TIME_MS2I(200));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -761,8 +761,11 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
TIME_MS2I(100));
|
||||
|
||||
if(myPktBuffer == NULL) {
|
||||
/* Decrease ref count on AX25 FIFO and stop PWM. */
|
||||
chFactoryReleaseObjectsFIFO(pkt_fifo);
|
||||
pktAddEventFlags(myHandler, EVT_AX25_NO_BUFFER);
|
||||
myDriver->active_demod_object->status |= EVT_AX25_NO_BUFFER;
|
||||
myDriver->active_demod_object->status |=
|
||||
EVT_AX25_NO_BUFFER | EVT_PWM_QUEUE_LOCK;
|
||||
myDriver->decoder_state = DECODER_ERROR;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ void pktClosePWMChannelI(ICUDriver *myICU, eventflags_t evt, pwm_code_t reason)
|
|||
icuDisableNotificationsI(myICU);
|
||||
if(myDemod->active_radio_object != NULL) {
|
||||
myDemod->active_radio_object->status |= (EVT_PWM_QUEUE_LOCK | evt);
|
||||
pktAddEventFlagsI(myHandler, (EVT_PWM_QUEUE_LOCK | evt));
|
||||
pktAddEventFlagsI(myHandler, evt);
|
||||
input_queue_t *myQueue = &myDemod->active_radio_object->radio_pwm_queue;
|
||||
/* End of data flag. */
|
||||
#if USE_12_BIT_PWM == TRUE
|
||||
|
|
|
@ -661,7 +661,6 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
|
|||
/* Increase outstanding callback count. */
|
||||
handler->cb_count++;
|
||||
}
|
||||
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
|
|
@ -477,6 +477,23 @@ static inline bool pktIsBufferValidAX25Frame(pkt_data_object_t *object) {
|
|||
&& (frame_size >= PKT_MIN_FRAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets status of frame.
|
||||
* @note This returns validity (size) and CRC result.
|
||||
* @details This function is called from thread level.
|
||||
*
|
||||
* @param[in] object pointer to a @p objects FIFO.
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval true if the frame is valid and has good CRC.
|
||||
* @retval false if the frame is valid and has bad CRC.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline bool pktGetAX25FrameStatus(pkt_data_object_t *object) {
|
||||
chDbgAssert(object != NULL, "no pointer to packet object buffer");
|
||||
return !(object->status & (EVT_PKT_INVALID_FRAME | EVT_AX25_CRC_ERROR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets service object associated with radio.
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#define EVT_PRIORITY_BASE 0
|
||||
|
||||
/*
|
||||
* Decoder global system events.
|
||||
* Decoder global system event masks.
|
||||
* The packet channel object holds the global events.
|
||||
* Events are broadcast to any listeners.
|
||||
*/
|
||||
|
@ -98,7 +98,8 @@
|
|||
#define EVT_PKT_CBK_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 31)
|
||||
|
||||
|
||||
/* Decoder thread events (sent from initiator to decoder). */
|
||||
/* Decoder thread event IDs (sent from initiator to decoder). */
|
||||
/*TODO: These needs to be values and NOT bit shifted masks. */
|
||||
|
||||
#define DEC_COMMAND_START EVENT_MASK(EVT_PRIORITY_BASE + 0)
|
||||
#define DEC_COMMAND_STOP EVENT_MASK(EVT_PRIORITY_BASE + 1)
|
||||
|
@ -107,8 +108,9 @@
|
|||
#define DEC_SUSPEND_EXIT EVENT_MASK(EVT_PRIORITY_BASE + 4)
|
||||
|
||||
|
||||
/* Reserved system thread events (in user threads level). */
|
||||
#define USB_SHELL_EVT EVENT_MASK(EVT_PRIORITY_BASE + 0)
|
||||
/* Reserved system event broadcast IDs (set mask in user threads level). */
|
||||
#define USB_SHELL_EVT EVT_PRIORITY_BASE + 0
|
||||
#define USB_SDU1_EVT EVT_PRIORITY_BASE + 16
|
||||
|
||||
/* Response thread events (from decoder to initiator). */
|
||||
#define DEC_OPEN_EXEC EVENT_MASK(EVT_PRIORITY_BASE + 15)
|
||||
|
|
|
@ -1180,43 +1180,54 @@ void ax25_remove_addr (packet_t this_p, int n)
|
|||
*
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
int ax25_get_num_addr (packet_t this_p)
|
||||
{
|
||||
//unsigned char *pf;
|
||||
int a;
|
||||
int addr_bytes;
|
||||
int ax25_get_num_addr (packet_t this_p) {
|
||||
int a;
|
||||
//int addr_bytes;
|
||||
|
||||
|
||||
if(this_p->magic1 != MAGIC || this_p->magic2 != MAGIC) {
|
||||
TRACE_ERROR("PKT > Buffer overflow");
|
||||
return 0;
|
||||
}
|
||||
if(this_p->magic1 != MAGIC || this_p->magic2 != MAGIC) {
|
||||
TRACE_ERROR("PKT > Buffer overflow");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use cached value if already set. */
|
||||
/* Use cached value if already set. */
|
||||
|
||||
if (this_p->num_addr >= 0) {
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
if (this_p->num_addr >= 0) {
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
|
||||
/* Otherwise, determine the number of addresses. */
|
||||
/*
|
||||
* Otherwise, determine the number of addresses.
|
||||
* Start with assumption of zero.
|
||||
*/
|
||||
|
||||
this_p->num_addr = 0; /* Number of addresses extracted. */
|
||||
|
||||
addr_bytes = 0;
|
||||
for (a = 0; a < this_p->frame_len && addr_bytes == 0; a++) {
|
||||
if (this_p->frame_data[a] & SSID_LAST_MASK) {
|
||||
addr_bytes = a + 1;
|
||||
}
|
||||
}
|
||||
this_p->num_addr = 0;
|
||||
|
||||
if (addr_bytes % 7 == 0) {
|
||||
int addrs = addr_bytes / 7;
|
||||
if (addrs >= AX25_MIN_ADDRS && addrs <= AX25_MAX_ADDRS) {
|
||||
this_p->num_addr = addrs;
|
||||
}
|
||||
}
|
||||
|
||||
return (this_p->num_addr);
|
||||
/* Check that address characters are valid. */
|
||||
|
||||
for(a = 0;
|
||||
a < this_p->frame_len && a < (AX25_MAX_ADDRS * AX25_ADDR_LEN);
|
||||
a++) {
|
||||
/*
|
||||
* Check the call sign characters with isgraph
|
||||
* Could be more strict and accept upper case alpha & numeric only.
|
||||
*/
|
||||
if(a % 7 != 6) {
|
||||
if(isgraph(this_p->frame_data[a] >> 1))
|
||||
continue;
|
||||
}
|
||||
if((this_p->frame_data[a] & SSID_LAST_MASK))
|
||||
break;
|
||||
} /* End for. */
|
||||
|
||||
/* Check if last happened on an address boundary. */
|
||||
if (++a % 7 == 0) {
|
||||
int addrs = a / 7;
|
||||
if (addrs >= AX25_MIN_ADDRS && addrs <= AX25_MAX_ADDRS) {
|
||||
this_p->num_addr = addrs;
|
||||
}
|
||||
}
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1401,7 +1412,7 @@ int ax25_get_ssid (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
return ((this_p->frame_data[n*7+6] & SSID_SSID_MASK) >> SSID_SSID_SHIFT);
|
||||
return ((this_p->frame_data[n * AX25_ADDR_LEN + 6] & SSID_SSID_MASK) >> SSID_SSID_SHIFT);
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("Internal error: ax25_get_ssid(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1437,7 +1448,8 @@ void ax25_set_ssid (packet_t this_p, int n, int ssid)
|
|||
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
this_p->frame_data[n*7+6] = (this_p->frame_data[n*7+6] & ~ SSID_SSID_MASK) |
|
||||
this_p->frame_data[n * AX25_ADDR_LEN + 6] =
|
||||
(this_p->frame_data[n * AX25_ADDR_LEN + 6] & ~ SSID_SSID_MASK) |
|
||||
((ssid << SSID_SSID_SHIFT) & SSID_SSID_MASK) ;
|
||||
}
|
||||
else {
|
||||
|
@ -1476,7 +1488,7 @@ int ax25_get_h (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
return ((this_p->frame_data[n*7+6] & SSID_H_MASK) >> SSID_H_SHIFT);
|
||||
return ((this_p->frame_data[n * AX25_ADDR_LEN + 6] & SSID_H_MASK) >> SSID_H_SHIFT);
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("PKT > Internal error: ax25_get_h(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1511,7 +1523,7 @@ void ax25_set_h (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
this_p->frame_data[n*7+6] |= SSID_H_MASK;
|
||||
this_p->frame_data[n * AX25_ADDR_LEN + 6] |= SSID_H_MASK;
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("PKT > Internal error: ax25_set_hd(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1921,15 +1933,13 @@ void ax25_format_addrs (packet_t this_p, char *result, int8_t size)
|
|||
}
|
||||
*result = '\0';
|
||||
|
||||
/* New in 0.9. */
|
||||
/* Don't get upset if no addresses. */
|
||||
/* This will allow packets that do not comply to AX.25 format. */
|
||||
/* There must be at least two addresses. */
|
||||
|
||||
if (this_p->num_addr == 0) {
|
||||
if (this_p->num_addr < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Make a safe strcat function. */
|
||||
/* TODO: Refactor this to use a single loop and safe write to buffer. */
|
||||
ax25_get_addr_with_ssid (this_p, AX25_SOURCE, stemp);
|
||||
|
||||
if(size - (strlen(stemp) + 1) < 2)
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
/* to be safe. */
|
||||
#define AX25_MAX_ADDR_LEN 12
|
||||
|
||||
/* The length of an address field in an AX25 header. */
|
||||
#define AX25_ADDR_LEN 7
|
||||
|
||||
/* Previously 1 when considering only APRS. */
|
||||
#define AX25_MIN_INFO_LEN 0U
|
||||
|
||||
|
@ -61,9 +64,9 @@
|
|||
/* The more general case. */
|
||||
/* An AX.25 frame can have a control byte and no protocol. */
|
||||
|
||||
#define AX25_MIN_PACKET_LEN ( 2 * 7 + 1 )
|
||||
#define AX25_MIN_PACKET_LEN ( 2 * AX25_ADDR_LEN + 1 )
|
||||
|
||||
#define AX25_MAX_PACKET_LEN ( AX25_MAX_ADDRS * 7 + 2 + 3 + AX25_MAX_INFO_LEN)
|
||||
#define AX25_MAX_PACKET_LEN ( AX25_MAX_ADDRS * AX25_ADDR_LEN + 2 + 3 + AX25_MAX_INFO_LEN)
|
||||
|
||||
#define AX25_UI_FRAME 3 /* Control field value. */
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "hal.h"
|
||||
#include "chprintf.h"
|
||||
#include "portab.h"
|
||||
#include "usb.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -158,6 +159,10 @@ void sysConfigureCoreIO(void) {
|
|||
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
|
||||
| PAL_STM32_OSPEED_HIGHEST
|
||||
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
|
||||
|
||||
#if ACTIVATE_USB
|
||||
startUSB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
|
||||
#define USE_SPI_ATTACHED_RADIO TRUE
|
||||
#define DUMP_PACKET_TO_SERIAL TRUE
|
||||
#define DUMP_PACKET_TO_SERIAL FALSE
|
||||
|
||||
/*
|
||||
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
|
||||
|
@ -67,7 +67,7 @@
|
|||
#endif
|
||||
|
||||
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
|
||||
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
|
||||
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
|
||||
|
||||
/**
|
||||
* ICU related definitions.
|
||||
|
@ -124,7 +124,7 @@ extern "C" {
|
|||
void pktSetLineModeICU(void);
|
||||
void pktSerialStart(void);
|
||||
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
|
||||
int dbgPrintf(uint8_t level, const char *format, ...);
|
||||
int dbgPrintf(uint8_t level, const char *format, ...);
|
||||
void pktWrite(uint8_t *buf, uint32_t len);
|
||||
void pktPowerUpRadio(radio_unit_t radio);
|
||||
void pktPowerDownRadio(radio_unit_t radio);
|
||||
|
|
|
@ -45,7 +45,6 @@ static bool dedupe_initialized;
|
|||
const conf_command_t command_list[] = {
|
||||
{TYPE_INT, "pos_pri.active", sizeof(conf_sram.pos_pri.thread_conf.active), &conf_sram.pos_pri.thread_conf.active },
|
||||
{TYPE_TIME, "pos_pri.init_delay", sizeof(conf_sram.pos_pri.thread_conf.init_delay), &conf_sram.pos_pri.thread_conf.init_delay },
|
||||
/* {TYPE_TIME, "pos_pri.send_spacing", sizeof(conf_sram.pos_pri.thread_conf.send_spacing), &conf_sram.pos_pri.thread_conf.send_spacing },*/
|
||||
{TYPE_INT, "pos_pri.sleep_conf.type", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.type), &conf_sram.pos_pri.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vbat_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vsol_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres},
|
||||
|
@ -54,8 +53,6 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_INT, "pos_pri.freq", sizeof(conf_sram.pos_pri.radio_conf.freq), &conf_sram.pos_pri.radio_conf.freq },
|
||||
{TYPE_INT, "pos_pri.mod", sizeof(conf_sram.pos_pri.radio_conf.mod), &conf_sram.pos_pri.radio_conf.mod },
|
||||
{TYPE_INT, "pos_pri.rssi", sizeof(conf_sram.pos_pri.radio_conf.rssi), &conf_sram.pos_pri.radio_conf.rssi },
|
||||
/* {TYPE_INT, "pos_pri.speed", sizeof(conf_sram.pos_pri.radio_conf.speed), &conf_sram.pos_pri.radio_conf.speed },*/
|
||||
/* {TYPE_INT, "pos_pri.redundantTx", sizeof(conf_sram.pos_pri.radio_conf.redundantTx), &conf_sram.pos_pri.radio_conf.redundantTx },*/
|
||||
{TYPE_STR, "pos_pri.call", sizeof(conf_sram.pos_pri.call), &conf_sram.pos_pri.call },
|
||||
{TYPE_STR, "pos_pri.path", sizeof(conf_sram.pos_pri.path), &conf_sram.pos_pri.path },
|
||||
{TYPE_INT, "pos_pri.symbol", sizeof(conf_sram.pos_pri.symbol), &conf_sram.pos_pri.symbol },
|
||||
|
@ -64,7 +61,6 @@ const conf_command_t command_list[] = {
|
|||
|
||||
{TYPE_INT, "pos_sec.active", sizeof(conf_sram.pos_sec.thread_conf.active), &conf_sram.pos_sec.thread_conf.active },
|
||||
{TYPE_TIME, "pos_sec.init_delay", sizeof(conf_sram.pos_sec.thread_conf.init_delay), &conf_sram.pos_sec.thread_conf.init_delay },
|
||||
/* {TYPE_TIME, "pos_sec.send_spacing", sizeof(conf_sram.pos_sec.thread_conf.send_spacing), &conf_sram.pos_sec.thread_conf.send_spacing },*/
|
||||
{TYPE_INT, "pos_sec.sleep_conf.type", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.type), &conf_sram.pos_sec.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vbat_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vsol_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres},
|
||||
|
@ -73,8 +69,6 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_INT, "pos_sec.freq", sizeof(conf_sram.pos_sec.radio_conf.freq), &conf_sram.pos_sec.radio_conf.freq },
|
||||
{TYPE_INT, "pos_sec.mod", sizeof(conf_sram.pos_sec.radio_conf.mod), &conf_sram.pos_sec.radio_conf.mod },
|
||||
{TYPE_INT, "pos_sec.rssi", sizeof(conf_sram.pos_sec.radio_conf.rssi), &conf_sram.pos_sec.radio_conf.rssi },
|
||||
/* {TYPE_INT, "pos_sec.speed", sizeof(conf_sram.pos_sec.radio_conf.speed), &conf_sram.pos_sec.radio_conf.speed },*/
|
||||
/* {TYPE_INT, "pos_sec.redundantTx", sizeof(conf_sram.pos_sec.radio_conf.redundantTx), &conf_sram.pos_sec.radio_conf.redundantTx },*/
|
||||
{TYPE_STR, "pos_sec.call", sizeof(conf_sram.pos_sec.call), &conf_sram.pos_sec.call },
|
||||
{TYPE_STR, "pos_sec.path", sizeof(conf_sram.pos_sec.path), &conf_sram.pos_sec.path },
|
||||
{TYPE_INT, "pos_sec.symbol", sizeof(conf_sram.pos_sec.symbol), &conf_sram.pos_sec.symbol },
|
||||
|
@ -138,13 +132,7 @@ const conf_command_t command_list[] = {
|
|||
|
||||
{TYPE_INT, "aprs.active", sizeof(conf_sram.aprs.thread_conf.active), &conf_sram.aprs.thread_conf.active },
|
||||
{TYPE_TIME, "aprs.init_delay", sizeof(conf_sram.aprs.thread_conf.init_delay), &conf_sram.aprs.thread_conf.init_delay },
|
||||
/*
|
||||
{TYPE_TIME, "aprs.packet_spacing", sizeof(conf_sram.aprs.rx.thread_conf.packet_spacing), &conf_sram.aprs.rx.thread_conf.packet_spacing },
|
||||
{TYPE_INT, "aprs.sleep_conf.type", sizeof(conf_sram.aprs.rx.thread_conf.sleep_conf.type), &conf_sram.aprs.rx.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "aprs.sleep_conf.vbat_thres", sizeof(conf_sram.aprs.rx.thread_conf.sleep_conf.vbat_thres), &conf_sram.aprs.rx.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "aprs.sleep_conf.vsol_thres", sizeof(conf_sram.aprs.rx.thread_conf.sleep_conf.vsol_thres), &conf_sram.aprs.rx.thread_conf.sleep_conf.vsol_thres},
|
||||
{TYPE_TIME, "aprs.rx.cycle", sizeof(conf_sram.aprs.rx.thread_conf.cycle), &conf_sram.aprs.rx.thread_conf.cycle },
|
||||
*/
|
||||
|
||||
{TYPE_INT, "aprs.rx.freq", sizeof(conf_sram.aprs.rx.radio_conf.freq), &conf_sram.aprs.rx.radio_conf.freq },
|
||||
{TYPE_INT, "aprs.rx.mod", sizeof(conf_sram.aprs.rx.radio_conf.mod), &conf_sram.aprs.rx.radio_conf.mod },
|
||||
{TYPE_INT, "aprs.rx.speed", sizeof(conf_sram.aprs.rx.radio_conf.speed), &conf_sram.aprs.tx.radio_conf.speed },
|
||||
|
@ -179,7 +167,7 @@ const APRSCommand aprs_commands[] = {
|
|||
{"?aprsd", aprs_send_aprsd_message},
|
||||
{"?aprsh", aprs_send_aprsh_message},
|
||||
{"?aprsp", aprs_send_position_beacon},
|
||||
{"?gpio", aprs_handle_gpio_command},
|
||||
{"?gpio", aprs_execute_gpio_command},
|
||||
{"?gps", aprs_handle_gps_command},
|
||||
{"?reset", aprs_execute_system_reset},
|
||||
{"?save", aprs_execute_config_save},
|
||||
|
@ -188,7 +176,7 @@ const APRSCommand aprs_commands[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief parse arguments from a command string.
|
||||
*
|
||||
* @return pointer to next element in string.
|
||||
|
@ -227,7 +215,7 @@ static char *aprs_parse_arguments(char *str, char **saveptr) {
|
|||
return *p != '\0' ? p : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Execute a command in an APRS message.
|
||||
* @notes Known commands are in APRS command table.
|
||||
* @notes Commands themselves return only MSG_OK or MSG_ERROR.
|
||||
|
@ -252,7 +240,7 @@ static msg_t aprs_cmd_exec(const APRSCommand *acp,
|
|||
return MSG_TIMEOUT;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void aprs_debug_getPacket(packet_t pp, char* buf, uint32_t len)
|
||||
|
@ -286,7 +274,7 @@ void aprs_debug_getPacket(packet_t pp, char* buf, uint32_t len)
|
|||
* @notes - Number of satellites being used
|
||||
* @notes - Number of cycles where GPS has been lost (if applicable in cycle)
|
||||
*
|
||||
* @param[in] callsign originator calls sign
|
||||
* @param[in] callsign origination call sign
|
||||
* @param[in] path path to use
|
||||
* @param[in] symbol symbol for originator
|
||||
* @param[in] dataPoint position data object
|
||||
|
@ -547,7 +535,7 @@ msg_t aprs_send_aprsh_message(aprs_identity_t *id,
|
|||
* @retval MSG_OK if the command completed.
|
||||
* @retval MSG_ERROR if there was an error.
|
||||
*/
|
||||
msg_t aprs_handle_gpio_command(aprs_identity_t *id,
|
||||
msg_t aprs_execute_gpio_command(aprs_identity_t *id,
|
||||
int argc, char *argv[]) {
|
||||
if(argc != 1)
|
||||
return MSG_ERROR;
|
||||
|
@ -1018,14 +1006,15 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
msg_t msg = aprs_cmd_exec(aprs_commands, cmd, &identity, n, args);
|
||||
|
||||
if(msg == MSG_TIMEOUT) {
|
||||
TRACE_INFO("RX > Command not found by parser");
|
||||
TRACE_INFO("RX > No command found in message");
|
||||
}
|
||||
|
||||
if(msg_id_rx[0]) {
|
||||
/* Incoming message ID exists so an ACK or REJ has to be sent. */
|
||||
char buf[16];
|
||||
chsnprintf(buf, sizeof(buf), "%s%s",
|
||||
(msg == MSG_OK) ? "ack" : "rej", msg_id_rx);
|
||||
(msg == MSG_OK || msg == MSG_TIMEOUT) ?
|
||||
"ack" : "rej", msg_id_rx);
|
||||
|
||||
/*
|
||||
* Use the receiving node identity as sender.
|
||||
|
@ -1050,31 +1039,33 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Transmit failure will release the packet memory.
|
||||
*/
|
||||
static void aprs_digipeat(packet_t pp) {
|
||||
if(!dedupe_initialized) {
|
||||
dedupe_init(TIME_S2I(10));
|
||||
dedupe_initialized = true;
|
||||
}
|
||||
if(!dedupe_initialized) {
|
||||
dedupe_init(TIME_S2I(10));
|
||||
dedupe_initialized = true;
|
||||
}
|
||||
|
||||
if(!dedupe_check(pp, 0)) { // Last identical packet older than 10 seconds
|
||||
packet_t result = digipeat_match(0, pp, conf_sram.aprs.rx.call,
|
||||
conf_sram.aprs.tx.call, alias_re,
|
||||
wide_re, 0, preempt, NULL);
|
||||
if(result != NULL) { // Should be digipeated
|
||||
dedupe_remember(result, 0);
|
||||
/* If transmit fails the packet is freed. */
|
||||
transmitOnRadio(result,
|
||||
conf_sram.aprs.tx.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf_sram.aprs.tx.radio_conf.pwr,
|
||||
conf_sram.aprs.tx.radio_conf.mod,
|
||||
conf_sram.aprs.tx.radio_conf.rssi);
|
||||
}
|
||||
}
|
||||
if(!dedupe_check(pp, 0)) { // Last identical packet older than 10 seconds
|
||||
packet_t result = digipeat_match(0, pp, conf_sram.aprs.rx.call,
|
||||
conf_sram.aprs.tx.call, alias_re,
|
||||
wide_re, 0, preempt, NULL);
|
||||
if(result != NULL) { // Should be digipeated
|
||||
dedupe_remember(result, 0);
|
||||
/* If transmit fails the packet buffer is released. */
|
||||
if(!transmitOnRadio(result,
|
||||
conf_sram.aprs.tx.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf_sram.aprs.tx.radio_conf.pwr,
|
||||
conf_sram.aprs.tx.radio_conf.mod,
|
||||
conf_sram.aprs.tx.radio_conf.rssi)) {
|
||||
TRACE_INFO("RX > Failed to digipeat packet");
|
||||
} /* TX failed. */
|
||||
} /* Should be digipteated. */
|
||||
} /* Duplicate check. */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1106,7 +1097,8 @@ void aprs_decode_packet(packet_t pp) {
|
|||
do {
|
||||
v++;
|
||||
ax25_get_addr_with_ssid(pp, ax25_get_heard(pp)-v, call);
|
||||
} while(ax25_get_heard(pp) - v >= AX25_SOURCE && (!strncmp("WIDE", call, 4) || !strncmp("TRACE", call, 5)));
|
||||
} while(((ax25_get_heard(pp) - v) >= AX25_SOURCE)
|
||||
&& (!strncmp("WIDE", call, 4) || !strncmp("TRACE", call, 5)));
|
||||
|
||||
// Fill/Update direct list
|
||||
sysinterval_t first_time = 0xFFFFFFFF; // Timestamp of oldest heard list entry
|
||||
|
@ -1142,7 +1134,9 @@ void aprs_decode_packet(packet_t pp) {
|
|||
* Execute any command found in the message.
|
||||
* If not then digipeat it.
|
||||
*/
|
||||
if(pinfo[0] == ':') digipeat = aprs_decode_message(pp); // ax25_get_dti(pp)
|
||||
if(pinfo[0] == ':') {
|
||||
digipeat = aprs_decode_message(pp); // ax25_get_dti(pp)
|
||||
}
|
||||
|
||||
// Digipeat packet
|
||||
if(conf_sram.aprs.dig_active && digipeat) {
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define SYM_CAR 0x2F3E
|
||||
#define SYM_SHIP 0x2F73
|
||||
#define SYM_DIGIPEATER 0x2F23
|
||||
#define SYM_ANTENNA 0x2F72
|
||||
|
||||
#define APRS_HEARD_LIST_SIZE 20
|
||||
|
||||
|
@ -104,7 +105,7 @@ extern "C" {
|
|||
int argc, char *argv[]);
|
||||
msg_t aprs_send_aprsh_message(aprs_identity_t *id,
|
||||
int argc, char *argv[]);
|
||||
msg_t aprs_handle_gpio_command(aprs_identity_t *id,
|
||||
msg_t aprs_execute_gpio_command(aprs_identity_t *id,
|
||||
int argc, char *argv[]);
|
||||
msg_t aprs_handle_gps_command(aprs_identity_t *id,
|
||||
int argc, char *argv[]);
|
||||
|
|
|
@ -27,16 +27,14 @@ static bool threadStarted = false;
|
|||
/**
|
||||
* Returns most recent data point which is complete.
|
||||
*/
|
||||
dataPoint_t* getLastDataPoint(void)
|
||||
{
|
||||
dataPoint_t* getLastDataPoint(void) {
|
||||
return lastDataPoint;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void waitForNewDataPoint(void)
|
||||
{
|
||||
void waitForNewDataPoint(void) {
|
||||
uint32_t old_id = getLastDataPoint()->id;
|
||||
while(old_id == getLastDataPoint()->id)
|
||||
chThdSleep(TIME_S2I(1));
|
||||
|
@ -45,8 +43,8 @@ void waitForNewDataPoint(void)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp, sysinterval_t timeout)
|
||||
{
|
||||
static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
||||
sysinterval_t timeout) {
|
||||
sysinterval_t start = chVTGetSystemTime();
|
||||
|
||||
gpsFix_t gpsFix;
|
||||
|
@ -62,7 +60,7 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp, sysinterval_t time
|
|||
bool status = GPS_Init();
|
||||
|
||||
if(status) {
|
||||
// Search for lock as long enough power is available
|
||||
// Search for lock as long as enough power is available
|
||||
do {
|
||||
batt = stm32_get_vbat();
|
||||
gps_get_fix(&gpsFix);
|
||||
|
@ -185,7 +183,7 @@ static void getSensors(dataPoint_t* tp)
|
|||
tp->sen_e1_press = 0;
|
||||
tp->sen_e1_hum = 0;
|
||||
tp->sen_e1_temp = 0;
|
||||
bme280_error |= 0x2;
|
||||
bme280_error |= 0x4;
|
||||
}
|
||||
|
||||
// External BME280 Sensor 2
|
||||
|
@ -199,8 +197,11 @@ static void getSensors(dataPoint_t* tp)
|
|||
tp->sen_e2_press = 0;
|
||||
tp->sen_e2_hum = 0;
|
||||
tp->sen_e2_temp = 0;
|
||||
bme280_error |= 0x4;
|
||||
bme280_error |= 0x10;
|
||||
}
|
||||
#else
|
||||
/* Set status to "not installed". */
|
||||
bme280_error |= 0x28;
|
||||
#endif
|
||||
// Measure various temperature sensors
|
||||
tp->stm32_temp = stm32_get_temp();
|
||||
|
@ -214,7 +215,19 @@ static void getSensors(dataPoint_t* tp)
|
|||
*
|
||||
*/
|
||||
static void setSystemStatus(dataPoint_t* tp) {
|
||||
// Set system errors
|
||||
|
||||
/*
|
||||
* Set system errors.
|
||||
*
|
||||
* Bit usage:
|
||||
* - 0:1 I2C status
|
||||
* - 2:2 GPS status
|
||||
* - 3:4 pac1720 status
|
||||
* - 5:7 OV5640 status
|
||||
* - 8:9 BMEi1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 9:10 BMEe1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 10:11 BMEe2 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
*/
|
||||
tp->sys_error = 0;
|
||||
|
||||
tp->sys_error |= (I2C_hasError() & 0x1) << 0;
|
||||
|
@ -222,7 +235,7 @@ static void setSystemStatus(dataPoint_t* tp) {
|
|||
tp->sys_error |= (pac1720_hasError() & 0x3) << 3;
|
||||
tp->sys_error |= (OV5640_hasError() & 0x7) << 5;
|
||||
|
||||
tp->sys_error |= (bme280_error & 0x7) << 8;
|
||||
tp->sys_error |= (bme280_error & 0x3F) << 8;
|
||||
|
||||
// Set system time
|
||||
tp->sys_time = TIME_I2S(chVTGetSystemTime());
|
||||
|
@ -320,7 +333,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
||||
"%s Sats %d TTFF %dsec\r\n"
|
||||
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV Pbat=%dmW\r\n"
|
||||
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%%",
|
||||
"%s AIR p=%d.%01dPa T=%d.%02ddegC phi=%d.%01d%%",
|
||||
tp->id,
|
||||
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
|
||||
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
|
||||
|
@ -345,9 +358,9 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
*/
|
||||
void init_data_collector(void)
|
||||
{
|
||||
if(!threadStarted)
|
||||
{
|
||||
threadStarted = true;
|
||||
if(!threadStarted) {
|
||||
|
||||
threadStarted = true;
|
||||
|
||||
TRACE_INFO("COLL > Startup data collector thread");
|
||||
thread_t *th = chThdCreateFromHeap(NULL,
|
||||
|
|
|
@ -648,14 +648,14 @@ THD_FUNCTION(imgThread, arg) {
|
|||
chThdSleep(TIME_S2I(60));
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t my_image_id = gimage_id++;
|
||||
/* Create image capture buffer. */
|
||||
uint8_t *buffer = chHeapAllocAligned(NULL, conf->buf_size,
|
||||
DMA_FIFO_BURST_ALIGN);
|
||||
if(buffer == NULL) {
|
||||
/* Could not get a capture buffer. */
|
||||
TRACE_WARN("IMG > Unable to get capture buffer for image %i",
|
||||
gimage_id);
|
||||
my_image_id);
|
||||
/* Allow time for other threads. */
|
||||
chThdSleep(TIME_MS2I(10));
|
||||
/* Try again at next run time. */
|
||||
|
@ -668,11 +668,11 @@ THD_FUNCTION(imgThread, arg) {
|
|||
/* Nothing captured? */
|
||||
if(size_sampled == 0) {
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV (camera error) ID=%d",
|
||||
gimage_id);
|
||||
my_image_id);
|
||||
if(!transmit_image_packets(noCameraFound, sizeof(noCameraFound),
|
||||
conf, (uint8_t)(gimage_id))) {
|
||||
conf, (uint8_t)(my_image_id))) {
|
||||
TRACE_ERROR("IMG > Error in encoding dummy image %i"
|
||||
" - discarded", gimage_id);
|
||||
" - discarded", my_image_id);
|
||||
}
|
||||
/* Return the buffer to the heap. */
|
||||
chHeapFree(buffer);
|
||||
|
@ -699,7 +699,7 @@ THD_FUNCTION(imgThread, arg) {
|
|||
|
||||
chsnprintf(filename, sizeof(filename), "r%02xi%04x.jpg",
|
||||
getLastDataPoint()->reset % 0xFF,
|
||||
(gimage_id - 1) % 0xFFFF);
|
||||
(my_image_id) % 0xFFFF);
|
||||
|
||||
writeBufferToFile(filename, &buffer[soi], size_sampled - soi);
|
||||
} /* End initSD() */
|
||||
|
@ -710,13 +710,12 @@ THD_FUNCTION(imgThread, arg) {
|
|||
}
|
||||
|
||||
/* Encode and transmit picture. */
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV ID=%d", gimage_id);
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV ID=%d", my_image_id);
|
||||
if(!transmit_image_packets(buffer, size_sampled, conf,
|
||||
(uint8_t)(gimage_id))) {
|
||||
(uint8_t)(my_image_id))) {
|
||||
TRACE_ERROR("IMG > Error in encoding snapshot image"
|
||||
" %i - discarded", gimage_id);
|
||||
" %i - discarded", my_image_id);
|
||||
}
|
||||
gimage_id++;
|
||||
break;
|
||||
} /* End if SOI in buffer. */
|
||||
} /* End while soi < size_sampled - 1. */
|
||||
|
|
|
@ -69,11 +69,12 @@ void mapCallback(pkt_data_object_t *pkt_buff) {
|
|||
pktDiagnosticOutput(pkt_buff->handler, pkt_buff);
|
||||
#endif
|
||||
*/
|
||||
if(pktIsBufferValidAX25Frame(pkt_buff)) {
|
||||
if(pktGetAX25FrameStatus(pkt_buff)) {
|
||||
|
||||
/* Perform the callback. */
|
||||
processPacket(frame_buffer, frame_size);
|
||||
} else {
|
||||
TRACE_INFO("RX > Invalid frame - dropped");
|
||||
TRACE_INFO("RX > Frame has bad CRC - dropped");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue