sst78rus 0 27 ноября, 2019 Опубликовано 27 ноября, 2019 · Жалоба Добрый день. Осваиваю SPI на МК H743. Без использования DMA отправляю и получаю, все работает. Отправлять с DMA тоже получается, а вот с приемом какая-то странность. Отправляю устройству 7 байт при помощи DMA2_Stream6, получаю при помощи DMA2_Stream5. Инициализация DMA: RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // DMA2 clock enable; // Set the peripheral and memory addresses: DMA2_Stream6->PAR = (uint32_t) &(SPI1->TXDR); DMA2_Stream6->M0AR = (uint32_t )LIS3DH_CMD_LIST; DMA2_Stream6->CR = 0; DMA2_Stream6->CR |= (1u << DMA_SxCR_DIR_Pos)|\ DMA_SxCR_MINC; DMA2_Stream6->NDTR = sizeof(LIS3DH_CMD_LIST); //DMA transfer length DMAMUX1_Channel14->CCR = 38; //SPI1_TX DMA2_Stream5->PAR = (uint32_t) &(SPI1->RXDR); DMA2_Stream5->M0AR = (uint32_t )response; DMA2_Stream5->CR = 0; DMA2_Stream5->CR |= DMA_SxCR_MINC; DMA2_Stream5->NDTR = sizeof(LIS3DH_CMD_LIST); //DMA transfer length DMAMUX1_Channel13->CCR = 37; //SPI1_RX Память с которой работает DMA находится в D2, выравнивание на 4 сделано, тактирование SRAM2 включено. uint8_t RAM_D2 ALGN4 LIS3DH_CMD_LIST[] = {0xE8,0x0,0x0,0x0,0x0,0x0,0x0}; volatile uint8_t RAM_D2 ALGN4 response[sizeof(LIS3DH_CMD_LIST)]; В реф. мане описана процедура запуска передачи при помощи DMA, делаю как описано.: Спойлер 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CFG1 register, if DMA Rx is used. 2. Enable DMA requests for Tx and Rx in DMA registers, if the DMA is used. 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CFG1 register, if DMA Tx is used. 4. Enable the SPI by setting the SPE bit. - отключаю SPI для изменения CFG1 - Устанавливаю в CR2 количество байт в пакете, чтобы по окончанию поднялся CS - Включаю RXDMAEN (п.1) - Включаю DMA (п.2) - Включаю TXDMAEN (п.3) - Включаю SPI (п.4) В таком варианте передача не начинается, надо еще CSTART бит выставить. SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR2 = 7; SPI1->CFG1 |= SPI_CFG1_RXDMAEN; //RX DMA2_Stream5 -> CR |= DMA_SxCR_EN; //TX DMA2_Stream6 -> CR |= DMA_SxCR_EN; SPI1->CFG1 |= SPI_CFG1_TXDMAEN; SPI1->CR1 |= SPI_CR1_SPE; SPI1->CR1 |= SPI_CR1_CSTART; Результат проверяю по флагам DMA шагая в отладчике и в логическом анализаторе. После включения SPI1->CR1 |= SPI_CR1_SPE устанавливаются флаги: TCIF6, HTIF6 (dma передачи) и это вроде понятно. А так же флаги TCIF5 и HTIF5 (dma приема) и это совсем не понятно. Физической передачи при этом не происходит. С передачей, как я понимаю, DMA отправляет все в FIFO SPI и поэтому выставляет флаги окончания. После выставления флага CSTART происходит реальная передача в шину. Я в лог. анализаторе вижу именно то, что и ожидаю. А вот с флагами DMA на прием я не понимаю, почему после включения SPI_CR1_SPE DMA выставляет флаги окончания, если ничего еще не было передано. И выглядит все так, как-будто передача действительно была, NDTR становится в 0. Но реальной передачи еще не было и флаг RXP в SPI не поднимался. Реальная передача, после выставления CSTART уже естественно ничего не меняет в приемном DMA. А в регистрах SPI я как раз вижу, что после передачи принятые данные остались в FIFO, стоит RXP. Что я делаю не правильно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 27 ноября, 2019 Опубликовано 27 ноября, 2019 · Жалоба Не работал с H7, но правильно ли выставлен источник событий для DMA2_Stream5? Может какая-то другая периферия вместо SPI заставляет DMA2_Stream5 делать пересылку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 27 ноября, 2019 Опубликовано 27 ноября, 2019 · Жалоба Это устанавливается при помощи DMAMUX. DMAMUX1_Channel13->CCR = 37; //SPI1_RX Каналы DMAMUX связаны с каналами DMA. Связь там вот такая: DMAMUX1 channels 0 to 7 are connected to DMA1 channels 0 to 7 DMAMUX1 channels 8 to 15 are connected to DMA2 channels 0 to 7 DMAMUX2 channels 0 to 7 are connected to BDMA channels 0 to 7 Или проще говоря: DMA1_Stream_x -> DMAMUX1_Channel_x DMA2_Stream_x -> DMAMUX1_Channel_(x+8) А к чему конкретно из периферии будет подключен канал DMA устанавливается в CCR регистре DMAMUX. Для каждого источника свой номер, они в RM указаны. Для DMAMUX1 в моем случае это: 37 spi1_rx_dma 38 spi1_tx_dma Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sst78rus 0 28 ноября, 2019 Опубликовано 28 ноября, 2019 · Жалоба Похоже что эта проблема описана в Errata. По описанию я сразу не признал "Spurious DMA Rx transaction after simplex Tx traffic" Решение - сброс SPI перед включением DMA на прием. Сброс через SPE бит не помогает, делаю RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; __NOP(); RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; После этого, естественно, надо снова инициализировать SPI. В новых ревизиях вроде бы поправили. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 16 января, 2021 Опубликовано 16 января, 2021 · Жалоба Я могу попросить показать инициализацию SPI? Все сделал по инструкции, но не работает. Опытным путем определил, что пины спиаем не управляются. Пины рабочие, простым дерганием меандр получаю. Хочу узнать что не так делаю. Кстати куб тоже не дает результата. Что вручную, что кубом, все одно и тоже. Не работает. Подскажите, что я не учел? Может в коде увижу. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 16 января, 2021 Опубликовано 16 января, 2021 (изменено) · Жалоба // Настроим модуль SPI. RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // подать тактирование (void) RCC->APB2ENR; //SPI1->CR1 = 0x0000; //очистить первый управляющий регистр //SPI1->CR2 = 0x0000; #if WITHSPIHWDMA DMA2_SPI1_TX_initialize(); DMA2_SPI1_RX_initialize(); #endif /* WITHSPIHWDMA */ /* настраиваем в режиме disconnect */ SPIIO_INITIALIZE(); Подгттовка параметрв для разнфз режимов и скоростей: unsigned value; /* делителя нет, есть только прескалер - значение делителя не используется */ const uint_fast8_t prei = calcdivider(calcdivround_per_ck(spispeed), STM32F_SPIBR_WIDTH, STM32F_SPIBR_TAPS, & value, 1); const uint_fast32_t cfg1baudrate = (prei * SPI_CFG1_MBR_0) & SPI_CFG1_MBR_Msk; const uint_fast32_t cfg1 = cfg1baudrate;// | (SPI_CFG1_CRCSIZE_0 * 7); //PRINTF(PSTR("hardware_spi_master_setfreq: prei=%u, value=%u, spispeed=%u\n"), prei, value, spispeed); spi_cfg1_val8w [spispeedindex] = cfg1 | 7 * SPI_CFG1_DSIZE_0 | 0; spi_cfg1_val16w [spispeedindex] = cfg1 | 15 * SPI_CFG1_DSIZE_0 | 0; spi_cfg1_val32w [spispeedindex] = cfg1 | 31 * SPI_CFG1_DSIZE_0 | 0; const uint_fast32_t cfg2bits = SPI_CFG2_SSOM_Msk | SPI_CFG2_SSOE_Msk | SPI_CFG2_SSM_Msk | // 1: SS input value is determined by the SSI bit SPI_CFG2_MASTER_Msk | SPI_CFG2_AFCNTR_Msk | // 1: the peripheral keeps always control of all associated GPIOs 0; enum { CFG2_MODE0 = 0, // TODO: not tested CFG2_MODE1 = SPI_CFG2_CPHA_Msk, // TODO: not tested CFG2_MODE2 = SPI_CFG2_CPOL_Msk, // CLK leave HIGH CFG2_MODE3 = SPI_CFG2_CPOL_Msk | SPI_CFG2_CPHA_Msk // wrk = CLK leave "HIGH" }; // подготовка управляющих слов для разных spi mode, используемых контроллером. // 8-битная или 16-битная передача программируется в CR2 spi_cfg2_val [SPIC_MODE0] = cfg2bits | CFG2_MODE0; spi_cfg2_val [SPIC_MODE1] = cfg2bits | CFG2_MODE1; spi_cfg2_val [SPIC_MODE2] = cfg2bits | CFG2_MODE2; spi_cfg2_val [SPIC_MODE3] = cfg2bits | CFG2_MODE3; Передв 8-бит обменами: HARDWARE_SPI_CONNECT(); SPI1->CFG1 = spi_cfg1_val8w [spispeedindex]; SPI1->CFG2 = spi_cfg2_val [spimode]; SPI1->CR1 |= SPI_CR1_SSI; SPI1->CR1 |= SPI_CR1_SPE; SPI1->CR1 |= SPI_CR1_CSTART; Отключаемся: SPI1->CR1 |= SPI_CR1_CSUSP; while ((SPI1->CR1 & SPI_CR1_CSTART) != 0) ; SPI1->CR1 &= ~ SPI_CR1_SPE; // connect back to GPIO HARDWARE_SPI_DISCONNECT(); hftrx/hardware.c at master · ua1arn/hftrx (github.com) Изменено 16 января, 2021 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба А вот это как выглядит? HARDWARE_SPI_CONNECT(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба Это присоединение контроллера SPI к выводам проессора в соответствии с альтернативными функциями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба SPI похоже заработал. Инициализировал и гоняю 16 бит с проверкой флага TXC. Уходит. С ДМА не пробовал пока. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 18 января, 2021 Опубликовано 18 января, 2021 (изменено) · Жалоба А что было то? Если с программным опросом правильнее rxp ждать (и сбрасывать его чтением данных ). Опять же ждать эффективнее по скорости перед передачей не первый раз. Мне не интересно. Но кому-то может помочь. Изменено 18 января, 2021 пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smk 0 18 января, 2021 Опубликовано 18 января, 2021 · Жалоба Да так и не понял. Выкинул все и оставил в цикле запись на передачу по флагу завершения передачи. Все и заработало. Завтра выложу если интересно. Купился по сути на танцы куба и других примеров. Через некоторое время сделаю передачу-прием буферов. Пока другое надо подтянуть. Усарт кстати просто с ходу заработал. Там все просто. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 24 марта, 2021 Опубликовано 24 марта, 2021 · Жалоба smk а SPI заработал с ДМА? Какая у вас ревизия чипа? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Reflector 0 25 марта, 2021 Опубликовано 25 марта, 2021 (изменено) · Жалоба У меня и без DMA нормально не работает(H750 Rev. V)... Суть проблемы в следующем, допустим у SPI 16 байт FIFO, соединяем MISO с MOSI и отправляем 16 байт, без чтения, затем читаем все 16(они правильные), отправляем еще один байт и его принимаем, все работает. Но если отправить больше 16 байт, допустим 17, то устанавливает флаг OVR, в документации сказано, что в таком случае его нужно сбросить и вычитать FIFO, но если после этого отправить очередной байт, то он уходит, но ничего не принимается. После отправки следующего байта принимается уже он. Проблему решает отключение SPI, т.к. при этом происходит сброс машины состояний, но тогда дергается NSS и это не всегда приемлемо... Изменено 25 марта, 2021 пользователем Reflector Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andre22 0 5 июня, 2022 Опубликовано 5 июня, 2022 · Жалоба В 27.11.2019 в 14:46, sst78rus сказал: Добрый день. Осваиваю SPI на МК H743. Без использования DMA отправляю и получаю, все работает. Отправлять с DMA тоже получается, а вот с приемом какая-то странность. Отправляю устройству 7 байт при помощи DMA2_Stream6, получаю при помощи DMA2_Stream5. Инициализация DMA: RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; // DMA2 clock enable; // Set the peripheral and memory addresses: DMA2_Stream6->PAR = (uint32_t) &(SPI1->TXDR); DMA2_Stream6->M0AR = (uint32_t )LIS3DH_CMD_LIST; DMA2_Stream6->CR = 0; DMA2_Stream6->CR |= (1u << DMA_SxCR_DIR_Pos)|\ DMA_SxCR_MINC; DMA2_Stream6->NDTR = sizeof(LIS3DH_CMD_LIST); //DMA transfer length DMAMUX1_Channel14->CCR = 38; //SPI1_TX DMA2_Stream5->PAR = (uint32_t) &(SPI1->RXDR); DMA2_Stream5->M0AR = (uint32_t )response; DMA2_Stream5->CR = 0; DMA2_Stream5->CR |= DMA_SxCR_MINC; DMA2_Stream5->NDTR = sizeof(LIS3DH_CMD_LIST); //DMA transfer length DMAMUX1_Channel13->CCR = 37; //SPI1_RX Память с которой работает DMA находится в D2, выравнивание на 4 сделано, тактирование SRAM2 включено. uint8_t RAM_D2 ALGN4 LIS3DH_CMD_LIST[] = {0xE8,0x0,0x0,0x0,0x0,0x0,0x0}; volatile uint8_t RAM_D2 ALGN4 response[sizeof(LIS3DH_CMD_LIST)]; В реф. мане описана процедура запуска передачи при помощи DMA, делаю как описано.: Показать контент 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CFG1 register, if DMA Rx is used. 2. Enable DMA requests for Tx and Rx in DMA registers, if the DMA is used. 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CFG1 register, if DMA Tx is used. 4. Enable the SPI by setting the SPE bit. Что я делаю не правильно? Здравствуйте . Я раньше на стм32ф4 успешно сделал был вывод по SPI MOSI через DMA, когда завершалась передача ДМА я генерировал прерывание и переключал свободный пин светодиода - моргал светодиодом. Теперь решил тоже самое на STM32H743 сделать. Нашел пример куба для SPI_FullDuplex_ComDMA и по примеру него написал свой код, чтобы моргать светодиодом. Но почемуто не запускается у меня передача по ДМА и не заходит во внутрь функции прерываний. Вы можете мне показать свой код, как вы настраивали SPI DMA ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ivan_ivan 0 15 декабря, 2022 Опубликовано 15 декабря, 2022 (изменено) · Жалоба добрый всем, Может кто подскажет, перешол на stm32h7b0 добрый всем, Может кто подскажет, перешол на stm32h7b0 не могу не как разобратся с SPI такое чуства что карнел_клок не поступает. movw r0,#RCC_L movt r0,#RCC_H ldr r1,[r0,#RCC_CDCCIP1R_B] bic r1,#SPI123SEL_MASK orr r1,#SPI123SEL_PER ; str r1,[r0,#RCC_CDCCIP1R_B] ldr r1,[r0,#RCC_APB1LENR_B] orr r1,#SPI3 ;enable spi3 clk in str r1,[r0,#RCC_APB1LENR_B] movw r0,#SPI3_L movt r0,#SPI3_H mov32 r1,#(MBR_DIV2+0x7) ;clc/2 8bit lenght str r1,[r0,#SPI_CFG1_B] ;enable spi mov r1,#(MASTER|SSOE) ; str r1,[r0,#SPI_CFG2_B] ldr r1,[r0,#SPI_CR1_B] ;enable spi orr r1,#(SPE) str r1,[r0,#SPI_CR1_B] Модератор: если русский язык не Ваш родной, лучше укажите в профиле местоположение, в противном случае пишите грамотно. Иначе - это нарушение правил. Изменено 16 декабря, 2022 пользователем haker_fox Для оформления кода есть кнопка <>. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться