реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Какая то странность с SPI4 в stm32f429zi
Alex_Golubev
сообщение Jun 27 2018, 04:34
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 221
Регистрация: 18-03-17
Пользователь №: 95 877



Привет.

Создал проект для начало в кубе. И увидал странность.
Зависает 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 */
}


Сообщение отредактировал Alex_Golubev - Jun 27 2018, 05:14
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
golf2109
сообщение Jun 29 2018, 02:46
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 15-04-10
Из: Kiev
Пользователь №: 56 654



я как то боролся с 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)wink.gif
что приводит к невозможности установки бита 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);
то все работает нормально.
Go to the top of the page
 
+Quote Post
Alex_Golubev
сообщение Jul 5 2018, 01:38
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 221
Регистрация: 18-03-17
Пользователь №: 95 877



Столкнулся с проблемой вылезает ошибка:
Код
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;
  }
  }
  }
  
}


Сообщение отредактировал Alex_Golubev - Jul 5 2018, 01:47
Go to the top of the page
 
+Quote Post
Alex_Golubev
сообщение Jul 12 2018, 03:26
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 221
Регистрация: 18-03-17
Пользователь №: 95 877



Можете мне объяснить.
При каких условиях появляться ошибка DMA_LISR_FEIF1, если в регистре FCR бит DMDIS установлен в нуль, то есть установлен direct mode ?
Порог FTH установлен в 1/4 от полного FIFO.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 12 2018, 06:55
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 568
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Для начала для сброса битов в LIFCR / HIFCR применяёте операцию присвоения, без считывания... Может все и образуется.

Вместо
DMA2->LIFCR |= DMA_LIFCR_CFEIF1;

в данном слчае надо
DMA2->LIFCR = DMA_LIFCR_CFEIF1;

Сообщение отредактировал Genadi Zawidowski - Jul 12 2018, 07:27
Go to the top of the page
 
+Quote Post
Alex_Golubev
сообщение Jul 12 2018, 07:42
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 221
Регистрация: 18-03-17
Пользователь №: 95 877



Цитата
Вместо
DMA2->LIFCR |= DMA_LIFCR_CFEIF1;

в данном слчае надо
DMA2->LIFCR = DMA_LIFCR_CFEIF1;

У меня так и сделано.
CODE

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;
}

}

Но ошибка все равно вываливается.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 12 2018, 09:38
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 568
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Если FIFO выключен, может наплевать на этц ошибку?
Цитата
У меня так и сделано.

В первом примере кода было неправильно.
Go to the top of the page
 
+Quote Post
Alex_Golubev
сообщение Jul 12 2018, 10:02
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 221
Регистрация: 18-03-17
Пользователь №: 95 877



Цитата
Если FIFO выключен, может наплевать на этц ошибку?
Это можно сделать, но нужно понять от куда она. Дыма без огня не бывает.
Цитата
В первом примере кода было неправильно.
Не смог отредактировать пример sad.gif.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2018 - 13:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01072 секунд с 7
ELECTRONIX ©2004-2016