Skip to content

Commit

Permalink
Added debug hooks into audio and PTT system
Browse files Browse the repository at this point in the history
  • Loading branch information
skuep committed Jan 1, 2024
1 parent 2fd3f70 commit 68e1e46
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 11 deletions.
55 changes: 48 additions & 7 deletions stm32/aioc-fw/Src/ptt.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "stm32f3xx_hal.h"
#include "aioc.h"
#include "led.h"
#include "settings.h"

#define PTT_MASK_NONE 0x00
#define PTT_MASK_PTT1 0x01
Expand All @@ -14,31 +15,71 @@
#define PTT_PIN_PTT1 GPIO_PIN_1
#define PTT_PIN_PTT2 GPIO_PIN_0

static inline void PTT_Control(uint8_t pttMask)
static inline void PTT_Assert(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) {
PTT_GPIO->BSRR = PTT_PIN_PTT1;
LED_SET(1, 1);
} else {
PTT_GPIO->BRR = PTT_PIN_PTT1;
LED_SET(1, 0);

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] |= SETTINGS_REG_DBGAIOC0_PTT1STATE_MASK;
}

if (pttMask & PTT_MASK_PTT2) {
PTT_GPIO->BSRR = PTT_PIN_PTT2;
LED_SET(0, 1);
} else {

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] |= SETTINGS_REG_DBGAIOC0_PTT2STATE_MASK;
}

__enable_irq();
}

static inline void PTT_Deassert(uint8_t pttMask)
{
__disable_irq();

if (pttMask & PTT_MASK_PTT1) {
PTT_GPIO->BRR = PTT_PIN_PTT1;
LED_SET(1, 0);

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] &= ~SETTINGS_REG_DBGAIOC0_PTT1STATE_MASK;
}

if (pttMask & PTT_MASK_PTT2) {
PTT_GPIO->BRR = PTT_PIN_PTT2;
LED_SET(0, 0);

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] &= ~SETTINGS_REG_DBGAIOC0_PTT2STATE_MASK;
}

__enable_irq();
}

static inline void PTT_Control(uint8_t pttMask)
{
/* TODO: Using this function, both PTTs can only be asserted/deasserted simultaneously.
* Switch to using fully event(edge) driven PTT assertion/deassertion using functions below */

if (pttMask & PTT_MASK_PTT1) {
PTT_Assert(PTT_MASK_PTT1);
} else {
PTT_Deassert(PTT_MASK_PTT1);
}

if (pttMask & PTT_MASK_PTT2) {
PTT_Assert(PTT_MASK_PTT2);
} else {
PTT_Deassert(PTT_MASK_PTT2);
}

}

static inline uint8_t PTT_Status(void)
{
uint32_t inputReg = PTT_GPIO->IDR;
Expand Down
97 changes: 93 additions & 4 deletions stm32/aioc-fw/Src/usb_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static void Timer_ADC_Init(void);
static void Timer_DAC_Init(void);
static void ADC_Init(void);
static void DAC_Init(void);
static void Timeout_Timers_Init(void);

//--------------------------------------------------------------------+
// Application Callback API Implementations
Expand Down Expand Up @@ -107,6 +108,11 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *

microphoneMute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~(SETTINGS_REG_DBGAUDIO0_RECMUTE0_MASK | SETTINGS_REG_DBGAUDIO0_RECMUTE1_MASK)) \
| (microphoneMute[0] ? SETTINGS_REG_DBGAUDIO0_RECMUTE0_MASK : 0) \
| (microphoneMute[1] ? SETTINGS_REG_DBGAUDIO0_RECMUTE1_MASK : 0);

TU_LOG2(" Set Mute: %d of channel: %u\r\n", microphoneMute[channelNum], channelNum);
return true;

Expand All @@ -119,6 +125,9 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
microphoneLinVolume[channelNum] = (microphoneLogVolume[channelNum] != 0x8000) ?
(uint16_t) (65535 * pow(10, logVolume/20) + 0.5) : 0; /* log to linear with rounding */

settingsRegMap[SETTINGS_REG_DBGAUDIO3] = ((((uint32_t) microphoneLinVolume[0]) << SETTINGS_REG_DBGAUDIO3_RECVOL0_OFFS) & SETTINGS_REG_DBGAUDIO3_RECVOL0_MASK) \
| ((((uint32_t) microphoneLinVolume[1]) << SETTINGS_REG_DBGAUDIO3_RECVOL1_OFFS) & SETTINGS_REG_DBGAUDIO3_RECVOL1_MASK);

TU_LOG2(" Set Volume: %u.%u dB of channel: %u\r\n", microphoneLogVolume[channelNum] / 256, microphoneLogVolume[channelNum] % 256, channelNum);
return true;

Expand All @@ -139,6 +148,11 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *

speakerMute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~(SETTINGS_REG_DBGAUDIO0_PLAYMUTE0_MASK | SETTINGS_REG_DBGAUDIO0_PLAYMUTE1_MASK)) \
| (speakerMute[0] ? SETTINGS_REG_DBGAUDIO0_PLAYMUTE0_MASK : 0) \
| (speakerMute[1] ? SETTINGS_REG_DBGAUDIO0_PLAYMUTE1_MASK : 0);

TU_LOG2(" Set Mute: %d of channel: %u\r\n", speakerMute[channelNum], channelNum);

return true;
Expand All @@ -152,6 +166,11 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
speakerLinVolume[channelNum] = (speakerLogVolume[channelNum] != 0x8000) ?
(uint16_t) (65535 * pow(10, logVolume/20) + 0.5) : 0; /* log to linear with rounding */

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO9] = ((((uint32_t) speakerLinVolume[0]) << SETTINGS_REG_DBGAUDIO9_PLAYVOL0_OFFS) & SETTINGS_REG_DBGAUDIO9_PLAYVOL0_MASK) \
| ((((uint32_t) speakerLinVolume[1]) << SETTINGS_REG_DBGAUDIO9_PLAYVOL1_OFFS) & SETTINGS_REG_DBGAUDIO9_PLAYVOL1_MASK);


TU_LOG2(" Set Volume: %u.%u dB of channel: %u\r\n", microphoneLogVolume[channelNum] / 256, microphoneLogVolume[channelNum] % 256, channelNum);
return true;

Expand All @@ -177,6 +196,9 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *

Timer_ADC_Init();

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO2] = (((uint32_t) microphoneSampleFreqCfg) << SETTINGS_REG_DBGAUDIO2_RECRATE_OFFS) & SETTINGS_REG_DBGAUDIO2_RECRATE_MASK;

return true;

// Unknown/Unsupported control
Expand Down Expand Up @@ -208,6 +230,9 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *

Timer_DAC_Init();

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO8] = (((uint32_t) speakerSampleFreqCfg) << SETTINGS_REG_DBGAUDIO8_PLAYRATE_OFFS) & SETTINGS_REG_DBGAUDIO8_PLAYRATE_MASK;

return true;

// Unknown/Unsupported control
Expand Down Expand Up @@ -493,6 +518,10 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u
/* Start ADC sampling as soon as device stacks starts loading data (will be a ZLP for first frame) */
NVIC_EnableIRQ(ADC1_2_IRQn);
microphoneState = STATE_RUN;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_RECSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_RECSTATE_RUN_ENUM) << SETTINGS_REG_DBGAUDIO0_RECSTATE_OFFS);
}

return true;
Expand All @@ -513,6 +542,10 @@ bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, u
/* Wait until whe are at buffer target fill level, then start DAC output */
speakerState = STATE_RUN;
NVIC_EnableIRQ(TIM6_DAC1_IRQn);

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_PLAYSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_PLAYSTATE_RUN_ENUM) << SETTINGS_REG_DBGAUDIO0_PLAYSTATE_OFFS);
}

/* Initialize/override min/max/avg during startup buffering */
Expand All @@ -521,6 +554,11 @@ bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, u
speakerBufferLvlMax = count;
}

/* Write to debug registers */
settingsRegMap[SETTINGS_REG_DBGAUDIO10] = ((uint32_t) (speakerBufferLvlAvg >> 16) << SETTINGS_REG_DBGAUDIO10_PLAYBUFAVG_OFFS) & SETTINGS_REG_DBGAUDIO10_PLAYBUFAVG_MASK;
settingsRegMap[SETTINGS_REG_DBGAUDIO11] = ((uint32_t) speakerBufferLvlMin << SETTINGS_REG_DBGAUDIO11_PLAYBUFMIN_OFFS) & SETTINGS_REG_DBGAUDIO11_PLAYBUFMIN_MASK;
settingsRegMap[SETTINGS_REG_DBGAUDIO12] = ((uint32_t) speakerBufferLvlMax << SETTINGS_REG_DBGAUDIO12_PLAYBUFMAX_OFFS) & SETTINGS_REG_DBGAUDIO12_PLAYBUFMAX_MASK;

return true;
}

Expand All @@ -538,13 +576,27 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
if (alt == 1) {
/* Microphone channel has been activated */
microphoneState = STATE_START;

/* Update VCOS/VPTT timeouts */
Timeout_Timers_Init();

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_RECSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_RECSTATE_START_ENUM) << SETTINGS_REG_DBGAUDIO0_RECSTATE_OFFS);
}
break;

case ITF_NUM_AUDIO_STREAMING_OUT:
if (alt == 1) {
/* Speaker channel has been activated */
speakerState = STATE_START;

/* Update VCOS/VPTT timeouts */
Timeout_Timers_Init();

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_PLAYSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_PLAYSTATE_START_ENUM) << SETTINGS_REG_DBGAUDIO0_PLAYSTATE_OFFS);
}
break;

Expand All @@ -567,12 +619,20 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const
/* Microphone channel has been stopped */
NVIC_DisableIRQ(ADC1_2_IRQn);
microphoneState = STATE_OFF;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_RECSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_RECSTATE_OFF_ENUM) << SETTINGS_REG_DBGAUDIO0_RECSTATE_OFFS);
break;

case ITF_NUM_AUDIO_STREAMING_OUT:
/* Speaker channel has been stopped */
NVIC_DisableIRQ(TIM6_DAC1_IRQn);
speakerState = STATE_OFF;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] = (settingsRegMap[SETTINGS_REG_DBGAUDIO0] & ~SETTINGS_REG_DBGAUDIO0_PLAYSTATE_MASK)
| (((uint32_t) SETTINGS_REG_DBGAUDIO0_PLAYSTATE_OFF_ENUM) << SETTINGS_REG_DBGAUDIO0_PLAYSTATE_OFFS);
break;

default:
Expand Down Expand Up @@ -638,6 +698,11 @@ TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t
speakerFeedbackMin = feedback;
speakerFeedbackMax = feedback;
}

/* Write to debug registers */
settingsRegMap[SETTINGS_REG_DBGAUDIO13] = ((uint32_t) (speakerFeedbackAvg >> 16) << SETTINGS_REG_DBGAUDIO13_PLAYFBAVG_OFFS) & SETTINGS_REG_DBGAUDIO13_PLAYFBAVG_MASK;
settingsRegMap[SETTINGS_REG_DBGAUDIO14] = ((uint32_t) speakerFeedbackMin << SETTINGS_REG_DBGAUDIO14_PLAYFBMIN_OFFS) & SETTINGS_REG_DBGAUDIO14_PLAYFBMIN_MASK;
settingsRegMap[SETTINGS_REG_DBGAUDIO15] = ((uint32_t) speakerFeedbackMax << SETTINGS_REG_DBGAUDIO15_PLAYFBMAX_OFFS) & SETTINGS_REG_DBGAUDIO15_PLAYFBMAX_MASK;
}

void ADC1_2_IRQHandler (void)
Expand Down Expand Up @@ -706,15 +771,29 @@ void TIM16_IRQHandler(void)
/* If timer was not enabled previously, enable timer and assert PTT */
TIM16->CR1 = cr | TIM_CR1_CEN;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] |= SETTINGS_REG_DBGAIOC0_VPTTSTATE_MASK;

/* Assert enabled PTTs */
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);

PTT_Assert(pttMask);
}
} else if (flags & TIM_SR_CC1IF) {
/* The idle timeout (without any action on the DAC) was reached. Disable timer and deassert PTT */
TIM16->CR1 &= ~TIM_CR1_CEN;
PTT_Control(PTT_MASK_NONE);

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] &= ~SETTINGS_REG_DBGAIOC0_VPTTSTATE_MASK;

/* Deassert enabled PTTs */
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_Deassert(pttMask);
}

TIM16->SR = ~flags;
Expand All @@ -731,11 +810,21 @@ void TIM17_IRQHandler(void)
if (!(cr & TIM_CR1_CEN)) {
/* If timer was not enabled previously, enable timer and notify host of COS */
TIM17->CR1 = cr | TIM_CR1_CEN;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] |= SETTINGS_REG_DBGAIOC0_VCOSSTATE_MASK;

/* Set COS state */
COS_SetState(0x01);
}
} else if (flags & TIM_SR_CC1IF) {
/* The idle timeout (without any action on the ADC) was reached. Disable timer and notify host */
TIM17->CR1 &= ~TIM_CR1_CEN;

/* Update debug register */
settingsRegMap[SETTINGS_REG_DBGAUDIO0] &= ~SETTINGS_REG_DBGAIOC0_VCOSSTATE_MASK;

/* Set COS state */
COS_SetState(0x00);
}

Expand Down Expand Up @@ -886,12 +975,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->PSC = timerFreq / 16000 - 1; /* 16 kHz counter */
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->PSC = timerFreq / 16000 - 1; /* 16 kHz counter */
TIM17->CCR1 = cosTimeout - 1;
TIM17->DIER = TIM_DIER_UIE | TIM_DIER_CC1IE;

Expand Down

0 comments on commit 68e1e46

Please sign in to comment.