kopia lustrzana https://github.com/DL7AD/pecanpico10
Merge branch 'master' of github.com:DL7AD/pecanpico10
commit
a7f41c89d1
|
@ -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'];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/pecanpico10-rescue.lib
|
|
@ -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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
|
@ -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_)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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");*/
|
||||
}
|
||||
|
||||
|
|
|
@ -6,60 +6,137 @@
|
|||
#include "pktconf.h"
|
||||
|
||||
static thread_t *shelltp;
|
||||
static bool usb_initialized;
|
||||
sdu_term_t sdu_chn_state;
|
||||
|
||||
event_listener_t shell_el;
|
||||
event_listener_t sdu1_el;
|
||||
|
||||
static const ShellConfig shell_cfg = {
|
||||
(BaseSequentialStream*)&SDU1,
|
||||
commands
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void startUSB(void) {
|
||||
if(usb_initialized)
|
||||
return; // Avoid duplicate initialization
|
||||
usbObjectInit(&USBD1);
|
||||
|
||||
/* Initialize USB. */
|
||||
sduObjectInit(&SDU1);
|
||||
usbStart(&USBD1, &usbcfg);
|
||||
|
||||
/* Currently does nothing. */
|
||||
usbDisconnectBus(serusbcfg.usbp);
|
||||
usbDisconnectBus(&USBD1);
|
||||
|
||||
chThdSleep(TIME_MS2I(100));
|
||||
|
||||
usbStart(serusbcfg.usbp, &usbcfg);
|
||||
|
||||
/* Currently does nothing. */
|
||||
usbConnectBus(serusbcfg.usbp);
|
||||
usbConnectBus(&USBD1);
|
||||
|
||||
sduStart(&SDU1, &serusbcfg);
|
||||
|
||||
// Initialize shell
|
||||
shelltp = NULL;
|
||||
shellInit();
|
||||
|
||||
usb_initialized = true;
|
||||
sdu_chn_state = TERM_SDU_INIT;
|
||||
}
|
||||
|
||||
void manageShell(void) {
|
||||
if(shelltp == NULL && isUSBactive()) {
|
||||
|
||||
shelltp = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(4*1024),
|
||||
"shell", NORMALPRIO + 1,
|
||||
shellThread,
|
||||
(void*)&shell_cfg);
|
||||
|
||||
|
||||
chEvtRegister(&shell_terminated, &shell_el, USB_SHELL_EVT);
|
||||
}
|
||||
chEvtWaitAnyTimeout(EVENT_MASK(USB_SHELL_EVT), TIME_S2I(1));
|
||||
if(chThdTerminatedX(shelltp)) {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
chEvtUnregister(&shell_terminated, &shell_el);
|
||||
}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void startSDU(void) {
|
||||
if(sdu_chn_state != TERM_SDU_INIT)
|
||||
return;
|
||||
sduObjectInit(&SDU1);
|
||||
chEvtRegister(chnGetEventSource(&SDU1), &sdu1_el, USB_SDU1_EVT);
|
||||
sduStart(&SDU1, &serusbcfg);
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Manage trace output and shell on Serial Over USB.
|
||||
* @notes TRACE output is sent to USB serial.
|
||||
* @notes TRACE output is suspended when any key is pressed on terminal.
|
||||
* @notes A new shell is invoked and remains active until logout.
|
||||
* @notes TRACE output is then resotored.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void manageTraceAndShell(void) {
|
||||
|
||||
if(chEvtGetAndClearEvents(EVENT_MASK(USB_SDU1_EVT)) == 0)
|
||||
return;
|
||||
|
||||
BaseSequentialStream *chp = (BaseSequentialStream *)&SDU1;
|
||||
|
||||
eventflags_t evtf = chEvtGetAndClearFlags(&sdu1_el);
|
||||
|
||||
switch(sdu_chn_state) {
|
||||
case TERM_SDU_INIT:
|
||||
return;
|
||||
|
||||
case TERM_SDU_IDLE: {
|
||||
if(evtf == 0)
|
||||
return;
|
||||
if(evtf & CHN_CONNECTED) {
|
||||
sdu_chn_state = TERM_SDU_OUT;
|
||||
chprintf(chp, "\r\n*** Trace output enabled ***\r\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_IDLE */
|
||||
|
||||
case TERM_SDU_OUT: {
|
||||
if(evtf & CHN_DISCONNECTED) {
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
return;
|
||||
}
|
||||
if(evtf & CHN_INPUT_AVAILABLE) {
|
||||
/* Flush the input queue. */
|
||||
while(chnGetTimeout((SerialUSBDriver *)chp, TIME_MS2I(100)) != STM_TIMEOUT);
|
||||
chprintf(chp, "\r\n*** Trace suspended - type ^D or use the "
|
||||
"'exit' command to resume trace ***\r\n");
|
||||
shellInit();
|
||||
shelltp = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(4*1024),
|
||||
"shell", NORMALPRIO + 1,
|
||||
shellThread,
|
||||
(void*)&shell_cfg);
|
||||
if(shelltp == NULL) {
|
||||
chprintf(chp, "\r\n*** Failed to open shell ***\r\n");
|
||||
break;
|
||||
}
|
||||
sdu_chn_state = TERM_SDU_SHELL;
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_OUT */
|
||||
|
||||
case TERM_SDU_SHELL: {
|
||||
/* USB disconnect. */
|
||||
if(evtf & CHN_DISCONNECTED) {
|
||||
chThdTerminate(shelltp);
|
||||
sdu_chn_state = TERM_SDU_EXIT;
|
||||
break;
|
||||
}
|
||||
/* Was shell terminated from CLI? */
|
||||
if(chThdTerminatedX(shelltp)) {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
sdu_chn_state = TERM_SDU_OUT;
|
||||
chprintf(chp, "\r\n*** Trace resumed by user ***\r\n");
|
||||
}
|
||||
break;
|
||||
} /* End case TERM_SDU_SHELL */
|
||||
|
||||
case TERM_SDU_EXIT: {
|
||||
chThdWait(shelltp);
|
||||
shelltp = NULL;
|
||||
sdu_chn_state = TERM_SDU_IDLE;
|
||||
break;
|
||||
} /* End case TERM_SDU_EXIT */
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* End switch. */
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
bool isSDUAvailable(void) {
|
||||
return usb_initialized;
|
||||
/* Return channel connection status of SDU. */
|
||||
return (bool)(sdu_chn_state == TERM_SDU_OUT);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,19 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
typedef enum sduTermStates {
|
||||
TERM_SDU_INIT = 0,
|
||||
TERM_SDU_IDLE,
|
||||
TERM_SDU_OUT,
|
||||
TERM_SDU_SHELL,
|
||||
TERM_SDU_EXIT
|
||||
} sdu_term_t;
|
||||
|
||||
#define isUSBactive() (SDU1.config->usbp->state == USB_ACTIVE)
|
||||
|
||||
void startUSB(void);
|
||||
void manageShell(void);
|
||||
void startSDU(void);
|
||||
void manageTraceAndShell(void);
|
||||
bool isSDUAvailable(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,344 +1,344 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Virtual serial port over USB.*/
|
||||
SerialUSBDriver SDU1;
|
||||
|
||||
/*
|
||||
* Endpoints to be used for USBD1.
|
||||
*/
|
||||
#define USBD1_DATA_REQUEST_EP 1
|
||||
#define USBD1_DATA_AVAILABLE_EP 1
|
||||
#define USBD1_INTERRUPT_REQUEST_EP 2
|
||||
|
||||
/*
|
||||
* USB Device Descriptor.
|
||||
*/
|
||||
static const uint8_t vcom_device_descriptor_data[18] = {
|
||||
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
|
||||
0x02, /* bDeviceClass (CDC). */
|
||||
0x00, /* bDeviceSubClass. */
|
||||
0x00, /* bDeviceProtocol. */
|
||||
0x40, /* bMaxPacketSize. */
|
||||
0x0483, /* idVendor (ST). */
|
||||
0x5740, /* idProduct. */
|
||||
0x0200, /* bcdDevice. */
|
||||
1, /* iManufacturer. */
|
||||
2, /* iProduct. */
|
||||
3, /* iSerialNumber. */
|
||||
1) /* bNumConfigurations. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_device_descriptor = {
|
||||
sizeof vcom_device_descriptor_data,
|
||||
vcom_device_descriptor_data
|
||||
};
|
||||
|
||||
/* Configuration Descriptor tree for a CDC.*/
|
||||
static const uint8_t vcom_configuration_descriptor_data[67] = {
|
||||
/* Configuration Descriptor.*/
|
||||
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
|
||||
0x02, /* bNumInterfaces. */
|
||||
0x01, /* bConfigurationValue. */
|
||||
0, /* iConfiguration. */
|
||||
0xC0, /* bmAttributes (self powered). */
|
||||
50), /* bMaxPower (100mA). */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x01, /* bNumEndpoints. */
|
||||
0x02, /* bInterfaceClass (Communications
|
||||
Interface Class, CDC section
|
||||
4.2). */
|
||||
0x02, /* bInterfaceSubClass (Abstract
|
||||
Control Model, CDC section 4.3). */
|
||||
0x01, /* bInterfaceProtocol (AT commands,
|
||||
CDC section 4.4). */
|
||||
0), /* iInterface. */
|
||||
/* Header Functional Descriptor (CDC section 5.2.3).*/
|
||||
USB_DESC_BYTE (5), /* bLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
|
||||
Functional Descriptor. */
|
||||
USB_DESC_BCD (0x0110), /* bcdCDC. */
|
||||
/* Call Management Functional Descriptor. */
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
|
||||
USB_DESC_BYTE (0x01), /* bDataInterface. */
|
||||
/* ACM Functional Descriptor.*/
|
||||
USB_DESC_BYTE (4), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
|
||||
Control Management Descriptor). */
|
||||
USB_DESC_BYTE (0x02), /* bmCapabilities. */
|
||||
/* Union Functional Descriptor.*/
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
|
||||
Class Interface). */
|
||||
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
|
||||
Interface). */
|
||||
/* Endpoint 2 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
|
||||
0x03, /* bmAttributes (Interrupt). */
|
||||
0x0008, /* wMaxPacketSize. */
|
||||
0xFF), /* bInterval. */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
0x0A, /* bInterfaceClass (Data Class
|
||||
Interface, CDC section 4.5). */
|
||||
0x00, /* bInterfaceSubClass (CDC section
|
||||
4.6). */
|
||||
0x00, /* bInterfaceProtocol (CDC section
|
||||
4.7). */
|
||||
0x00), /* iInterface. */
|
||||
/* Endpoint 3 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00), /* bInterval. */
|
||||
/* Endpoint 1 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00) /* bInterval. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_configuration_descriptor = {
|
||||
sizeof vcom_configuration_descriptor_data,
|
||||
vcom_configuration_descriptor_data
|
||||
};
|
||||
|
||||
/*
|
||||
* U.S. English language identifier.
|
||||
*/
|
||||
static const uint8_t vcom_string0[] = {
|
||||
USB_DESC_BYTE(4), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||
};
|
||||
|
||||
/*
|
||||
* Vendor string.
|
||||
*/
|
||||
static const uint8_t vcom_string1[] = {
|
||||
USB_DESC_BYTE(38), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
|
||||
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
|
||||
'c', 0, 's', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Description string.
|
||||
*/
|
||||
static const uint8_t vcom_string2[] = {
|
||||
USB_DESC_BYTE(56), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
|
||||
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
|
||||
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
|
||||
'o', 0, 'r', 0, 't', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial Number string.
|
||||
*/
|
||||
static const uint8_t vcom_string3[] = {
|
||||
USB_DESC_BYTE(8), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'0' + CH_KERNEL_MAJOR, 0,
|
||||
'0' + CH_KERNEL_MINOR, 0,
|
||||
'0' + CH_KERNEL_PATCH, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings wrappers array.
|
||||
*/
|
||||
static const USBDescriptor vcom_strings[] = {
|
||||
{sizeof vcom_string0, vcom_string0},
|
||||
{sizeof vcom_string1, vcom_string1},
|
||||
{sizeof vcom_string2, vcom_string2},
|
||||
{sizeof vcom_string3, vcom_string3}
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
|
||||
* handled here.
|
||||
*/
|
||||
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang) {
|
||||
|
||||
(void)usbp;
|
||||
(void)lang;
|
||||
switch (dtype) {
|
||||
case USB_DESCRIPTOR_DEVICE:
|
||||
return &vcom_device_descriptor;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
return &vcom_configuration_descriptor;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
if (dindex < 4)
|
||||
return &vcom_strings[dindex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IN EP1 state.
|
||||
*/
|
||||
static USBInEndpointState ep1instate;
|
||||
|
||||
/**
|
||||
* @brief OUT EP1 state.
|
||||
*/
|
||||
static USBOutEndpointState ep1outstate;
|
||||
|
||||
/**
|
||||
* @brief EP1 initialization structure (both IN and OUT).
|
||||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
USB_EP_MODE_TYPE_BULK,
|
||||
NULL,
|
||||
sduDataTransmitted,
|
||||
sduDataReceived,
|
||||
0x0040,
|
||||
0x0040,
|
||||
&ep1instate,
|
||||
&ep1outstate,
|
||||
2,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IN EP2 state.
|
||||
*/
|
||||
static USBInEndpointState ep2instate;
|
||||
|
||||
/**
|
||||
* @brief EP2 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
USB_EP_MODE_TYPE_INTR,
|
||||
NULL,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
0x0000,
|
||||
&ep2instate,
|
||||
NULL,
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||
extern SerialUSBDriver SDU1;
|
||||
|
||||
switch (event) {
|
||||
case USB_EVENT_ADDRESS:
|
||||
return;
|
||||
case USB_EVENT_CONFIGURED:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Enables the endpoints specified into the configuration.
|
||||
Note, this callback is invoked from an ISR so I-Class functions
|
||||
must be used.*/
|
||||
usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
|
||||
usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
|
||||
|
||||
/* Resetting the state of the CDC subsystem.*/
|
||||
sduConfigureHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_RESET:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_SUSPEND:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduSuspendHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_WAKEUP:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduWakeupHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_STALLED:
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void sof_handler(USBDriver *usbp) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
osalSysLockFromISR();
|
||||
sduSOFHookI(&SDU1);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
/*
|
||||
* USB driver configuration.
|
||||
*/
|
||||
const USBConfig usbcfg = {
|
||||
usb_event,
|
||||
get_descriptor,
|
||||
sduRequestsHook,
|
||||
sof_handler
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial over USB driver configuration.
|
||||
*/
|
||||
const SerialUSBConfig serusbcfg = {
|
||||
&USBD1,
|
||||
USBD1_DATA_REQUEST_EP,
|
||||
USBD1_DATA_AVAILABLE_EP,
|
||||
USBD1_INTERRUPT_REQUEST_EP
|
||||
};
|
||||
|
||||
/*
|
||||
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Virtual serial port over USB.*/
|
||||
SerialUSBDriver SDU1;
|
||||
|
||||
/*
|
||||
* Endpoints to be used for USBD1.
|
||||
*/
|
||||
#define USBD1_DATA_REQUEST_EP 1
|
||||
#define USBD1_DATA_AVAILABLE_EP 1
|
||||
#define USBD1_INTERRUPT_REQUEST_EP 2
|
||||
|
||||
/*
|
||||
* USB Device Descriptor.
|
||||
*/
|
||||
static const uint8_t vcom_device_descriptor_data[18] = {
|
||||
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
|
||||
0x02, /* bDeviceClass (CDC). */
|
||||
0x00, /* bDeviceSubClass. */
|
||||
0x00, /* bDeviceProtocol. */
|
||||
0x40, /* bMaxPacketSize. */
|
||||
0x0483, /* idVendor (ST). */
|
||||
0x5740, /* idProduct. */
|
||||
0x0200, /* bcdDevice. */
|
||||
1, /* iManufacturer. */
|
||||
2, /* iProduct. */
|
||||
3, /* iSerialNumber. */
|
||||
1) /* bNumConfigurations. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_device_descriptor = {
|
||||
sizeof vcom_device_descriptor_data,
|
||||
vcom_device_descriptor_data
|
||||
};
|
||||
|
||||
/* Configuration Descriptor tree for a CDC.*/
|
||||
static const uint8_t vcom_configuration_descriptor_data[67] = {
|
||||
/* Configuration Descriptor.*/
|
||||
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
|
||||
0x02, /* bNumInterfaces. */
|
||||
0x01, /* bConfigurationValue. */
|
||||
0, /* iConfiguration. */
|
||||
0xC0, /* bmAttributes (self powered). */
|
||||
50), /* bMaxPower (100mA). */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x01, /* bNumEndpoints. */
|
||||
0x02, /* bInterfaceClass (Communications
|
||||
Interface Class, CDC section
|
||||
4.2). */
|
||||
0x02, /* bInterfaceSubClass (Abstract
|
||||
Control Model, CDC section 4.3). */
|
||||
0x01, /* bInterfaceProtocol (AT commands,
|
||||
CDC section 4.4). */
|
||||
0), /* iInterface. */
|
||||
/* Header Functional Descriptor (CDC section 5.2.3).*/
|
||||
USB_DESC_BYTE (5), /* bLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
|
||||
Functional Descriptor. */
|
||||
USB_DESC_BCD (0x0110), /* bcdCDC. */
|
||||
/* Call Management Functional Descriptor. */
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
|
||||
USB_DESC_BYTE (0x01), /* bDataInterface. */
|
||||
/* ACM Functional Descriptor.*/
|
||||
USB_DESC_BYTE (4), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
|
||||
Control Management Descriptor). */
|
||||
USB_DESC_BYTE (0x02), /* bmCapabilities. */
|
||||
/* Union Functional Descriptor.*/
|
||||
USB_DESC_BYTE (5), /* bFunctionLength. */
|
||||
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
|
||||
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
|
||||
Functional Descriptor). */
|
||||
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
|
||||
Class Interface). */
|
||||
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
|
||||
Interface). */
|
||||
/* Endpoint 2 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80,
|
||||
0x03, /* bmAttributes (Interrupt). */
|
||||
0x0008, /* wMaxPacketSize. */
|
||||
0xFF), /* bInterval. */
|
||||
/* Interface Descriptor.*/
|
||||
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
|
||||
0x00, /* bAlternateSetting. */
|
||||
0x02, /* bNumEndpoints. */
|
||||
0x0A, /* bInterfaceClass (Data Class
|
||||
Interface, CDC section 4.5). */
|
||||
0x00, /* bInterfaceSubClass (CDC section
|
||||
4.6). */
|
||||
0x00, /* bInterfaceProtocol (CDC section
|
||||
4.7). */
|
||||
0x00), /* iInterface. */
|
||||
/* Endpoint 3 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00), /* bInterval. */
|
||||
/* Endpoint 1 Descriptor.*/
|
||||
USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/
|
||||
0x02, /* bmAttributes (Bulk). */
|
||||
0x0040, /* wMaxPacketSize. */
|
||||
0x00) /* bInterval. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Configuration Descriptor wrapper.
|
||||
*/
|
||||
static const USBDescriptor vcom_configuration_descriptor = {
|
||||
sizeof vcom_configuration_descriptor_data,
|
||||
vcom_configuration_descriptor_data
|
||||
};
|
||||
|
||||
/*
|
||||
* U.S. English language identifier.
|
||||
*/
|
||||
static const uint8_t vcom_string0[] = {
|
||||
USB_DESC_BYTE(4), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
|
||||
};
|
||||
|
||||
/*
|
||||
* Vendor string.
|
||||
*/
|
||||
static const uint8_t vcom_string1[] = {
|
||||
USB_DESC_BYTE(38), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
|
||||
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
|
||||
'c', 0, 's', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Device Description string.
|
||||
*/
|
||||
static const uint8_t vcom_string2[] = {
|
||||
USB_DESC_BYTE(56), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
|
||||
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
|
||||
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
|
||||
'o', 0, 'r', 0, 't', 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial Number string.
|
||||
*/
|
||||
static const uint8_t vcom_string3[] = {
|
||||
USB_DESC_BYTE(8), /* bLength. */
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
|
||||
'0' + CH_KERNEL_MAJOR, 0,
|
||||
'0' + CH_KERNEL_MINOR, 0,
|
||||
'0' + CH_KERNEL_PATCH, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Strings wrappers array.
|
||||
*/
|
||||
static const USBDescriptor vcom_strings[] = {
|
||||
{sizeof vcom_string0, vcom_string0},
|
||||
{sizeof vcom_string1, vcom_string1},
|
||||
{sizeof vcom_string2, vcom_string2},
|
||||
{sizeof vcom_string3, vcom_string3}
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
|
||||
* handled here.
|
||||
*/
|
||||
static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang) {
|
||||
|
||||
(void)usbp;
|
||||
(void)lang;
|
||||
switch (dtype) {
|
||||
case USB_DESCRIPTOR_DEVICE:
|
||||
return &vcom_device_descriptor;
|
||||
case USB_DESCRIPTOR_CONFIGURATION:
|
||||
return &vcom_configuration_descriptor;
|
||||
case USB_DESCRIPTOR_STRING:
|
||||
if (dindex < 4)
|
||||
return &vcom_strings[dindex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IN EP1 state.
|
||||
*/
|
||||
static USBInEndpointState ep1instate;
|
||||
|
||||
/**
|
||||
* @brief OUT EP1 state.
|
||||
*/
|
||||
static USBOutEndpointState ep1outstate;
|
||||
|
||||
/**
|
||||
* @brief EP1 initialization structure (both IN and OUT).
|
||||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
USB_EP_MODE_TYPE_BULK,
|
||||
NULL,
|
||||
sduDataTransmitted,
|
||||
sduDataReceived,
|
||||
0x0040,
|
||||
0x0040,
|
||||
&ep1instate,
|
||||
&ep1outstate,
|
||||
2,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IN EP2 state.
|
||||
*/
|
||||
static USBInEndpointState ep2instate;
|
||||
|
||||
/**
|
||||
* @brief EP2 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
USB_EP_MODE_TYPE_INTR,
|
||||
NULL,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
0x0000,
|
||||
&ep2instate,
|
||||
NULL,
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||
extern SerialUSBDriver SDU1;
|
||||
|
||||
switch (event) {
|
||||
case USB_EVENT_ADDRESS:
|
||||
return;
|
||||
case USB_EVENT_CONFIGURED:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Enables the endpoints specified into the configuration.
|
||||
Note, this callback is invoked from an ISR so I-Class functions
|
||||
must be used.*/
|
||||
usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
|
||||
usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
|
||||
|
||||
/* Resetting the state of the CDC subsystem.*/
|
||||
sduConfigureHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_RESET:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_UNCONFIGURED:
|
||||
/* Falls into.*/
|
||||
case USB_EVENT_SUSPEND:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Disconnection event on suspend.*/
|
||||
sduSuspendHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_WAKEUP:
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Wake up event.*/
|
||||
sduWakeupHookI(&SDU1);
|
||||
|
||||
chSysUnlockFromISR();
|
||||
return;
|
||||
case USB_EVENT_STALLED:
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles the USB driver global events.
|
||||
*/
|
||||
static void sof_handler(USBDriver *usbp) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
osalSysLockFromISR();
|
||||
sduSOFHookI(&SDU1);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
/*
|
||||
* USB driver configuration.
|
||||
*/
|
||||
const USBConfig usbcfg = {
|
||||
usb_event,
|
||||
get_descriptor,
|
||||
sduRequestsHook,
|
||||
sof_handler
|
||||
};
|
||||
|
||||
/*
|
||||
* Serial over USB driver configuration.
|
||||
*/
|
||||
const SerialUSBConfig serusbcfg = {
|
||||
&USBD1,
|
||||
USBD1_DATA_REQUEST_EP,
|
||||
USBD1_DATA_AVAILABLE_EP,
|
||||
USBD1_INTERRUPT_REQUEST_EP
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "padc.h"
|
||||
|
||||
/**
|
||||
* Main routine is starting up system, runs the software watchdog (module monitoring), controls LEDs
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -661,7 +661,6 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
|
|||
/* Increase outstanding callback count. */
|
||||
handler->cb_count++;
|
||||
}
|
||||
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#define EVT_PRIORITY_BASE 0
|
||||
|
||||
/*
|
||||
* Decoder global system events.
|
||||
* Decoder global system event masks.
|
||||
* The packet channel object holds the global events.
|
||||
* Events are broadcast to any listeners.
|
||||
*/
|
||||
|
@ -98,7 +98,8 @@
|
|||
#define EVT_PKT_CBK_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 31)
|
||||
|
||||
|
||||
/* Decoder thread events (sent from initiator to decoder). */
|
||||
/* Decoder thread event IDs (sent from initiator to decoder). */
|
||||
/*TODO: These needs to be values and NOT bit shifted masks. */
|
||||
|
||||
#define DEC_COMMAND_START EVENT_MASK(EVT_PRIORITY_BASE + 0)
|
||||
#define DEC_COMMAND_STOP EVENT_MASK(EVT_PRIORITY_BASE + 1)
|
||||
|
@ -107,8 +108,9 @@
|
|||
#define DEC_SUSPEND_EXIT EVENT_MASK(EVT_PRIORITY_BASE + 4)
|
||||
|
||||
|
||||
/* Reserved system thread events (in user threads level). */
|
||||
#define USB_SHELL_EVT EVENT_MASK(EVT_PRIORITY_BASE + 0)
|
||||
/* Reserved system event broadcast IDs (set mask in user threads level). */
|
||||
#define USB_SHELL_EVT EVT_PRIORITY_BASE + 0
|
||||
#define USB_SDU1_EVT EVT_PRIORITY_BASE + 16
|
||||
|
||||
/* Response thread events (from decoder to initiator). */
|
||||
#define DEC_OPEN_EXEC EVENT_MASK(EVT_PRIORITY_BASE + 15)
|
||||
|
|
|
@ -1180,43 +1180,54 @@ void ax25_remove_addr (packet_t this_p, int n)
|
|||
*
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
int ax25_get_num_addr (packet_t this_p)
|
||||
{
|
||||
//unsigned char *pf;
|
||||
int a;
|
||||
int addr_bytes;
|
||||
int ax25_get_num_addr (packet_t this_p) {
|
||||
int a;
|
||||
//int addr_bytes;
|
||||
|
||||
|
||||
if(this_p->magic1 != MAGIC || this_p->magic2 != MAGIC) {
|
||||
TRACE_ERROR("PKT > Buffer overflow");
|
||||
return 0;
|
||||
}
|
||||
if(this_p->magic1 != MAGIC || this_p->magic2 != MAGIC) {
|
||||
TRACE_ERROR("PKT > Buffer overflow");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use cached value if already set. */
|
||||
/* Use cached value if already set. */
|
||||
|
||||
if (this_p->num_addr >= 0) {
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
if (this_p->num_addr >= 0) {
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
|
||||
/* Otherwise, determine the number of addresses. */
|
||||
/*
|
||||
* Otherwise, determine the number of addresses.
|
||||
* Start with assumption of zero.
|
||||
*/
|
||||
|
||||
this_p->num_addr = 0; /* Number of addresses extracted. */
|
||||
|
||||
addr_bytes = 0;
|
||||
for (a = 0; a < this_p->frame_len && addr_bytes == 0; a++) {
|
||||
if (this_p->frame_data[a] & SSID_LAST_MASK) {
|
||||
addr_bytes = a + 1;
|
||||
}
|
||||
}
|
||||
this_p->num_addr = 0;
|
||||
|
||||
if (addr_bytes % 7 == 0) {
|
||||
int addrs = addr_bytes / 7;
|
||||
if (addrs >= AX25_MIN_ADDRS && addrs <= AX25_MAX_ADDRS) {
|
||||
this_p->num_addr = addrs;
|
||||
}
|
||||
}
|
||||
|
||||
return (this_p->num_addr);
|
||||
/* Check that address characters are valid. */
|
||||
|
||||
for(a = 0;
|
||||
a < this_p->frame_len && a < (AX25_MAX_ADDRS * AX25_ADDR_LEN);
|
||||
a++) {
|
||||
/*
|
||||
* Check the call sign characters with isgraph
|
||||
* Could be more strict and accept upper case alpha & numeric only.
|
||||
*/
|
||||
if(a % 7 != 6) {
|
||||
if(isgraph(this_p->frame_data[a] >> 1))
|
||||
continue;
|
||||
}
|
||||
if((this_p->frame_data[a] & SSID_LAST_MASK))
|
||||
break;
|
||||
} /* End for. */
|
||||
|
||||
/* Check if last happened on an address boundary. */
|
||||
if (++a % 7 == 0) {
|
||||
int addrs = a / 7;
|
||||
if (addrs >= AX25_MIN_ADDRS && addrs <= AX25_MAX_ADDRS) {
|
||||
this_p->num_addr = addrs;
|
||||
}
|
||||
}
|
||||
return (this_p->num_addr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1401,7 +1412,7 @@ int ax25_get_ssid (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
return ((this_p->frame_data[n*7+6] & SSID_SSID_MASK) >> SSID_SSID_SHIFT);
|
||||
return ((this_p->frame_data[n * AX25_ADDR_LEN + 6] & SSID_SSID_MASK) >> SSID_SSID_SHIFT);
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("Internal error: ax25_get_ssid(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1437,7 +1448,8 @@ void ax25_set_ssid (packet_t this_p, int n, int ssid)
|
|||
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
this_p->frame_data[n*7+6] = (this_p->frame_data[n*7+6] & ~ SSID_SSID_MASK) |
|
||||
this_p->frame_data[n * AX25_ADDR_LEN + 6] =
|
||||
(this_p->frame_data[n * AX25_ADDR_LEN + 6] & ~ SSID_SSID_MASK) |
|
||||
((ssid << SSID_SSID_SHIFT) & SSID_SSID_MASK) ;
|
||||
}
|
||||
else {
|
||||
|
@ -1476,7 +1488,7 @@ int ax25_get_h (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
return ((this_p->frame_data[n*7+6] & SSID_H_MASK) >> SSID_H_SHIFT);
|
||||
return ((this_p->frame_data[n * AX25_ADDR_LEN + 6] & SSID_H_MASK) >> SSID_H_SHIFT);
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("PKT > Internal error: ax25_get_h(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1511,7 +1523,7 @@ void ax25_set_h (packet_t this_p, int n)
|
|||
}
|
||||
|
||||
if (n >= 0 && n < this_p->num_addr) {
|
||||
this_p->frame_data[n*7+6] |= SSID_H_MASK;
|
||||
this_p->frame_data[n * AX25_ADDR_LEN + 6] |= SSID_H_MASK;
|
||||
}
|
||||
else {
|
||||
TRACE_ERROR ("PKT > Internal error: ax25_set_hd(%d), num_addr=%d", n, this_p->num_addr);
|
||||
|
@ -1921,15 +1933,13 @@ void ax25_format_addrs (packet_t this_p, char *result, int8_t size)
|
|||
}
|
||||
*result = '\0';
|
||||
|
||||
/* New in 0.9. */
|
||||
/* Don't get upset if no addresses. */
|
||||
/* This will allow packets that do not comply to AX.25 format. */
|
||||
/* There must be at least two addresses. */
|
||||
|
||||
if (this_p->num_addr == 0) {
|
||||
if (this_p->num_addr < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Make a safe strcat function. */
|
||||
/* TODO: Refactor this to use a single loop and safe write to buffer. */
|
||||
ax25_get_addr_with_ssid (this_p, AX25_SOURCE, stemp);
|
||||
|
||||
if(size - (strlen(stemp) + 1) < 2)
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
/* to be safe. */
|
||||
#define AX25_MAX_ADDR_LEN 12
|
||||
|
||||
/* The length of an address field in an AX25 header. */
|
||||
#define AX25_ADDR_LEN 7
|
||||
|
||||
/* Previously 1 when considering only APRS. */
|
||||
#define AX25_MIN_INFO_LEN 0U
|
||||
|
||||
|
@ -61,9 +64,9 @@
|
|||
/* The more general case. */
|
||||
/* An AX.25 frame can have a control byte and no protocol. */
|
||||
|
||||
#define AX25_MIN_PACKET_LEN ( 2 * 7 + 1 )
|
||||
#define AX25_MIN_PACKET_LEN ( 2 * AX25_ADDR_LEN + 1 )
|
||||
|
||||
#define AX25_MAX_PACKET_LEN ( AX25_MAX_ADDRS * 7 + 2 + 3 + AX25_MAX_INFO_LEN)
|
||||
#define AX25_MAX_PACKET_LEN ( AX25_MAX_ADDRS * AX25_ADDR_LEN + 2 + 3 + AX25_MAX_INFO_LEN)
|
||||
|
||||
#define AX25_UI_FRAME 3 /* Control field value. */
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "hal.h"
|
||||
#include "chprintf.h"
|
||||
#include "portab.h"
|
||||
#include "usb.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -158,6 +159,10 @@ void sysConfigureCoreIO(void) {
|
|||
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
|
||||
| PAL_STM32_OSPEED_HIGHEST
|
||||
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
|
||||
|
||||
#if ACTIVATE_USB
|
||||
startUSB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
|
||||
#define USE_SPI_ATTACHED_RADIO TRUE
|
||||
#define DUMP_PACKET_TO_SERIAL TRUE
|
||||
#define DUMP_PACKET_TO_SERIAL FALSE
|
||||
|
||||
/*
|
||||
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
|
||||
|
@ -67,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);
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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
|
||||
|
||||
|
|
|
@ -27,16 +27,14 @@ static bool threadStarted = false;
|
|||
/**
|
||||
* Returns most recent data point which is complete.
|
||||
*/
|
||||
dataPoint_t* getLastDataPoint(void)
|
||||
{
|
||||
dataPoint_t* getLastDataPoint(void) {
|
||||
return lastDataPoint;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void waitForNewDataPoint(void)
|
||||
{
|
||||
void waitForNewDataPoint(void) {
|
||||
uint32_t old_id = getLastDataPoint()->id;
|
||||
while(old_id == getLastDataPoint()->id)
|
||||
chThdSleep(TIME_S2I(1));
|
||||
|
@ -45,8 +43,8 @@ void waitForNewDataPoint(void)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp, sysinterval_t timeout)
|
||||
{
|
||||
static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
||||
sysinterval_t timeout) {
|
||||
sysinterval_t start = chVTGetSystemTime();
|
||||
|
||||
gpsFix_t gpsFix;
|
||||
|
@ -62,7 +60,7 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp, sysinterval_t time
|
|||
bool status = GPS_Init();
|
||||
|
||||
if(status) {
|
||||
// Search for lock as long enough power is available
|
||||
// Search for lock as long as enough power is available
|
||||
do {
|
||||
batt = stm32_get_vbat();
|
||||
gps_get_fix(&gpsFix);
|
||||
|
@ -185,7 +183,7 @@ static void getSensors(dataPoint_t* tp)
|
|||
tp->sen_e1_press = 0;
|
||||
tp->sen_e1_hum = 0;
|
||||
tp->sen_e1_temp = 0;
|
||||
bme280_error |= 0x2;
|
||||
bme280_error |= 0x4;
|
||||
}
|
||||
|
||||
// External BME280 Sensor 2
|
||||
|
@ -199,8 +197,11 @@ static void getSensors(dataPoint_t* tp)
|
|||
tp->sen_e2_press = 0;
|
||||
tp->sen_e2_hum = 0;
|
||||
tp->sen_e2_temp = 0;
|
||||
bme280_error |= 0x4;
|
||||
bme280_error |= 0x10;
|
||||
}
|
||||
#else
|
||||
/* Set status to "not installed". */
|
||||
bme280_error |= 0x28;
|
||||
#endif
|
||||
// Measure various temperature sensors
|
||||
tp->stm32_temp = stm32_get_temp();
|
||||
|
@ -214,7 +215,19 @@ static void getSensors(dataPoint_t* tp)
|
|||
*
|
||||
*/
|
||||
static void setSystemStatus(dataPoint_t* tp) {
|
||||
// Set system errors
|
||||
|
||||
/*
|
||||
* Set system errors.
|
||||
*
|
||||
* Bit usage:
|
||||
* - 0:1 I2C status
|
||||
* - 2:2 GPS status
|
||||
* - 3:4 pac1720 status
|
||||
* - 5:7 OV5640 status
|
||||
* - 8:9 BMEi1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 9:10 BMEe1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 10:11 BMEe2 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
*/
|
||||
tp->sys_error = 0;
|
||||
|
||||
tp->sys_error |= (I2C_hasError() & 0x1) << 0;
|
||||
|
@ -222,7 +235,7 @@ static void setSystemStatus(dataPoint_t* tp) {
|
|||
tp->sys_error |= (pac1720_hasError() & 0x3) << 3;
|
||||
tp->sys_error |= (OV5640_hasError() & 0x7) << 5;
|
||||
|
||||
tp->sys_error |= (bme280_error & 0x7) << 8;
|
||||
tp->sys_error |= (bme280_error & 0x3F) << 8;
|
||||
|
||||
// Set system time
|
||||
tp->sys_time = TIME_I2S(chVTGetSystemTime());
|
||||
|
@ -320,7 +333,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
||||
"%s Sats %d TTFF %dsec\r\n"
|
||||
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV Pbat=%dmW\r\n"
|
||||
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%%",
|
||||
"%s AIR p=%d.%01dPa T=%d.%02ddegC phi=%d.%01d%%",
|
||||
tp->id,
|
||||
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
|
||||
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
|
||||
|
@ -345,9 +358,9 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
*/
|
||||
void init_data_collector(void)
|
||||
{
|
||||
if(!threadStarted)
|
||||
{
|
||||
threadStarted = true;
|
||||
if(!threadStarted) {
|
||||
|
||||
threadStarted = true;
|
||||
|
||||
TRACE_INFO("COLL > Startup data collector thread");
|
||||
thread_t *th = chThdCreateFromHeap(NULL,
|
||||
|
|
|
@ -648,14 +648,14 @@ THD_FUNCTION(imgThread, arg) {
|
|||
chThdSleep(TIME_S2I(60));
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t my_image_id = gimage_id++;
|
||||
/* Create image capture buffer. */
|
||||
uint8_t *buffer = chHeapAllocAligned(NULL, conf->buf_size,
|
||||
DMA_FIFO_BURST_ALIGN);
|
||||
if(buffer == NULL) {
|
||||
/* Could not get a capture buffer. */
|
||||
TRACE_WARN("IMG > Unable to get capture buffer for image %i",
|
||||
gimage_id);
|
||||
my_image_id);
|
||||
/* Allow time for other threads. */
|
||||
chThdSleep(TIME_MS2I(10));
|
||||
/* Try again at next run time. */
|
||||
|
@ -668,11 +668,11 @@ THD_FUNCTION(imgThread, arg) {
|
|||
/* Nothing captured? */
|
||||
if(size_sampled == 0) {
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV (camera error) ID=%d",
|
||||
gimage_id);
|
||||
my_image_id);
|
||||
if(!transmit_image_packets(noCameraFound, sizeof(noCameraFound),
|
||||
conf, (uint8_t)(gimage_id))) {
|
||||
conf, (uint8_t)(my_image_id))) {
|
||||
TRACE_ERROR("IMG > Error in encoding dummy image %i"
|
||||
" - discarded", gimage_id);
|
||||
" - discarded", my_image_id);
|
||||
}
|
||||
/* Return the buffer to the heap. */
|
||||
chHeapFree(buffer);
|
||||
|
@ -699,7 +699,7 @@ THD_FUNCTION(imgThread, arg) {
|
|||
|
||||
chsnprintf(filename, sizeof(filename), "r%02xi%04x.jpg",
|
||||
getLastDataPoint()->reset % 0xFF,
|
||||
(gimage_id - 1) % 0xFFFF);
|
||||
(my_image_id) % 0xFFFF);
|
||||
|
||||
writeBufferToFile(filename, &buffer[soi], size_sampled - soi);
|
||||
} /* End initSD() */
|
||||
|
@ -710,13 +710,12 @@ THD_FUNCTION(imgThread, arg) {
|
|||
}
|
||||
|
||||
/* Encode and transmit picture. */
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV ID=%d", gimage_id);
|
||||
TRACE_INFO("IMG > Encode/Transmit SSDV ID=%d", my_image_id);
|
||||
if(!transmit_image_packets(buffer, size_sampled, conf,
|
||||
(uint8_t)(gimage_id))) {
|
||||
(uint8_t)(my_image_id))) {
|
||||
TRACE_ERROR("IMG > Error in encoding snapshot image"
|
||||
" %i - discarded", gimage_id);
|
||||
" %i - discarded", my_image_id);
|
||||
}
|
||||
gimage_id++;
|
||||
break;
|
||||
} /* End if SOI in buffer. */
|
||||
} /* End while soi < size_sampled - 1. */
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue