diff --git a/openrtx/include/interfaces/rtx.h b/openrtx/include/interfaces/rtx.h index bf301394..6be9715e 100644 --- a/openrtx/include/interfaces/rtx.h +++ b/openrtx/include/interfaces/rtx.h @@ -21,6 +21,7 @@ #ifndef RTX_H #define RTX_H +#include #include #include @@ -29,7 +30,8 @@ typedef struct uint8_t opMode : 2, /**< Operating mode (FM, DMR, ...) */ bandwidth : 2, /**< Channel bandwidth */ 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 txFrequency; /**< TX frequency, in Hz */ @@ -40,7 +42,7 @@ typedef struct tone_t rxTone; /**< RX CTC/DCS tone */ tone_t txTone; /**< TX CTC/DCS tone */ } -rtxConfig_t; +rtxStatus_t; 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 @@ -75,11 +79,18 @@ void rtx_terminate(); /** * 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 - * been called. The driver takes care of its deallocation. + * \b must be protected by the same mutex whose pointer has been passed as a + * 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. */ -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 @@ -87,6 +98,10 @@ void rtx_configure(const rtxConfig_t *cfg); */ void rtx_taskFunc(); +/** + * Get current RSSI voltage. + * @return RSSI voltage. + */ float rtx_getRssi(); #endif /* RTX_H */ diff --git a/platform/drivers/baseband/rtx_MD3x0.c b/platform/drivers/baseband/rtx_MD3x0.c index 99e3063b..4cf57ec3 100644 --- a/platform/drivers/baseband/rtx_MD3x0.c +++ b/platform/drivers/baseband/rtx_MD3x0.c @@ -30,34 +30,19 @@ #include #include #include -#include #include "HR-C5000_MD3x0.h" #include "pll_MD3x0.h" #include -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 */ +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 sqlCloseTsh; /* Squelch closing threshold */ @@ -231,8 +216,11 @@ void _updateSqlThresholds() (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 */ OS_ERR err; 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; OSQPost((OS_Q *) &cfgMailbox, (void *) cfg, - (OS_MSG_SIZE) sizeof(rtxConfig_t *), + (OS_MSG_SIZE) sizeof(rtxStatus_t *), (OS_OPT ) OS_OPT_POST_FIFO, (OS_ERR *) &err); @@ -363,12 +351,17 @@ void rtx_configure(const rtxConfig_t *cfg) OSQPost((OS_Q *) &cfgMailbox, (void *) cfg, - (OS_MSG_SIZE) sizeof(rtxConfig_t *), + (OS_MSG_SIZE) sizeof(rtxStatus_t *), (OS_OPT ) OS_OPT_POST_FIFO, (OS_ERR *) &err); } } +rtxStatus_t rtx_getCurrentStatus() +{ + return rtxStatus; +} + void rtx_taskFunc() { OS_ERR err; @@ -382,19 +375,29 @@ void rtx_taskFunc() if((err == OS_ERR_NONE) && (msg != NULL)) { - uint8_t tmp = rtxStatus.opStatus; - memcpy(&rtxStatus, msg, sizeof(rtxConfig_t)); - free(msg); - rtxStatus.opStatus = tmp; + /* Try locking mutex for read access */ + OSMutexPend(cfgMutex, 0, OS_OPT_PEND_NON_BLOCKING, NULL, &err); - _setOpMode(); - _setBandwidth(); - _updateC5000IQparams(); - _setCTCSS(); - _updateSqlThresholds(); + if(err == OS_ERR_NONE) + { + /* Copy new configuration and override opStatus flags */ + uint8_t tmp = rtxStatus.opStatus; + memcpy(&rtxStatus, msg, sizeof(rtxStatus_t)); + rtxStatus.opStatus = tmp; - /* TODO: temporarily force to RX mode if rtx is off. */ - if(rtxStatus.opStatus == OFF) _enableRxStage(); + /* Done, release mutex */ + 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) diff --git a/tests/platform/MD380_FM_simpleRtx.c b/tests/platform/MD380_FM_simpleRtx.c index c51b8541..8d4d13ce 100644 --- a/tests/platform/MD380_FM_simpleRtx.c +++ b/tests/platform/MD380_FM_simpleRtx.c @@ -30,40 +30,49 @@ #include "hwconfig.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) { platform_init(); toneGen_init(); - rtx_init(); + OSMutexCreate(&mutex, "", &err); - freq_t rptFreq = 430100000; - freq_t rptShift = 1600000; - tone_t ctcss = 719; + rtx_init(&mutex); - /* - * 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; - cfg->bandwidth = BW_25; - cfg->rxFrequency = rptFreq; - cfg->txFrequency = rptFreq + rptShift; - cfg->txPower = 1.0f; - cfg->sqlLevel = 3; - cfg->rxTone = 0; - cfg->txTone = ctcss; - rtx_configure(cfg); + rtxStatus_t cfg; + + /* Take mutex and update the RTX configuration */ + OSMutexPend(&mutex, 0, OS_OPT_PEND_BLOCKING, NULL, &err); + + cfg.opMode = FM; + cfg.bandwidth = BW_25; + cfg.rxFrequency = rptFreq; + 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) { - 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); }