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
CInsights 2018-04-20 00:12:25 +10:00
rodzic f3f99aaaf4
commit 40042dc7c0
22 zmienionych plików z 674 dodań i 543 usunięć

Wyświetl plik

@ -0,0 +1 @@
/pecanpico10-rescue.lib

Wyświetl plik

@ -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_)

Wyświetl plik

@ -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",

Wyświetl plik

@ -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__ */

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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
};

Wyświetl plik

@ -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));
}
}

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -661,7 +661,6 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
/* Increase outstanding callback count. */
handler->cb_count++;
}
}
return flags;
}

Wyświetl plik

@ -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.

Wyświetl plik

@ -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)

Wyświetl plik

@ -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)

Wyświetl plik

@ -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. */

Wyświetl plik

@ -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
}
/** @} */

Wyświetl plik

@ -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);

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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[]);

Wyświetl plik

@ -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,

Wyświetl plik

@ -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. */

Wyświetl plik

@ -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");
}
}