реклама на сайте
подробности

 
 
> DMAC + SSP на STR912, полный ступор...
Dron_Gus
сообщение Jan 2 2008, 01:36
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Пытаюсь переписать функции для работы с MMC картой для работы через DMA Полный ноль.

Для начала, как я понимаю, запрос на ДМА воникает при приеме данных. Чтобы что-то принять нужно что-то передать. Настраиваю один канал на прием, второй на передачу. Как запустить передачу? Сигнал SSP TX постоянно активен, пока не заполнено FIFO? Или надо произвести какие-то телодвижения, чтобы запустить передачу?



Пока имею такой код. ДМА не запускается, код ничего никуда не грузит... sad.gif



Код
   DMA_InitTypeDef  DMA_InitStruct;
  
  DMA_ChannelCmd(DMA_Channel0, DISABLE);                      // Disable the DMA channel
  DMA_ChannelCmd(DMA_Channel1, DISABLE);                      // Disable the DMA channel
  
  /* RECIVE */
  DMA_StructInit(&DMA_InitStruct);

  /* Write the first LLI*/
  DMA_InitStruct.DMA_Channel_LLstItm = 0;                     // Set the addresses of next linked list for the first LLI structure
  DMA_InitStruct.DMA_Channel_SrcAdd = (u32)&(SSP0->DR);       // source address for the first LLI structure
  DMA_InitStruct.DMA_Channel_DesAdd = (u32)pData;             // Destination address for the first LLI structure
  DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_Byte;    // The source bus width is a byte
  DMA_InitStruct.DMA_Channel_DesWidth = DMA_SrcWidth_Byte;    // The Destination bus width is a byte
  DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl_Perip2;// DMA is The flow controller
  DMA_InitStruct.DMA_Channel_TrsfSize = 512;                  // Transfer size
  DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX;           // Chanel source

  /* Configure the DMA channel1 "the chosen channel to perform the transfer" */

  DMA_ChannelSRCIncConfig (DMA_Channel0, DISABLE);
  DMA_ChannelDESIncConfig (DMA_Channel0, ENABLE);
  DMA_SyncConfig(0, ENABLE);

  DMA_Init(DMA_Channel0,&DMA_InitStruct);                     // update the DMA channel1 registers with the cfirst LLI structure
  
  /* TRANSFER */
  DMA_StructInit(&DMA_InitStruct);

  /* Write the first LLI*/
  DMA_InitStruct.DMA_Channel_LLstItm = 0;                     // Set the addresses of next linked list for the first LLI structure
  DMA_InitStruct.DMA_Channel_SrcAdd = (u32)pData;             // source address for the first LLI structure
  DMA_InitStruct.DMA_Channel_DesAdd = (u32)&(SSP0->DR);       // Destination address for the first LLI structure
  DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_Byte;    // The source bus width is a byte
  DMA_InitStruct.DMA_Channel_DesWidth = DMA_SrcWidth_Byte;    // The Destination bus width is a byte
  DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl_Perip1;// DMA is The flow controller
  DMA_InitStruct.DMA_Channel_TrsfSize = 512;                  // Transfer size
  DMA_InitStruct.DMA_Channel_Src = DMA_DES_SSP0_TX;           // Chanel destination

  /* Configure the DMA channel1 "the chosen channel to perform the transfer" */

  DMA_ChannelSRCIncConfig(DMA_Channel1, ENABLE);
  DMA_ChannelDESIncConfig(DMA_Channel1, DISABLE);
  DMA_SyncConfig(1, ENABLE);

  DMA_Init(DMA_Channel1,&DMA_InitStruct);                     // update the DMA channel1 registers with the cfirst LLI structure
  
  DMA_ChannelCmd(DMA_Channel0,ENABLE);                        // Enable the DMA channel
  DMA_ChannelCmd(DMA_Channel1,ENABLE);                        // Enable the DMA channel
  
  

  /*wait for the fifo to be empty*/
  while(DMA_GetChannelActiveStatus(DMA_Channel1));


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Dron_Gus
сообщение Jan 3 2008, 00:08
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Код
void MmcReceiveBlock (pInt8U pData, Int32U Size)
  {
  char SSP_WriteByte = 0xff;
  DMA_InitTypeDef  DMA_InitStruct;
  
  /* Enable FIFO */
  SSP_DMACmd(SSP0, SSP_DMA_Receive, ENABLE);
  SSP_DMACmd(SSP0, SSP_DMA_Transmit, ENABLE);
  
  /* RECIVE - DMA ch 0 */
  DMA_StructInit(&DMA_InitStruct);
  
  /*No linked lists used*/
  DMA_InitStruct.DMA_Channel_LLstItm = 0;
  /*Source address*/
  DMA_InitStruct.DMA_Channel_SrcAdd = (u32)(&SSP0->DR);
  /*Destination address*/
  DMA_InitStruct.DMA_Channel_DesAdd = (u32)pData;
  /*Source width of one byte*/
  DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_Byte;
  /*DMA burst size of 4 data*/
  DMA_InitStruct.DMA_Channel_SrcBstSize = DMA_SrcBst_4Data;
  /*Destination width of one byte*/
  DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_Byte;
  /*The flow controller is the DMAC*/
  DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl2_DMA;
  /* DMA req source */
  DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP0_RX;
  /*Transfer size */
  DMA_InitStruct.DMA_Channel_TrsfSize = Size;
  /*We increment the destination not the source */
  DMA_ChannelSRCIncConfig (DMA_Channel0, DISABLE);
  DMA_ChannelDESIncConfig (DMA_Channel0, ENABLE);
  /* Init */
  DMA_Init(DMA_Channel0, &DMA_InitStruct);
  
  /* TRANSFER - DMA ch 1 */
  DMA_StructInit(&DMA_InitStruct);
  
  /*No linked lists used*/
  DMA_InitStruct.DMA_Channel_LLstItm = 0;
  /*Source address*/
  DMA_InitStruct.DMA_Channel_SrcAdd = (u32)&SSP_WriteByte;
  /*Destination address*/
  DMA_InitStruct.DMA_Channel_DesAdd = (u32)((&SSP0->DR));
  /*Source width of one byte*/
  DMA_InitStruct.DMA_Channel_SrcWidth = DMA_SrcWidth_Byte;
  /*Destination width of one byte*/
  DMA_InitStruct.DMA_Channel_DesWidth = DMA_DesWidth_Byte;
  /*The flow controller is the DMAC*/
  DMA_InitStruct.DMA_Channel_FlowCntrl = DMA_FlowCntrl1_DMA;
  DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP0_TX;
  /*Transfer size */
  DMA_InitStruct.DMA_Channel_TrsfSize = Size;
  /*We increment not the source not the destination*/
  DMA_ChannelSRCIncConfig (DMA_Channel1, DISABLE);
  DMA_ChannelDESIncConfig (DMA_Channel1, DISABLE);
  /* Init */
  DMA_Init(DMA_Channel1, &DMA_InitStruct);
  
  /* Start transfer */
  DMA_ChannelCmd(DMA_Channel0, ENABLE);
  DMA_ChannelCmd(DMA_Channel1, ENABLE);
  
  /* wait for the transmit channel FIFO to be empty */
  while(DMA_GetChannelActiveStatus(DMA_Channel1));
  /* wait for the recive channel FIFO to be empty */
  while(DMA_GetChannelActiveStatus(DMA_Channel0));


Рабочий код. Производительность не мерил, но с ним уже удается без остановки "кормить" двухканальный PWM wav-файлом (44100 16 x 2) через EFSL. Это апримерно 176 Кбайт/сек. В два раза ускоряю - уже не вытягивает.

На всяк случай косяки на которые я наступил:
DMA на прием запускается не сразу - поэтому ловить его остановку стоит только после остановки DMA на передачу, иначе можем выскочить из функции еще до того, как DMA на прем принял хоть байт.
На сайте ST есть прмеры DMA под многие периферии. Правда примеров с одновременной передачей-приемом нет.

З.Ы. от шумов (потрескивания) PWM можно как-нить избавиться? Сейчас на выходе стоит цепочка (резистор)-(кондер на землю)-(резистор)-(кондер на землю). Противно посчелкивает сразу же после включения PWM.


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 01:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01523 секунд с 7
ELECTRONIX ©2004-2016