Improved message passing mechanism for rtx driver configuration

This commit is contained in:
Silvano Seva 2020-12-13 09:17:08 +01:00
parent d98611fbed
commit 4f0ffe8565
3 changed files with 91 additions and 64 deletions

View File

@ -21,6 +21,7 @@
#ifndef RTX_H #ifndef RTX_H
#define RTX_H #define RTX_H
#include <os.h>
#include <stdint.h> #include <stdint.h>
#include <datatypes.h> #include <datatypes.h>
@ -29,7 +30,8 @@ typedef struct
uint8_t opMode : 2, /**< Operating mode (FM, DMR, ...) */ uint8_t opMode : 2, /**< Operating mode (FM, DMR, ...) */
bandwidth : 2, /**< Channel bandwidth */ bandwidth : 2, /**< Channel bandwidth */
txDisable : 1, /**< Disable TX operation */ txDisable : 1, /**< Disable TX operation */
_padding : 3; scan : 1, /**< Scan enabled */
opStatus : 2; /**< Operating status (OFF, ...) */
freq_t rxFrequency; /**< RX frequency, in Hz */ freq_t rxFrequency; /**< RX frequency, in Hz */
freq_t txFrequency; /**< TX frequency, in Hz */ freq_t txFrequency; /**< TX frequency, in Hz */
@ -40,7 +42,7 @@ typedef struct
tone_t rxTone; /**< RX CTC/DCS tone */ tone_t rxTone; /**< RX CTC/DCS tone */
tone_t txTone; /**< TX CTC/DCS tone */ tone_t txTone; /**< TX CTC/DCS tone */
} }
rtxConfig_t; rtxStatus_t;
enum bandwidth enum bandwidth
{ {
@ -64,9 +66,11 @@ enum opstatus
/** /**
* Initialise rtx stage * Initialise rtx stage.
* @param m: pointer to the mutex protecting the shared configuration data
* structure.
*/ */
void rtx_init(); void rtx_init(OS_MUTEX *m);
/** /**
* Shut down rtx stage * Shut down rtx stage
@ -75,11 +79,18 @@ void rtx_terminate();
/** /**
* Post a new RTX configuration on the internal message queue. Data structure * Post a new RTX configuration on the internal message queue. Data structure
* \b must be heap-allocated and \b must not be modified after this function has * \b must be protected by the same mutex whose pointer has been passed as a
* been called. The driver takes care of its deallocation. * parameter to rtx_init(). This driver only copies its content into the internal
* data structure, eventual garbage collection has to be performed by caller.
* @param cfg: pointer to a structure containing the new RTX configuration. * @param cfg: pointer to a structure containing the new RTX configuration.
*/ */
void rtx_configure(const rtxConfig_t *cfg); void rtx_configure(const rtxStatus_t *cfg);
/**
* Obtain a copy of the RTX driver's internal status data structure.
* @return copy of the RTX driver's internal status data structure.
*/
rtxStatus_t rtx_getCurrentStatus();
/** /**
* High-level code is in charge of calling this function periodically, since it * High-level code is in charge of calling this function periodically, since it
@ -87,6 +98,10 @@ void rtx_configure(const rtxConfig_t *cfg);
*/ */
void rtx_taskFunc(); void rtx_taskFunc();
/**
* Get current RSSI voltage.
* @return RSSI voltage.
*/
float rtx_getRssi(); float rtx_getRssi();
#endif /* RTX_H */ #endif /* RTX_H */

View File

@ -30,34 +30,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <gpio.h> #include <gpio.h>
#include <rtx.h> #include <rtx.h>
#include <os.h>
#include "HR-C5000_MD3x0.h" #include "HR-C5000_MD3x0.h"
#include "pll_MD3x0.h" #include "pll_MD3x0.h"
#include <stdio.h> #include <stdio.h>
struct rtxStatus_t
{
uint8_t opMode : 2, /**< Operating mode (FM, DMR, ...) */
bandwidth : 2, /**< Channel bandwidth */
txDisable : 1, /**< Disable TX operation */
opStatus : 3; /**< RTX status (OFF, RX, TX) */
freq_t rxFrequency; /**< RX frequency, in Hz */
freq_t txFrequency; /**< TX frequency, in Hz */
float txPower; /**< TX power, in W */
uint8_t sqlLevel; /**< Squelch opening level */
tone_t rxTone; /**< RX CTC/DCS tone */
tone_t txTone; /**< TX CTC/DCS tone */
}
rtxStatus;
OS_Q cfgMailbox; /* Queue for incoming config messages */
const md3x0Calib_t *calData; /* Pointer to calibration data */
const freq_t IF_FREQ = 49950000; /* Intermediate frequency: 49.95MHz */ const freq_t IF_FREQ = 49950000; /* Intermediate frequency: 49.95MHz */
OS_MUTEX *cfgMutex; /* Mutex for incoming config messages */
OS_Q cfgMailbox; /* Queue for incoming config messages */
const md3x0Calib_t *calData; /* Pointer to calibration data */
rtxStatus_t rtxStatus; /* RTX driver status */
uint8_t sqlOpenTsh; /* Squelch opening threshold */ uint8_t sqlOpenTsh; /* Squelch opening threshold */
uint8_t sqlCloseTsh; /* Squelch closing threshold */ uint8_t sqlCloseTsh; /* Squelch closing threshold */
@ -231,8 +216,11 @@ void _updateSqlThresholds()
(sql9CloseTsh - sql1CloseTsh))/8; */ (sql9CloseTsh - sql1CloseTsh))/8; */
} }
void rtx_init() void rtx_init(OS_MUTEX *m)
{ {
/* Initialise mutex for configuration access */
cfgMutex = m;
/* Create the message queue for RTX configuration */ /* Create the message queue for RTX configuration */
OS_ERR err; OS_ERR err;
OSQCreate((OS_Q *) &cfgMailbox, OSQCreate((OS_Q *) &cfgMailbox,
@ -343,12 +331,12 @@ void rtx_terminate()
} }
void rtx_configure(const rtxConfig_t *cfg) void rtx_configure(const rtxStatus_t *cfg)
{ {
OS_ERR err; OS_ERR err;
OSQPost((OS_Q *) &cfgMailbox, OSQPost((OS_Q *) &cfgMailbox,
(void *) cfg, (void *) cfg,
(OS_MSG_SIZE) sizeof(rtxConfig_t *), (OS_MSG_SIZE) sizeof(rtxStatus_t *),
(OS_OPT ) OS_OPT_POST_FIFO, (OS_OPT ) OS_OPT_POST_FIFO,
(OS_ERR *) &err); (OS_ERR *) &err);
@ -363,12 +351,17 @@ void rtx_configure(const rtxConfig_t *cfg)
OSQPost((OS_Q *) &cfgMailbox, OSQPost((OS_Q *) &cfgMailbox,
(void *) cfg, (void *) cfg,
(OS_MSG_SIZE) sizeof(rtxConfig_t *), (OS_MSG_SIZE) sizeof(rtxStatus_t *),
(OS_OPT ) OS_OPT_POST_FIFO, (OS_OPT ) OS_OPT_POST_FIFO,
(OS_ERR *) &err); (OS_ERR *) &err);
} }
} }
rtxStatus_t rtx_getCurrentStatus()
{
return rtxStatus;
}
void rtx_taskFunc() void rtx_taskFunc()
{ {
OS_ERR err; OS_ERR err;
@ -382,19 +375,29 @@ void rtx_taskFunc()
if((err == OS_ERR_NONE) && (msg != NULL)) if((err == OS_ERR_NONE) && (msg != NULL))
{ {
uint8_t tmp = rtxStatus.opStatus; /* Try locking mutex for read access */
memcpy(&rtxStatus, msg, sizeof(rtxConfig_t)); OSMutexPend(cfgMutex, 0, OS_OPT_PEND_NON_BLOCKING, NULL, &err);
free(msg);
rtxStatus.opStatus = tmp;
_setOpMode(); if(err == OS_ERR_NONE)
_setBandwidth(); {
_updateC5000IQparams(); /* Copy new configuration and override opStatus flags */
_setCTCSS(); uint8_t tmp = rtxStatus.opStatus;
_updateSqlThresholds(); memcpy(&rtxStatus, msg, sizeof(rtxStatus_t));
rtxStatus.opStatus = tmp;
/* TODO: temporarily force to RX mode if rtx is off. */ /* Done, release mutex */
if(rtxStatus.opStatus == OFF) _enableRxStage(); OSMutexPost(cfgMutex, OS_OPT_POST_NONE, &err);
/* Update HW configuration */
_setOpMode();
_setBandwidth();
_updateC5000IQparams();
_setCTCSS();
_updateSqlThresholds();
/* TODO: temporarily force to RX mode if rtx is off. */
if(rtxStatus.opStatus == OFF) _enableRxStage();
}
} }
if(rtxStatus.opStatus == RX) if(rtxStatus.opStatus == RX)

View File

@ -30,40 +30,49 @@
#include "hwconfig.h" #include "hwconfig.h"
#include "toneGenerator_MDx.h" #include "toneGenerator_MDx.h"
OS_MUTEX mutex;
OS_ERR err;
static const freq_t rptFreq = 430100000;
static const freq_t rptShift = 1600000;
static const tone_t ctcss = 719;
int main(void) int main(void)
{ {
platform_init(); platform_init();
toneGen_init(); toneGen_init();
rtx_init(); OSMutexCreate(&mutex, "", &err);
freq_t rptFreq = 430100000; rtx_init(&mutex);
freq_t rptShift = 1600000;
tone_t ctcss = 719;
/*
* Allocate a configuration message for RTX.
* This memory chunk is then freed inside the driver, so you must not call
* free() in this pointer!
*/
rtxConfig_t *cfg = ((rtxConfig_t *) malloc(sizeof(rtxConfig_t)));
cfg->opMode = FM; rtxStatus_t cfg;
cfg->bandwidth = BW_25;
cfg->rxFrequency = rptFreq; /* Take mutex and update the RTX configuration */
cfg->txFrequency = rptFreq + rptShift; OSMutexPend(&mutex, 0, OS_OPT_PEND_BLOCKING, NULL, &err);
cfg->txPower = 1.0f;
cfg->sqlLevel = 3; cfg.opMode = FM;
cfg->rxTone = 0; cfg.bandwidth = BW_25;
cfg->txTone = ctcss; cfg.rxFrequency = rptFreq;
rtx_configure(cfg); cfg.txFrequency = rptFreq + rptShift;
cfg.txPower = 1.0f;
cfg.sqlLevel = 3;
cfg.rxTone = 0;
cfg.txTone = ctcss;
OSMutexPost(&mutex, OS_OPT_POST_NONE, &err);
/* After mutex has been released, post the new configuration */
rtx_configure(&cfg);
while (1) while (1)
{ {
rtx_taskFunc(); rtx_taskFunc();
OS_ERR err; /* You can also resync the cfg */
cfg = rtx_getCurrentStatus();
OSTimeDlyHMSM(0u, 0u, 0u, 10u, OS_OPT_TIME_HMSM_STRICT, &err); OSTimeDlyHMSM(0u, 0u, 0u, 10u, OS_OPT_TIME_HMSM_STRICT, &err);
} }