kopia lustrzana https://github.com/skuep/AIOC
rodzic
2fd3f70917
commit
68e1e46ea1
|
@ -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
|
||||
|
@ -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 {
|
||||
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_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;
|
||||
|
|
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -538,6 +576,13 @@ 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;
|
||||
|
||||
|
@ -545,6 +590,13 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
|
|||
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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue