STM32F4

I got one of the discovery development boards for the princely sum of £9!!

I have been reading and searching and reading some more about how to program the thing and its left my head hurting!!

STLINK V2, CN3 jumpers? WTF???

Can anyone hold my hand and explain in laymens terms how to get started with this very powerful piece of kit

I have lots of questions I just want to test the waters here to see whos actually using one!

Thanks in advance

discovery development boards

Do you have a link ?

Its this little baby

Basically my questions are many, but I just want to know what compiler I should use and how on earth do i get started according to the literature its really easy to get going but not in my experience

and it's left my head hurting!

Yeah, that's one of the nice things about Arduino. Start blinking LEDs without having to first understand a complicated IDE and programming environment...

The best free IDE I have found for the discovery board is Atollic light, I tried others with less luck. http://www.atollic.com/index.php/download/truestudio-for-arm

You also need to download nearly all these PDFs. http://www.st.com/internet/evalboard/product/252419.jsp

You need to start reading, it will take some work.

Arduino is a lot easier in my opinion, but STM32 has massive speed and possibilities.

Thanks for the replies

I was trying with CooCox CoIde but its left me bewildered

I already have the PDF's (courtesy of work!) and I have been reading them (all day!) but like you point out its pretty hard work

Hard work I am ok with, I am downloading attolic now, I dont suppose you have any test codes? blink LED hello world anything! I am a total noob

You can also check out leaflabs.com. They are working on the Maple Native II using this chip, so there might be something there you can use.

I had seen the maple IDE (looks exactly like Arduino IDE!)

But the tech speak really scared me off!, I just want something I can learn with relatively easily

Oh goodness.. If Maple scares you off, I don't think there's much ARM stuff out there that will be palatable. You could TRY Simple Cortex SimpleCortex, For When An Arduino Is Too Wimpy | Hackaday Although that is a completely different chip.

Anyway, I think it's safe to say that "easy" and "STM32F4" don't really go together right now.

Resinator:
I dont suppose you have any test codes? blink LED hello world anything! I am a total noob

Sorry, so far I have only got as far as changing the loaded program with one that makes the leds come on and stay on. I still have plenty to learn about the language for Atollic and STM32.

Some people on LeafLabs forum have made a Maple IDE port to the STM32F4 discovery but, I have not figured out how to use it. The Maple IDE is a based on Arduino IDE but, the hardware makes programming a little different in some cases.

maniacbug:
Oh goodness.. If Maple scares you off, I don't think there's much ARM stuff out there that will be palatable. You could TRY Simple Cortex SimpleCortex, For When An Arduino Is Too Wimpy | Hackaday Although that is a completely different chip.

Anyway, I think it's safe to say that "easy" and "STM32F4" don't really go together right now.

What scared me off was all the multitude of problems people have! like remapping the peripherals etc etc! but my main argument is I want to learn how to program properley, Arduino IDE is really good for getting started but its so simplified and I think the Maple IDE is just the same good for beginners but a lot more to learn

cyclegadget:
Sorry, so far I have only got as far as changing the loaded program with one that makes the leds come on and stay on. I still have plenty to learn about the language for Atollic and STM32.

Some people on LeafLabs forum have made a Maple IDE port to the STM32F4 discovery but, I have not figured out how to use it. The Maple IDE is a based on Arduino IDE but, the hardware makes programming a little different in some cases.

Well I have not given up!, I have tried Coocox CoIDE with no luck but I have had some success with Attolic True Studio, pretty straight forward process once you know what options to set etc.

So I first started uploading a program that just turned the four LEDs on and after lots of messing about I have this very basic program

#include "stm32f4_discovery.h"
int T=1000000;

GPIO_InitTypeDef  GPIO_InitStructure;

void Delay(__IO uint32_t nCount);

int main(void)
{
 

  /* GPIOD Periph clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  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(GPIOD, &GPIO_InitStructure);

  while (1)
  {
    /* PD12 to be toggled */
    GPIO_SetBits(GPIOD, GPIO_Pin_12);
    
    /* Insert delay */
    Delay(T);
    
    /* PD13 to be toggled */
    GPIO_SetBits(GPIOD, GPIO_Pin_13);
    
    /* Insert delay */
    Delay(T);
  
    /* PD14 to be toggled */
    GPIO_SetBits(GPIOD, GPIO_Pin_14);
    
    /* Insert delay */
    Delay(T);
    
    /* PD15 to be toggled */
    GPIO_SetBits(GPIOD, GPIO_Pin_15);
    
    /* Insert delay */
    Delay(T);
    
    GPIO_ResetBits(GPIOD, GPIO_Pin_12);
    Delay(T);

    GPIO_ResetBits(GPIOD, GPIO_Pin_13);
    Delay(T);
        
    GPIO_ResetBits(GPIOD, GPIO_Pin_14);
    Delay(T);
   
    GPIO_ResetBits(GPIOD, GPIO_Pin_15);
    Delay(T);

    GPIO_SetBits(GPIOD, GPIO_Pin_15);
    Delay(T);

    GPIO_SetBits(GPIOD, GPIO_Pin_14);
    Delay(T);

    GPIO_SetBits(GPIOD, GPIO_Pin_13);
    Delay(T);

    GPIO_SetBits(GPIOD, GPIO_Pin_12);
    Delay(T);

    GPIO_ResetBits(GPIOD, GPIO_Pin_15);
    Delay(T);

    GPIO_ResetBits(GPIOD, GPIO_Pin_14);
    Delay(T);
      
    GPIO_ResetBits(GPIOD, GPIO_Pin_13);
    Delay(T);
                           
    GPIO_ResetBits(GPIOD, GPIO_Pin_12);
    Delay(T);
  }
}


void Delay(__IO uint32_t nCount)
{
  while(nCount--)
  {
  }
}

I can upload the code and alter the delay value T, the great thing with attolic is I can debug the program and single step through which is a massive help for me to learn how a C program runs in fact this has learnt me a lot

Any other noobs need help getting this going just drop me a message and I will do my best to help, its taken me about 5 days reading and playing

I have lots of questions

void Delay(__IO uint32_t nCount)
{
  while(nCount--)
  {
  }
}

Can anyone explain what this part does?

uint32_t is an unsigned 32 bit Int, I know what a while loop does but I dont get what that does in the code

GPIO_InitTypeDef  GPIO_InitStructure;

What about this one any explanations?

Finally for today

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;

I see this a lot | its the Or command yeah?, whats it do in the above line?

Many thanks for looking

I see this a lot | its the Or command yeah?, whats it do in the above line?

it is the bitwise OR (as opposed to the logical or boolean OR) and it "adds up" bittpatterns

The rules are

0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1

so if you have 2 bytes A=00001111 and B=00111100 then C= A|B = 00111111 it is bitwised or-ed

This technique is used often to set registers and masks, more see - Arduino Playground - BitMath

Thanks for that Rob, I had actually read that before!

Well I have been working a lot on this STM32F4 and it hasn't been easy but nothing in life worth doing ever is

I have so far managed to:

Set up ports and blink LED's

Do some hardcore maths (well power series!, and it is pretty quick)

Use a timer to count and generate an interrupt

Use the ADC (this is something I am currently working on as the reading seems to saturate at 3V????) its pretty complex with all the settings

Got much better with Attolic and C programming and learnt to debug (ish)

So much more to learn not least with C

For instance what the hell does the typedef do to a structure??

typedef struct
{
  uint32_t ADC_Resolution;                /*!< Configures the ADC resolution dual mode. 
                                               This parameter can be a value of @ref ADC_resolution */                                   
  FunctionalState ADC_ScanConvMode;       /*!< Specifies whether the conversion 
                                               is performed in Scan (multichannels) 
                                               or Single (one channel) mode.
                                               This parameter can be set to ENABLE or DISABLE */ 
  FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion 
                                               is performed in Continuous or Single mode.
                                               This parameter can be set to ENABLE or DISABLE. */
  uint32_t ADC_ExternalTrigConvEdge;      /*!< Select the external trigger edge and
                                               enable the trigger of a regular group. 
                                               This parameter can be a value of 
                                               @ref ADC_external_trigger_edge_for_regular_channels_conversion */
  uint32_t ADC_ExternalTrigConv;          /*!< Select the external event used to trigger 
                                               the start of conversion of a regular group.
                                               This parameter can be a value of 
                                               @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */
  uint32_t ADC_DataAlign;                 /*!< Specifies whether the ADC data  alignment
                                               is left or right. This parameter can be 
                                               a value of @ref ADC_data_align */
  uint8_t  ADC_NbrOfConversion;           /*!< Specifies the number of ADC conversions
                                               that will be done using the sequencer for
                                               regular channel group.
                                               This parameter must range from 1 to 16. */
}ADC_InitTypeDef;

which is a structure so that when I type the below

ADC_InitTypeDef ADC_InitStructure;

  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv=0x00000000;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;
  ADC_Init(ADC1, &ADC_InitStructure);

A structure is created called ADC_InitStructure which is identical to the structure ADC_Init

The different members are populated then the program uses

ADC_Init(ADC1, &ADC_InitStructure);

To go to the ACD_INIT structure with the variable ADC1 and the address of the ADC_InitStructure

I also see uint32_t/uint16_t etc now its obviously an unsigned 32/16 bit int but whats the difference with just the unsigned int data type?

Now thats my understanding and I am wrong a lot please explain/discuss

these STM32F4 boards are really really good fun

I also see uint32_t/uint16_t etc now its obviously an unsigned 32/16 bit int but whats the difference with just the unsigned int data type?

Types are defined that are are explictitly 16 or 32 bits long. The normal C data types (int, long) are not defined to be of a particular size (and an "int" is 16 bits on an AVR, but 32bits on an ARM, for example.)

so an int is 32bit on an ARM I can understand the uint16_t is different to an int as its half the length

So am I right that a uint32_t is identical to an Int i.e both 32 bits long so no difference at all

What does Typedef do to a structure and why is it sometimes a capital T?

Questions questions questions

a uint32_t is the same as an unsigned long (not long) on the arduino... Other platforms may not have the same equivalence.

The captital in the typedef above is simply a means of using the term typedef as part of the variable name, when the keyword typedef is use in c/c++ it is a way of assigning a synonym to an existing data type.

So am I right that a uint32_t is identical to an Int i.e both 32 bits long so no difference at all

On an ARM, yes. On an AVR, they would be different sizes. If you wanted to hold something like an IP address (32bits for v4), you could use an "int" on an ARM, but you'd have to use a "long" on an AVR: an incompatibility. Instead, your program should use "uint32_t" for the IP address, and it would run on both AVR and ARM (assuming all other architectural dependencies are fixed as well.)

"typedef" defines a name that acts like a type (ie like "int" or "long"); it's a shorthand convenience, especially when you get to more complex structures (containing other structures, etc.)

So someplace in an AVR include file there is likely to be a line that looks like:
typedef unsigned long uint32_t; that means "treat the name "uint32_t" as a variable type, that is the same as "unsigned long". The similar file on an ARM might contain "typedef unsigned int uint32_t;"

typedef uint32_t ip_addr_t;

typedef struct ip_pheader {ip_addr_t phdr_ip;
uint16_t phdr_sourceport;
uint16_t phdr_destport;} ip_pheader_t;

typedef struct socket {ip_pheader_t socket_local;
ip_pheader_t socket_remote;
uint32_t socket_timestamp;
 // etc
} socket_t;

int open_socket (socket_t *s) {
  // code
}

is somewhat clearer than having to having to include the "struct xxx yyy" at each point.

I don't know anything about "Typedef" with a capital T. As wanderson noted, there are all sorts of (local) conventions to indentifying a type as such, and coming up with a name that is easy to understand.

westfw:

So am I right that a uint32_t is identical to an Int i.e both 32 bits long so no difference at all

On an ARM, yes. On an AVR, they would be different sizes.

Even on the ARM wouldn't uint32_t be an unsigned value, int be a signed value? So while they would have the same physical size and could be cast to one another with no loss, they would be interpreted differently by the compiler, correct?

On an ARM, yes. On an AVR, they would be different sizes. If you wanted to hold something like an IP address (32bits for v4), you could use an "int" on an ARM, but you'd have to use a "long" on an AVR: an incompatibility. Instead, your program should use "uint32_t" for the IP address, and it would run on both AVR and ARM (assuming all other architectural dependencies are fixed as well.

Thats clear thanks

"typedef" defines a name that acts like a type (ie like "int" or "long"); it's a shorthand convenience, especially when you get to more complex structures (containing other structures, etc.)

So someplace in an AVR include file there is likely to be a line that looks like:
typedef unsigned long uint32_t; that means "treat the name "uint32_t" as a variable type, that is the same as "unsigned long". The similar file on an ARM might contain "typedef unsigned int uint32_t;"

Not so clear!

Its the code that confuses me

Heres the form for the STM32F4, the name appears after the closing }

//

 In a header file//
typedef struct
{
         Hours_Spent;                
                                 
         Hairs_Pulled_Out;   

}Learning_CTypeDef; //Capital T


Learning_CTypeDef Resinators_Learning_C; 

  Resinators_Learning_C.Hours_Spent = 999;
  Resinators_Learning_C.Hairs_Pulled_Out = LOTS;
Learning_CTypeDef Resinators_Learning_C;

This makes a structure called Resinators_Learning_C which identical to the Learning_C

Resinators_Learning_C.Hours_Spent = 999;
  Resinators_Learning_C.Hairs_Pulled_Out = LOTS;

This populates the structure with the values

What I dont get is the typedef it appears twice once at start with no capital and at the end where I name the structure

Where it appears at the end with the Capital the word Typedef is being used as part of the name used to indicate that particular structure. For instance it could have been created like so, and would still perform the same function

typedef struct
{
         Hours_Spent;                
                                 
         Hairs_Pulled_Out;   

} ArbitraryName; //Capital T


ArbitraryName Resinators_Learning_C; 

  Resinators_Learning_C.Hours_Spent = 999;
  Resinators_Learning_C.Hairs_Pulled_Out = LOTS;