В демке от ST написано чуть по-другому. В колбэке setup request сохраняем параметры и взводим флаг, что надо обработать.
А сам запрос можно уже обрабатывать в колбэке usbd_audio_EP0_RxReady, используя сохраненный запрос и значения флагов, которые нужно обнулить после отработки запроса.
Код:
struct usb_setup_req USB_SETUP_REQ2;
/**
* @brief AUDIO_Req_SetCurrent
* Handles the SET_CUR Audio control request.
* @param pdev: instance
* @param req: setup class request
* @retval status
*/
static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req)
{
if (req->wLength)
{
/* Prepare the reception of the buffer over EP0 */
USBD_CtlPrepareRx (pdev,
AudioCtl,
req->wLength);
/* Set the global variables indicating current request and its length
to the function usbd_audio_EP0_RxReady() which will process the request */
AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */
AudioCtlLen = req->wLength; /* Set the request data length */
AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */
USB_SETUP_REQ2=*req;
}
}
static uint8_t usbd_audio_EP0_RxReady (void *pdev)
{
uint32_t temp;
/* Check if an AudioControl request has been issued */
if (AudioCtlCmd == AUDIO_REQ_SET_CUR)
{/* In this driver, to simplify code, only SET_CUR request is managed */
/* Check for which addressed unit the AudioControl request has been issued */
AUDIO_Req_SetCurrent2(&USB_SETUP_REQ2);
/*if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL)
{// In this driver, to simplify code, only one unit is manage
// Call the audio interface mute function
AUDIO_OUT_fops.MuteCtl(AudioCtl[0]);
}*/
/* Reset the AudioCtlCmd variable to prevent re-entering this function */
AudioCtlCmd = 0;
AudioCtlLen = 0;
}
/* if (AudioCtlCmd == AUDIO_REQ_GET_CUR)
{
temp=48000;
AudioCtl[0]=(uint8_t)(temp&0xff);
AudioCtl[1]=(uint8_t)((temp>>8)&0xff);
AudioCtl[2]=(uint8_t)((temp>>16)&0xff);
//Reset the AudioCtlCmd variable to prevent re-entering this function
AudioCtlCmd = 0;
AudioCtlLen = 0;
}
*/
return USBD_OK;
}
static void AUDIO_Req_SetCurrent2(USB_SETUP_REQ *req)
{
if (req->wLength)
{
/* Prepare the reception of the buffer over EP0 */
//USBD_CtlPrepareRx (pdev,\
AudioCtl,\
req->wLength);
if (HIBYTE(req->wValue) == SAMPLING_FREQ_MUTE_CONTROL)//если команда SAMPLING_FREQ_CONTROL или MUTE
{
if ((req->bmRequest & 0x0f) == ENDPOINT_REQUEST_TYPE)//если запрос к конечной точке
{
//считываем значение частоты
Sampling_freq = (*(uint32_t *)&AudioCtl[0]) & 0x00ffffff;
//управление внешними генераторами и выбор FB_RATE для разных частот
switch (Sampling_freq)
{
case 44100 :
{
FB_NOM = (44 << 14) + (1 << 14) / 10;
//SPI3->I2SPR = 0x0004;//коэффициент деления I2S = 4
SetI2SMCLK(Sampling_freq);
GEN2_OFF;
GEN1_ON;
};break;
case 48000 :
{
FB_NOM = 48 << 14;
//SPI3->I2SPR = 0x0004;//коэффициент деления I2S = 4
SetI2SMCLK(Sampling_freq);
GEN1_OFF;
GEN2_ON;
};break;
case 88200 :
{
FB_NOM = (88 << 14) + (2 << 14) / 10;
//SPI3->I2SPR = 0x0002;//коэффициент деления I2S = 2
SetI2SMCLK(Sampling_freq);
GEN2_OFF;
GEN1_ON;
};break;
case 96000 :
{
FB_NOM = 96 << 14;
//SPI3->I2SPR = 0x0002;//коэффициент деления I2S = 2
SetI2SMCLK(Sampling_freq);
GEN1_OFF;
GEN2_ON;
};break;
case 192000 :
{
FB_NOM = 192 << 14;
//SPI3->I2SPR = 0x0002;//коэффициент деления I2S = 2
SetI2SMCLK(Sampling_freq);
GEN1_OFF;
GEN2_ON;
};break;
}
FB_RATE = FB_NOM;
delta_num = 0;
PlayStart = 0;
spk_buffer_in = 0;
spk_buffer_out = 0;
spk_index = 0;
delta_num = 0;
old_gap = AUDIO_BUFFER_SIZE;
}
else if (HIBYTE(req->wIndex) == AUDIO_OUT_STREAMING_CTRL)//иначе это команда MUTE
{
mute = AudioCtl[0];
// if (mute) GPIO_SetBits(GPIOB,GPIO_Pin_4);
// else GPIO_ResetBits(GPIOB,GPIO_Pin_4);
}
}
}
}
Криво, конечно, но работает.
Социальные закладки