Made Virtual COS/PTT configurable via new configuration interface

pull/53/head
Simon Kueppers 2023-12-31 15:30:16 +01:00
rodzic af0ddf9714
commit c0fbd8c746
5 zmienionych plików z 61 dodań i 23 usunięć

Wyświetl plik

@ -4,13 +4,43 @@
#include <stdint.h>
#include "stm32f3xx_hal.h"
#include "usb_hid.h"
#include "settings.h"
static inline void COS_SetState(uint8_t state)
{
LED_SET(0, state & 0x01 ? 1 : 0);
USB_HIDSendButtonState(state & 0x01 ? USB_HID_BUTTON_VOLDN : 0x00);
USB_SerialSendLineState(state & 0x01 ? USB_SERIAL_LINESTATE_DCD : 0x00);
if (settingsRegMap[SETTINGS_REG_CM108_IOMUX0] & SETTINGS_REG_CM108_IOMUX0_BTN1SRC_VCOS_MASK) {
USB_HIDSendButtonState(state & 0x01 ? USB_HID_BUTTON_VOLUP : 0x00);
}
if (settingsRegMap[SETTINGS_REG_CM108_IOMUX1] & SETTINGS_REG_CM108_IOMUX1_BTN2SRC_VCOS_MASK) {
USB_HIDSendButtonState(state & 0x01 ? USB_HID_BUTTON_VOLDN : 0x00);
}
if (settingsRegMap[SETTINGS_REG_CM108_IOMUX2] & SETTINGS_REG_CM108_IOMUX2_BTN3SRC_VCOS_MASK) {
USB_HIDSendButtonState(state & 0x01 ? USB_HID_BUTTON_PLAYMUTE : 0x00);
}
if (settingsRegMap[SETTINGS_REG_CM108_IOMUX3] & SETTINGS_REG_CM108_IOMUX3_BTN4SRC_VCOS_MASK) {
USB_HIDSendButtonState(state & 0x01 ? USB_HID_BUTTON_RECMUTE : 0x00);
}
if (settingsRegMap[SETTINGS_REG_SERIAL_IOMUX0] & SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_VCOS_MASK) {
USB_SerialSendLineState(state & 0x01 ? USB_SERIAL_LINESTATE_DCD : 0x00);
}
if (settingsRegMap[SETTINGS_REG_SERIAL_IOMUX1] & SETTINGS_REG_SERIAL_IOMUX1_DSRSRC_VCOS_MASK) {
USB_SerialSendLineState(state & 0x01 ? USB_SERIAL_LINESTATE_DSR : 0x00);
}
if (settingsRegMap[SETTINGS_REG_SERIAL_IOMUX2] & SETTINGS_REG_SERIAL_IOMUX2_RISRC_VCOS_MASK) {
USB_SerialSendLineState(state & 0x01 ? USB_SERIAL_LINESTATE_RI : 0x00);
}
if (settingsRegMap[SETTINGS_REG_SERIAL_IOMUX3] & SETTINGS_REG_SERIAL_IOMUX3_BRKSRC_VCOS_MASK) {
USB_SerialSendLineState(state & 0x01 ? USB_SERIAL_LINESTATE_BREAK : 0x00);
}
}
#endif /* COS_H_ */

Wyświetl plik

@ -16,6 +16,8 @@
static inline void PTT_Control(uint8_t pttMask)
{
/* TODO: This way, both PTTs can only be asserted/deasserted simultaneously.
* Maybe better for future applications to have PTT1 and PTT2 controlled separately. */
__disable_irq();
if (pttMask & PTT_MASK_PTT1) {

Wyświetl plik

@ -44,6 +44,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALRTS_MASK 0x00000200UL
#define SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALDTRNRTS_MASK 0x00000400UL
#define SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALNDTRRTS_MASK 0x00000800UL
#define SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_VPTT_MASK 0x00001000UL
/* AIOC IOMUX1 register */
#define SETTINGS_REG_AIOC_IOMUX1 0x25
@ -61,7 +62,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_AIOC_IOMUX1_PTT2SRC_SERIALRTS_MASK SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALRTS_MASK
#define SETTINGS_REG_AIOC_IOMUX1_PTT2SRC_SERIALDTRNRTS_MASK SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALDTRNRTS_MASK
#define SETTINGS_REG_AIOC_IOMUX1_PTT2SRC_SERIALNDTRRTS_MASK SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_SERIALNDTRRTS_MASK
#define SETTINGS_REG_AIOC_IOMUX1_PTT2SRC_VPTT_MASK SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_VPTT_MASK
/* CM108 IOMUX0 register */
#define SETTINGS_REG_CM108_IOMUX0 0x44
@ -112,17 +113,17 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_CM108_IOMUX3_BTN4SRC_VCOS_MASK SETTINGS_REG_CM108_IOMUX0_BTN1SRC_VCOS_MASK
/* Serial (CDC) Control register */
#define SETTINGS_REG_SERIAL_CTRL 0x50
#define SETTINGS_REG_SERIAL_CTRL 0x60
#define SETTINGS_REG_SERIAL_CTRL_DEFAULT (SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_DFLT | SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_DFLT)
/* TXFRCPTT: Forces PTT signal(s) to zero when transmitting serial data to radio if enabled */
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_DFLT (SETTINGS_REG_SERIAL_CTRL_FORCEPTT_PTT1)
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_DFLT (SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_PTT1_MASK)
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_OFFS 8
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_MASK 0x00000F00UL
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_NONE_MASK 0x00000000UL
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_PTT1_MASK 0x00000100UL
#define SETTINGS_REG_SERIAL_CTRL_TXFRCPTT_PTT2_MASK 0x00000200UL
/* RXIGNPTT: Ignores reception of data from radio when PTT signal(s) asserted if enabled */
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_DFLT (SETTINGS_REG_SERIAL_CTRL_IGNPTT_PTT1)
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_DFLT (SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_PTT1_MASK)
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_OFFS 16
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_MASK 0x000F0000UL
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_NONE_MASK 0x00000000UL
@ -130,7 +131,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_SERIAL_CTRL_RXIGNPTT_PTT2_MASK 0x00020000UL
/* Serial (CDC) IOMUX0 register */
#define SETTINGS_REG_SERIAL_IOMUX0 0x54
#define SETTINGS_REG_SERIAL_IOMUX0 0x64
#define SETTINGS_REG_SERIAL_IOMUX0_DEFAULT (SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_DFLT)
/* DCDSRC: DCD (Data Carrier Detect) signal source */
#define SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_DFLT (SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_VCOS_MASK)
@ -142,7 +143,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_VCOS_MASK SETTINGS_REG_CM108_IOMUX0_BTN1SRC_VCOS_MASK
/* Serial (CDC) IOMUX1 register */
#define SETTINGS_REG_SERIAL_IOMUX1 0x55
#define SETTINGS_REG_SERIAL_IOMUX1 0x65
#define SETTINGS_REG_SERIAL_IOMUX1_DEFAULT (SETTINGS_REG_SERIAL_IOMUX1_DSRSRC_DFLT)
/* DSRSRC: DSR (Data Set Ready) signal source */
#define SETTINGS_REG_SERIAL_IOMUX1_DSRSRC_DFLT (SETTINGS_REG_SERIAL_IOMUX1_DSRSRC_NONE_MASK)
@ -154,7 +155,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_SERIAL_IOMUX1_DSRSRC_VCOS_MASK SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_VCOS_MASK
/* Serial (CDC) IOMUX2 register */
#define SETTINGS_REG_SERIAL_IOMUX2 0x56
#define SETTINGS_REG_SERIAL_IOMUX2 0x66
#define SETTINGS_REG_SERIAL_IOMUX2_DEFAULT (SETTINGS_REG_SERIAL_IOMUX2_RISRC_DFLT)
/* RISRC: RI (Ring Indicator) signal source */
#define SETTINGS_REG_SERIAL_IOMUX2_RISRC_DFLT (SETTINGS_REG_SERIAL_IOMUX2_RISRC_NONE_MASK)
@ -166,7 +167,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_SERIAL_IOMUX2_RISRC_VCOS_MASK SETTINGS_REG_SERIAL_IOMUX0_DCDSRC_VCOS_MASK
/* Serial (CDC) IOMUX3 register */
#define SETTINGS_REG_SERIAL_IOMUX3 0x57
#define SETTINGS_REG_SERIAL_IOMUX3 0x67
#define SETTINGS_REG_SERIAL_IOMUX3_DEFAULT (SETTINGS_REG_SERIAL_IOMUX3_BRKSRC_DFLT)
/* BRKSRC: BREAK (Break) signal source */
#define SETTINGS_REG_SERIAL_IOMUX3_BRKSRC_DFLT (SETTINGS_REG_SERIAL_IOMUX3_BRKSRC_NONE_MASK)
@ -197,7 +198,7 @@ extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_VCOS_LVLCTRL 0x92
#define SETTINGS_REG_VCOS_LVLCTRL_DEFAULT (SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_DFLT)
/* THRSHLD: Virtual COS threshold level */
#define SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_DFLT ((uint32_t) 16 << SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_OFFS)
#define SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_DFLT ((uint32_t) 256 << SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_OFFS)
#define SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_OFFS 0
#define SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_MASK 0x0000FFFFUL

Wyświetl plik

@ -18,11 +18,6 @@
/* We try to stay on this target with the buffer level */
#define SPEAKER_BUFFERLVL_TARGET (5 * CFG_TUD_AUDIO_EP_SZ_OUT) /* Keep our buffer at 5 frames, i.e. 5ms at full-speed USB and maximum sample rate */
#define PTT_THRESHOLD 16
#define PTT_TIMEOUT 10000 /* us */
#define COS_THRESHOLD (16 << 4)
#define COS_TIMEOUT 10000 /* us */
typedef enum {
SAMPLERATE_48000, /* The high-quality default */
@ -653,7 +648,9 @@ void ADC1_2_IRQHandler (void)
int16_t sample = ((int32_t) ADC2->DR - 32768) & 0xFFFFU;
/* Automatic COS */
if (!microphoneMute[1] && ( (sample > COS_THRESHOLD) || (sample < -COS_THRESHOLD) )) {
uint16_t cosThreshold = (settingsRegMap[SETTINGS_REG_VCOS_LVLCTRL] & SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_MASK) >> SETTINGS_REG_VCOS_LVLCTRL_THRSHLD_OFFS;
if (!microphoneMute[1] && ( (sample > cosThreshold) || (sample < -cosThreshold) )) {
/* Reset timeout and make sure timer is enabled */
TIM17->EGR = TIM_EGR_UG; /* Generate an update event in the timer */
}
@ -679,7 +676,9 @@ void TIM6_DAC_IRQHandler(void)
tud_audio_read(&sample, sizeof(sample));
/* Automatic PTT */
if (!speakerMute[1] && ( (sample > PTT_THRESHOLD) || (sample < -PTT_THRESHOLD) )) {
uint16_t pttThreshold = (settingsRegMap[SETTINGS_REG_VPTT_LVLCTRL] & SETTINGS_REG_VPTT_LVLCTRL_THRSHLD_MASK) >> SETTINGS_REG_VPTT_LVLCTRL_THRSHLD_OFFS;
if (!speakerMute[1] && ( (sample > pttThreshold) || (sample < -pttThreshold) )) {
/* Reset timeout and make sure timer is enabled */
TIM16->EGR = TIM_EGR_UG; /* Generate an update event in the timer */
}
@ -706,7 +705,11 @@ void TIM16_IRQHandler(void)
if (!(cr & TIM_CR1_CEN)) {
/* If timer was not enabled previously, enable timer and assert PTT */
TIM16->CR1 = cr | TIM_CR1_CEN;
PTT_Control(PTT_MASK_PTT1);
uint8_t pttMask = PTT_MASK_NONE;
pttMask |= settingsRegMap[SETTINGS_REG_AIOC_IOMUX0] & SETTINGS_REG_AIOC_IOMUX0_PTT1SRC_VPTT_MASK ? PTT_MASK_PTT1 : 0;
pttMask |= settingsRegMap[SETTINGS_REG_AIOC_IOMUX1] & SETTINGS_REG_AIOC_IOMUX1_PTT2SRC_VPTT_MASK ? PTT_MASK_PTT2 : 0;
PTT_Control(pttMask);
}
} else if (flags & TIM_SR_CC1IF) {
/* The idle timeout (without any action on the DAC) was reached. Disable timer and deassert PTT */
@ -875,6 +878,8 @@ static void DAC_Init(void)
static void Timeout_Timers_Init()
{
uint32_t timerFreq = (HAL_RCC_GetHCLKFreq() == HAL_RCC_GetPCLK2Freq()) ? HAL_RCC_GetPCLK2Freq() : 2 * HAL_RCC_GetPCLK2Freq();
uint32_t pttTimeout = (settingsRegMap[SETTINGS_REG_VPTT_TIMCTRL] & SETTINGS_REG_VPTT_TIMCTRL_TIMEOUT_MASK) >> SETTINGS_REG_VPTT_TIMCTRL_TIMEOUT_OFFS;
uint32_t cosTimeout = (settingsRegMap[SETTINGS_REG_VCOS_TIMCTRL] & SETTINGS_REG_VCOS_TIMCTRL_TIMEOUT_MASK) >> SETTINGS_REG_VCOS_TIMCTRL_TIMEOUT_OFFS;
__HAL_RCC_TIM16_CLK_ENABLE();
__HAL_RCC_TIM17_CLK_ENABLE();
@ -882,12 +887,12 @@ static void Timeout_Timers_Init()
/* TIM16 and TIM17 are timeout-counters for PTT and COS */
TIM16->CR1 = TIM_CLOCKDIVISION_DIV1 | TIM_COUNTERMODE_UP;
TIM16->PSC = timerFreq / 1000000 - 1; /* Microseconds counter */
TIM16->CCR1 = PTT_TIMEOUT - 1;
TIM16->CCR1 = pttTimeout - 1;
TIM16->DIER = TIM_DIER_UIE | TIM_DIER_CC1IE;
TIM17->CR1 = TIM_CLOCKDIVISION_DIV1 | TIM_COUNTERMODE_UP;
TIM17->PSC = timerFreq / 1000000 - 1; /* Microseconds counter */
TIM17->CCR1 = COS_TIMEOUT - 1;
TIM17->CCR1 = cosTimeout - 1;
TIM17->DIER = TIM_DIER_UIE | TIM_DIER_CC1IE;
NVIC_SetPriority(TIM16_IRQn, AIOC_IRQ_PRIO_AUDIO);

Wyświetl plik

@ -51,8 +51,8 @@ tusb_desc_device_t desc_device = {
// Application return pointer to descriptor
uint8_t const* tud_descriptor_device_cb(void) {
/* Get up-to-date USB settings */
desc_device.idVendor = (settingsRegMap[SETTINGS_REG_USBID] >> SETTINGS_REG_USBID_VID_OFFS) & SETTINGS_REG_USBID_VID_MASK;
desc_device.idProduct = (settingsRegMap[SETTINGS_REG_USBID] >> SETTINGS_REG_USBID_PID_OFFS) & SETTINGS_REG_USBID_PID_MASK;
desc_device.idVendor = (settingsRegMap[SETTINGS_REG_USBID] & SETTINGS_REG_USBID_VID_MASK) >> SETTINGS_REG_USBID_VID_OFFS;
desc_device.idProduct = (settingsRegMap[SETTINGS_REG_USBID] & SETTINGS_REG_USBID_PID_MASK) >> SETTINGS_REG_USBID_PID_OFFS;
return (uint8_t const*) &desc_device;
}