SAI протокол (Serial Audio Interface)
Это навороченный i2s
В моем процессоре он есть. И его надо стартануть.
У меня есть проблема в понимании.
Вот настройки sai в CubeMX
И формат данный и формат слота.
SAI протокол (Serial Audio Interface) stm32f429
36076 просмотров, 38 ответов — стр. 1 из 3
20 сентября 2020 г. в 07:34#1
20 сентября 2020 г. в 07:56#2
Идет поток данных (пока один канал) но квадратура (в левый и правый каналы) так считать размер одного замера =32 бита , то есть фактически амплитуды 32битного АЦП (для простоты понимания). Поток непрерывный.
Что такое FRAME LENGTH? (это вопрос) Он должен совпадать с дампом памяти который я выделил в процессоре, точнее не так...это минимальная длина массива в процессоре, которое должно быть выделено? либо кратно этой цифре.
В Кубе там размер стоит (FRAME LENGTH )от 8 ло 256 бит или от 256 байт и выше за один сэмпл.
Если брать 48000Гц поток то это 20мкСек на один сэмпл. У меня в одной банке 1024 сэмплов ...итого около 20мСек на один прием. За 20мСек нужно посчитать смеситель, АРУ, ФИР фильтр, там еще что-то. Круто блин.
Я запутался в трех соснах. Какой длины должна быть передача(FRAME LENGTH)? И это стерео?
Что такое FRAME LENGTH? (это вопрос) Он должен совпадать с дампом памяти который я выделил в процессоре, точнее не так...это минимальная длина массива в процессоре, которое должно быть выделено? либо кратно этой цифре.
В Кубе там размер стоит (FRAME LENGTH )от 8 ло 256 бит или от 256 байт и выше за один сэмпл.
Если брать 48000Гц поток то это 20мкСек на один сэмпл. У меня в одной банке 1024 сэмплов ...итого около 20мСек на один прием. За 20мСек нужно посчитать смеситель, АРУ, ФИР фильтр, там еще что-то. Круто блин.
Я запутался в трех соснах. Какой длины должна быть передача(FRAME LENGTH)? И это стерео?
20 сентября 2020 г. в 08:19#3
Разобрался.
Все очень просто и логично.
В данном процессоре 8 каналов для звука, можно по SAI гнать. Это 4 канала на левый и 4 канала на правый (слотов). И если размерность амплитуды 32бита, то как раз на общих 8 слотов будет в длину 256 бит или 32 байта за одно передачу. И это все в бесконечном потоке.
Или у меня: 32+32 бита квадратура =64бита FRAME LENGTH.
Или ДМА скушает 8байт за один прием. за 20мкСек. длина буфера получается при 1024 замеров ацп =8192байта.
Все очень просто и логично.
В данном процессоре 8 каналов для звука, можно по SAI гнать. Это 4 канала на левый и 4 канала на правый (слотов). И если размерность амплитуды 32бита, то как раз на общих 8 слотов будет в длину 256 бит или 32 байта за одно передачу. И это все в бесконечном потоке.
Или у меня: 32+32 бита квадратура =64бита FRAME LENGTH.
Или ДМА скушает 8байт за один прием. за 20мкСек. длина буфера получается при 1024 замеров ацп =8192байта.
20 сентября 2020 г. в 09:24#4
Пока не могу стартануть на передачу...
20 сентября 2020 г. в 10:21#5
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
HAL_SAI_TxCpltCallback(&hsai_BlockA1);
__HAL_SAI_ENABLE(&hsai_BlockA1);
HAL_SAI_IRQHandler(&hsai_BlockA1);
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4 * FRAME_SIZE) != HAL_OK) Error_Handler();
Хрен его знает как ТХ запустить через ДМА и чтоб еще прерывание сработало об окончанию.
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
HAL_SAI_TxCpltCallback(&hsai_BlockA1);
__HAL_SAI_ENABLE(&hsai_BlockA1);
HAL_SAI_IRQHandler(&hsai_BlockA1);
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4 * FRAME_SIZE) != HAL_OK) Error_Handler();
Хрен его знает как ТХ запустить через ДМА и чтоб еще прерывание сработало об окончанию.
21 сентября 2020 г. в 12:08#6
Если тактовые сигналы на соответствующий канал а или б приходят, он начнет запрвшивать у dma. Еажется там был бит в слове состояния, который состояние ws показывал? Или то у spi/i2s было... не помню.
21 сентября 2020 г. в 12:09#7
Прервания от sai при нормальной работе вам и не потребуются.
21 сентября 2020 г. в 12:10#8
Предполагаю что не приходят. На ws и bclk есть сигналы?
21 сентября 2020 г. в 12:14#9
Хоть один активный слот в конфигурации стоит?
21 сентября 2020 г. в 06:53#10
Я пытаюсь передать блок в воздух. Не один провод не подключен.
ПЕрвая передача проходит (вроде, нечем смотреть)
if (hsai_BlockA1.State == HAL_SAI_STATE_READY)
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4*FRAME_SIZE) != HAL_OK) Error_Handler();
и после выполнения - тишина, ни прерывание ни callback не срабатывают.
проверяю состояние =HAL_SAI_STATE_BUSY_TX постоянно.
Может в воздух нельзя передавать?
ПЕрвая передача проходит (вроде, нечем смотреть)
if (hsai_BlockA1.State == HAL_SAI_STATE_READY)
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4*FRAME_SIZE) != HAL_OK) Error_Handler();
и после выполнения - тишина, ни прерывание ни callback не срабатывают.
проверяю состояние =HAL_SAI_STATE_BUSY_TX постоянно.
Может в воздух нельзя передавать?
21 сентября 2020 г. в 07:12#11
Вот настройки saiA и DMA
21 сентября 2020 г. в 11:10#12
SAI TX - нет 
перед вызовом функции ТХ hsai_BlockA1.State=READY дает....ну готов значит sai к TX
Дальше:
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4 ) != HAL_OK) Error_Handler();
дает HAL_OK. Значит функция работает корректно.
HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
{
if((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
if(hsai->State == HAL_SAI_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hsai);
hsai->pBuffPtr = pData;
hsai->XferSize = Size;
hsai->XferCount = Size;
hsai->ErrorCode = HAL_SAI_ERROR_NONE;
hsai->State = HAL_SAI_STATE_BUSY_TX;
/* Set the SAI Tx DMA Half transfer complete callback */
hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
/* Set the SAI TxDMA transfer complete callback */
hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
/* Set the DMA error callback */
hsai->hdmatx->XferErrorCallback = SAI_DMAError;
/* Set the DMA Tx abort callback */
hsai->hdmatx->XferAbortCallback = NULL;
/* Enable the Tx DMA Stream */
if(HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
{
__HAL_UNLOCK(hsai);
return HAL_ERROR;
}
/* Check if the SAI is already enabled */
if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
{
/* Enable SAI peripheral */
__HAL_SAI_ENABLE(hsai);
}
/* Enable the interrupts for error handling */
__HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
/* Enable SAI Tx DMA Request */
hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
/* Process Unlocked */
__HAL_UNLOCK(hsai);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
самая основная функция "красная" и она тоже дает = HAL_OK.

перед вызовом функции ТХ hsai_BlockA1.State=READY дает....ну готов значит sai к TX
Дальше:
if (HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *) saiTxBank, 4 ) != HAL_OK) Error_Handler();
дает HAL_OK. Значит функция работает корректно.
HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
{
if((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
if(hsai->State == HAL_SAI_STATE_READY)
{
/* Process Locked */
__HAL_LOCK(hsai);
hsai->pBuffPtr = pData;
hsai->XferSize = Size;
hsai->XferCount = Size;
hsai->ErrorCode = HAL_SAI_ERROR_NONE;
hsai->State = HAL_SAI_STATE_BUSY_TX;
/* Set the SAI Tx DMA Half transfer complete callback */
hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
/* Set the SAI TxDMA transfer complete callback */
hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
/* Set the DMA error callback */
hsai->hdmatx->XferErrorCallback = SAI_DMAError;
/* Set the DMA Tx abort callback */
hsai->hdmatx->XferAbortCallback = NULL;
/* Enable the Tx DMA Stream */
if(HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
{
__HAL_UNLOCK(hsai);
return HAL_ERROR;
}
/* Check if the SAI is already enabled */
if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
{
/* Enable SAI peripheral */
__HAL_SAI_ENABLE(hsai);
}
/* Enable the interrupts for error handling */
__HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
/* Enable SAI Tx DMA Request */
hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
/* Process Unlocked */
__HAL_UNLOCK(hsai);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
самая основная функция "красная" и она тоже дает = HAL_OK.
21 сентября 2020 г. в 11:14#13
Но после выполнения HAL_SAI_Transmit_DMA, статус становится hsai_BlockA1.State =BUSY
И так и остается в таком положении...
И так и остается в таком положении...
21 сентября 2020 г. в 11:43#14
И HAL_SAI_Transmit просто даже эта команда вылетает с ошибкой по таймауту , без всяких ДМА.
Я явно делаю что-то не то.
Я явно делаю что-то не то.
21 сентября 2020 г. в 02:21#15
HAL_SAI_Transmit_DMA
Работает, исправил настройки слотов.
С приемом номер не прошел.
Хочу через А канал передавать, по каналу В принимать. ВСе синхро выводы у них соединены, только ДАТА надо кинуть проводком (которого нет)
Настройки канала А (ТХ)
Работает, исправил настройки слотов.
С приемом номер не прошел.
Хочу через А канал передавать, по каналу В принимать. ВСе синхро выводы у них соединены, только ДАТА надо кинуть проводком (которого нет)
Настройки канала А (ТХ)