MasterElectric 0 21 июля, 2018 Опубликовано 21 июля, 2018 (изменено) · Жалоба В общем не получилось побороть SPI, когда количество кадров данных >1 в одном пакете. Ладно все-равно цель чтобы это все работало в связке с DMA. Буду разбираться и прикручивать теперь DMA. Изменено 21 июля, 2018 пользователем MasterElectric Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 21 июля, 2018 Опубликовано 21 июля, 2018 · Жалоба Я кое-как скрутил отправку одного байта ... SPI дисплей (без ноги MISO) вроде задышал. На каких-то странных костылях... Сейчас попробую BME280 прикрутить.. Там обмен двунаправленный. PS. Первые впечатления - хрень полная и тихий ужас .... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 21 июля, 2018 Опубликовано 21 июля, 2018 · Жалоба Почему одного байта? Я пакеты нормально слал. Да не хрень, просто сложно по сравнению со старыми версиями периферии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 21 июля, 2018 Опубликовано 21 июля, 2018 · Жалоба Да нормально все работет... перепишите АККУРАТНО из моего проекта по смыслу обмен. И DMA и программный обмен... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 21 июля, 2018 Опубликовано 21 июля, 2018 · Жалоба О вы уже успели и ДМА изучить... это олично... намекните кде конкрентее рыть в вашем коде Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 21 июля, 2018 Опубликовано 21 июля, 2018 (изменено) · Жалоба Файл hardware.c hardware_spi_master_initialize hardware_spi_master_setfreq hardware_spi_connect hardware_spi_b8_p1, hardware_spi_b8_p2, hardware_spi_complete_b8 hardware_spi_master_send_frame hardware_spi_master_read_frame (на H7 не тестировал) hardware_spi_disconnect Так же оттестирована 16-битная группа функций обмена (кроме чтения по DMA) - hardware_spi_connect_b16 и остальные. А DMA в обе стороны с I2S и SAI оттестировано - файл hardwarecodecs.c Подключение тактирования у источникам клока это не в этих функциях, но об этом уже тут говорили. // RCC Domain 1 Kernel Clock Configuration Register // Set per_ck clock output RCC->D1CCIPR = (RCC->D1CCIPR & ~ (RCC_D1CCIPR_CKPERSEL)) | 0 * RCC_D1CCIPR_CKPERSEL_0 | // 00: hsi_ker_ck clock selected as per_ck clock (default after reset) - 64 MHz - used as PER_CK_FREQ 0; // RCC Domain 2 Kernel Clock Configuration Register RCC->D2CCIP1R = (RCC->D2CCIP1R & ~ (RCC_D2CCIP1R_SPI123SEL | RCC_D2CCIP1R_SPI45SEL)) | 4 * RCC_D2CCIP1R_SPI123SEL_0 | // per_ck 3 * RCC_D2CCIP1R_SPI45SEL_0 | // 011: hsi_ker_ck clock is selected as kernel clock 0; Проект делался в том числе для вот этой платы - https://electronix.ru/forum/index.php?act=a...t&id=113464. Изменено 21 июля, 2018 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 21 июля, 2018 Опубликовано 21 июля, 2018 · Жалоба Genadi Zawidowski Спасибо, буду изучать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 22 июля, 2018 Опубликовано 22 июля, 2018 · Жалоба Почему одного байта? Я пакеты нормально слал. Да не хрень, просто сложно по сравнению со старыми версиями периферии. Я просто постепенно делаю. Для простой инициализации дисплея и рисования точек и по одному достаточно. Попробую блоками картинки в дисплей кидать. Ещё напоролся на какой-то странный баг: я работаю в Atollic TrueStudio, когда использовал код MasterElectric while ( SPI_PORT->SR & SPI_SR_RXP != 0 ) { if ( RxBuffPos < TransLength ) { RxBuff[RxBuffPos++] = *(volatile uint8_t *) &(SPI_PORT->RXDR); } // if else break; } // while В цикл вообще не заходило, естетвенно ничего не принимало, хотя под отладкой виден бит SR.RXP==1 и в RXDR правильное принятое значение. Соответственно всё последующее летит к такой-то матери. Переписал так: while ( 1 ) { uint32_t val; val = SPI_PORT->SR; val &= SPI_SR_RXP; if ( val != 0 ) { if ( RxBuffPos < TransLength ) { r_value = RxBuff[RxBuffPos++] = *(volatile uint8_t *) &(SPI_PORT->RXDR); } // if } // if else break; if ( RxBuffPos == TransLength ) break; } // while Те же яйца, вид сбоку. Но работает. Никто не натыкался? Оптимизацию проверял, там None (-O0). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 22 июля, 2018 Опубликовано 22 июля, 2018 (изменено) · Жалоба ( SPI_PORT->SR & SPI_SR_RXP != 0 ) Скобками обозначте нужную Вам последовательность операций. Вот так: ((SPI_PORT->SR & SPI_SR_RXP) != 0) Изменено 22 июля, 2018 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 22 июля, 2018 Опубликовано 22 июля, 2018 · Жалоба Genadi Zawidowski , да, чёт я тупанул, спасибо, помогло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 22 июля, 2018 Опубликовано 22 июля, 2018 · Жалоба Ситуация с передачей через ДМА совсем отвратительная. Пробовал 2 варианта первый вариант: когда числом передаваймых байт управляет модуль ДМА т.е. кол-во записываеться в NDTR модуля ДМА, так и в SPI->CR2. В итоге когда число передаваемых байт больше буфера SPI (16 байт) - передает нормально первые 16 байт и все ждет чего-то при этом ДМА стрим вываливает флаг ошибки. И второй вариант когда число передаваемых байт управляет перефирийное устройство (бит PFCTRL в регистре CR ДМА стрим установлен), так передает например все 19 байт, при этом после 16 пошел мусор, и в конце вываливает ошибку передачи (FEIFx: Stream x FIFO error interrupt flag) + к этому в NDTR (0xFFFF - NDTR) переваливает за 1500. В эррате тишина по этому направлению, значит косячу я. У кого есть положительный опыт, поделитесь кодом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 22 июля, 2018 Опубликовано 22 июля, 2018 · Жалоба поделитесь кодом А чем мой не устраивает-то? SPI по DMA передает нормально... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 22 июля, 2018 Опубликовано 22 июля, 2018 (изменено) · Жалоба Я смотрел Ваш код (частично взял оттуда), вроде бы все как обычно. Мой почти такой же. Если есть возможность попробуйте передать пакет > 16 байт. Мой код: // RCC->D2CCIP1R = RCC_D2CCIP1R_SPI123SEL_2; // kernel clock выбираем per_ck RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; RCC->AHB2ENR |= RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN; // разрешили тактирование GPIO на котором висит SPI RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // включаем тактирование модуля SPI_NRF = new TSPI(); SPI_NRF->SPI = SPI1; // конфигурируем SPI1 SPI_NRF->SPI->CFG1 = SPI_CFG1_MBR_0 | SPI_CFG1_MBR_2 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_2; SPI_NRF->SPI->CFG2 = SPI_CFG2_SSOE | SPI_CFG2_MASTER | SPI_CFG2_AFCNTR; SPI_NRF->SPI->CR1 |= SPI_CR1_SPE; // настраиваем ДМА на передачу SPI1 DMAMUX1_Channel11->CCR = 38 * DMAMUX_CxCR_DMAREQ_ID_0; // SPI1_TX DMA2_Stream3->PAR = (uint32_t)&SPI_NRF->SPI->TXDR; DMA2_Stream3->FCR &= ~ DMA_SxFCR_DMDIS; // use direct mode DMA2_Stream3->CR = DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL; NVIC_EnableIRQ(SPI1_IRQn); // передаем a = 10; SPI_NRF->SendBuff_DMA(SPI1_TxBuff, SPI1_RxBuff, a); функция передачи: void TSPI::SendBuff_DMA(uint8_t *aTxBuff, uint8_t *aRxBuff, uint16_t aCnt) { DMA2_Stream3->CR &= ~(DMA_SxCR_EN); RxBuffPos = 0; TxBuffPos = 0; RxBuff = aRxBuff; TxBuff = aTxBuff; TransLength = aCnt; SPI->CR2 = aCnt; SPI->CFG1 |= SPI_CFG1_TXDMAEN; DMA2->LIFCR = DMA_LIFCR_CFEIF3 | DMA_LIFCR_CDMEIF3 | DMA_LIFCR_CTEIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CTCIF3; DMA2_Stream3->M0AR = (uint32_t)aTxBuff; DMA2_Stream3->CR |= DMA_SxCR_EN; SPI->CR1 |= SPI_CR1_CSTART; SPI->IER |= SPI_IER_EOTIE | SPI_IER_RXPIE; } Genadi Zawidowski, с пакетом < 16 байт передает нормально, хоть у канала ДМА ошибка. Но если пакеты при работе с неким устройством меньше 16 байт, то смысла в ДМА нет вовсе. А вот если > 16 байт, как я и писал передает 16 и процесс прекращаеться, когда ДМА рулит SPI передает напимер все 19 но после 16 байта мусор, во всех случаях у ДМА ошибка. Изменено 22 июля, 2018 пользователем MasterElectric Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 22 июля, 2018 Опубликовано 22 июля, 2018 · Жалоба Если есть возможность попробуйте передать пакет > 16 байт Все-таки у меня передается блоками большими чем 16 байт. ПОд рукой сейчас H7 нету. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 23 июля, 2018 Опубликовано 23 июля, 2018 · Жалоба Удалось побороть как всегда благодаря RM: When starting communication using DMA, to prevent DMA channel management raising error events, these steps must be followed in order: 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. Все нормально в двух режимах, когда DMA ведет SPI, и когда SPI ведет DMA, без ошибок и прочего, но... только 1 раз... второй пакет вообще не идет, совсем... нет запроса ДМА. Прием по прерыванию. Совсем не ожидал что столь незначительная разница в инициализации дала такой результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться