2023-10-30 02:45 AM
Hello,
I found an example on the internet of a project but I don't understand the usefulness of using a Timer 7. Could you tell me why ? Thanks in advance.
__IO uint32_t usTick;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* Prevent unused argument(s) compilation warning */
if(htim==&htim7){
usTick++;
}
/* NOTE : This function Should not be modified, when the callback is needed,
the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
}
void delay_us(__IO uint32_t Delay){
uint32_t t=usTick;
uint32_t wait = Delay;
while( usTick - t < wait);
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM7_Init();
/*if (HAL_TIM_Base_Start(&htim7) != HAL_OK) {
_Error_Handler(__FILE__, __LINE__);
}*/
if (HAL_TIM_Base_Start_IT(&htim7) != HAL_OK) {
_Error_Handler(__FILE__, __LINE__);
}
MX_I2C1_Init();
MX_I2S2_Init();
HAL_Delay(100);
audio.init();
bool ptt=HAL_GPIO_ReadPin(GPIOE,PTT_SWITCH);
bool pttstate=ptt;
uint16_t index = 0;
uint16_t buf = 0;
audio.set_volume(0);
/* Infinite loop */
while (1)// read power switch
{
ptt=HAL_GPIO_ReadPin(GPIO_PINS,PTT_SWITCH);
if(ptt!=pttstate){
if(ptt==0){
audio.start_receive();
for(buf=0;buf<32;buf++){
for(index=0;index < AUDIO_BUF_SIZE;index++){
HAL_I2SEx_TransmitReceive(&hi2s2, &i2s_zero,&i2s_buf[buf][index], 1,0xFF);
}
}
audio.start_play();
for(buf=0;buf<32;buf++){
for(index=0;index < AUDIO_BUF_SIZE;index++){
HAL_I2SEx_TransmitReceive(&hi2s2, &i2s_buf[buf][index],&i2s_zero, 1,0xFF);
}
}
}
pttstate=ptt;
}
}
}
2023-11-02 05:51 AM
Hi,
It's a good idea but after my configuration :
Right for SAI data output to data input but what should I do for the other 3 connections ? Which are :
SAI1_MCLK_B (Master CLK)
SAI1_FS_B (Frame Synchro)
SAI1_SCK_B (Bit Clock).
I still let them connect to the CODEC, it seems to me, right ? In my case I just connect
SAI1_SD_B with SAI1_SD_A. Right ?
2023-11-02 07:21 AM - edited 2023-11-02 07:56 AM
After connecting SAI1_SD_B with SAI1_SD_A and do the for loop.
But now How to check if I have theses values via SAI1_SD_B ?
I wonder what is the meaning of 'Memory To Peripheral'. After me the DMA stores data in a device but what is this device? A user-defined memory area ?
2023-11-02 08:11 AM
The SAI blocks can be synchronized internally.
Connection: I mean a hardware connection from pin to pin, don't know if that is feasible on your board, there might be some soldering involved.
Memory: internal SRAM buffer, those you assign by calling the DMA start function
Peripheral: all that stuff not CPU or memory, like interfaces (in your case the SAI), ADC, DAC, Timers, ...
Data go this way:
2023-11-02 08:43 AM - edited 2023-11-02 08:48 AM
Thank you for your helps, this information is very clear (for me) compared to the numerous videos or code examples that I have seen. No problem for the connection, I've the evaluation board STM32L5 and the CODEC so I use this jump between 2 connections :
Sorry In my program I did not call the DMA Start function as you say. I configured the DMA in circular mode only :
I don't know if this is the right method but I have no errors when my program runs.
2023-11-02 08:50 AM
Here is my Main for this moment :
int main(void)
{
/* USER CODE BEGIN 1 */
HAL_StatusTypeDef fresult;
int32_t playbuf[4096*2] __attribute__ ((aligned (32)));
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SAI1_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
HAL_SAI_RegisterCallback(&hsai_BlockB1, HAL_SAI_TX_HALFCOMPLETE_CB_ID, HAL_SAI_TxHalfCpltCallback);
HAL_SAI_RegisterCallback(&hsai_BlockB1, HAL_SAI_TX_COMPLETE_CB_ID, HAL_SAI_TxCpltCallback);
fresult= HAL_SAI_Init(&hsai_BlockB1);
if (fresult != HAL_OK)
{
return HAL_ERROR;
}
fresult = HAL_SAI_Transmit_DMA(&hsai_BlockB1, (uint8_t *)playbuf , (sizeof(playbuf))/4);
HAL_Delay(100);
SGTL5000_init();
set_volume(0);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
int32_t i;
for (i=0;i<100;i++)
{playbuf[i]=i;}
start_receive();
HAL_Delay(100);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
2023-11-02 10:23 AM
I'd rather fill the buffer once, before the while loop, and fill it completely.
2023-11-02 03:14 PM - edited 2023-11-02 03:22 PM
Yes of course, you're right about this buffer. But I would like to have a little precision please. After your explanation
So when I fill the array (playbuf) with the values, I only check the way
SRAM DA buffer -> DMA -> SAI TX -> ext. DAC (not for me). In this case why to connect SAI1_SD_B with SAI1_SD_A ? Is this really necessary ?
I can't verify for the moment the way : ext.ADC -> SAI RX -> DMA -> SRAM AD buffers. Right ?
2023-11-03 04:16 AM
What kind of of hardware do you actually have?
Is a Codec connected, and if yes, how?
How are the SAI blocks set up? Which is transmitter, which is receiver?
2023-11-03 04:20 AM - edited 2023-11-03 07:34 AM
"What kind of of hardware do you actually have ?"
I have a STM32L552E-EV evaluation board with audio board (CODEC SGTL5000, Audio Adaptor Rev D for Teensy 4.0).
https://www.pjrc.com/store/teensy3_audio.html
"Is a Codec connected, and if yes, how?"
Yes the CODEC is connect to the STM32 and my configuration with the CODEC is :
According to my knowledge via the documentation
FSx - Frame Synchronisation
SCKx - bit Clock
SDx - Serial data line
MCLK - Master Clock
And for I2S LRCLK is equivalent FS for SAI.
"How are the SAI blocks set up?"
I have this configuration but I don't know if I answer your question ?
Which is transmitter, which is receiver?
The transmitter is SAI B and the receiver is SAI A (so CODEC is the slave after me). I hope I answered your questions.
2023-11-03 08:46 AM
That is some helpful info for helping. ;)
LRCK is the good old "Left Right Clock" for stereo decoders, which is equal to the sampling rate.
So you have an extra audio board, that makes some things easier.
So, again, I would start:
- without the audio board
- then connect the SAI data IOs
- fill playbuf completely
- start DMAs (first start the slave, then the master)
- check all the SAI clocks and data IOs with a scope, LRCK should equal your sampling rate
If all is working correctly, you should see DA data in the AD buffers.
To check AD data, you could simply compare the buffers.
PS: set the SAI DMA priorities higher (probably not necessary at low sampling rates)