stm32f407 SPI DMA transmitter

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
jazz393
Встал на лапы
Сообщения: 118
Зарегистрирован: Ср фев 05, 2014 18:54:39

stm32f407 SPI DMA transmitter

Сообщение jazz393 »

Добрый день.
Настроил отправку данных по SPI при помощи DMA, хочу сделать его как кольцевой буфер и после отправки данных( да там есть режим circle , но с ним я как-то не понял как реализовать такое действо), по прерыванию об отправке данных я сдвигаю регистр M0AR на длину переданных данных(т.е. 4), но после 1ого отправленного "пакета"(Длинной COMMAND_SIZE == 4 байта) данные не отправляются, я так понял что после передачи "stream" сам выключается и его просто надо включить по новой...т.е. в прерывании я его должен включить и указать длину данных снова...вообщем ничего не выходит, хоть что-то отправить после 1ой посылки не получается, как правильно это делать не понимаю

сама идея союбственно и заключается в смысле DMA, вызываем функцию, в неё передаём адрес и данные, которые пишем в буфер(но буфер аля кольцевой, т.е. я добавляю в буфер данные как в FIFO структуру данных), после чего DMA делает работу за нас, читая данные добавленные в буфер, т.е. я отправил 4 байта, дал команду(вот с этим проблема...) данные отправились, потом записал ещё 1 команду, ещё раз отправил... итд

код:

Код: Выделить всё

void init_DMA1(){
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
    DMA1_Stream5->CR |= DMA_SxCR_PBURST_1 | DMA_SxCR_DIR_0 | DMA_SxCR_MINC;// | DMA_SxCR_CIRC;
    DMA1_Stream5->CR |= DMA_SxCR_TCIE; // ппрерывание по окончании передачи
    DMA1_Stream5->NDTR = COMMAND_SIZE; // длинна пакета

    DMA1_Stream5->PAR = (uint32_t)&(SPI3->DR);
    DMA1_Stream5->M0AR = (uint32_t)&(buffer[0]);

    NVIC_EnableIRQ(DMA1_Stream5_IRQn);
    }

Код: Выделить всё

void DMA1_Stream5_IRQHandler(){
   orange_on();
   if(DMA1->HISR & DMA_HISR_TCIF5){
      DMA1->HISR &= ~DMA_HISR_TCIF5;
      DMA1_Stream5->CR &= ~DMA_SxCR_TCIE;
      head_buffer+=4;
      DMA1_Stream5->M0AR = (uint32_t)&(buffer[head_buffer]);
      counter--;
      if(counter){
         DMA1_Stream5->CR &= ~DMA_SxCR_EN;
         DMA1_Stream5->NDTR = COMMAND_SIZE;
         DMA1_Stream5->CR |= DMA_SxCR_EN;
      }
   }
   if(DMA1->HISR &  DMA_HISR_HTIF5){
      DMA1->HISR &= ~DMA_HISR_HTIF5;
   }
   if(DMA1->HISR &  DMA_HISR_FEIF5){
      DMA1->HISR &= ~DMA_HISR_FEIF5;
   }
    orange_off();
}
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: stm32f407 SPI DMA transmitter

Сообщение dosikus »

Насколько помнится- в прерывании по окончанию трансфера DMA :
- выключаем канал
- ждем окончание передачи SPI(мониторим BSY)
-выключаем SPI .
- конфигурим канал DMA ( счетчик, адрес буфера)

опционально
- включаем канал
- включаем SPI
Ответить

Вернуться в «ARM»