Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Доброго времени суток Подскажите пожалуйста, что я делаю не так в настройке DMA для SPI для отправки без DMA работает void SPI3_Init() { // SPI3 RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; SPI3->CR1 = 0 << SPI_CR1_DFF_Pos // Размер кадра 8 бит | 0<<SPI_CR1_LSBFIRST_Pos // MSB first | 1<<SPI_CR1_SSM_Pos // Программное управление SS | 1<<SPI_CR1_SSI_Pos // SS в высоком состоянии | 0x00<<SPI_CR1_BR_Pos // Скорость передачи = Fpclk/2 | 1<<SPI_CR1_MSTR_Pos // Режим Master | 0<<SPI_CR1_CPOL_Pos | 0<<SPI_CR1_CPHA_Pos; SPI3->CR2 = SPI_CR2_TXDMAEN; // Отправка через DMA SPI3->CR1 |= SPI_CR1_SPE; // Включаем SPI3 } void SPI3_Send(volatile uint8_t *data, uint16_t len) { //DMA1 Stream 7 SPI3_TX DMA1_Stream7->CR = 0; DMA1_Stream7->CR |= 0x01 << DMA_SxCR_PSIZE_Pos; // SPI data register is 16 bit DMA1_Stream7->CR |= 0x00 << DMA_SxCR_MSIZE_Pos; // memory size is 8bit DMA1_Stream7->CR |= DMA_SxCR_MINC; // memory increment DMA1_Stream7->CR |= 0x01 << DMA_SxCR_DIR_Pos; // memory to peripheral DMA1_Stream7->CR |= 0x03 << DMA_SxCR_PL_Pos; // Priority level DMA1_Stream7->PAR = (uint32_t)(&SPI3->DR); DMA1_Stream7->M0AR = (uint32_t)data; DMA1_Stream7->NDTR = len; DMA1_Stream7->FCR = 0; // Настройка FIFO буфера DMA1_Stream7->CR |= DMA_SxCR_EN; } ................ volatile uint8_t data[3] = {1,2,3}; while(1) SPI3_Send(data,3); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deni 6 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Может быть стоит дождаться окончания передачи DMA? Если в бесконечном цикле постоянно перенастраивать, то канал скорее всего встанет в ошибку. Надо смотреть статус регистр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Без цикла тоже не работает. Одиночную отправку тоже не производит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deni 6 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба В F4 DMA контроллер работает несколько отлично от того же F1. Если источник 8 бит, а назначение 16 бит, то из памяти будет два чтения и одна запись. При этом первый байт попадет в младшие [7..0] бит SPI, а второй в старшие [15..8], при этом передач должно быть кратно 2. Но насколько я понимаю хотелось не этого, нужно изменить размер назначения в 8 bit. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Поменял. На ситуацию не повлияло Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deni 6 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Возможно не стоит настройки последовательно записывать в регистр CR, а сформировать в переменной и разом записать значение CR. А что показывает отладчик, что в итоге попало в регистры DMA контроллера? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба В своих исходниках вижу установленный в 1 бит SPI->CR2.SSOE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба 4 часа назад, Reystlin сказал: SPI3->CR2 = SPI_CR2_TXDMAEN; // Отправка через DMA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Желательно использовать макрос _VAL2FLD(field, value) для заполнения полей регистра, он позволяет избежать ошибки переполнения. DMA кроме номера потока (в названии), имеет номер канала - по которому принимает управление на запись/чтение CHSEL[3:0]. Информация о каналах DMA находится Reference manual для вашего мк. Регистр DMAx_Streamx->CR имеет 19 обязательных полей для заполнения, буквально 19 строк. Каждый раз печатать одинаковые буквы весьма утомительно, одинаковые буквы для любого дма. Проще один раз напечатать запись в переменную всех обязательных полей, и при copy/paste - удалять ненужное в данный момент. Удалять проще чем печатать заново. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба 13 минут назад, AVI-crak сказал: Желательно использовать макрос _VAL2FLD(field, value) для заполнения полей регистра, он позволяет избежать ошибки переполнения. DMA кроме номера потока (в названии), имеет номер канала - по которому принимает управление на запись/чтение CHSEL[3:0]. Информация о каналах DMA находится Reference manual для вашего мк. Регистр DMAx_Streamx->CR имеет 19 обязательных полей для заполнения, буквально 19 строк. Каждый раз печатать одинаковые буквы весьма утомительно, одинаковые буквы для любого дма. Проще один раз напечатать запись в переменную всех обязательных полей, и при copy/paste - удалять ненужное в данный момент. Удалять проще чем печатать заново. Канал 0 какие я регистры не заполнил из обязательных? 19 минут назад, Сергей Борщ сказал: уже исправлено SPI3->CR1 = 0<<SPI_CR1_DFF_Pos //Размер кадра 8 бит | 0<<SPI_CR1_LSBFIRST_Pos //MSB first | 1<<SPI_CR1_SSM_Pos //Программное управление SS | 1<<SPI_CR1_SSI_Pos //SS в высоком состоянии | 0x04<<SPI_CR1_BR_Pos //Скорость передачи: F_PCLK/32 | 1<<SPI_CR1_MSTR_Pos //Режим Master (ведущий) | 0<<SPI_CR1_CPOL_Pos | 0<<SPI_CR1_CPHA_Pos; //Режим работы SPI: 0 SPI3->CR2 |= 1<<SPI_CR2_TXDMAEN_Pos; SPI3->CR2 |= 1<<SPI_CR2_SSOE_Pos; SPI3->CR2 |= 1<<SPI_CR2_RXDMAEN_Pos; SPI3->CR1 |= 1<<SPI_CR1_SPE_Pos; //Включаем SPI volatile uint8_t data[3] = {1,2,3}; SPI3_Send(data,3); Спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба Инициализация DMA сейчас выглядит вот так //DMA1 Stream 7 SPI3_TX channel 0 DMA1_Stream7->CR = 0; DMA1_Stream7->PAR = (uint32_t)(&SPI3->DR); DMA1_Stream7->M0AR = (uint32_t)data; DMA1_Stream7->NDTR = len; DMA1_Stream7->FCR = 0; // Настройка FIFO буфера DMA1_Stream7->CR = (0x00) << DMA_SxCR_CHSEL_Pos // Выбор канала |(0x00) << DMA_SxCR_MBURST_Pos // |(0x00) << DMA_SxCR_PBURST_Pos // |0 << DMA_SxCR_CT_Pos // Текущий буфер |0 << DMA_SxCR_DBM_Pos // Двойной буфер |(0x03) << DMA_SxCR_PL_Pos // Приоритет |0 << DMA_SxCR_PINCOS_Pos // Инкремент адреса периферии |(0x00) << DMA_SxCR_MSIZE_Pos // Размер данных в памяти 8 бит |(0x00) << DMA_SxCR_PSIZE_Pos // Размер данных в периферии 8 бит |1 << DMA_SxCR_MINC_Pos // Инкремент адреса памяти |0 << DMA_SxCR_PINC_Pos // Инкремент адреса периферии |0 << DMA_SxCR_CIRC_Pos // Циркуляционный режим |(0x01) << DMA_SxCR_DIR_Pos // Направление данных из памяти в периферию |0 << DMA_SxCR_PFCTRL_Pos // DMA управляет процессом |0 << DMA_SxCR_TCIE_Pos // Прерывание по окончанию передачи |0 << DMA_SxCR_HTIE_Pos // Прерывание по половине передачи |0 << DMA_SxCR_TEIE_Pos // Прерывание по ошибке передачи |0 << DMA_SxCR_DMEIE_Pos // Прерывание по |1 << DMA_SxCR_EN_Pos; // Активация DMA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 177 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба О чем вообще тема, если автор даже вопроса никакого не задал? Нам что, гадать, отправляет МК какой-то мусор, вообще ничего не отправляет, или что? Пока что я вижу открытые окна отладчика, кои открытыми быть не должны при штатной работе DMA и SPI. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reystlin 0 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба SPI вообще ничего не отправляет, если отправку делаю через DMA. ни один из выводов SPI не дергается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 51 30 октября, 2022 Опубликовано 30 октября, 2022 · Жалоба То есть пример SPI_FullDuplex_ComDMA This example shows how to perform SPI data buffer ransmission/reception between two boards via DMA. работает, а Ваш код не работает ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться