STM32L432 problem z SPI

Tu możesz pisać o swoich problemach z pisaniem programów w języku C/C++ dla STM.
Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

STM32L432 problem z SPI

Postautor: StaryAnoda_NEW » wtorek 01 maja 2018, 10:57

Hej

Staram się uruchomić SPI na mikrokontrolerze STM32L432. Wszystko działa jednak SPI wysyła 16 bitowe ramki, a nie 8 bitowe tak jakbym sobie ja życzył. Czy może ktoś mi podpowiedzieć co robię źle ? Podglądając rejestry przy użyciu debugera w rejestrze CR2 jest ustawiona długość na 8 bitów.

Kod: Zaznacz cały

#include <stm32l432xx.h>
#include <stdbool.h>
#include <stdlib.h>


#define CS_HIGH (GPIOB -> BSRR = GPIO_BSRR_BS0)
#define CS_LOW (GPIOB -> BSRR = GPIO_BSRR_BR0)


int main(void)
{
   RCC -> AHB2ENR |=  RCC_AHB2ENR_GPIOBEN | RCC_AHB2ENR_GPIOAEN;
   RCC -> APB2ENR |= RCC_APB2ENR_SPI1EN;

   __DSB();

   GPIOB -> MODER &= ~GPIO_MODER_MODE0_1; // CS
   CS_HIGH;
                     // MOSI                            SCK
   GPIOA -> MODER  &= ~(GPIO_MODER_MODE1_0 | GPIO_MODER_MODE7_0);

   GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL7_0 | GPIO_AFRL_AFSEL7_2;
   GPIOA -> AFR[0] |= GPIO_AFRL_AFSEL1_0 | GPIO_AFRL_AFSEL1_2;

   SPI1 -> CR1 =  SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | SPI_CR1_BR_1 | SPI_CR1_MSTR       |SPI_CR1_CPOL | SPI_CR1_CPHA;
   SPI1 -> CR2 =  SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;


   while(true)
   {
      CS_LOW;
      SPI1->DR = 0x0F;
      while(!(SPI1->SR & SPI_SR_TXE));
      while(SPI1->SR & SPI_SR_BSY);
      CS_HIGH;
   }
   return EXIT_SUCCESS;
}


Pozdrawiam i dzięki za każdą podpowiedź :)

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: STM32L432 problem z SPI

Postautor: Antystatyczny » wtorek 01 maja 2018, 11:20

A masz wyłączoną optymalizację? W powyższym kodzie masz podniesienie pinu SS, a następnie opuszczenie pinu SS. Często kompilator uznaje takie działanie za zbędne i je usuwa (pozostawia jedynie opuszczenie pinu SS). Sama konfiguracja na razie wydaje mi się poprawna, ale cały czas sprawdzam bit po bicie, czy coś nie zostało przeoczone.

PS. Jeśli nie chcesz wyłączać optymalizacji, dorzuć globalną zmienną volatile i inkrementuj ją pomiędzy instrukcjami CS_HIGH i CS_LOW.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

Re: STM32L432 problem z SPI

Postautor: StaryAnoda_NEW » wtorek 01 maja 2018, 11:21

Ok problem rozwiązany to znaczy działa, ale tak jakby nie wiem dlaczego. W F103 i F429 nigdy nie dokonywałem takiej modyfikacji:
Optymalizacja wyłączona.

Kod: Zaznacz cały

*(volatile uint8_t*)&SPI1->DR = 0xF0;
Ostatnio zmieniony wtorek 01 maja 2018, 11:23 przez StaryAnoda_NEW, łącznie zmieniany 1 raz.

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: STM32L432 problem z SPI

Postautor: Antystatyczny » wtorek 01 maja 2018, 11:23

Proponuję tak:

Kod: Zaznacz cały

SPI1->DR = (uint8_t) 0xF0;

Powinno wystarczyć...
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

Re: STM32L432 problem z SPI

Postautor: StaryAnoda_NEW » wtorek 01 maja 2018, 11:28

Właśnie nie w takim przypadku mam dalej format 16 bitowy :)

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: STM32L432 problem z SPI

Postautor: Antystatyczny » wtorek 01 maja 2018, 11:31

Aha, czyli nadal odwołuje się do całego rejestru mimo wyraźnego wskazania, że ma literał traktować jako 8 bitów. Trzeba będzie dokładniej zbadać ten przypadek.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: STM32L432 problem z SPI

Postautor: dambo » wtorek 01 maja 2018, 11:54

Ja zawsze używam takiego wpisania do SPI, żeby władować mu 8 bitów:

Kod: Zaznacz cały

*(uint8_t *)&ILI9341_SPI->DR = (uint8_t)data;


A co do optymalizacji z CS - chyba nigdy się z tym nie spotkałem - nie powinno to być w jakikolwiek sposób ruszone, bo rejestry GPIO są jako volatile (tzn jako __IO -> czyli volatile). Tak samo - gdy ważna jest jakaś kolejność ustawiania flag w rejestrze np uartu to kompilator też nie może nam namieszać i zrobić kilku ustawień i uruchomienia jednocześnie w jednym wpisaniu.
Ostatnio zmieniony wtorek 01 maja 2018, 11:56 przez dambo, łącznie zmieniany 1 raz.
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: STM32L432 problem z SPI

Postautor: Antystatyczny » wtorek 01 maja 2018, 11:56

Zbychu niedawno miał przypadek zoptymalizowania machnięcia pinem w testowym kodzie, dlatego tutaj o tym wspominam.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Re: STM32L432 problem z SPI

Postautor: ZbeeGin » wtorek 01 maja 2018, 12:30

Antystatyczny pisze:Zbychu niedawno miał przypadek zoptymalizowania machnięcia pinem w testowym kodzie, dlatego tutaj o tym wspominam.

U mnie to był mój błąd, bo powrót CS był robiony po return() co nie miało przecież prawa działać.

StaryAnoda_NEW pisze:Staram się uruchomić SPI na mikrokontrolerze STM32L432. Wszystko działa jednak SPI wysyła 16 bitowe ramki, a nie 8 bitowe tak jakbym sobie ja życzył. Czy może ktoś mi podpowiedzieć co robię źle ?

Zacznijmy może od tego, jaką chcesz transmisję zrealizować, po ilu przewodach i konkretnie z czym po drugiej stronie? W kodzie widzę, że włączasz BIDIMODE, co powoduje, że transmisja w obie strony odbywa się jednym przewodem MOSI<->MISO i jest to transmisja half-duplex. Podejrzewam, że nie tego chciałeś, lecz zwykłej transmisji w trybie full-duplex, gdzie jako master nadajesz 8 bitów ale nie oczekujesz niczego w zamian. W takim wypadku myślę, że Twoja bieżąca konfiguracja jest błędna, i daje takie efekty przez ustawienie BIDIMODE.

Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

Re: STM32L432 problem z SPI

Postautor: StaryAnoda_NEW » wtorek 01 maja 2018, 14:52

Ok tutaj masz rację nie do końca powiedziałem jaki typ transmisji chcę zaprojektować. Chodzi mi o transmisję typu SIMPEX do wyświetlacza.
Czy teraz jest poprawnie ?

Kod: Zaznacz cały

SPI1 -> CR1 = SPI_CR1_BIDIOE | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | SPI_CR1_MSTR | SPI_CR1_CPOL | SPI_CR1_CPHA;
SPI1 -> CR2 = SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;


Pozdrawiam

Awatar użytkownika
ZbeeGin
User
User
Posty: 492
Rejestracja: sobota 08 lip 2017, 17:16
Lokalizacja: Śląsko-Zagłębiowska Metropolia
Kontaktowanie:

Re: STM32L432 problem z SPI

Postautor: ZbeeGin » wtorek 01 maja 2018, 15:01

Zostaw te bity BIDIxxxx w spokoju.


Wróć do „Programowanie STM w C/C++”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 5 gości