Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

SPI, DMA
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=14826
Страница 1 от 1

Автор:  bobi13 [ Вто Окт 11, 2016 1:02 pm ]
Заглавие:  SPI, DMA

Здравейте, чета от едно външно АЦП, което има SPI интерфейс, данните от SPI ги прехвурлям към вътрешния буфер чрез DMA контролер. Данните които получавам са наред, но по някаква причина се появава допълнителен клок след като съм приключил с четенето. С други думи ако съм задал че искам да чета 4 sample, на изхода виждам 80 clock вместо 64 (в прикачения файл е резултата). Tози допълнителен clock не знам как да го премахна.
Контролерът ми е stm32f746.
Това са настройките на SPI и DMA

Код:
spi_handler.Instance                  = SPI2;
   spi_handler.Init.Mode               = SPI_MODE_MASTER;
   spi_handler.Init.Direction            = SPI_DIRECTION_2LINES_RXONLY; // Receive mode only
   spi_handler.Init.DataSize             = SPI_DATASIZE_16BIT;
   spi_handler.Init.CLKPolarity          = SPI_POLARITY_LOW;
   spi_handler.Init.CLKPhase             = SPI_PHASE_1EDGE;
   spi_handler.Init.NSS                  = SPI_NSS_HARD_OUTPUT;
   spi_handler.Init.NSSPMode            = SPI_NSS_PULSE_ENABLE;
   spi_handler.Init.BaudRatePrescaler    = SPI_BAUDRATEPRESCALER_32;   // Baud rate = APB1 / BRprescaler. Max Fsample of MCP3301 is 1,7MHz
   spi_handler.Init.FirstBit             = SPI_FIRSTBIT_MSB;
   spi_handler.Init.TIMode               = SPI_TIMODE_DISABLE;
   spi_handler.Init.CRCCalculation         = SPI_CRCCALCULATION_DISABLE;
   spi_handler.Init.CRCPolynomial       = 0;
   HAL_SPI_Init(&spi_handler);


Код:
dma_handler_rx.Instance                 = DMA1_Stream3;
      dma_handler_rx.Init.Channel             = DMA_CHANNEL_0;
      dma_handler_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
      dma_handler_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
      dma_handler_rx.Init.MemBurst            = DMA_MBURST_SINGLE;
      dma_handler_rx.Init.PeriphBurst         = DMA_PBURST_SINGLE;
      dma_handler_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
      dma_handler_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
      dma_handler_rx.Init.MemInc              = DMA_MINC_ENABLE;
      dma_handler_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
      dma_handler_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
      dma_handler_rx.Init.Mode                = DMA_NORMAL;           // The DMA circular mode cannot be used when the SPI is configured in this mode: Master 2Lines RxOnly
      dma_handler_rx.Init.Priority            = DMA_PRIORITY_HIGH;

      HAL_DMA_Init(&dma_handler_rx);

      // Associate the initialized DMA handle to the the SPI handle
      __HAL_LINKDMA(hspi, hdmarx, dma_handler_rx);

      // Set DMA1 stream 3 priority.
      // When 2 interrupts have same preemption priority, then he one who has higher sub priority will be execute first.
      // If both interrupts both have same preemption priority and sub priority, the one comes first will be execute first
      HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 1, 1);
      HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

      // Set SPI2 receive priority.
      // When 2 interrupts have same preemption priority, then he one who has higher sub priority will be execute first.
      // If both interrupts both have same preemption priority and sub priority, the one comes first will be execute first
      HAL_NVIC_SetPriority(SPI2_IRQn, 1, 0);
      HAL_NVIC_EnableIRQ(SPI2_IRQn);


Прикачени файлове:
clk.jpg
clk.jpg [ 277.01 KiB | Прегледано 4206 пъти ]

Автор:  Цецо [ Вто Окт 11, 2016 1:21 pm ]
Заглавие:  Re: SPI, DMA

Така както изглежда, четеш един семпъл повече, все едно трансфера ти е за 5 вместо 4 аксеса. Обаче в тоя отрязък от кода никъде не виждам къде зареждаш броя на трансферите. Виж там да не бъркаш нещо. Ако имаш дебъгер сложи прекъсване точно преди енейбъла на ДМА-то и виж в регистъра за броя трансфери какво имаш - 5 или 4.

Автор:  bobi13 [ Вто Окт 11, 2016 1:25 pm ]
Заглавие:  Re: SPI, DMA

Извинявам се, така го зареждам


Код:
#define SPI_REC_BUFFER    4
static U16 spi_convert_value[SPI_REC_BUFFER];

void hw_adc_spi_communination()
{
      CS_OFF;
      HAL_SPI_Receive_DMA(get_spi_handler(), (U8*)spi_convert_value, SPI_REC_BUFFER);

}

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef* spi_callback)
{
   CS_ON;
   hw_adc_spi_result();
}

Автор:  Цецо [ Вто Окт 11, 2016 1:34 pm ]
Заглавие:  Re: SPI, DMA

Не съм работил с 7ма серия, като за 4та изглежда ОК кода. Да няма някава особенност в ДМА-то на 7ма серия, ама едва ли.

Автор:  tolstolob [ Вто Окт 11, 2016 1:36 pm ]
Заглавие:  Re: SPI, DMA

.

Автор:  miro_atc [ Вто Окт 11, 2016 1:51 pm ]
Заглавие:  Re: SPI, DMA

bobi13 написа:
Това са настройките на SPI и DMA


А дали са само това?

Имаш някаква структура, на която просвояваш някои полета, ами другите полета каква стойност имат? Поне виж дали декларацията е статик или ауто, ако е ауто вземи я забърши тая структура щото простотиите на ST край нямат...

А най-добре дето ти каза Цецо - слагаш един брейкпоинт и гледаш как се програмира и SPI и DMA-то.

Автор:  miro_atc [ Вто Окт 11, 2016 2:22 pm ]
Заглавие:  Re: SPI, DMA

Сори, не погледнах добре кода... той не е и за гледане, ама това е друга тема ;-)

Значи RX-Only режима на SPI е някакво безумие. В момента в който разрешиш периферията и тя тръгва да чете и така до откат. Няма значение какви дължини слагаш на DMA-то, те си важат само за DMA-то.

Съветът ми е да не ползваш подобни щуротии. Сложи си го на нормален режим, нека си праща.. ти като не му програмиш MOSI никой няма да разбере че "праща" ;-)
За пращането пускаш ДМА без MINC, така ще прати едно и също нещо колкото пъти му кажеш и ще спре.

Автор:  bobi13 [ Вто Окт 11, 2016 2:30 pm ]
Заглавие:  Re: SPI, DMA

Добре, ще пробвам.

Автор:  Цецо [ Вто Окт 11, 2016 5:39 pm ]
Заглавие:  Re: SPI, DMA

Да Миро е прав. Единствения проблем е, че губиш един канал на DMA-то залудо, а те в СТМ-а са малко кът.

Автор:  miro_atc [ Сря Окт 12, 2016 9:06 am ]
Заглавие:  Re: SPI, DMA

Ако има проблем с ДМА-то може да види как работи пущината. От картинката се вижда, че все пак спира. Въпросът е дали спира щото изключва SPI-a или той спира сам да изчака да му изпразниш DR-a. Ако е второто може да мине без пращане, само трябва да си пуска ДМА-то с един трансфер по-малко, а последните данни да си ги чете ръчно след като изчака да дойдат и спре животното.

И друго дето се вижда от картинката - много криви сигнали... Не знам с какво е снимано и доколко е истина, ама сякаш трябва да се намали силата на драйверите или някаква серийна терминация, че така изглежда като радио Хоризонт ;-)

Автор:  bobi13 [ Чет Окт 13, 2016 12:31 pm ]
Заглавие:  Re: SPI, DMA

Цитат:
И друго дето се вижда от картинката - много криви сигнали... Не знам с какво е снимано и доколко е истина, ама сякаш трябва да се намали силата на драйверите или някаква серийна терминация, че така изглежда като радио Хоризонт


От осцилоскопа е.

Сложих SPI в режим Rx/Tx и всичко се оправи. Все още ми е интересно къде е проблема, в хардуера или в самата библиотека. Благодаря за помощта.

Автор:  miro_atc [ Чет Окт 13, 2016 12:53 pm ]
Заглавие:  Re: SPI, DMA

Нямаш проблем, просто така си работи в RX only режим - още като го конфигурираш и тръгва автоматично и така докато може... Не е ясно само дали изкава да опразниш получените данни или не. Ако изчаква както казах по-горе, пускаш един трансфер по-малко и докато чака го спираш. Иначе в движение няма как да го спреш точно след определен брой трансфер, трябва да налучкваш времена и да играеш тото...

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/