cancel
Showing results for 
Search instead for 
Did you mean: 

Errors in firmware ?

thibaut2
Associate II
Posted on August 21, 2012 at 11:33

Hi.

As i m currently working on an application running on both STM8S and STM32, i'm using firmware libraries to get a portable code. i already found several mistakes.

As an example : Software NSS bit.

- first mistake is in usermanual of STM8S, it is written :

Bit 0 SSI: Internal slave select

 

This bit has effect only when SSM bit is set. The value of this bit is forced onto the NSS pin and the I/O

 

value of the NSS pin is ignored.

 

0: Slave mode

 

1: Master mode

whereas it's

0 : NSS set to LOW

1 : NSS set to HIGH

2nd mistake is in firmware :

void SPI_NSSInternalSoftwareCmd(FunctionalState NewState)

 

{

 

    /* Check function parameters */

 

    assert_param(IS_FUNCTIONALSTATE_OK(NewState));

 

 

    if (NewState != DISABLE)

 

    {

 

        SPI->CR2 |= SPI_CR2_SSI; /* Set NSS pin internally by software*/

 

    }

 

    else

 

    {

 

        SPI->CR2 &= (uint8_t)(~SPI_CR2_SSI); /* Reset NSS pin internally by software*/

 

    }

 

}

So here, if i call this function:  SPI_NSSInternalSoftwareCmd(ENABLE);

it sets NSS to HIGH, and therefor DISABLE the communication....

Now that i m done with STM8S i m starting with stm32.

first function i try to port :

STM8S version :

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)

stm32F1 version :

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

I'm wondering why this change, to use a structure to regroup informations of pin# and pin_mode... That i have now to create a structure and then call the function for each pin i want to configure, whereas i only had to call 1 function before. But ok, welcome in 32-bit world ^^

and now in the definition of the structure you find :

typedef struct

 

{

 

  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.

 

                                      This parameter can be any value of @ref GPIO_pins_define */

 

 

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.

 

                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

 

 

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.

 

                                      This parameter can be a value of @ref GPIOMode_TypeDef */

 

}GPIO_InitTypeDef;

and

typedef enum

 

{

 

  GPIO_Speed_10MHz = 1,

 

  GPIO_Speed_2MHz,

 

  GPIO_Speed_50MHz

 

}GPIOSpeed_TypeDef;

 

They aren't defining which value correspond to 2 and 50MHz, moreover, i find in datasheet :

Bits 29:28, 25:24,

 

21:20, 17:16, 13:12,

 

9:8, 5:4, 1:0

 

 

MODEy[1:0]: Port x mode bits (y= 0 .. 7)

 

These bits are written by software to configure the corresponding I/O port.

 

Refer to Table 16: Port bit configuration table on page 101.

 

00: Input mode (reset state)

 

01: Output mode, max speed 10 MHz.

 

10: Output mode, max speed 2 MHz.

 

11: Output mode, max speed 50 MHz.

So 10Mhz, shall be b''01'' and not 1.

in GPIO_Init, they re loading the value of Speed directly into register at right position..

In conclusion when i see such mistakes, i wonder if there are erratas on ST firmware or if i shall definitly stop to use them ?

5 REPLIES 5
thibaut2
Associate II
Posted on August 21, 2012 at 14:57

reading more of GPIO firmware, i find more and more nonsenses...

what they call ''GPIO_mode'' is loading into CNFy registers, and what they call ''SPEED'' load into MODEy registers... type_definitions aren't complete as i ve shown just before.

GPIO_StructInit isn't setting GPIO to reset value as it is supposed to do, and as comments say, but to a different value, using GPIO_Speed_2MHz which isn't properly defined... (i guess it's why it wasn't seen when they tested it.. )

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

 won't also work :

  GPIOx->BSRR = GPIO_Pin;

BSRR is word access only, means if i m not mistaking, you got to write a 32bits long word...

these are only examples. so where can i find correct firmware which wasn't coded with feet ?

Posted on August 21, 2012 at 16:15

They aren't defining which value correspond to 2 and 50MHz, moreover

enum increments the enumerator, you only need to explicitly define numbers which are out of sequence. It works in decimal, not binary, the values assigned appear correct.

16-bit writes against BSRR are valid (ie the Set half, vs Reset half), what won't work properly will be Bit Banding.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
thibaut2
Associate II
Posted on August 21, 2012 at 17:29

enum increments the enumerator, you only need to explicitly define numbers which are out of sequence. It works in decimal, not binary, the values assigned appear correct.

Oops, i ever used enum with explicitly defined values, my mistake.

Still this ''GPIO_Speed'' isn't defined for input, but it's still ''reinitialized'' to 2MHz when using ''GPIO_StructInit()''. Even if it's not read when in input mode, I'm not fan of this method.

Well, i guess it's just a way codin it, disturbing my habits, not to declare a variable i won't have any use :p

16-bit writes against BSRR are valid (ie the Set half, vs Reset half), what won't work properly will be Bit Banding.

Then reference manual for STM32F1 (RM0041) is wrong :

These bits are write-only and can be accessed in Word mode only. p112

(and when i wondered if word was 16 or 32bit long on stm32, i found this p119

The peripheral registers have to be accessed by words (32-bit).

so a word is 32 bits as i suspected)

Reading myself, i'm afraid i could sound aggressive, but i'm only trying to know what i can take from firmware without always refering to manual and verify it's right.

Posted on August 21, 2012 at 18:42

GPIOA->BSRR= 0x1248;

same as

GPIOA->BSRR = 0x00001248;

There are occasionally bugs with the firmware libraries, and examples which aren't completely portable ie renaming TIM5 to TIM1 might not be sufficient to change TIM initialization code.

The biggest pitfall is to look at the .H files and compare with the register bits directly. The libraries in many circumstances use encoded forms which are later cracked by the functions. Some parameters expect bit vectors, other indices.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
thibaut2
Associate II
Posted on August 22, 2012 at 12:35

GPIOA->BSRR= 0x1248;

 

same as

 

GPIOA->BSRR = 0x00001248;

 

then the ref manual is erroneous..

The biggest pitfall is to look at the .H files and compare with the register bits directly.

You mean i shall not watch .H files and compare them to the ref manual ? What is best method to use them then ?