Перейти к содержанию
    

SAI to SPI

Привет народ. Необходимо переслать по СПИ шине данные , полученные со звукового кодека, который подключен по SAI в другой процессор.

Судя по осциллограмме на ножках кодека, инициализация проходит успешно и можно видеть , как данные от левого и правого каналов меняются независимо друг от друга( проверял с помощью подачи синуса на каждый канал).

То есть данные передаются в буфер в порядке 16 бит левого канала, затем 16 бит правого канала и т.д. то есть как в даташите прописано.

Пытаюсь для передачи  по СПИ перетасовать данные в порядок 512 байт левого канала, затем 512 байт правого канала таким кодом:

#define NSAMPLES 512                //Must be order of 2
#define NDUMMY 32                   //Dummy samples are needed to minimize influence of filter settling after invoking the SAI

int16_t audioBuf[(NSAMPLES + NDUMMY) * 2];

int16_t audioBuff[(NSAMPLES + NDUMMY) * 2];//

void DSP_Sample_send(int ch){

    int16_t* pBuf = &audioBuf[NDUMMY + (ch!=0)];

    for(int i = 0; i < NSAMPLES; i++)
                                       {
                                  if (ch!=0) audioBuff[i] = (int16_t)*pBuf; 
                                 else        audioBuff[ NSAMPLES + i ] = (int16_t)*pBuf;
                                             pBuf += 2;
                                       } pBuf = 0;
}

void DSP_Sample(void){

    extern SAI_HandleTypeDef haudio_in_sai;

 HAL_StatusTypeDef res =     
 HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) audioBuf, (NSAMPLES + NDUMMY) * 2, HAL_MAX_DELAY);
 
 if (HAL_OK != res)
    {
     CRASH_(15,"HAL_SAI_Receive failed");
    }
    
 DSP_Sample_send(0); //заполняем 512байт левый канал
 DSP_Sample_send(1);//заполняем 512байт  правый канал
 HAL_SPI_Transmit(&hspi3, (uint8_t*) audioBuff, (NSAMPLES + NDUMMY) * 2, HAL_MAX_DELAY);
}

однако на ножке MOSI  вижу, что данные левого и правого канала идентичны, то есть меняются одновременно от одного из каналов на входе кодека, а от другого не меняются вовсе, хотя на самом кодеке, как я писал выше, видно чёткое разделение данных левого и правого каналов.

Подскажите битте, где я косячу и помогите исправить ошибки. Спасибо заранее...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, VladimirG сказал:

По моему ошибка тут 

В чем, по-вашему, она заключается?

15 часов назад, andreichk сказал:

Подскажите битте, где я косячу

Криминала я не вижу. Конечно назвать переменные audioBuf и audioBuff - знатная грабля на будущее, но это каждый сам себе злобный сами знаете кто. А что мешает в целях отладки сделать 

#define NSAMPLES 4                //Must be order of 2
#define NDUMMY 1                   //Dummy samples are needed to minimize influence of filter settling after invoking the SAI

int16_t audioBuf[(NSAMPLES + NDUMMY) * 2] = 
{
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
};

...
  
void DSP_Sample(void){
/*
    extern SAI_HandleTypeDef haudio_in_sai;

 HAL_StatusTypeDef res =     
 HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) audioBuf, (NSAMPLES + NDUMMY) * 2, HAL_MAX_DELAY);
 
 if (HAL_OK != res)
    {
     CRASH_(15,"HAL_SAI_Receive failed");
    }
*/    
 DSP_Sample_send(0); //заполняем 512байт левый канал
 DSP_Sample_send(1);//заполняем 512байт  правый канал
/*  
 HAL_SPI_Transmit(&hspi3, (uint8_t*) audioBuff, (NSAMPLES + NDUMMY) * 2, HAL_MAX_DELAY);
*/
}

и прогнать это под отладчиком? Если нет отладчика - написать простейшую консольную программу для PC, которая прогонит на этом массиве тот же алгоритм и распечатает выходной массив на экран.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

P.S. я бы писал это примерно так:


#define NCHANNELS   2
#define NSAMPLES    4
#define NDUMMY      1

typedef int16_t sample;
typedef sample input_sample[NCHANNELS];
typedef input_sample input_buffer[NSAMPLES + NDUMMY];

typedef sample output_channel[NSAMPLES];
typedef output_channel output_buffer[NCHANNELS];

input_buffer Input = 
{
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
output_buffer Output;

void shuffle(int channel)
{
    for(int i = 0; i < NSAMPLES; ++i)
        Output[channel][i] = Input[i + NDUMMY][channel];
}

https://onlinegdb.com/S1fShTnED

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 часов назад, andreichk сказал:

void DSP_Sample_send(int ch){

    int16_t* pBuf = &audioBuf[NDUMMY + (ch!=0)];

    for(int i = 0; i < NSAMPLES; i++)
                                       {
                                  if (ch!=0) audioBuff[i] = (int16_t)*pBuf; 
                                 else        audioBuff[ NSAMPLES + i ] = (int16_t)*pBuf;
                                             pBuf += 2;
                                       } pBuf = 0;
}

...

 DSP_Sample_send(0); //заполняем 512байт левый канал
 DSP_Sample_send(1);//заполняем 512байт  правый канал

 

Жесть какая.... :shok:  Такое ощущение, что автор только и думал - "Как посильнее затормозить и запутать код?"  :suicide2:

 

1 час назад, Сергей Борщ сказал:

P.S. я бы писал это примерно так:


void shuffle(int channel)
{
    for(int i = 0; i < NSAMPLES; ++i)
        Output[channel][i] = Input[i + NDUMMY][channel];
}

 

Там за один проход всё легко делается. Оба канала.  :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо всем отозвавшимся, я проверил все ваши поправки  и вот что получил, только я немного увеличил размер тестового буфера, чтобы приблизить к реальным условиям.

#define NCHANNEL   2
#define NSAMPLE    256
#define NDUMM      1

typedef int16_t sample;
typedef sample input_sample[NCHANNEL];
typedef input_sample input_buffer[NSAMPLE + NDUMM];

typedef sample output_channel[NSAMPLE];
typedef output_channel output_buffer[NCHANNEL];

input_buffer Input = 
{
 0,1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31,
   1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31, 1008, 31
};

output_buffer Output;

void shuffle(int channel)
{
    for(int i = 0; i < NSAMPLE; ++i)
    
        Output[!channel][i] = Input[i + NDUMM][channel];
}

void DSP_Sample(void){

//    extern SAI_HandleTypeDef haudio_in_sai;

// HAL_StatusTypeDef res =     
// HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) audioBuf, (NSAMPLE + NDUMMY) * 2, HAL_MAX_DELAY);
 
// if (HAL_OK != res)
  //  {
  //   CRASH_(15,"HAL_SAI_Receive failed");
 //   }
    
    for(int i = 0; i < NCHANNEL; ++i)
        shuffle(i);    
    
 HAL_SPI_Transmit(&hspi3, (uint8_t*) &Output[0], (NSAMPLE + NDUMM) * 2, HAL_MAX_DELAY);
}

однако , применительно к конкретному процессору  STM32H743, получилось не совсем то, что ожидалось, а именно как на картинке. наверное потому что данных в буфере в 2 раза меньше

1.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

увеличил кол-во данных в буфере и заполнение стало непрерывным.

#define NCHANNEL   2
#define NSAMPLE    256
#define NDUMM      1

typedef int16_t sample;
typedef sample input_sample[NCHANNEL];
typedef input_sample input_buffer[NSAMPLE + NDUMM];

typedef sample output_channel[NSAMPLE];
typedef output_channel output_buffer[NCHANNEL];

input_buffer Input = 
{
 0,1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1,
   1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008, 1, 1008
};

output_buffer Output;

void shuffle(int channel)
{
    for(int i = 0; i < NSAMPLE*2; ++i)
    
        Output[channel][i] = Input[i + NDUMM][channel];
}

void DSP_Sample(void){

    extern SAI_HandleTypeDef haudio_in_sai;

 HAL_StatusTypeDef res =     
 HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) audioBuf, (NSAMPLE + NDUMMY) * 2, HAL_MAX_DELAY);
 
 if (HAL_OK != res)
    {
     CRASH_(15,"HAL_SAI_Receive failed");
    }
    
    for(int i = 0; i < NCHANNEL; ++i) {shuffle(i);}    
    
 HAL_SPI_Transmit(&hspi3, (uint8_t*) &Output[0], (NSAMPLE + NDUMM) * 2, HAL_MAX_DELAY);
}

на картинке видно, что данные с буфера уложились правильно

2.png

3.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

попробовал подменить тестовый буфер на реальные данные, полученные с кодека по SAI шине.

#define NCHANNEL   2
#define NSAMPLE    512
#define NDUMM      32

typedef int16_t sample;
typedef sample input_sample[NCHANNEL];
typedef input_sample audioBuf[NSAMPLE + NDUMM];

typedef sample output_channel[NSAMPLE];
typedef output_channel output_buffer[NCHANNEL];

audioBuf Input ; 

output_buffer Output;

void shuffle(int channel)
{
    for(int i = 0; i < NSAMPLE*2; ++i)
    
        Output[channel][i] = Input[i + NDUMM][channel];
}

void DSP_Sample(void){

    extern SAI_HandleTypeDef haudio_in_sai;

 HAL_StatusTypeDef res =     
 HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) Input, (NSAMPLE + NDUMM) * 2, HAL_MAX_DELAY);
 
 if (HAL_OK != res)
    {
     CRASH_(15,"HAL_SAI_Receive failed");
    }
    
    for(int i = 0; i < NCHANNEL; ++i) {shuffle(i);}    
    
 HAL_SPI_Transmit(&hspi3, (uint8_t*) &Output[0], (NSAMPLE + NDUMM) * 2, HAL_MAX_DELAY);
}

однако применительно к моему процессору,на выходе  ничего не изменилось , то есть всё так и осталось , как с моим быдлокодом. разделения на левый и правый каналы к сож. не произошло.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

57 минут назад, andreichk сказал:

то есть всё так и осталось , как с моим быдлокодом

Значит проблема где-то раньше, во входной массив уже попадают кривые данные. А почему вы не хотите посмотреть эти принятые данные внутрисхемным отладчиком?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Сергей Борщ said:

Значит проблема где-то раньше, во входной массив уже попадают кривые данные. А почему вы не хотите посмотреть эти принятые данные внутрисхемным отладчиком?

я бы с удовольствием, но не знаю, как. а есть букварь для чайников на эту тему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 я все настройки кодека перепроверил. там всё как у других пользователей этого прибора. даже не представляю, куда ещё копать:dash2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/14/2020 at 1:38 PM, Сергей Борщ said:

В чем, по-вашему, она заключается?

Перечитал, нет ошибки =)

 

Изменено пользователем VladimirG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 HAL_SAI_Receive(&haudio_in_sai,(uint8_t*) Input, (NSAMPLE + NDUMM) * 2, HAL_MAX_DELAY);

Проверьте размерность.

У вас Input по коду 16 бит на элемент, а принимаете вы 8 бит на элемент.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/14/2020 at 8:22 PM, Сергей Борщ said:

Значит проблема где-то раньше, во входной массив уже попадают кривые данные. А почему вы не хотите посмотреть эти принятые данные внутрисхемным отладчиком?

Вы были правы, косяк находился в инициализации SAI . После исправления, данные стали передаваться правильно.

Большое спасибо  всем участникам...:good2:

 

вот собственно то, что должно получиться в итоге:

 

K640_DSC00002.JPG

K640_DSC00003.JPG

K640_DSC00004.JPG

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...