Skip to main content
jean_prieur
Associate III
December 19, 2013
Question

How to calculate and set the SPI speed ?

  • December 19, 2013
  • 16 replies
  • 8691 views
Posted on December 19, 2013 at 15:03

Hello everybody,

I communicate with a popular screen, the DOGM128 (ST7565RLCD Controller) with my STM32F4 uC. Sometimes, when I power on my board, the screen have troubles to be initialized (it remains white, whatever I do). I think it's due to the SPI speed, that I can't estimate. The max SPI clock speed of the screen controller is 20MHz. This is my SPI screen init :

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// CLOCK and MOSI Pins declaration
GPIO_InitStructure.GPIO_Pin = PIN_SCL|PIN_SI;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// CS pin
GPIO_InitStructure.GPIO_Pin = PIN_CS|PIN_A0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);

// SI & SCL = Alternate Functions
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); 

SPI_InitTypeDef SPI_InitStruct;
SPI_I2S_DeInit(SPI2);
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; 
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; 
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE);

With SPI_BaudRatePrescaler_2 : The screen works almost everytime

With SPI_BaudRatePrescaler_4 :

The screen works half the time

With SPI_BaudRatePrescaler_8 :

The screen never works

So how can I increase the SPI speed, in order to try to solve my problem ?
    This topic has been closed for replies.

    16 replies

    chen
    Associate II
    December 19, 2013
    Posted on December 19, 2013 at 15:53

    Hi

    I think you are jumping to the wrong conclusion - that the problem is the SPI speed.

    ''

    Sometimes, when I power on my board, the screen have troubles to be initialized

    ''

    ''

    The max SPI clock speed of the screen controller is 20MHz.

    ''

    You should be able to configure the SPI for 20MHz.

    (Do not ask me - I have not work with the SPI peripheral yet)

    ''

    With SPI_BaudRatePrescaler_2 : The screen works almost everytime

    With SPI_BaudRatePrescaler_4 : 

    The screen works half the time

    With SPI_BaudRatePrescaler_8 : 

    The screen never works

    ''

    This tell me that the screen can work at the

    SPI_BaudRatePrescaler_4

    speed.

    However, sometimes there is something during the start up that causes a problem.

    What voltage does the

    DOGM128

    work at?

    (Some STM32 can work on as little as 1.8V - so it can start to boot at 1.8V)

    What is the start up time for the

    DOGM128

    ?

    What is the boot up time for the STM32 ?

    What reset circuit do you have for the STM32 ?

    Do you have an oscilloscope to look at what is happening during the bootup on the SPI?

    jean_prieur
    Associate III
    December 20, 2013
    Posted on December 20, 2013 at 15:17

    Hello, thanks for the reply !

    - The DOGM128 voltage is 3.3V, like the STM32F4

    - I have no idea of the start up time of the screen, I can't find this information in the controller datasheet.

    - The hardware BOOT circuit is a divider bridge (the top resistor is 10K and the bottom is 510R). This is what you call a reset circuit ? In fact, I don't code anything with this BOOT pin, I have to ?

    - My oscilloscope is not enought powerfull to see the SPI messages, the speed is too high.

    I had a large delay before the screen init but it change nothing...
    francescatodiego
    Associate III
    December 20, 2013
    Posted on December 20, 2013 at 16:34

    I worked with an LCD DOGM128 but with texas stellaris micro. I don't remember well but my SPI speed was 10Mhz

    My personal opinion: slowing down the clock should work better

    On top of my lcd init code I have this reset sequence.

    LCD_RST_PIN _LOW

    wait  5ms

    LCD_RST_PIN _HIGH

    wait 5ms

    and then start the registers init procedure.

    jean_prieur
    Associate III
    December 20, 2013
    Posted on December 20, 2013 at 16:43

    Thanks !

    Unfortunately my RESET pin is directly connected to the 3.3V, I was thinking it's an optionnal pin. But I hope there is another way to resolve my problem...

    In many examples on the internet the RESET pin is optionnal. So I think this is not the solution.
    jean_prieur
    Associate III
    December 23, 2013
    Posted on December 23, 2013 at 15:32

    Can I reiterate my question, How to know and how to change the SPI speed ?

    I think that the SPI2 clock is based on APB2 frequency, but I'm unable to find APB2 frequency...

    Thanks !

    chen
    Associate II
    December 23, 2013
    Posted on December 23, 2013 at 17:38

    Hi

    ''Unfortunately my RESET pin is directly connected to the 3.3V''

    Are you sure that the STM32 is starting correctly every time?

    Check the data sheet (the one for the electronics design) but I think most designs

    have at least a capacitor on the nreset, usually a resistor and capacitor.

    If you LEDs, can you have then toggling so that you can see the STM32 is working when it power up.

    jean_prieur
    Associate III
    December 25, 2013
    Posted on December 25, 2013 at 16:02

    Yes I'm sure that my STM32F4 start correctly everytime because everything works (UART, LEDS, input pins, I2C, USB...) even when the screen is not initialized.

    francescatodiego
    Associate III
    December 26, 2013
    Posted on December 26, 2013 at 10:55

    I'm NOT sure the

    reset pin

    is

    the problem but from the LCD controller manual (Ver1.5 pag.51)

    0690X00000602cmQAA.jpg Your init procedure not follow the standard and this can cause problem Also Electronic Assembly in their datasheet never connect LCD reset pin to +V

    Looking at your

    code

    I

    have a doubt

    Have you added

    RCC_APB1PeriphClockCmd(SPI2_CLK, ENABLE);

    ? You use SPI2 and ask for APB2 but SPI2 clock in STM32F4 is APB1 the clock value depend on clock peripheral configuration Internal oscillator or esternal crystal ? if external value ?

    You have

    edited the file

    system_stm32f4xx.c

    ?

    If

    you have not made

    changes

    ,

    at the beginning

    of the file

    there is a

    table

    with

    the values ​​of the

    prescaler

    clocks

    including

    APB1

    APB2

    and

    knowing the frequency

    of your

    clock source

    can

    calculate

    the frequencies

    APB1

    APB

    2
    jean_prieur
    Associate III
    December 27, 2013
    Posted on December 27, 2013 at 21:54

    Thanks francescato,

    I added RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); but the problem is still here.

    True for the controller init procedure but a lot of examples on the internet don't use the reset PIN.

    I use a 8MHz external oscillator, and I think I made changes to system_stm32f4xx.c :

    #define PLL_M      8

     

    #define PLL_N      336

     

    #define PLL_P      2

     

    #define PLL_Q      7

     

    SystemCoreClock = 168000000;

     

    AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

    So the clock speed of the clock is :

    (Coreclock / APB1) / Prescaler

    (168000000 / 4) / 2

    = 21 MHz ?

    francescatodiego
    Associate III
    December 28, 2013
    Posted on December 28, 2013 at 09:56

    OK the Main clock is configured for 168MHz

    APB1 and APB2 can be changed with RCC_CFGR fields PPRE1 and PPRE2 File system_stm32f4xx.c SetSysclock procedure contain this code

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
    #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */
    #if defined (STM32F401xx)
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
    #endif /* STM32F401xx */

    I don't know

    what device

    you

    are using

    for

    the

    F

    407

    that I use

    : AHB max 168MHz --> HPRE = 0 (RCC_CFGR_HPRE_DIV1) use PPL frequency output = 168MHz APB1 max 42MHz --> PPRE1 = 101 (RCC_CFGR_PPRE2_DIV4) datasheet max frequency APB2 max 84MHz --> PPRE2 = 100 (RCC_CFGR_PPRE2_DIV2) datasheet max freqeuncy SPI2 prescaler divide APB1 clock

    For your problem

    try to

    fix

    the clock line

    with

    a

    resistor

    pullup

    /

    dn

    (sorry my mistake use a pullup on CS line

    but you probably

    already do

    )

    at startup

    until the

    micro

    does not configure

    the

    SPI

    line

    the clock line is is held to fixed value