Merge branch 'master' of github.com:DL7AD/pecanpico10

pull/4/head
Sven Steudte 2018-04-20 00:04:25 +02:00
commit a7f41c89d1
34 zmienionych plików z 1655 dodań i 922 usunięć

Wyświetl plik

@ -3,15 +3,15 @@ class Image {
function __construct($sqlResult) {
$this->id = $sqlResult['id'];
$this->id = (int)$sqlResult['id'];
$this->call = $sqlResult['call'];
$this->time_first = $sqlResult['time_first'];
$this->time_last = $sqlResult['time_last'];
$this->time_first = (int)$sqlResult['time_first'];
$this->time_last = (int)$sqlResult['time_last'];
$this->imageID = $sqlResult['imageID'];
$this->packetID = $sqlResult['packetID'];
$this->count = $sqlResult['count'];
$this->imageID = (int)$sqlResult['imageID'];
$this->packetID = (int)$sqlResult['packetID'];
$this->count = (int)$sqlResult['count'];
}
}

Wyświetl plik

@ -16,14 +16,12 @@ class Tracker {
$query = Database::getInstance()->query("
SELECT * FROM (
SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'pos' as `type` FROM `position` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "' AND `org` = 'pos'
(SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'pos' as `type` FROM `position` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "' AND `org` = 'pos' ORDER BY `rxtime` DESC LIMIT 1)
UNION ALL
SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'img' as `type` FROM `image` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "'
(SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'img' as `type` FROM `image` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "' ORDER BY `rxtime` DESC LIMIT 1)
UNION ALL
SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'log' as `type` FROM `position` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "' AND `org` = 'log'
(SELECT UNIX_TIMESTAMP() - `rxtime` as `lasttime`,'log' as `type` FROM `position` WHERE `call` = '" . Database::getInstance()->escape_string($this->call) . "' AND `org` = 'log' ORDER BY `rxtime` DESC LIMIT 1)
) AS d
GROUP BY `type`
ORDER BY `lasttime` DESC
");
while($row = $query->fetch_assoc())
@ -38,8 +36,8 @@ class Tracker {
if($from > $to)
return array(); // Error $from is larger than $to
if($from - $to > 64281600)
$from = $from + 64281600; // Max. 744 days (2 non leap years + 14 weeks)
if($to - $from > 64281600)
$from = $to - 64281600; // Max. 744 days (2 non leap years + 14 weeks)
$query = Database::getInstance()->query("
SELECT t.`id`,`call`,MIN(`rxtime`) as `time_first`,MAX(`rxtime`) as `time_last`,
@ -74,8 +72,8 @@ class Tracker {
if($from > $to)
return array(); // Error $from is larger than $to
if($from - $to > 64281600)
$from = $from + 64281600; // Max. 744 days (2 non leap years + 14 weeks)
if($to - $from > 64281600)
$from = $to - 64281600; // Max. 744 days (2 non leap years + 14 weeks)
$query = Database::getInstance()->query("
SELECT *,

Wyświetl plik

@ -216,14 +216,29 @@ function loadRecentData() {
dataTemp.addRow([null,null,null,null,null,null]);
dataGPS.addRow([null,null,null,null]);
dataLight.addRow([null,null]);
dataAlt.addRow([null,null,null,null,null]);
}
dataBattery.addRow([time, data['adc_vbat'], data['pac_vbat'], data['pac_pbat']/10]);
dataSolar.addRow([time, data['adc_vsol'], data['pac_vsol'], data['pac_psol']/10]);
dataTemp.addRow([time, data['sen_i1_temp']/100, data['sen_e1_temp']/100, data['sen_e2_temp']/100, data['stm32_temp']/100, data['si4464_temp']/100]);
dataTemp.addRow([
time,
data['sen_i1_temp'] && data['sen_i1_temp'] > -10000 && data['sen_i1_temp'] < 10000 ? data['sen_i1_temp']/100 : null,
data['sen_e1_temp'] && data['sen_e1_temp'] > -10000 && data['sen_e1_temp'] < 10000 ? data['sen_e1_temp']/100 : null,
data['sen_e2_temp'] && data['sen_e2_temp'] > -10000 && data['sen_e2_temp'] < 10000 ? data['sen_e2_temp']/100 : null,
data['stm32_temp'] && data['stm32_temp'] > -10000 && data['stm32_temp'] < 10000 ? data['stm32_temp']/100 : null,
data['si4464_temp'] && data['si4464_temp'] > -10000 && data['si4464_temp'] < 10000 ? data['si4464_temp']/100 : null
]);
dataGPS.addRow([time, data['gps_sats'], data['gps_ttff'], data['gps_pdop']/20]);
dataLight.addRow([time, data['light_intensity']]);
dataAlt.addRow([
time,
data['gps_alt'],
data['sen_i1_press'] && data['sen_i1_press'] < 1100000 ? data['sen_i1_press']/10 : null,
data['sen_e1_press'] && data['sen_e1_press'] < 1100000 ? data['sen_e1_press']/10 : null,
data['sen_e2_press'] && data['sen_e2_press'] < 1100000 ? data['sen_e2_press']/10 : null
]);
last = time;
});
@ -237,6 +252,7 @@ function loadRecentData() {
dataTemp.removeRow(c);
dataGPS.removeRow(c);
dataLight.removeRow(c);
dataAlt.removeRow(c);
}
}
@ -246,6 +262,7 @@ function loadRecentData() {
tempChart.draw(dataTemp, tempOptions);
gpsChart.draw(dataGPS, gpsOptions);
lightChart.draw(dataLight, lightOptions);
altChart.draw(dataAlt, altOptions);
lastChartUpdate = json['time'];
}
@ -335,6 +352,30 @@ var gpsOptions = {
};
// Chart 5
var altChart;
var dataAlt;
var altOptions = {
explorer: scroll,
width: 1285,
height: 300,
series: {
0: {targetAxisIndex: 0},
1: {targetAxisIndex: 1},
2: {targetAxisIndex: 1},
3: {targetAxisIndex: 1}
},
vAxes: {
0: {title: 'Altitude'},
1: {title: 'Airpressure'},
},
legend: {
position: 'top'
},
hAxis: xAxis,
chartArea: area
};
// Chart 6
var lightChart;
var dataLight;
var lightOptions = {
@ -390,6 +431,15 @@ function drawChart() {
gpsChart = new google.visualization.LineChart(document.getElementById('gpsDiv'));
// Chart 5
dataAlt = new google.visualization.DataTable();
dataAlt.addColumn('date', 'Time');
dataAlt.addColumn('number', "GPS_ALT");
dataAlt.addColumn('number', "PRESS_BME_I1");
dataAlt.addColumn('number', "PRESS_BME_E1");
dataAlt.addColumn('number', "PRESS_BME_E2");
altChart = new google.visualization.LineChart(document.getElementById('altDiv'));
// Chart 6
dataLight = new google.visualization.DataTable();
dataLight.addColumn('date', 'Time');
dataLight.addColumn('number', "LIGHT");
@ -448,6 +498,14 @@ include "sidebar.inc.php";
<td width="70"><span id="pos_cnt86400"></span></td>
<td><span id="act_pos"></span></td>
</tr>
<tr>
<td></td>
<td width="40">DIR:</td>
<td width="50"><span id="dir_cnt300"></span></td>
<td width="70"><span id="dir_cnt3600"></span></td>
<td width="70"><span id="dir_cnt86400"></span></td>
<td><span id="act_dir"></span></td>
</tr>
<tr>
<td></td>
<td>IMG:</td>
@ -600,6 +658,9 @@ include "sidebar.inc.php";
<tr>
<td colspan="3" height="315"><div id="gpsDiv" class="inner"></div></td>
</tr>
<tr>
<td colspan="3" height="315"><div id="altDiv" class="inner"></div></td>
</tr>
<tr>
<td colspan="3" height="315"><div id="lightDiv" class="inner"></div></td>
</tr>

Wyświetl plik

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

Wyświetl plik

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1072336591835851262" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="185104218123605097" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

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

@ -253,7 +253,7 @@ CPPWARN = -Wall -Wextra -Wundef
# List all user C define here, like -D_DEBUG=1
UDEFS = -D_GNU_SOURCE -DARM_MATH_CM4 -DSHELL_CMD_TEST_ENABLED=0 \
-DSHELL_CMD_EXIT_ENABLED=1 -DUSB_TRACE_LEVEL=4 \
-DSHELL_CMD_EXIT_ENABLED=1 -DUSB_TRACE_LEVEL=5 \
-DSHELL_CMD_MEM_ENABLED=0
# -DDISABLE_HW_WATCHDOG=1

Wyświetl plik

@ -297,7 +297,7 @@
// USB
#define LINE_USB_ID PAL_LINE(GPIOA, 10U)
#define LINE_USB_VUSB PAL_LINE(GPIOA, 9U)
#define LINE_USB_VUSB PAL_LINE(GPIOA, 9U)
#define LINE_USB_DM PAL_LINE(GPIOA, 11U)
#define LINE_USB_DP PAL_LINE(GPIOA, 12U)

Wyświetl plik

@ -8,12 +8,12 @@
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(10)
.init_delay = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
@ -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,13 +52,13 @@ const conf_t conf_flash_default = {
.tel_enc_cycle = TIME_S2I(10800)
},
// Primary image transmission thread
// Primary image node
.img_pri = {
.thread_conf = {
.active = true,
.cycle = TIME_S2I(60*30),
.init_delay = TIME_S2I(60*1),
.send_spacing = TIME_S2I(10)
.active = false,
.cycle = TIME_S2I(60*10),
.init_delay = TIME_S2I(60*5),
.send_spacing = TIME_S2I(5)
},
.radio_conf = {
.pwr = 0x7F,
@ -67,22 +67,22 @@ 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 = false,
.cycle = TIME_S2I(600),
.init_delay = TIME_S2I(20),
.send_spacing = TIME_MS2I(100)
.cycle = TIME_S2I(60*5),
.init_delay = TIME_S2I(60*1),
.send_spacing = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
@ -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_VGA,
.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,11 +140,17 @@ const conf_t conf_flash_default = {
.mod = MOD_AFSK,
.rssi = 0x4F
},
// Node tx identity
.call = "VK2GJ-5",
.path = "WIDE2-1",
.symbol = SYM_DIGIPEATER
.symbol = SYM_DIGIPEATER,
.fixed = true,
.lat = -337331175,
.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

@ -978,24 +978,26 @@ void vsync_cb(void *arg) {
* Other drivers using resources that can cause DMA competition are locked.
*/
msg_t OV5640_LockResourcesForCapture(void) {
I2C_Lock();
msg_t msg = pktAcquireRadio(PKT_RADIO_1, TIME_INFINITE);
if(msg != MSG_OK) {
return msg;
}
I2C_Lock();
pktPauseReception(PKT_RADIO_1);
//chMtxLock(&trace_mtx);
/* Hold TRACE output on USB. */
if(isUSBactive())
chMtxLock(&trace_mtx);
return MSG_OK;
/* FIXME: USB has to be locked? */
}
/*
* Unlock competing drivers.
*/
void OV5640_UnlockResourcesForCapture(void) {
/* FIXME: USB has to be unlocked? */
//chMtxUnlock(&trace_mtx);
/* Re-enable TRACE output on USB. */
if(isUSBactive())
chMtxUnlock(&trace_mtx);
I2C_Unlock();
pktResumeReception(PKT_RADIO_1);
pktReleaseRadio(PKT_RADIO_1);

Wyświetl plik

@ -26,21 +26,20 @@ const SerialConfig gps_config =
/**
* Transmits a string of bytes to the GPS
*/
void gps_transmit_string(uint8_t *cmd, uint8_t length)
{
#if defined(UBLOX_USE_I2C)
I2C_writeN(UBLOX_MAX_ADDRESS, cmd, length);
#elif defined(UBLOX_USE_UART)
sdWrite(&SD5, cmd, length);
#endif
void gps_transmit_string(uint8_t *cmd, uint8_t length) {
gps_calc_ubx_csum(cmd, length);
#if defined(UBLOX_USE_I2C)
I2C_writeN(UBLOX_MAX_ADDRESS, cmd, length);
#elif defined(UBLOX_USE_UART)
sdWrite(&SD5, cmd, length);
#endif
}
/**
* Receives a single byte from the GPS and assigns to supplied pointer.
* Returns false is there is no byte available else true
*/
bool gps_receive_byte(uint8_t *data)
{
bool gps_receive_byte(uint8_t *data) {
#if defined(UBLOX_USE_I2C)
uint16_t len;
I2C_read16(UBLOX_MAX_ADDRESS, 0xFD, &len);
@ -190,7 +189,7 @@ bool gps_get_fix(gpsFix_t *fix) {
static uint8_t navstatus[32];
// Transmit request
uint8_t navpvt_req[] = {0xB5, 0x62, 0x01, 0x07, 0x00, 0x00, 0x08, 0x19};
uint8_t navpvt_req[] = {0xB5, 0x62, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00};
gps_transmit_string(navpvt_req, sizeof(navpvt_req));
if(!gps_receive_payload(0x01, 0x07, navpvt, 3000)) { // Receive request
@ -198,7 +197,7 @@ bool gps_get_fix(gpsFix_t *fix) {
return false;
}
uint8_t navstatus_req[] = {0xB5, 0x62, 0x01, 0x03, 0x00, 0x00, 0x04, 0x0D};
uint8_t navstatus_req[] = {0xB5, 0x62, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00};
gps_transmit_string(navstatus_req, sizeof(navstatus_req));
if(!gps_receive_payload(0x01, 0x03, navstatus, 3000)) { // Receive request
@ -250,13 +249,22 @@ bool gps_get_fix(gpsFix_t *fix) {
fix->time.second = navpvt[10];
fix->lat = (int32_t) (
(uint32_t)(navpvt[28]) + ((uint32_t)(navpvt[29]) << 8) + ((uint32_t)(navpvt[30]) << 16) + ((uint32_t)(navpvt[31]) << 24)
(uint32_t)(navpvt[28])
+ ((uint32_t)(navpvt[29]) << 8)
+ ((uint32_t)(navpvt[30]) << 16)
+ ((uint32_t)(navpvt[31]) << 24)
);
fix->lon = (int32_t) (
(uint32_t)(navpvt[24]) + ((uint32_t)(navpvt[25]) << 8) + ((uint32_t)(navpvt[26]) << 16) + ((uint32_t)(navpvt[27]) << 24)
(uint32_t)(navpvt[24])
+ ((uint32_t)(navpvt[25]) << 8)
+ ((uint32_t)(navpvt[26]) << 16)
+ ((uint32_t)(navpvt[27]) << 24)
);
int32_t alt_tmp = (((int32_t)
((uint32_t)(navpvt[36]) + ((uint32_t)(navpvt[37]) << 8) + ((uint32_t)(navpvt[38]) << 16) + ((uint32_t)(navpvt[39]) << 24))
((uint32_t)(navpvt[36])
+ ((uint32_t)(navpvt[37]) << 8)
+ ((uint32_t)(navpvt[38]) << 16)
+ ((uint32_t)(navpvt[39]) << 24))
) / 1000);
if (alt_tmp <= 0) {
fix->alt = 1;
@ -298,7 +306,6 @@ uint8_t gps_disable_nmea_output(void) {
0x00, 0x00 // CRC place holders
};
gps_calc_ubx_csum(nonmea, sizeof(nonmea));
gps_transmit_string(nonmea, sizeof(nonmea));
return gps_receive_ack(0x06, 0x00, 1000);
}
@ -338,7 +345,6 @@ uint8_t gps_set_airborne_model(void) {
0x00, 0x00 // CRC place holders
};
gps_calc_ubx_csum(model6, sizeof(model6));
gps_transmit_string(model6, sizeof(model6));
return gps_receive_ack(0x06, 0x24, 1000);
}
@ -369,7 +375,6 @@ uint8_t gps_set_power_save(void) {
0x00, 0x00 // CRC place holders
};
gps_calc_ubx_csum(powersave, sizeof(powersave));
gps_transmit_string(powersave, sizeof(powersave));
return gps_receive_ack(0x06, 0x3B, 1000);
}
@ -386,7 +391,6 @@ uint8_t gps_power_save(int on) {
0x00, 0x00 // CRC place holders
};
gps_calc_ubx_csum(recvmgmt, sizeof(recvmgmt));
gps_transmit_string(recvmgmt, sizeof(recvmgmt));
return gps_receive_ack(0x06, 0x11, 1000);
}
@ -448,14 +452,15 @@ void GPS_Deinit(void)
/*
* Calculate checksum and inserts into buffer.
* Calling function must allocate space in message buff for csum.
*
*/
bool gps_calc_ubx_csum(uint8_t *mbuf, uint16_t mlen) {
uint16_t i;
uint8_t ck_a = 0, ck_b = 0;
/* Counting sync bytes there must be at least one byte to checksum. */
if(mlen < 5)
/* Counting sync bytes there must be at least one byte to checksum. */
return false;
for (i = 2; i < mlen - 2; i++) {

Wyświetl plik

@ -241,10 +241,10 @@ void usb_cmd_send_aprs_message(BaseSequentialStream *chp, int argc, char *argv[]
chprintf(chp, "Message: %s\r\n", m);
/* Send with ack request (last arg false). */
/* Send with ack request (last arg true). */
packet_t packet = aprs_encode_message(conf_sram.aprs.tx.call,
conf_sram.aprs.tx.path,
argv[0], m, false);
argv[0], m, true);
if(packet == NULL) {
TRACE_WARN("CMD > No free packet objects");
return;
@ -258,9 +258,5 @@ void usb_cmd_send_aprs_message(BaseSequentialStream *chp, int argc, char *argv[]
conf_sram.aprs.tx.radio_conf.rssi);
chprintf(chp, "Message sent!\r\n");
/*
(void)argc;
(void)argv;
chprintf(chp, "TODO: Not implemented\r\n");*/
}

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
@ -18,17 +17,18 @@ int main(void) {
// Init debugging (Serial debug port, LEDs)
DEBUG_INIT();
// This won't actually display since USB isn't initialized yet.
TRACE_INFO("MAIN > Startup");
/*
* Setup buffers in CCM if available.
* Setup IO device arbitration.
* Setup packet primary data.
*/
bool pkt = pktSystemInit();
chDbgAssert(pkt == true, "failed to init packet system");
/* Start Serial Over USB. */
startSDU();
/* Start serial channels if selected. */
pktSerialStart();
@ -39,24 +39,19 @@ int main(void) {
pktEnableEventTrace();
}
#if ACTIVATE_USB
startUSB();
#endif
TRACE_INFO("MAIN > Startup");
// Startup threads
start_essential_threads(); // Startup required modules (tracking manager, watchdog)
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

@ -642,11 +642,11 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* Activity LED blink rate scaling variable. */
uint16_t led_count = 0;
#define DECODER_WAIT_TIME 200U /* 200mS. */
#define DECODER_IDLE_TIME 2000U /* 2000uS. */
#define DECODER_WAIT_TIME 100U /* 100mS. */
//#define DECODER_IDLE_TIME 2000U /* 2000uS. */
#define DECODER_POLL_TIME 10U /* 10mS. */
#define DECODER_LED_RATE_POLL 100U /* 1000uS. */
#define DECODER_ACTIVE_TIMEOUT 5U /* 5mS. */
//#define DECODER_LED_RATE_POLL 100U /* 1000uS. */
//#define DECODER_ACTIVE_TIMEOUT 5U /* 5mS. */
#define DECODER_SUSPEND_TIME 2000U /* 2000uS. */
#define DECODER_LED_RATE_SUSPEND 250U /* Blink at 250mS during suspend. */
@ -693,6 +693,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* Something went wrong if we arrive here. */
chSysHalt("ThdExit");
}
/* Toggle decoder LED in wait state. */
pktWriteDecoderLED(PAL_TOGGLE);
continue;
}
@ -723,12 +724,15 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
TIME_MS2I(DECODER_POLL_TIME));
if(fifo_msg != MSG_OK) {
if(++led_count >= DECODER_LED_RATE_POLL) {
/* Toggle decoder LED. */
/* if(++led_count >= DECODER_LED_RATE_POLL) {
Toggle decoder LED.
pktWriteDecoderLED(PAL_TOGGLE);
led_count = 0;
}
/* No FIFO object posted so loop again. */
}*/
/*
* No FIFO object posted so loop.
* Go back through IDLE and check for STOP event.
*/
myDriver->decoder_state = DECODER_IDLE;
break;
}
@ -757,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;
}
@ -796,8 +803,9 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
byte_packed_pwm_t data;
size_t n = iqReadTimeout(myQueue, data.bytes,
sizeof(packed_pwm_counts_t),
TIME_MS2I(DECODER_ACTIVE_TIMEOUT));
/* TODO: Timeout to be calculated from SYMBOL time x (8?). */
chTimeUS2I(833 * 8)
/*TIME_MS2I(DECODER_ACTIVE_TIMEOUT)*/);
/* Timeout calculated as SYMBOL time x 8. */
if(n == sizeof(packed_pwm_counts_t)) {
array_min_pwm_counts_t radio;
@ -901,7 +909,13 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
radio_cca_fifo_t *myFIFO = myDriver->active_demod_object;
if(myFIFO != NULL) {
/* Wait for queue object to be released by PWM. */
/*
* Wait for queue object to be released by PWM.
* Normally this is the case.
* If can be a forced release by semaphore reset.
* TODO: This may happen if the watchdog system forces reset.
* TBD.
*/
(void)chBSemWait(&myFIFO->sem);
#if USE_HEAP_PWM_BUFFER == TRUE

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

@ -589,7 +589,7 @@ static bool Si446x_transmit(radio_unit_t radio,
}
/* Try to get clear channel. */
TRACE_INFO( "SI > Wait maximum of %.1f seconds for clear channel on"
TRACE_INFO( "SI > Run CCA for %.1f seconds on"
" %d.%03d MHz",
(float32_t)(TIME_I2MS(cca_timeout) / 1000),
op_freq/1000000, (op_freq%1000000)/1000);
@ -601,7 +601,7 @@ static bool Si446x_transmit(radio_unit_t radio,
chThdSleep(TIME_MS2I(1));
}
/* Clear channel timing. */
TRACE_INFO( "SI > CCA time = %d milliseconds",
TRACE_INFO( "SI > CCA completed in %d milliseconds",
chTimeI2MS(chVTTimeElapsedSinceX(t0)));
}

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

@ -21,8 +21,8 @@
#define PKT_SEND_BUFFER_SEM_NAME "pbsem"
#define PKT_CALLBACK_WA_SIZE 8192
#define PKT_TERMINATOR_WA_SIZE 1024
#define PKT_CALLBACK_WA_SIZE (1024 * 10)
#define PKT_TERMINATOR_WA_SIZE (1024 * 1)
/*===========================================================================*/
/* Module data structures and types. */
@ -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,6 +67,7 @@
#endif
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
/**
* ICU related definitions.
@ -123,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

@ -40,8 +40,8 @@
#define ORIGIN_OTHER_TRACKER 0x6
#define ORIGIN_DIGIPEATER_CONVERSION 0x7
#define APRS_DEST_CALLSIGN "APECAN" // APExxx = Pecan device
#define APRS_DEST_SSID 0
#define APRS_DEVICE_CALLSIGN "APECAN" // APExxx = Pecan device
//#define APRS_DEST_SSID 0
#define SYM_BALLOON 0x2F4F
#define SYM_SMALLAIRCRAFT 0x2F27
@ -49,18 +49,76 @@
#define SYM_CAR 0x2F3E
#define SYM_SHIP 0x2F73
#define SYM_DIGIPEATER 0x2F23
#define SYM_ANTENNA 0x2F72
#define APRS_HEARD_LIST_SIZE 20
#define APRS_MAX_MSG_ARGUMENTS 10
typedef struct APRSIdentity {
char num[8];
char src[AX25_MAX_ADDR_LEN];
char call[AX25_MAX_ADDR_LEN];
char path[16];
uint16_t symbol;
uint32_t freq;
uint8_t pwr;
mod_t mod;
uint8_t rssi;
} aprs_identity_t;
/**
* @brief Command handler function type.
*/
typedef msg_t (*aprscmd_t)(aprs_identity_t *id, int argc, char *argv[]);
/**
* @brief APRS command entry type.
*/
typedef struct {
const char *ac_name; /**< @brief Command name. */
aprscmd_t ac_function; /**< @brief Command function. */
} APRSCommand;
/* Temporary. Will be deprecated when fixed station feature is implemented. */
extern bool test_gps_enabled;
void aprs_debug_getPacket(packet_t pp, char* buf, uint32_t len);
packet_t aprs_encode_position(const char *callsign, const char *path, uint16_t symbol, dataPoint_t *dataPoint);
packet_t aprs_encode_telemetry_configuration(const char *callsign, const char *path, uint8_t type);
packet_t aprs_encode_message(const char *callsign, const char *path, const char *receiver, const char *text, const bool noCounter);
packet_t aprs_encode_data_packet(const char *callsign, const char *path, char packetType, uint8_t *data);
packet_t aprs_encode_query_answer_aprsd(const char *callsign, const char *path, const char *receiver);
void aprs_decode_packet(packet_t pp);
#ifdef __cplusplus
extern "C" {
#endif
void aprs_debug_getPacket(packet_t pp, char* buf, uint32_t len);
packet_t aprs_encode_position(const char *callsign, const char *path,
uint16_t symbol, dataPoint_t *dataPoint);
packet_t aprs_encode_telemetry_configuration(const char *callsign,
const char *path, uint8_t type);
packet_t aprs_encode_message(const char *callsign, const char *path,
const char *receiver, const char *text,
const bool ack);
packet_t aprs_encode_data_packet(const char *callsign, const char *path,
char packetType, uint8_t *data);
packet_t aprs_compose_aprsd_message(const char *callsign, const char *path,
const char *receiver);
void aprs_decode_packet(packet_t pp);
msg_t aprs_send_position_beacon(aprs_identity_t *id,
int argc, char *argv[]);
msg_t aprs_send_aprsd_message(aprs_identity_t *id,
int argc, char *argv[]);
msg_t aprs_send_aprsh_message(aprs_identity_t *id,
int argc, char *argv[]);
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[]);
msg_t aprs_execute_config_command(aprs_identity_t *id,
int argc, char *argv[]);
msg_t aprs_execute_config_save(aprs_identity_t *id,
int argc, char *argv[]);
msg_t aprs_execute_img_command(aprs_identity_t *id,
int argc, char *argv[]);
msg_t aprs_execute_system_reset(aprs_identity_t *id,
int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif

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

@ -61,17 +61,23 @@ THD_FUNCTION(posThread, arg)
chThdSleep(TIME_S2I(5));
}
// Encode/Transmit APRSD packet
/*
* This is a tracker originated message (not a reply to an incoming).
* The message will be sent to the base station if set.
* Encode/Transmit APRSD packet.
* This is a tracker originated message (not a reply to a request).
* The message will be sent to the base station set in path.
*/
if(conf_sram.aprs.base.enabled) {
packet = aprs_encode_query_answer_aprsd(conf->call, /* from */
conf_sram.aprs.base.path, /* via */
conf_sram.aprs.base.call); /* to */
/*
* Send message from this device.
* Use call sign and path as specified in base config.
* There is no acknowledgment requested.
*/
packet = aprs_compose_aprsd_message(
APRS_DEVICE_CALLSIGN,
conf_sram.aprs.base.path,
conf_sram.aprs.base.call);
if(packet == NULL) {
TRACE_WARN("POS > No free packet objects for "
TRACE_WARN("POS > No free packet objects "
"or badly formed APRSD message");
} else {
if(!transmitOnRadio(packet,
@ -87,6 +93,7 @@ THD_FUNCTION(posThread, arg)
chThdSleep(TIME_S2I(5));
}
} else {
/* TODO: Implement a fallback destination if no base station set? */
TRACE_INFO("POS > APRSD data not sent - no base station specified");
}

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

Wyświetl plik

@ -128,6 +128,10 @@ typedef struct {
uint16_t symbol;
uint8_t rssi; // Squelch for CCA check
bool enabled;
bool fixed;
int32_t lat;
int32_t lon;
int32_t alt;
} thd_tx_conf_t;