Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32F746][C/Atollic] SPI dziwne zachowanie

piti___ 04 Sty 2018 14:40 438 5
  • #1 04 Sty 2018 14:40
    piti___
    Poziom 23  

    Witam,

    Przenoszę duży projekt z LCP4357 na STM32F746. Przeniesione jest już 80% projektu i zatrzymałem się na komunikacji SPI z pamięcią FRAM FM25CL64.

    Inicjalizację pamięci FRAM objąłem pętlą while oczekującą na prawidłową wartość zwracaną przez funkcję. Inicjalizacja po zaprogramowaniu procesora lub odłączeniu zasilania wisi na pętli. Jeśli jednak po zaprogramowaniu zatrzymam gdzieś aplikację breakpointem wszystko rusza dalej i SPI odczytuje prawidłową wartość z pamięci. Na oscyloskopie przy błędnych wartościach odczytanych z pamięci wygląda to tak jakby był jakiś loopback MOSI/MISO na pamięci FRAM. Przy prawidłowej inicjalizacji (po breakpoincie) na oscyloskopie widzę to czego się spodziewałem tylko 0x00 i 0xAB. Próbowałem korzystać z funkcji HALa do odczytu zapisu ale jest to samo.

    Jeśli po takim breakpoincie puszcze aplikację dalej to wszystko jest OK. Reset z debuggera i dalej jest dobrze. Przestaje działać po odłączeniu zasilania lub po zaprogramowaniu procesora. Na breakpoincie analizowałem rejestry CR1 i CR2 są prawidłowo ustawione przez HALa.

    Już nie wiem co mam robić.

    Inicjalizacja SPI przez biblioteki HALa:

    Code:

    static void MX_SPI2_Init(void)
    {
       hspi2.Instance = SPI2;
       hspi2.Init.Mode = SPI_MODE_MASTER;
       hspi2.Init.Direction = SPI_DIRECTION_2LINES;
       hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
       hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
       hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
       hspi2.Init.NSS = SPI_NSS_SOFT;
       hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
       hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
       hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
       hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
       hspi2.Init.CRCPolynomial = 7;
       hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
       hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLED;
       if (HAL_SPI_Init(&hspi2) != HAL_OK)
       {
          Error_Handler();
       }
    }


    Transmisja/odbiór
    Code:
    static u8 fram_spi(u8 data)
    
    {
       *(__IO uint8_t *)&SPI2->DR = data;
       while(!(SPI2->SR & SPI_SR_RXNE));
       return *(__IO uint8_t *)&SPI2->DR;
    }


    Sprawdzenie obecności pamięci FRAM to odczyt pierwszego bajtu z pamieci zapis 0xAB odczyt i przywrócenie pierwszego bajtu z pamięci. Funkcje fram działają w wielu projektach.
    Code:
    s32 init_fram(void)
    
    {
       static u8 tmp1,tmp2;

       static u8 status;

       GPIO_InitTypeDef GPIO_InitStruct;

       GPIO_InitStruct.Pin = GPIO_PIN_0;
       GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
       GPIO_InitStruct.Pull = GPIO_NOPULL;
       GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
       HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);


       SET_BIT(SPI2->CR2, SPI_RXFIFO_THRESHOLD);
       SPI2->CR1 |= SPI_CR1_SPE;

       FRAM_CS_OFF;

       tmp1 = fram_read_byte(0);
       fram_write_byte(0,0xAB);
       tmp2 = fram_read_byte(0);
       fram_write_byte(0,tmp1);

       if(tmp2 == 0xAB)
          return 0;
       else
          return -1;
    }

    0 5
  • #2 04 Sty 2018 15:38
    Freddie Chopin
    Specjalista - Mikrokontrolery

    1. Gdy wystąpi problem, sprawdź profilaktycznie wszystkie bity statusowe SPI.
    2. Może to po prostu kwestia jakiegoś delaya po uruchomieniu urządzenia, który pozwoli na ustabilizowanie napięć? Dla testów dodał bym delay przed jakimkolwiek kodem w main i/lub delay po przestawieniu CSa dla pamięci.

    No chyba że po prostu nie włączyłeś GPIO i SPI w RCC? Nie widać też konfiguracji GPIO dla SPI.

    0
  • #3 04 Sty 2018 17:57
    2675900
    Użytkownik usunął konto  
  • #4 04 Sty 2018 19:21
    .Wiśnia
    Poziom 28  

    Sprawdzić czy SPI jest już wolne od nadawania lub zapisu bo FRAM np :

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 04 Sty 2018 21:15
    Freddie Chopin
    Specjalista - Mikrokontrolery

    .Wiśnia napisał:
    Sprawdzić czy SPI jest już wolne od nadawania lub zapisu bo FRAM np :

    Ciekawe po co, skoro funkcja fram_spi() już to robi?

    0
  • #6 05 Sty 2018 08:08
    piti___
    Poziom 23  

    Dzięki za podpowiedzi. Temat do zamknięcia. Nie wziąłem pod uwagę, że na tym samym SPI siedzi scalak do RFID i jest inicjalizowany po pamięci FRAM. Niestety zawsze ustawiam piny dla każdego z peryferiów indywidualnie i CS dla RFID wisiał w powietrzu. Wszystko już działa.

    0