• Welcome to Andy's Workshop Forums. Please login or sign up.
 
March 28, 2024, 03:50:28 pm

News:

SMF - Just Installed!


How to use GPIO pins?

Started by yaqwsx, August 01, 2016, 02:43:41 pm

Previous topic - Next topic

yaqwsx

Hello,

I want to create a class for an external peripheral, which uses several GPIO pins. I want to let user to specify an arbitrary IO pins, which don't have to be on the same port and the class would initialized them. I read almost all examples and I searched through the library source code and I am not sure if I understood, how should the GPIOs be used. There are my observations:


  • There are the Gpio{A,B,C,D,E,F} classes, which can configure several IO pins. Is it possible to have multiple instances of one class? Won't they collide?


  • There is the GpioPinRef class, which I am not sure how to use. If I construct it directly (by base address and pin), is the port and pin correctly initialized? Or there has to be an instance of GpioX, which initializes the port and pin (and the pin instance can be obtained by GpioX::operator[])?


  • There is a pin map, which defines a structure for each pin. Could it be used in my program?



I am not sure, how to use these observations. The only way I see is to have an instance of GpioX for every port (owned by main function or the application class) and then pass GpioPinRef to the peripheral. In this way I however have to configure the pins outside the peripheral class, which I don't really like (user is responsible for the proper pin configuration). Is there a way for easy pin configuration inside the peripheral class? Could a pin map be used?

Is my way of thinking against the library style? If so, how should I manage GPIOs (initialize them and pass them to peripheral control classes) in "STM32Plus style"?

Thank you for your answer

PS: My last question - when all instances of classes representing peripherals on a bus (eg. GPIO and Timers on AHB2) are destructed, is the bus clock disabled or not?

Andy Brown

It sounds like you're using the library to create a higher level library of sorts. That means that you probably do not want the GpioA... etc templates because these are for when you are the 'user' and you want to configure a port to a known state. GpioPinRef is closely related to the port template and is used to pass around pins from the port. It's lightweight and can be passed around easily to general purpose methods because it's not a template. But it's not what you want.


  GpioB<DefaultDigitalInputFeature<6> > pb;
  GpioPinRef thePin=pb[6];


Quote
There is a pin map, which defines a structure for each pin. Could it be used in my program?


Yes. In my opinion that's the ideal way. If I were you I would create a template and parameterize it with a single type that's assumed to contain the user's selection of pins for your peripheral.

A good example is how I did the Ethernet MAC peripheral. Have your user create a type that defines the pins required by your peripheral using typedefs. Like this example for the MAC.

Now your template needs to receive the users type as a parameter. You know that each one of your pins is in that type as a typedef and so you can initialize them in your code. Here's the initializer for the ethernet MAC.
It's worse than that, it's physics Jim!

yaqwsx

Thanks! GpioPinInitialiser is probably what I am looking for. I have one more question - when I am "user" and use the GpioX template, is it possible to have a multiple instances? Or is it meant as a singleton?

Andy Brown

August 03, 2016, 01:39:52 pm #3 Last Edit: August 03, 2016, 01:47:06 pm by Andy Brown
Quote from: yaqwsx on August 03, 2016, 04:59:59 am
Thanks! GpioPinInitialiser is probably what I am looking for. I have one more question - when I am "user" and use the GpioX template, is it possible to have a multiple instances? Or is it meant as a singleton?


You can have as many instances as you like, even if they're identical types (ie. having same template parameters).

Quote
PS: My last question - when all instances of classes representing peripherals on a bus (eg. GPIO and Timers on AHB2) are destructed, is the bus clock disabled or not?


Not for GPIO. To achieve that reliably when a user could have multiple templates declared against the same GPIO port would require some tricky reference counting that would take up more space and use more cycles than it would be worth.

The other peripherals (adc/can/dac/spi/timer/usart etc....) do deactivate the peripheral clock when the destructor is called.
It's worse than that, it's physics Jim!