kopia lustrzana https://github.com/DL7AD/pecanpico10
Rework radio manager locking/startup of radio. Bug still in afks_feeder
rodzic
e79f8e555e
commit
4c49a9104c
|
@ -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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Ładowanie…
Reference in New Issue