Я скрещиваю DMA с SPI1 следующим образом:
Код
SPI1->CR2 = 0;
SPI1->CR1 &= ~SPI_CR1_SPE;
SPI1->CR1 |= SPI_CR1_LSBFIRST | SPI_CR1_DFF;
SPI1->CRCPR = 10;
DMA2_Stream2->CR = 0x06022d1f - 1;
DMA2_Stream2->NDTR = 0x800;
DMA2_Stream2->M0AR = (uint32_t)spirx;
DMA2_Stream2->PAR = 0x4001300c;
DMA2_Stream3->CR = 0x06022d5f - 1;
DMA2_Stream3->NDTR = 0x800;
DMA2_Stream3->M0AR = (uint32_t)spitx;
DMA2_Stream3->PAR = 0x4001300c;
DMA2_Stream2->CR |= DMA_SxCR_EN;
DMA2_Stream3->CR |= DMA_SxCR_EN;
SPI1->CR2 |= SPI_CR2_RXDMAEN;
SPI1->CR2 |= SPI_CR2_TXDMAEN;
SPI1->CR1 |= SPI_CR1_SPE;
SPI1->CR1 &= ~SPI_CR1_SPE;
SPI1->CR1 |= SPI_CR1_LSBFIRST | SPI_CR1_DFF;
SPI1->CRCPR = 10;
DMA2_Stream2->CR = 0x06022d1f - 1;
DMA2_Stream2->NDTR = 0x800;
DMA2_Stream2->M0AR = (uint32_t)spirx;
DMA2_Stream2->PAR = 0x4001300c;
DMA2_Stream3->CR = 0x06022d5f - 1;
DMA2_Stream3->NDTR = 0x800;
DMA2_Stream3->M0AR = (uint32_t)spitx;
DMA2_Stream3->PAR = 0x4001300c;
DMA2_Stream2->CR |= DMA_SxCR_EN;
DMA2_Stream3->CR |= DMA_SxCR_EN;
SPI1->CR2 |= SPI_CR2_RXDMAEN;
SPI1->CR2 |= SPI_CR2_TXDMAEN;
SPI1->CR1 |= SPI_CR1_SPE;
SPI работает в режиме слейва и мастер передает данные.
После ресета все хорошо. Но у меня возможна ситуация, когда
мастер перестает передавать данные. Я этот момент знаю и хочу переставить счетчики и указатели DMA
таким образом, что когда мастер возобновит передачу, новые данные писались бы в начало буфера spirx
и читались бы (передавались мастеру) из spitx.
Я тупо вызываю код выше еще раз, когда мастер хочет начать передачу (я этот момент тоже знаю).
Так вот с буфером от мастера (spirx) все хорошо, а spitx съезжает на 1 слово!
Я заметил, что после ресета регистр DMA2_Stream3->NDTR становится не 0x800, а 0x7ff после выполнения строки
SPI1->CR2 |= SPI_CR2_TXDMAEN
т.е. как я понимаю, DMA переписывает 1 слово из памяти в сдвиговый регистр SPI.
а вот если делать переинициализацию, то такого не происходит - т.е. после
SPI1->CR2 |= SPI_CR2_TXDMAEN
значение DMA2_Stream3->NDTR не изменяется.
Вопрос -
как мне переинициализировать DMA правильно?