Alex_Golubev 0 27 июня, 2018 Опубликовано 27 июня, 2018 (изменено) · Жалоба Привет. Создал проект для начало в кубе. И увидал странность. Зависает SPI4 у меня, не сразу а через какое то время работы. Причем зависает а биты ошибок не ставит. Примерно на пол пути передачи ставит бит RXNE в единицу и молчит. Если в ручною сбросить его то все дальше работает. Потом проходит какое то время и снова бит RXNE в единице. Такое ощущение что не читается регистр SPI_DR. В счетчики DMA_SxNDTR остается число, каждый раз разное. Бит OVR не установлен. Ошибок от DMA нет. Проверял несколько раз. Вот скриншот всех основных битов. Видно бит RXNE в нуле. Значит данные из SPI не переданы в ОЗУ. DMA2 3 канал приемник 1 канал передатчик. Может кто подскажет в чем проблема ? Пытался выловить ошибки DMA: void DMA2_Stream1_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream1_IRQn 0 */ /* if(DMA2->LISR & DMA_LISR_TCIF1) { while(1); } */ if(DMA2->LISR & DMA_LISR_TEIF1) { while(1); } if(DMA2->LISR & DMA_LISR_DMEIF1) { while(1); } if(DMA2->LISR & DMA_LISR_FEIF1) { while(1); } /* USER CODE END DMA2_Stream1_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_spi4_tx); /* USER CODE BEGIN DMA2_Stream1_IRQn 1 */ /* USER CODE END DMA2_Stream1_IRQn 1 */ } Изменено 27 июня, 2018 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
golf2109 0 29 июня, 2018 Опубликовано 29 июня, 2018 · Жалоба я как то боролся с L0 серией, может поможет в файле stm32l0xx_hal_spi.c HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); в данной строке преждевременно запускается DMA (до подачи команды /* Enable SPI peripheral */ __HAL_SPI_ENABLE(hspi);) что приводит к невозможности установки бита SPE регистра CR1 SPI (подробности его установки описаны в datasheet). Если откорректировать stm32l0xx_hal_spi.c и перенести строку HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); после процедуры __HAL_SPI_ENABLE(hspi); то все работает нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 5 июля, 2018 Опубликовано 5 июля, 2018 (изменено) · Жалоба Столкнулся с проблемой вылезает ошибка: if(DMA2->LISR & DMA_LISR_FEIF1) //+ { DMA2->LIFCR |= DMA_LIFCR_CFEIF1; } [code]void start_TDC_7200 (void) { TDC720x_CS_ON; TDC7200.Register_Read_Write = 0xc0; TDC7200.CONFIG1 = TDC7200_CONFIG1; TDC7200.CONFIG2 = TDC7200_CONFIG2; TDC7200.INT_STATUS = TDC7200_INT_STATUS; TDC7200.INT_MASK = TDC7200_INT_MASK; TDC7200.COARSE_CNTR_OVF_H = TDC7200_COARSE_CNTR_OVF_H; TDC7200.COARSE_CNTR_OVF_L = TDC7200_COARSE_CNTR_OVF_L; TDC7200.CLOCK_CNTR_OVF_H = TDC7200_CLOCK_CNTR_OVF_H; TDC7200.CLOCK_CNTR_OVF_L = TDC7200_CLOCK_CNTR_OVF_L; TDC7200.CLOCK_CNTR_STOP_MASK_H = TDC7200_CLOCK_CNTR_STOP_MASK_H; TDC7200.CLOCK_CNTR_STOP_MASK_L = TDC7200_CLOCK_CNTR_STOP_MASK_L; DMA2_Stream1->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream1->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream1->M0AR = (unsigned long)&TDC7200; DMA2_Stream1->FCR = 0x00000000; DMA2_Stream1->FCR |= DMA_SxFCR_DMDIS; DMA2->LIFCR |= DMA_LIFCR_CTEIF1; DMA2->LIFCR |= DMA_LIFCR_CDMEIF1; DMA2->LIFCR |= DMA_LIFCR_CFEIF1; DMA2->LIFCR |= DMA_LIFCR_CTCIF1; DMA2_Stream1->CR = 0x00000000; DMA2_Stream1->CR |= DMA_CHANNEL_4; DMA2_Stream1->CR |= DMA_MEMORY_TO_PERIPH; DMA2_Stream1->CR |= DMA_PINC_DISABLE; DMA2_Stream1->CR |= DMA_MINC_ENABLE; DMA2_Stream1->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_NORMAL; DMA2_Stream1->CR |= DMA_PRIORITY_LOW; DMA2_Stream1->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream1->CR |= DMA_SxCR_TCIE; DMA2_Stream1->CR |= DMA_SxCR_EN; DMA2_Stream3->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream3->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream3->M0AR = (unsigned long)&TDC7200; DMA2_Stream3->FCR = 0x00000000; DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS; DMA2->LIFCR |= DMA_LIFCR_CTEIF3; DMA2->LIFCR |= DMA_LIFCR_CDMEIF3; DMA2->LIFCR |= DMA_LIFCR_CFEIF3; DMA2->LIFCR |= DMA_LIFCR_CTCIF3; DMA2_Stream3->CR = 0x00000000; DMA2_Stream3->CR |= DMA_CHANNEL_5; DMA2_Stream3->CR |= DMA_PERIPH_TO_MEMORY; DMA2_Stream3->CR |= DMA_PINC_DISABLE; DMA2_Stream3->CR |= DMA_MINC_ENABLE; DMA2_Stream3->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_NORMAL; DMA2_Stream3->CR |= DMA_PRIORITY_LOW; DMA2_Stream3->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream3->CR |= DMA_SxCR_TCIE; DMA2_Stream3->CR |= DMA_SxCR_EN; SPI4->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI4->CR1 |= SPI_CR1_SPE; } void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_13){ TDC720x_CS_ON; TDC7200.Register_Read_Write = 0x80; TDC7200.CONFIG1 = 0; TDC7200.CONFIG2 = 0; TDC7200.INT_STATUS = 0; TDC7200.INT_MASK = 0; TDC7200.COARSE_CNTR_OVF_H = 0; TDC7200.COARSE_CNTR_OVF_L = 0; TDC7200.CLOCK_CNTR_OVF_H = 0; TDC7200.CLOCK_CNTR_OVF_L = 0; TDC7200.CLOCK_CNTR_STOP_MASK_H = 0; TDC7200.CLOCK_CNTR_STOP_MASK_L = 0; DMA2_Stream1->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream1->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream1->M0AR = (unsigned long)&TDC7200; DMA2_Stream1->FCR = 0x00000000; DMA2_Stream1->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream1->CR = 0x00000000; DMA2_Stream1->CR |= DMA_CHANNEL_4; DMA2_Stream1->CR |= DMA_MEMORY_TO_PERIPH; DMA2_Stream1->CR |= DMA_PINC_DISABLE; DMA2_Stream1->CR |= DMA_MINC_ENABLE; DMA2_Stream1->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_NORMAL; DMA2_Stream1->CR |= DMA_PRIORITY_LOW; DMA2_Stream1->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream1->CR |= DMA_SxCR_TCIE; DMA2_Stream1->CR |= DMA_SxCR_EN; DMA2_Stream3->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream3->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream3->M0AR = (unsigned long)&TDC7200; DMA2_Stream3->FCR = 0x00000000; DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream3->CR = 0x00000000; DMA2_Stream3->CR |= DMA_CHANNEL_5; DMA2_Stream3->CR |= DMA_PERIPH_TO_MEMORY; DMA2_Stream3->CR |= DMA_PINC_DISABLE; DMA2_Stream3->CR |= DMA_MINC_ENABLE; DMA2_Stream3->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_NORMAL; DMA2_Stream3->CR |= DMA_PRIORITY_LOW; DMA2_Stream3->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream3->CR |= DMA_SxCR_TCIE; DMA2_Stream3->CR |= DMA_SxCR_EN; SPI4->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI4->CR1 |= SPI_CR1_SPE; INT_TDC7200 = 1; } } void DMA2_TDC7200(void) { static unsigned char i; while(!(SPI4->SR & SPI_SR_TXE)); while( SPI4->SR & SPI_SR_BSY); SPI4->CR1 &= ~SPI_CR1_SPE; TDC720x_CS_OFF; if(INT_TDC7200){ if(TDC7200.INT_STATUS & 0x6){ // если переполнение TDC7200 то просто херим измерение и запускаем заново TDC720x_CS_ON; TDC7200.Register_Read_Write = 0xc0; TDC7200.CONFIG1 = TDC7200_CONFIG1; TDC7200.CONFIG2 = TDC7200_CONFIG2; TDC7200.INT_STATUS = TDC7200_INT_STATUS; TDC7200.INT_MASK = TDC7200_INT_MASK; TDC7200.COARSE_CNTR_OVF_H = TDC7200_COARSE_CNTR_OVF_H; TDC7200.COARSE_CNTR_OVF_L = TDC7200_COARSE_CNTR_OVF_L; TDC7200.CLOCK_CNTR_OVF_H = TDC7200_CLOCK_CNTR_OVF_H; TDC7200.CLOCK_CNTR_OVF_L = TDC7200_CLOCK_CNTR_OVF_L; TDC7200.CLOCK_CNTR_STOP_MASK_H = TDC7200_CLOCK_CNTR_STOP_MASK_H; TDC7200.CLOCK_CNTR_STOP_MASK_L = TDC7200_CLOCK_CNTR_STOP_MASK_L; DMA2_Stream1->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream1->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream1->M0AR = (unsigned long)&TDC7200; DMA2_Stream1->FCR = 0x00000000; DMA2_Stream1->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream1->CR = 0x00000000; DMA2_Stream1->CR |= DMA_CHANNEL_4; DMA2_Stream1->CR |= DMA_MEMORY_TO_PERIPH; DMA2_Stream1->CR |= DMA_PINC_DISABLE; DMA2_Stream1->CR |= DMA_MINC_ENABLE; DMA2_Stream1->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_NORMAL; DMA2_Stream1->CR |= DMA_PRIORITY_LOW; DMA2_Stream1->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream1->CR |= DMA_SxCR_TCIE; DMA2_Stream1->CR |= DMA_SxCR_EN; DMA2_Stream3->NDTR = sizeof(TDC7200); // счетчик сколько передать данных DMA2_Stream3->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream3->M0AR = (unsigned long)&TDC7200; DMA2_Stream3->FCR = 0x00000000; DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream3->CR = 0x00000000; DMA2_Stream3->CR |= DMA_CHANNEL_5; DMA2_Stream3->CR |= DMA_PERIPH_TO_MEMORY; DMA2_Stream3->CR |= DMA_PINC_DISABLE; DMA2_Stream3->CR |= DMA_MINC_ENABLE; DMA2_Stream3->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_NORMAL; DMA2_Stream3->CR |= DMA_PRIORITY_LOW; DMA2_Stream3->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream3->CR |= DMA_SxCR_TCIE; DMA2_Stream3->CR |= DMA_SxCR_EN; SPI4->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI4->CR1 |= SPI_CR1_SPE; counter_not_sample +=1; // прибовляем один для ошибки нет пробы INT_TDC7200 = 0; } else{ if(i){ for(uint8_t j = 0; j<TDC7200_ALL_DATA_SIZE; j++){ all_tdc7200_data[j] = all_data[j+1]; } tdc7200_build_mreg(all_tdc7200_data); // сортируем данные TDC7200 ccnt = (float) (meas_result_regrs[12]-meas_result_regrs[11])/(CALIBRATION2_PERIODS-1); norm_lsb = tdc_clk_period / ccnt; startstop_tdc7200 = norm_lsb * ((float)meas_result_regrs[0] - (float)meas_result_regrs[2]) + tdc_clk_period * (float)(meas_result_regrs[1]>>0); //1 i = 0; INT_TDC7200 = 0; return; } if(TDC7200.INT_STATUS & 0x1){ counter_not_sample = 0; // обнуляем ошибку нет пробы считаем что произошол сбой TDC720x_CS_ON; all_data[0] = 0x90; DMA2_Stream1->NDTR = sizeof(all_data); // счетчик сколько передать данных DMA2_Stream1->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream1->M0AR = (unsigned long)&all_data; DMA2_Stream1->FCR = 0x00000000; DMA2_Stream1->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream1->CR = 0x00000000; DMA2_Stream1->CR |= DMA_CHANNEL_4; DMA2_Stream1->CR |= DMA_MEMORY_TO_PERIPH; DMA2_Stream1->CR |= DMA_PINC_DISABLE; DMA2_Stream1->CR |= DMA_MINC_ENABLE; DMA2_Stream1->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream1->CR |= DMA_NORMAL; DMA2_Stream1->CR |= DMA_PRIORITY_LOW; DMA2_Stream1->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream1->CR |= DMA_SxCR_TCIE; DMA2_Stream1->CR |= DMA_SxCR_EN; DMA2_Stream3->NDTR = sizeof(all_data); // счетчик сколько передать данных DMA2_Stream3->PAR = (uint32_t)(&(SPI4->DR)); DMA2_Stream3->M0AR = (unsigned long)&all_data; DMA2_Stream3->FCR = 0x00000000; DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS; DMA2_Stream3->CR = 0x00000000; DMA2_Stream3->CR |= DMA_CHANNEL_5; DMA2_Stream3->CR |= DMA_PERIPH_TO_MEMORY; DMA2_Stream3->CR |= DMA_PINC_DISABLE; DMA2_Stream3->CR |= DMA_MINC_ENABLE; DMA2_Stream3->CR |= DMA_PDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_MDATAALIGN_BYTE; DMA2_Stream3->CR |= DMA_NORMAL; DMA2_Stream3->CR |= DMA_PRIORITY_LOW; DMA2_Stream3->CR |= DMA_FIFOMODE_DISABLE; DMA2_Stream3->CR |= DMA_SxCR_TCIE; DMA2_Stream3->CR |= DMA_SxCR_EN; SPI4->CR2 |= SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI4->CR1 |= SPI_CR1_SPE; i = 1; } } } } [/code] Изменено 5 июля, 2018 пользователем Alex_Golubev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 июля, 2018 Опубликовано 12 июля, 2018 · Жалоба Можете мне объяснить. При каких условиях появляться ошибка DMA_LISR_FEIF1, если в регистре FCR бит DMDIS установлен в нуль, то есть установлен direct mode ? Порог FTH установлен в 1/4 от полного FIFO. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 июля, 2018 Опубликовано 12 июля, 2018 (изменено) · Жалоба Для начала для сброса битов в LIFCR / HIFCR применяёте операцию присвоения, без считывания... Может все и образуется. Вместо DMA2->LIFCR |= DMA_LIFCR_CFEIF1; в данном слчае надо DMA2->LIFCR = DMA_LIFCR_CFEIF1; Изменено 12 июля, 2018 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 июля, 2018 Опубликовано 12 июля, 2018 · Жалоба Вместо DMA2->LIFCR |= DMA_LIFCR_CFEIF1; в данном слчае надо DMA2->LIFCR = DMA_LIFCR_CFEIF1; У меня так и сделано. void DMA2_Stream1_IRQHandler(void) { if(DMA2->LISR & DMA_LISR_TEIF1) { DMA2->LIFCR = DMA_LIFCR_CTEIF1; while(1); } if(DMA2->LISR & DMA_LISR_DMEIF1) { DMA2->LIFCR = DMA_LIFCR_CDMEIF1; while(1); } if(DMA2->LISR & DMA_LISR_FEIF1) //+ { DMA2->LIFCR = DMA_LIFCR_CFEIF1; // while(1); } if(DMA2->LISR & DMA_LIFCR_CHTIF1) { DMA2->LIFCR = DMA_LIFCR_CHTIF1; } if(DMA2->LISR & DMA_LISR_TCIF1) { DMA2->LIFCR = DMA_LIFCR_CTCIF1; } } Но ошибка все равно вываливается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 июля, 2018 Опубликовано 12 июля, 2018 · Жалоба Если FIFO выключен, может наплевать на этц ошибку? У меня так и сделано. В первом примере кода было неправильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 12 июля, 2018 Опубликовано 12 июля, 2018 · Жалоба Если FIFO выключен, может наплевать на этц ошибку? Это можно сделать, но нужно понять от куда она. Дыма без огня не бывает. В первом примере кода было неправильно. Не смог отредактировать пример :(. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться