Strona 1 z 1

STM32L432 problem z SPI

: wtorek 01 maja 2018, 10:57
autor: StaryAnoda_NEW
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ź :)

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:20
autor: Antystatyczny
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.

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:21
autor: StaryAnoda_NEW
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;

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:23
autor: Antystatyczny
Proponuję tak:

Kod: Zaznacz cały

SPI1->DR = (uint8_t) 0xF0;

Powinno wystarczyć...

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:28
autor: StaryAnoda_NEW
Właśnie nie w takim przypadku mam dalej format 16 bitowy :)

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:31
autor: Antystatyczny
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.

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:54
autor: dambo
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.

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 11:56
autor: Antystatyczny
Zbychu niedawno miał przypadek zoptymalizowania machnięcia pinem w testowym kodzie, dlatego tutaj o tym wspominam.

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 12:30
autor: ZbeeGin
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.

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 14:52
autor: StaryAnoda_NEW
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

Re: STM32L432 problem z SPI

: wtorek 01 maja 2018, 15:01
autor: ZbeeGin
Zostaw te bity BIDIxxxx w spokoju.