Author Topic: Setting the output mode and cfg on a STM32F103  (Read 2906 times)

0 Members and 1 Guest are viewing this topic.

Offline kennTopic starter

  • Contributor
  • Posts: 10
  • Country: us
Setting the output mode and cfg on a STM32F103
« on: April 26, 2017, 04:47:54 am »
Hi there,

Is there anyone out here who would be familiar with programming the STM32f103x in C++? I am working in eclipse and trying to teach myself about micro-controllers and while I find a lot of examples about the STM32F0xx the 103 seems to be a little different - the upside is I really have to understand it as opposed to just copy and pasting some code. With that said I wondering if I am correct about the code I have written so far. I am trying to set port A:1 up to do push pull output and this is what I have so far.

//enable GPOI clock for port A using AHB and RCC registers
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
//Set any control registers for PortA Pin 1
GPIOA->CRL |= GPIO_CRL_MODE1;
//Set the type
GPIOA->ODR |= (GPIO_ODR_ODR2);
GPIOA->ODR |= (GPIO_ODR_ODR3);
//I believe the result of all this would be 0000 0000 0000 0000 0000 0000 0000 0000 0011 1100 in the register for gpio A

Basically I was hoping someone could tell me "Yes, you are on the right track" or "No way - you are totally wrong" and if the later is the case then why.

Thanks a lot!
   
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4208
  • Country: us
Re: Setting the output mode and cfg on a STM32F103
« Reply #1 on: April 26, 2017, 09:24:54 am »
Quote
//Set any control registers for PortA Pin 1
GPIOA->CRL |= GPIO_CRL_MODE1;
It's not clear whether you understand that GPIO_CRL_MODE1 is a bitmask of the MODE bits for pin1, so you're setting both bits to 1 here.  Also, you're NOT setting the CNF bits that are in the same register.  Assuming that they start out at 0, this will give you the bit set for 50MHz push-pull output, which is probably what you actually want, anyway.  But even in assembly language ( https://github.com/WestfW/Minimal-ARM/blob/master/Blink/blink.S#L132 )I made it say:
Code: [Select]
((GPIO_MODE_OUT+GPIO_CNF_PP) << (mybit*4))(Alas, it looks like I had to create those constants; I don't see them in the stm32f10x.h file, or the documentation :-( )

Quote
//Set the type
GPIOA->ODR |= (GPIO_ODR_ODR2);
GPIOA->ODR |= (GPIO_ODR_ODR3);

"Set the type"??  ODR is the output data register, and the various ODR_ODR2 are just names for the individual bits.
So, having lucked out in setting pin1 to be an output, you appear to be writing to pins 2 and 3.  Probably not what you had in mind.

Quote
//I believe the result of all this would be 0000 0000 0000 0000 0000 0000 0000 0000 0011 1100 in the register for gpio A
Which register are you talking about?
The STM32f10x chips only have 16 pins associated with each GPIO port, and the CRL register had 4 bits for each of the first 8 pins, so for a fast push-pull output on pin 1, you WANT (probably)
CRL = 0000 0000 0000 0000 0000 0000 0000 0000 0011 0000   // mode =11, cnf = 00.  Other bits left at 0.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Setting the output mode and cfg on a STM32F103
« Reply #2 on: April 26, 2017, 09:58:02 am »
I recommended explicitly setting all IO.
Code: [Select]
  // CNF
  #define I_AN  0u // Input Analog
  #define I_FL  1u // Input Float
  #define I_DI  2u // Input Pull-up/down
  #define O_PP  0u // Output push-pull
  #define O_OD  1u // Output open-drain
  #define A_PP  2u // Periph push-pull
  #define A_OD  3u // Periph open-drain
  // MODE
  #define INPUT 0u // Input
  #define OUT_S 1u // Slow output
  #define OUT_M 2u // Medium output
  #define OUT_F 3u // Fast output 
  GPIOA->CRH =
  /*15*/ (A_PP << GPIO_CRH_CNF15_Pos)|(OUT_S << GPIO_CRH_MODE15_Pos)|   //
  /*14*/ (A_PP << GPIO_CRH_CNF14_Pos)|(OUT_S << GPIO_CRH_MODE14_Pos)|   //
  /*13*/ (O_OD << GPIO_CRH_CNF13_Pos)|(OUT_S << GPIO_CRH_MODE13_Pos)|   //
  /*12*/ (O_PP << GPIO_CRH_CNF12_Pos)|(OUT_S << GPIO_CRH_MODE12_Pos)|   //
  /*11*/ (I_DI << GPIO_CRH_CNF11_Pos)|(INPUT << GPIO_CRH_MODE11_Pos)|   //
  /*10*/ (I_AN << GPIO_CRH_CNF10_Pos)|(OUT_S << GPIO_CRH_MODE10_Pos)|   //
  /*09*/ (I_FL << GPIO_CRH_CNF9_Pos)| (INPUT << GPIO_CRH_MODE9_Pos)|    //
  /*08*/ (I_AN << GPIO_CRH_CNF8_Pos)| (OUT_S << GPIO_CRH_MODE8_Pos);    //
  GPIOA->CRL =
  /*07*/ (I_AN << GPIO_CRL_CNF7_Pos)| (INPUT << GPIO_CRL_MODE7_Pos)|    //
  /*06*/ (I_AN << GPIO_CRL_CNF6_Pos)| (INPUT << GPIO_CRL_MODE6_Pos)|    //
  /*05*/ (I_AN << GPIO_CRL_CNF5_Pos)| (INPUT << GPIO_CRL_MODE5_Pos)|    //
  /*04*/ (I_AN << GPIO_CRL_CNF4_Pos)| (INPUT << GPIO_CRL_MODE4_Pos)|    //
  /*03*/ (I_AN << GPIO_CRL_CNF3_Pos)| (INPUT << GPIO_CRL_MODE3_Pos)|    //
  /*02*/ (I_AN << GPIO_CRL_CNF2_Pos)| (INPUT << GPIO_CRL_MODE2_Pos)|    //
  /*01*/ (I_AN << GPIO_CRL_CNF1_Pos)| (INPUT << GPIO_CRL_MODE1_Pos)|    //
  /*00*/ (I_AN << GPIO_CRL_CNF0_Pos)| (INPUT << GPIO_CRL_MODE0_Pos);    //
 
  #define PIN_HIGH  +0u
  #define PIN_LOW   +16u
  GPIOA->BSRR =
  (1u << (0 PIN_LOW))|
  (1u << (1 PIN_LOW))|
  (1u << (2 PIN_LOW))|
  (1u << (3 PIN_LOW))|
  (1u << (4 PIN_LOW))|
  (1u << (5 PIN_LOW))|
  (1u << (6 PIN_LOW))|
  (1u << (7 PIN_LOW))|
  (1u << (8 PIN_LOW))|
  (1u << (9 PIN_LOW))|
  (1u << (10 PIN_LOW))|
  (1u << (11 PIN_HIGH))|
  (1u << (12 PIN_LOW))|
  (1u << (13 PIN_LOW))|
  (1u << (14 PIN_LOW))|
  (1u << (15 PIN_LOW));
 

Offline kennTopic starter

  • Contributor
  • Posts: 10
  • Country: us
Re: Setting the output mode and cfg on a STM32F103
« Reply #3 on: April 26, 2017, 01:33:57 pm »
Thanks for the responses, and yes, I realized that I was indeed setting the configuration bits on the wrong pin.


Forgetting the programming and what I have already done for a moment is it correct that the 4 bits I care about are 4 5 6 and 7? They control pin one I believe. With that said if I simply set bit four to 1 and 5 6 and 7 where 0 I would be setting pin 1 with an output with a max speed of 10mhz and then bits 5 and 6 would be read as General purpose output push-pull because the mode was output. I think I am right about that.



Here is the PDF I am looking at, it's page 170 - see the attached image as well.

http://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf
« Last Edit: April 26, 2017, 01:39:54 pm by kenn »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4208
  • Country: us
Re: Setting the output mode and cfg on a STM32F103
« Reply #4 on: April 26, 2017, 10:06:08 pm »
Quote
is it correct that the 4 bits I care about are 4 5 6 and 7? They control pin one I believe.
yes, that seems correct.

In principle, I like Jeroen3's suggestion that you set ALL the bits.   But in practice that seems to be one of the main reasons that ARM Vendor library code tends to be bloated - they really make use of that 32bit address space, and there are a LOT of registers to set, if you insist on setting them all rather than believing in the "default power-on values."  (In this particular case, it wouldn't be a big deal, especially done as Jeroen3 shows...)
 

Offline kennTopic starter

  • Contributor
  • Posts: 10
  • Country: us
Re: Setting the output mode and cfg on a STM32F103
« Reply #5 on: April 27, 2017, 02:17:06 am »
Thank you very much, at least I understand the concept with that I can figure out the code, the nice thing is that I already have experience with openOCD and debugging shouldn't be an issue, it will be fun but there is still a few more things to sort out.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf