Настроил отправку данных по 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();
}