RCC->AHBENR |= RCC_AHBENR_DMA1EN; //такты
// 4 канал DMA1 RX SPI2 -> память
DMA1_Channel4->CPAR = SPI2_BASE+0x0C; // адрес DR
DMA1_Channel4->CMAR = pSPI2_readbuf_addr->Buf_Addr; //адрес буфера приема
DMA1_Channel4->CNDTR = 12; // размер транзакции
DMA1_Channel4->CCR |= DMA_CCR4_MINC //инкремент адреса буфера
| DMA_CCR4_PSIZE_0; //размерность данных SPI 16 бит (происходит автоматическое преобразование 16->8 бит)
// 5 канал DMA1 память -> TX SPI2
DMA1_Channel5->CPAR = SPI2_BASE+0x0C; //адрес DR
DMA1_Channel5->CMAR = pSPI2_writebuf_addr->Buf_Addr; //адрес буфера передачи
DMA1_Channel5->CNDTR = 12; // размер транзакции
DMA1_Channel5->CCR |= DMA_CCR5_MINC //инкремент адреса буфера
| DMA_CCR5_DIR; // направление передачи из памяти в периферию
Транзакция запускается следующим куском кода:
void SPI2_start (void) // По сути это переинициализация каналов DMA
{
DMA1_Channel4->CPAR = SPI2_BASE+0x0C; //DR Base
DMA1_Channel4->CMAR = pSPI2_readbuf_addr->Buf_Addr;
DMA1_Channel4->CNDTR = 12;
DMA1_Channel5->CPAR = SPI2_BASE+0x0C; //DR Base
DMA1_Channel5->CMAR = pSPI2_writebuf_addr->Buf_Addr;
DMA1_Channel5->CNDTR = 12;
DMA1_Channel4->CCR |= DMA_CCR4_TCIE | DMA_CCR4_EN;
DMA1_Channel5->CCR |= DMA_CCR5_EN;
return;
}
Результаты обрабатываются по прерыванию завершения работы канала DMA работающего на прием данных от SPI:
void DMAChannel4_IRQHandler (void)
{
DMA1_Channel4->CCR &= (~(DMA_CCR4_TCIE | DMA_CCR4_EN)); // выключаем канал приемника и его прерывание
DMA1->IFCR |= DMA_IFCR_CTCIF4 | DMA_IFCR_CGIF4; //очищаем флаги
DMA1_Channel5->CCR &= (~(DMA_CCR5_EN)); // выключаем канал передатчика
pCurrent_mode->stat.led_data_send = 0; // выставляем нужные флаги для дальнейшей работы с данными
HC595_OUT;
pCurrent_mode->stat.read_key_data_ready=1;
return;
}
Комментариев нет:
Отправить комментарий