Rework radio manager locking/startup of radio. Bug still in afks_feeder

pull/4/head
CInsights 2018-03-12 02:10:24 +11:00
rodzic e79f8e555e
commit 4c49a9104c
11 zmienionych plików z 268 dodań i 226 usunięć

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="138446027592133826" 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="461136237790816521" 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

@ -56,22 +56,22 @@ const conf_t conf_flash_default = {
// Primary image transmission thread
.img_pri = {
.thread_conf = {
.active = false,
.active = true,
.cycle = CYCLE_CONTINUOUSLY,
.init_delay = TIME_S2I(5),
.packet_spacing = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
.freq = FREQ_APRS_DYNAMIC,
.step = 0,
.chan = 0,
.freq = 144000000,
.step = 12500,
.chan = 94,
.mod = MOD_AFSK,
.preamble = 200,
.redundantTx = true
},
.call = "DL7AD-13",
.call = "VK2GJ-15",
.path = "DB0BLO",
.res = RES_VGA,

Wyświetl plik

@ -367,7 +367,7 @@ static const struct regval_list OV5640_JPEG_QSXGA[] =
};
//5MP
static const struct regval_list OV5640_5MP_JPEG[] =
static const struct regval_list OV5640_5MP_JPEG[] __attribute__((unused)) =
{
{0x3800 ,0x00},
{0x3801 ,0x00},
@ -491,7 +491,7 @@ static const struct regval_list OV5640_QSXGA2VGA[] =
};
//800x480 WVGA
static const struct regval_list OV5640_QSXGA2WVGA[] =
static const struct regval_list OV5640_QSXGA2WVGA[] __attribute__((unused)) =
{
{0x3800 ,0x00},
{0x3801 ,0x00},
@ -526,7 +526,7 @@ static const struct regval_list OV5640_QSXGA2WVGA[] =
};
//352x288 CIF
static const struct regval_list OV5640_QSXGA2CIF[] =
static const struct regval_list OV5640_QSXGA2CIF[] __attribute__((unused)) =
{
{0x3800 ,0x00},
{0x3801 ,0x00},
@ -561,7 +561,7 @@ static const struct regval_list OV5640_QSXGA2CIF[] =
};
//1280x960 SXGA
static const struct regval_list OV5640_QSXGA2SXGA[] =
static const struct regval_list OV5640_QSXGA2SXGA[] __attribute__((unused)) =
{
{0x3800 ,0x00},
{0x3801 ,0x00},
@ -592,7 +592,7 @@ static const struct regval_list OV5640_QSXGA2SXGA[] =
};
//2048x1536 QXGA
static const struct regval_list OV5640_QSXGA2QXGA[] =
static const struct regval_list OV5640_QSXGA2QXGA[] __attribute__((unused)) =
{
{0x3800 ,0x00},
{0x3801 ,0x00},
@ -709,7 +709,7 @@ uint32_t OV5640_Snapshot2RAM(uint8_t* buffer, uint32_t size, resolution_t res)
bool status;
uint32_t size_sampled;
// Set resoultion
// Set resolution
if(res == RES_MAX) {
OV5640_SetResolution(RES_UXGA); // FIXME: We actually have to choose the resolution which fits in the memory
} else {
@ -741,8 +741,7 @@ const stm32_dma_stream_t *dmastp;
#if OV5640_USE_DMA_DBM == TRUE
uint16_t dma_index;
uint16_t dma_buffers;
#define DMA_SEGMENT_SIZE 1024
#define DMA_FIFO_BURST_ALIGN 32
#if !defined(dmaStreamGetCurrentTarget)
@ -930,6 +929,22 @@ void vsync_cb(void *arg) {
chSysUnlockFromISR();
}
/*
* Other drivers using resources that can cause DMA competition are locked.
*/
void OV5640_lockResourcesForCapture(void) {
I2C_Lock(); // Lock I2C because it uses the same DMA
Si446x_lockRadioByCamera(); // Lock the radio because it uses the DMA too
}
/*
* Unlock competing drivers.
*/
void OV5640_unlockResourcesForCapture(void) {
Si446x_unlockRadioByCamera();
I2C_Unlock();
}
bool OV5640_Capture(uint8_t* buffer, uint32_t size)
{
OV5640_setLightIntensity();
@ -940,9 +955,7 @@ bool OV5640_Capture(uint8_t* buffer, uint32_t size)
* In makefile add entry to UDEFS:
* UDEFS = -DSTM32_DMA_REQUIRED
*/
I2C_Lock(); // Lock I2C because it uses the same DMA
Si446x_lockRadioByCamera(); // Lock the radio because it uses the DMA too
OV5640_lockResourcesForCapture();
/* Setup DMA for transfer on TIM8_CH1 - DMA2 stream 2, channel 7 */
dmastp = STM32_DMA_STREAM(STM32_DMA_STREAM_ID(2, 2));
@ -975,7 +988,7 @@ bool OV5640_Capture(uint8_t* buffer, uint32_t size)
* See RM0430 9.3.12
*
* TODO: To use DMA_FIFO_BURST_ALIGN in setting of ssdv buffer alignment.
* Currently this is set to 32 manually in config.c.
* Currently this is set to 16 manually in image.c.
*/
if (((uint32_t)buffer % DMA_FIFO_BURST_ALIGN) != 0) {
@ -1048,9 +1061,8 @@ bool OV5640_Capture(uint8_t* buffer, uint32_t size)
palDisableLineEventI(LINE_CAM_VSYNC);
}
// Capture done, unlock I2C and the radio
Si446x_unlockRadio();
I2C_Unlock();
// Capture done, unlock competing processes.
OV5640_unlockResourcesForCapture();
if(dma_error)
{

Wyświetl plik

@ -9,9 +9,11 @@
#include "hal.h"
#include "types.h"
#define OV5640_I2C_ADR 0x3C
#define OV5640_I2C_ADR 0x3C
#define OV5640_USE_DMA_DBM TRUE
#define OV5640_USE_DMA_DBM TRUE
#define DMA_SEGMENT_SIZE 1024
#define DMA_FIFO_BURST_ALIGN 32
uint32_t OV5640_Snapshot2RAM(uint8_t* buffer, uint32_t size, resolution_t resolution);
bool OV5640_Capture(uint8_t* buffer, uint32_t size);

Wyświetl plik

@ -26,11 +26,11 @@ static mutex_t radio_mtx; // Radio mutex
static bool radio_mtx_init = false;
#else
// Binary semaphore
static binary_semaphore_t radio_bsem;
static bool radio_bsem_init = false;
static binary_semaphore_t radio_sem;
static bool radio_sem_init = false;
#endif
static bool nextTransmissionWaiting; // Flag that informs the feeder thread to keep the radio switched on
//static bool nextTransmissionWaiting; // Flag that informs the feeder thread to keep the radio switched on
// Feeder thread variables
static thread_t* feeder_thd = NULL;
@ -54,9 +54,9 @@ static uint16_t rx_step;
static uint8_t rx_chan;
static uint8_t rx_rssi;
static mod_t rx_mod;
static void (*rx_cb)(uint8_t*, uint32_t);
//static void (*rx_cb)(uint8_t*, uint32_t);
static packet_svc_t *packetHandler;
packet_svc_t *packetHandler;
//static int16_t Si446x_getTemperature(void);
@ -645,7 +645,7 @@ static void Si446x_setModem2FSK(uint32_t speed)
/* ====================================================================== Radio Settings ====================================================================== */
static uint8_t Si446x_getChannel(void) {
static uint8_t __attribute__((unused)) Si446x_getChannel(void) {
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
uint8_t rxData[4];
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
@ -701,45 +701,25 @@ static void Si446x_setRXState(uint8_t chan)
static void Si446x_shutdown(void)
{
// Wait for PH to finish transmission
while(Si446x_getState() == Si446x_STATE_TX)
chThdSleep(TIME_MS2I(1));
if(!nextTransmissionWaiting) { // No thread is waiting for radio, so shutdown radio
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > Shutdown radio");
dbgPrintf(DBG_INFO, "SI > Shutdown radio");
#else
TRACE_INFO("SI > Shutdown radio");
TRACE_INFO("SI > Shutdown radio");
#endif
pktDeconfigureRadioGPIO();
radioInitialized = false;
} else {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "RAD > Transmission finished");
dbgPrintf(DBG_INFO, "RAD > Keep radio switched on");
#else
TRACE_INFO("RAD > Transmission finished");
TRACE_INFO("RAD > Keep radio switched on");
#endif
}
pktDeconfigureRadioGPIO();
radioInitialized = false;
}
/* ======================================================================== Locking ========================================================================= */
static void Si446x_lockRadio(void)
{
void Si446x_lockRadio(radio_mode_t mode) {
#if Si446x_LOCK_BY_SEMAPHORE == TRUE
/* Initialize semaphore. */
if(!radio_bsem_init)
chBSemObjectInit(&radio_bsem, false);
radio_bsem_init = true;
if(!radio_sem_init)
chBSemObjectInit(&radio_sem, false);
radio_sem_init = true;
chSysLock();
chBSemWaitS(&radio_bsem);
nextTransmissionWaiting = true;
chSysUnlock();
chBSemWait(&radio_sem);
#else
// Initialize mutex
if(!radio_mtx_init)
@ -752,16 +732,37 @@ static void Si446x_lockRadio(void)
ChSysUnlock();
#endif
// Wait for old feeder thread to terminate
if(feeder_thd != NULL) // No waiting on first use
chThdWait(feeder_thd);
if(rx_frequency && mode == RADIO_TX) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > Pause packet reception for packet transmit\r\n");
#else
TRACE_INFO("SI > Pause packet reception for packet transmit");
#endif
pktPauseDecoder(packetHandler);
}
}
void Si446x_unlockRadio(void)
{
nextTransmissionWaiting = false;
static bool Si4464_restoreRX(void);
void Si446x_unlockRadio(radio_mode_t mode) {
#if Si446x_LOCK_BY_SEMAPHORE == TRUE
chBSemSignal(&radio_bsem);
chBSemSignal(&radio_sem);
#else
chMtxUnlock(&radio_mtx);
#endif
if(rx_frequency != 0 && mode == RADIO_TX) {
Si4464_restoreRX();
} else if(rx_frequency == 0) {
Si446x_shutdown();
}
}
void Si446x_unlockRadioByCamera(void) {
#if Si446x_LOCK_BY_SEMAPHORE == TRUE
chBSemSignal(&radio_sem);
#else
chMtxUnlock(&radio_mtx);
#endif
@ -771,10 +772,10 @@ void Si446x_lockRadioByCamera(void)
{
#if Si446x_LOCK_BY_SEMAPHORE == TRUE
/* Initialize semaphore. */
if(!radio_bsem_init)
chBSemObjectInit(&radio_bsem, false);
radio_bsem_init = true;
chBSemWait(&radio_bsem);
if(!radio_sem_init)
chBSemObjectInit(&radio_sem, false);
radio_sem_init = true;
chBSemWait(&radio_sem);
#else
// Initialize mutex
if(!radio_mtx_init)
@ -783,9 +784,6 @@ void Si446x_lockRadioByCamera(void)
chMtxLock(&radio_mtx);
#endif
// Wait for old feeder thread to terminate
if(feeder_thd != NULL) // No waiting on first use
chThdWait(feeder_thd);
}
/* ====================================================================== Radio TX/RX ======================================================================= */
@ -907,14 +905,12 @@ static bool Si446x_transmit(uint8_t chan,
TRACE_ERROR("SI > Frequency out of range");
TRACE_ERROR("SI > abort reception");
#endif
return false;
}
// Initialize radio
if(!radioInitialized)
Si446x_init();
/* if(!radioInitialized)
Si446x_init();*/
uint16_t tot = 0;
// Wait until transceiver finishes transmission (if there is any)
@ -938,7 +934,7 @@ static bool Si446x_transmit(uint8_t chan,
if(mod == MOD_AFSK) {
Si446x_setModemAFSK_RX();
} else {
Si446x_shutdown();
//Si446x_shutdown();
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_ERROR, "SI > Modulation type not supported in receive\r\n");
dbgPrintf(DBG_ERROR, "SI > abort reception\r\n");
@ -969,62 +965,50 @@ static bool Si446x_transmit(uint8_t chan,
return true;
}
/*bool Si446x_receive(uint32_t frequency, uint16_t step,
uint8_t rssi, uint8_t chan, mod_t mod)
{
Si446x_lockRadio();
bool ret = Si446x_receiveNoLock(chan, rssi, mod);
Si446x_unlockRadio();
return ret;
}*/
static bool Si4464_restoreRX(void)
{
static bool Si4464_restoreRX(void) {
bool ret = Si446x_receiveNoLock(rx_chan, rx_rssi, rx_mod);
uint32_t op_freq = Si446x_computeOperatingFrequency(rx_frequency,
rx_step,
rx_chan);
if(packetHandler) {
if(rx_frequency) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > Resume packet reception %d.%03d MHz,"
" (ch %d), RSSI %d, %s\r\n",
op_freq/1000000, (op_freq % 1000000)/1000,
Si446x_getChannel(),
rx_chan,
rx_rssi, getModulation(rx_mod);
#else
TRACE_INFO( "SI > Resume packet reception %d.%03d MHz (ch %d),"
" RSSI %d, %s",
op_freq/1000000, (op_freq % 1000000)/1000,
Si446x_getChannel(),
rx_chan,
rx_rssi, getModulation(rx_mod)
);
#endif
/* Resume decoding. */
pktResumeDecoder(packetHandler);
}
return ret;
}
void Si446x_receive_stop(void)
void Si446x_receiveStop(void)
{
/* FIXME: */
if(Si446x_getState() == Si446x_STATE_RX) {
rx_frequency = 0;
if(Si446x_getState() == Si446x_STATE_RX)
Si446x_shutdown();
Si446x_shutdown();
}
}
/* ==================================================================== AFSK Transmitter ==================================================================== */
#define PLAYBACK_RATE 13200
#define BAUD_RATE 1200 /* APRS AFSK baudrate */
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (192kHz / 1200baud = 160samp/baud) */
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (13200Hz / 1200baud = 11samp/baud) */
#define PHASE_DELTA_1200 (((2 * 1200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 1200Hz tone */
#define PHASE_DELTA_2200 (((2 * 2200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 2200Hz tone */
@ -1084,8 +1068,6 @@ static uint32_t Si446x_encodeDataToAFSK(uint8_t *inbuf, uint32_t inlen,
#else
TRACE_ERROR("SI > Packet too long");
#endif
return blen;
}
@ -1168,17 +1150,23 @@ static uint8_t Si446x_getUpsampledAFSKbits(uint8_t* buf/*, uint32_t blen*/)
packet_pos++;
}
}
return b;
}
THD_FUNCTION(si_fifo_feeder_afsk, arg)
{
static void Si446x_AFSKtransmitTimeout(thread_t *tp) {
/* The tell the thread to terminate. */
tp->flags |= CH_FLAG_TERMINATE;
}
THD_FUNCTION(si_fifo_feeder_afsk, arg) {
packet_t pp = arg;
chRegSetThreadName("radio_afsk_feeder");
/* Initialize variables for AFSK encoder. */
ctone = 0;
virtual_timer_t send_timer;
chVTObjectInit(&send_timer);
#define PREAMBLE_FLAGS_A 30
#define PREAMBLE_FLAGS_B 0
@ -1196,8 +1184,12 @@ THD_FUNCTION(si_fifo_feeder_afsk, arg)
uint32_t flag_blen = Si446x_encodeDataToAFSK(a_flag, sizeof(a_flag),
flag_nrz, sizeof(flag_nrz),
0);
/* WIP. */
#endif
Si446x_setReadyState();
/* Initialize variables for up sampler. */
phase_delta = PHASE_DELTA_1200;
phase = 0;
@ -1215,9 +1207,23 @@ THD_FUNCTION(si_fifo_feeder_afsk, arg)
* Account for all modulation bits (round up to a byte boundary).
* Calculate initial FIFO fill.
*/
uint16_t all = ((layer0_blen * SAMPLES_PER_BAUD) + 7) / 8;
uint16_t all = ((uint64_t)(layer0_blen * SAMPLES_PER_BAUD) + 7) / 8;
uint16_t c = (all > free) ? free : all;
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > AFSK upsampled bytes to send %i\r\n", c);
#else
TRACE_INFO("SI > AFSK upsampled bytes to send %i", c);
#endif
/*
* Start send timeout timer.
* If the 446x gets locked up we'll exit TX and release packet object.
*/
chVTSet(&send_timer, TIME_S2I(10),
(vtfunc_t)Si446x_AFSKtransmitTimeout, chThdGetSelfX());
msg_t exit_msg = MSG_TIMEOUT;
// Initial FIFO fill
for(uint16_t i = 0; i < c; i++)
localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0/*, layer0_blen*/);
@ -1227,20 +1233,40 @@ THD_FUNCTION(si_fifo_feeder_afsk, arg)
if(Si446x_transmit(tx_chan, tx_pwr, all, 0x4F, TIME_S2I(10))) {
/* Transmit started OK. */
while(c < all) { // Do while bytes not written into FIFO completely
// Determine free memory in Si446x-FIFO
uint8_t more = Si446x_getTXfreeFIFO();
if(more > all - c) {
if((more = all - c) == 0) // Calculate remainder to send
break; // End if nothing left
if(chThdShouldTerminateX()) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_ERROR, "SI > AFSK transmit timed out\r\n");
#else
TRACE_ERROR("SI > AFSK transmit timed out");
#endif
/* Force 446x out of TX state. */
Si446x_setReadyState();
break;
}
// Determine free memory in Si446x-FIFO
uint8_t more = Si446x_getTXfreeFIFO();
if(more > (all - c)) {
// Calculate remainder to send
more -= (all - c);
if(more < 1) {
/* Nothing remaining to send. Stop timer. */
/* Drop priority to enable other threads to run. */
//chThdSetPriority(LOWPRIO);
exit_msg = MSG_OK;
break;
}
}
uint16_t i;
for(i = 0; i < more; i++)
localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0/*, layer0_blen*/);
for(uint16_t i = 0; i < more; i++)
localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0/*, layer0_blen*/);
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
c += more;
chThdSleep(TIME_MS2I(15));
}
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
c += (++i);
chThdSleep(TIME_MS2I(15));
} /* End while. */
} else {
/* Transmit start failed. */
#ifdef PKT_IS_TEST_PROJECT
@ -1249,38 +1275,21 @@ THD_FUNCTION(si_fifo_feeder_afsk, arg)
TRACE_ERROR("SI > Transmit failed");
#endif
}
chVTReset(&send_timer);
while(Si446x_getState() == Si446x_STATE_TX)
continue;
/* Drop priority to enable other threads to run. */
chThdSetPriority(LOWPRIO);
/*
* Shutdown radio if reception has been interrupted. If reception was interrupted rx_frequency is set.
* If reception has not been interrupted rx_frequency is set 0.
*/
if(!rx_frequency) {
Si446x_shutdown();
} else {
Si4464_restoreRX();
}
// Free packet object memory
ax25_delete(pp);
chThdExit(MSG_OK);
/* Exit thread. */
chThdExit(exit_msg);
}
void Si446x_sendAFSK(packet_t pp,
uint8_t chan,
uint8_t pwr) {
Si446x_lockRadio();
// Stop packet handler (if started)
if(packetHandler) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > Pause packet reception\r\n");
#else
TRACE_INFO("SI > Pause packet reception");
#endif
pktPauseDecoder(packetHandler);
}
//Si446x_lockRadio();
// Initialize radio
if(!radioInitialized)
@ -1300,60 +1309,23 @@ void Si446x_sendAFSK(packet_t pp,
sizeof(si_fifo_feeder_wa),
HIGHPRIO,
si_fifo_feeder_afsk,
/*NULL*/pp);
pp);
// Wait for the transmitter to start (because it is used as mutex)
while(Si446x_getState() != Si446x_STATE_TX)
chThdSleep(TIME_MS2I(1));
Si446x_unlockRadio();
msg_t send_msg = chThdWait(feeder_thd);
if(send_msg == MSG_TIMEOUT) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_ERROR, "SI > Transmit AFSK timeout\r\n");
#else
TRACE_ERROR("SI > Transmit AFSK timeout");
#endif
}
/* Unlock radio. */
Si446x_unlockRadio(RADIO_TX);
}
/* ===================================================================== AFSK Receiver ====================================================================== */
void Si446x_mapCallback(pkt_data_object_t *pkt_buff) {
/* Packet buffer. */
ax25char_t *frame_buffer = pkt_buff->buffer;
ax25size_t frame_size = pkt_buff->packet_size;
/* FIXME: This is a quick diagnostic implementation only. */
#if DUMP_PACKET_TO_SERIAL == TRUE && ENABLE_EXTERNAL_I2C != TRUE
pktDiagnosticOutput(pkt_buff->handler, pkt_buff);
#endif
if(pktIsBufferValidAX25Frame(pkt_buff)) {
/* Perform the callback. */
rx_cb(frame_buffer, frame_size);
} else {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "RX > Invalid frame - dropped\r\n");
#else
TRACE_INFO("RX > Invalid frame - dropped");
#endif
}
}
void Si446x_startPacketReception(radio_freq_t freq,
channel_hz_t step,
radio_ch_t ch,
radio_squelch_t sq, void* cb) {
rx_cb = cb;
/* Open packet radio service. */
pktOpenRadioService(PKT_RADIO_1,
MOD_AFSK,
freq,
step,
&packetHandler);
/* Start the decoder. */
pktStartDataReception(packetHandler,
ch,
sq,
Si446x_mapCallback);
}
void Si446x_stopDecoder(void) {
@ -1412,15 +1384,11 @@ void Si446x_send2FSK(packet_t pp,
uint8_t chan,
uint8_t pwr,
uint32_t speed) {
Si446x_lockRadio();
// Stop packet handler (if started)
if(packetHandler)
pktPauseDecoder(packetHandler);
Si446x_lockRadio(RADIO_TX);
// Initialize radio
if(!radioInitialized)
Si446x_init();
//Si446x_init();
Si446x_setModem2FSK(speed);
// Set pointers for feeder
@ -1434,11 +1402,16 @@ void Si446x_send2FSK(packet_t pp,
si_fifo_feeder_fsk,
pp);
// Wait for the transmitter to start (because it is used as mutex)
while(Si446x_getState() != Si446x_STATE_TX)
chThdSleep(TIME_MS2I(1));
Si446x_unlockRadio();
msg_t send_msg = chThdWait(feeder_thd);
if(send_msg == MSG_TIMEOUT) {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_ERROR, "SI > Transmit 2FSK timeout\r\n");
#else
TRACE_ERROR("SI > Transmit 2FSK timeout");
#endif
}
/* Unlock radio. */
Si446x_unlockRadio(RADIO_TX);
}
/* ========================================================================== Misc ========================================================================== */
@ -1454,7 +1427,7 @@ static int16_t Si446x_getTemperature(void) {
int16_t Si446x_getLastTemperature(void) {
if(lastTemp == 0x7FFF) { // Temperature was never measured => measure it now
if(radioInitialized) {
Si446x_lockRadio();
Si446x_lockRadio(RADIO_RX);
// Temperature readout
lastTemp = Si446x_getTemperature();
#ifdef PKT_IS_TEST_PROJECT
@ -1462,7 +1435,7 @@ int16_t Si446x_getLastTemperature(void) {
#else
TRACE_INFO("SI > Transmitter temperature %d degC\r\n", lastTemp/100);
#endif
Si446x_unlockRadio();
Si446x_unlockRadio(RADIO_RX);
} else {
#ifdef PKT_IS_TEST_PROJECT
dbgPrintf(DBG_INFO, "SI > Transmitter temperature not available\r\n");

Wyświetl plik

@ -196,7 +196,6 @@ typedef enum radioMode {
RADIO_CCA
} radio_mode_t;
// Public methods
int16_t Si446x_getLastTemperature(void);
@ -205,14 +204,15 @@ void Si446x_sendAFSK(packet_t pp, uint8_t chan, uint8_t pwr);
void Si446x_send2FSK(packet_t pp, uint8_t chan,
uint8_t pwr, uint32_t speed);
bool Si446x_receive(uint32_t frequency, uint16_t step, uint8_t chan,
uint8_t rssi, mod_t mod);
void Si446x_receiveStop(void);
void Si446x_startPacketReception(uint32_t freq, uint16_t step,
uint8_t ch, uint8_t sq, void* cb);
void Si446x_stopDecoder(void);
bool Si446x_receiveNoLock(uint8_t chan, uint8_t rssi, mod_t mod);
void Si446x_unlockRadio(void);
void Si446x_lockRadio(radio_mode_t mode);
void Si446x_unlockRadio(radio_mode_t mode);
void Si446x_lockRadioByCamera(void);
void Si446x_unlockRadioByCamera(void);
void Si446x_conditional_init(void);
bool Si446x_setBandParameters(uint32_t freq,
uint16_t step,

Wyświetl plik

@ -16,6 +16,7 @@
#include "pktconf.h"
#include "radio.h"
#include "si446x.h"
/**
* @brief Process radio task requests.
@ -69,10 +70,6 @@ THD_FUNCTION(pktRadioManager, arg) {
if(driver == NULL) {
break;
}
/* TODO: Check for success/fail from band set. */
Si446x_setBandParameters(task_object->base_frequency,
task_object->step_hz,
RADIO_RX);
break;
} /* End case PKT_RADIO_OPEN. */
@ -80,23 +77,31 @@ THD_FUNCTION(pktRadioManager, arg) {
case MOD_2FSK: {
break;
}
} /* End switch on task_object->type. */
break;
} /* End switch on modulation type. */
/* Initialise the radio. */
//Si446x_conditional_init();
Si446x_conditional_init();
break;
} /* End case PKT_RADIO_OPEN. */
/* TODO: Tune radio to channel. */
case PKT_RADIO_RX_START: {
switch(task_object->type) {
case MOD_AFSK: {
Si446x_lockRadio(RADIO_RX);
Si446x_setBandParameters(task_object->base_frequency,
task_object->step_hz,
RADIO_RX);
pktStartDecoder(handler);
radio_ch_t chan = task_object->channel;
radio_squelch_t sq = task_object->squelch;
Si446x_receiveNoLock(chan, sq, MOD_AFSK);
/* Allow transmit requests. */
Si446x_unlockRadio(RADIO_RX);
//rx_active = true;
break;
} /* End case PKT_RADIO_RX. */
@ -137,7 +142,6 @@ THD_FUNCTION(pktRadioManager, arg) {
uint8_t pwr = task_object->tx_power;
uint32_t speed = task_object->tx_speed;
Si446x_setBandParameters(freq, step, RADIO_TX);
switch(task_object->type) {
case MOD_2FSK:
@ -145,6 +149,8 @@ THD_FUNCTION(pktRadioManager, arg) {
break;
case MOD_AFSK:
Si446x_lockRadio(RADIO_TX);
Si446x_setBandParameters(freq, step, RADIO_TX);
Si446x_sendAFSK(pp, chan, pwr);
break;
@ -161,6 +167,7 @@ THD_FUNCTION(pktRadioManager, arg) {
thread_t *decoder = NULL;
switch(task_object->type) {
case MOD_AFSK: {
Si446x_receiveStop();
esp = pktGetEventSource((AFSKDemodDriver *)handler->link_controller);
pktRegisterEventListener(esp, &el, USR_COMMAND_ACK, DEC_CLOSE_EXEC);
decoder = ((AFSKDemodDriver *)(handler->link_controller))->decoder_thd;
@ -204,12 +211,13 @@ THD_FUNCTION(pktRadioManager, arg) {
break;
} /*end case close. */
} /* End switch on command. */
/* Perform radio task callback if specified. */
if(task_object->callback != NULL)
/* Perform the callback. */
task_object->callback(handler);
/* Return radio task object to free list. */
chFifoReturnObject(radio_queue, (radio_task_object_t *)task_object);
}
} /* End while should terminate). */
chThdExit(MSG_OK);
}

Wyświetl plik

@ -444,16 +444,17 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
? EVT_AX25_FRAME_RDY
: EVT_AX25_CRC_ERROR;
} else {
flags |= EVT_AFSK_INVALID_FRAME;
flags |= EVT_PKT_INVALID_FRAME;
}
/* Update status in packet buffer object. */
pkt_buffer->status |= flags;
if(pkt_buffer->cb_func == NULL) {
objects_fifo_t *pkt_fifo = chFactoryGetObjectsFIFO(pkt_buffer->pkt_factory);
objects_fifo_t *pkt_fifo = chFactoryGetObjectsFIFO(pkt_buffer->pkt_factory);
chDbgAssert(pkt_fifo != NULL, "no packet FIFO");
chDbgAssert(pkt_fifo != NULL, "no packet FIFO");
if(pkt_buffer->cb_func == NULL) {
/* Send the packet buffer to the FIFO queue. */
chFifoSendObject(pkt_fifo, pkt_buffer);
@ -463,8 +464,16 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
chDbgAssert(cb_thd != NULL, "failed to create callback thread");
/* Increase outstanding callback count. */
handler->cb_count++;
if(cb_thd == NULL) {
/* Failed to create CB thread. Release buffer. Flag event. */
chFifoReturnObject(pkt_fifo, pkt_buffer);
flags |= EVT_PKT_FAILED_CB_THD;
} else {
/* Increase outstanding callback count. */
handler->cb_count++;
}
}
return flags;
}

Wyświetl plik

@ -63,7 +63,7 @@
#define EVT_AFSK_TERMINATED EVENT_MASK(EVT_PRIORITY_BASE + 4)
#define EVT_PWM_UNKNOWN_INBAND EVENT_MASK(EVT_PRIORITY_BASE + 5)
#define EVT_ICU_OVERFLOW EVENT_MASK(EVT_PRIORITY_BASE + 6)
//#define EVT_SUSPEND_EXIT EVENT_MASK(EVT_PRIORITY_BASE + 7)
#define EVT_PKT_FAILED_CB_THD EVENT_MASK(EVT_PRIORITY_BASE + 7)
#define EVT_PWM_NO_DATA EVENT_MASK(EVT_PRIORITY_BASE + 8)
#define EVT_PWM_FIFO_SENT EVENT_MASK(EVT_PRIORITY_BASE + 9)
@ -78,7 +78,7 @@
#define EVT_PKT_CHANNEL_STOP EVENT_MASK(EVT_PRIORITY_BASE + 16)
#define EVT_RADIO_CCA_FIFO_ERR EVENT_MASK(EVT_PRIORITY_BASE + 17)
#define EVT_AX25_BUFFER_FULL EVENT_MASK(EVT_PRIORITY_BASE + 18)
#define EVT_AFSK_INVALID_FRAME EVENT_MASK(EVT_PRIORITY_BASE + 19)
#define EVT_PKT_INVALID_FRAME EVENT_MASK(EVT_PRIORITY_BASE + 19)
#define EVT_AX25_CRC_ERROR EVENT_MASK(EVT_PRIORITY_BASE + 20)
#define EVT_HDLC_RESET_RCVD EVENT_MASK(EVT_PRIORITY_BASE + 21)

Wyświetl plik

@ -562,7 +562,7 @@ THD_FUNCTION(imgThread, arg)
TRACE_INFO("IMG > Startup image thread");
// Create buffer
uint8_t buffer[conf->buf_size] __attribute__((aligned(32)));
uint8_t buffer[conf->buf_size] __attribute__((aligned(DMA_FIFO_BURST_ALIGN)));
sysinterval_t time = chVTGetSystemTime();
while(true)

Wyświetl plik

@ -8,7 +8,7 @@
#include "pktconf.h"
#include "radio.h"
static void handlePacket(uint8_t *buf, uint32_t len) {
static void processPacket(uint8_t *buf, uint32_t len) {
/* Remove CRC from frame. */
if(len > 2) {
len -= 2;
@ -34,6 +34,23 @@ static void handlePacket(uint8_t *buf, uint32_t len) {
TRACE_DEBUG("RX > Packet dropped due to data length < 2");
}
void mapCallback(pkt_data_object_t *pkt_buff) {
/* Packet buffer. */
ax25char_t *frame_buffer = pkt_buff->buffer;
ax25size_t frame_size = pkt_buff->packet_size;
/* FIXME: This is a quick diagnostic implementation only. */
#if DUMP_PACKET_TO_SERIAL == TRUE && ENABLE_EXTERNAL_I2C != TRUE
pktDiagnosticOutput(pkt_buff->handler, pkt_buff);
#endif
if(pktIsBufferValidAX25Frame(pkt_buff)) {
/* Perform the callback. */
processPacket(frame_buffer, frame_size);
} else {
TRACE_INFO("RX > Invalid frame - dropped");
}
}
void start_rx_thread(uint32_t freq, uint16_t step,
radio_ch_t chan, uint8_t rssi) {
@ -45,8 +62,29 @@ void start_rx_thread(uint32_t freq, uint16_t step,
}
// Start decoder
Si446x_startPacketReception(freq, step, chan, rssi, handlePacket);
extern packet_svc_t *packetHandler;
/* Open packet radio service. */
msg_t omsg = pktOpenRadioService(PKT_RADIO_1,
MOD_AFSK,
freq,
step,
&packetHandler);
if(omsg != MSG_OK) {
TRACE_DEBUG("RX > Open of radio service failed");
return;
}
/* Start the decoder. */
msg_t smsg = pktStartDataReception(packetHandler,
chan,
rssi,
mapCallback);
if(smsg != MSG_OK) {
pktCloseRadioService(packetHandler);
TRACE_DEBUG("RX > Open of radio service failed");
}
}
/*