Stm32 Peripheral Drivers from Scartch : GPIO Programming Part 3

In this part of the series we begin to write the functions that will make use of all the defines in our header file.

The first function we will need to implement is one to configure the pin and it looks something like this:

static void config_pin(GPIO_TypeDef *gpio, uint32_t pinNumber , uint32_t mode_type)

The first parameter in the function is going to be one of GPIO_TypeDef. I am not pulling this typedef out of thin air, it is defined the header file for the microcontroller stm32f10x.h. The parameter The next parameter is of an integer type which tells the function the pin number we will be configuring. The last parameter tells the function what is the mode type, for example if its an output mode do we want it to be a general purpose output or an open drain output  or an alternate function output.  An acceptable function call will use the definitions we made in our header file and it will look something like this:

config_pin(PORTA, 13 , OUTPUT_GEN_PURPOSE);

Now lets think about what we have to do to configure a pin taking into account the information we are given through the arguments of the function call. From a previous post we know certain things
about configuring a pin. Those things are that we have to either write to the high register or the low register depending on the pin number we are using. Furthermore we know we have different modes we can choose  from and we also know the values for some of those modes are redundant for both input or output mode.

All that being said lets look at the inner workings of the function now:
static void config_pin (GPIO_TypeDef *port , uint32_t pinNumber , uint32_t mode_type)
{

  if(pinNumber >= 8) // CONTROL HIGH REGISTER
  {
 switch(mode_type)
 {
  
 //---------------OUTPUT & INPUT MODES---------------------------
 case OUTPUT_GEN_PURPOSE | INPUT_ANALOG:
  port->CRH &= ~(  (1<<CNF_POS_BIT1 ) | (1<<CNF_POS_BIT2) );
 break;
  
 case OUTPUT_OD | INPUT_FLOATING:
  port->CRH &= ~( 1<<CNF_POS_BIT2 );
  port->CRH |= (1<<CNF_POS_BIT1);
 break;
  
 case OUTPUT_ALT_FUNCTION | INPUT_PU_PD:
  port->CRH |= OUTPUT_ALT_FUNCTION<<(CNF_POS_BIT1);    
 break;
  
 case OUTPUT_ALT_FUNCTION_OD:
  port->CRH |= OUTPUT_ALT_FUNCTION_OD<<(CNF_POS_BIT1);
 break;  
  
  
 }//end switch
 
 
  }
  else  //CONTROL LOW REGISTER
  {
 switch(mode_type)
 {
  
 //---------------OUTPUT & INPUT MODES---------------------------
 case OUTPUT_GEN_PURPOSE | INPUT_ANALOG:
  port->CRL &= ~(  (1<<CNF_POS_BIT1 ) | (1<<CNF_POS_BIT2) );
 break;
  
 case OUTPUT_OD | INPUT_FLOATING:
  port->CRL &= ~( 1<<CNF_POS_BIT2 );
  port->CRL |= (1<<CNF_POS_BIT1);
 break;
  
 case OUTPUT_ALT_FUNCTION | INPUT_PU_PD:
  port->CRL |= OUTPUT_ALT_FUNCTION<<(CNF_POS_BIT1);    
 break;
  
 case OUTPUT_ALT_FUNCTION_OD:
  port->CRL |= OUTPUT_ALT_FUNCTION_OD<<(CNF_POS_BIT1);
 break;  
  
  
 }//end switch
 
 
  }//end else
//end function


Comments

Share your comments with me

Archive

Contact Form

Send