• Welcome to Andy's Workshop Forums. Please login or sign up.
 
April 27, 2024, 09:13:40 am

News:

SMF - Just Installed!


Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - yaqwsx

1
stm32plus C++ library / Re: How to use GPIO pins?
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?
2
stm32plus C++ library / How to use GPIO pins?
August 01, 2016, 02:43:41 pm
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?
3
Thanks for clarification! The blink example now works as expected. Even the file is generated once (when the project is created), I would appreciate if the library provided a macro for optional weak symbols (something like DISABLE_WEAK_SYMBOLS). Do you think it would be possible to add it to the library?

I was also struggling with the SGI extension in form of slist. With the compiler on windows, I had to change includes in event.h to "#include "ext/slist"" and I also had to change namespace from std to __gnu_cxx. I have never worked with this extension before - is there a compiler flag which enables them or is this a "feature" of the compiler?

Thanks for your help.
4
When I remove all weak alisese, I am not able to compile, since GCC doesn't compile the code.

Here's the auto-generated startup code:
/*
This file contains the entry point (Reset_Handler) of your firmware project.
The reset handled initializes the RAM and calls system library initializers as well as
the platform-specific initializer and the main() function.
*/

extern void *_estack;

#define NULL ((void *)0)

void Reset_Handler();
void Default_Handler();

#define BootRAM ((void *)0xF108F85F)

void NMI_Handler()                __attribute__ ((weak, alias ("Default_Handler")));
void HardFault_Handler()          __attribute__ ((weak, alias ("Default_Handler")));
void MemManage_Handler()          __attribute__ ((weak, alias ("Default_Handler")));
void BusFault_Handler()           __attribute__ ((weak, alias ("Default_Handler")));
void UsageFault_Handler()         __attribute__ ((weak, alias ("Default_Handler")));
void SVC_Handler()                __attribute__ ((weak, alias ("Default_Handler")));
void DebugMon_Handler()           __attribute__ ((weak, alias ("Default_Handler")));
void PendSV_Handler()             __attribute__ ((weak, alias ("Default_Handler")));
void SysTick_Handler()            __attribute__ ((weak, alias ("Default_Handler")));
void WWDG_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void PVD_IRQHandler()             __attribute__ ((weak, alias ("Default_Handler")));
void TAMPER_IRQHandler()          __attribute__ ((weak, alias ("Default_Handler")));
void RTC_IRQHandler()             __attribute__ ((weak, alias ("Default_Handler")));
void FLASH_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void RCC_IRQHandler()             __attribute__ ((weak, alias ("Default_Handler")));
void EXTI0_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void EXTI1_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void EXTI2_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void EXTI3_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void EXTI4_IRQHandler()           __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel1_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel2_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel3_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel4_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel5_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel6_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void DMA1_Channel7_IRQHandler()   __attribute__ ((weak, alias ("Default_Handler")));
void ADC1_2_IRQHandler()          __attribute__ ((weak, alias ("Default_Handler")));
void USB_HP_CAN1_TX_IRQHandler()  __attribute__ ((weak, alias ("Default_Handler")));
void USB_LP_CAN1_RX0_IRQHandler() __attribute__ ((weak, alias ("Default_Handler")));
void CAN1_RX1_IRQHandler()        __attribute__ ((weak, alias ("Default_Handler")));
void CAN1_SCE_IRQHandler()        __attribute__ ((weak, alias ("Default_Handler")));
void EXTI9_5_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void TIM1_BRK_IRQHandler()        __attribute__ ((weak, alias ("Default_Handler")));
void TIM1_UP_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void TIM1_TRG_COM_IRQHandler()    __attribute__ ((weak, alias ("Default_Handler")));
void TIM1_CC_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void TIM2_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void TIM3_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void TIM4_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void I2C1_EV_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void I2C1_ER_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void I2C2_EV_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void I2C2_ER_IRQHandler()         __attribute__ ((weak, alias ("Default_Handler")));
void SPI1_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void SPI2_IRQHandler()            __attribute__ ((weak, alias ("Default_Handler")));
void USART1_IRQHandler()          __attribute__ ((weak, alias ("Default_Handler")));
void USART2_IRQHandler()          __attribute__ ((weak, alias ("Default_Handler")));
void USART3_IRQHandler()          __attribute__ ((weak, alias ("Default_Handler")));
void EXTI15_10_IRQHandler()       __attribute__ ((weak, alias ("Default_Handler")));
void RTCAlarm_IRQHandler()        __attribute__ ((weak, alias ("Default_Handler")));
void USBWakeUp_IRQHandler()       __attribute__ ((weak, alias ("Default_Handler")));

void * g_pfnVectors[0x43] __attribute__ ((section (".isr_vector"))) =
{
&_estack,
&Reset_Handler,
&NMI_Handler,
&HardFault_Handler,
&MemManage_Handler,
&BusFault_Handler,
&UsageFault_Handler,
NULL,
NULL,
NULL,
NULL,
&SVC_Handler,
&DebugMon_Handler,
NULL,
&PendSV_Handler,
&SysTick_Handler,
&WWDG_IRQHandler,
&PVD_IRQHandler,
&TAMPER_IRQHandler,
&RTC_IRQHandler,
&FLASH_IRQHandler,
&RCC_IRQHandler,
&EXTI0_IRQHandler,
&EXTI1_IRQHandler,
&EXTI2_IRQHandler,
&EXTI3_IRQHandler,
&EXTI4_IRQHandler,
&DMA1_Channel1_IRQHandler,
&DMA1_Channel2_IRQHandler,
&DMA1_Channel3_IRQHandler,
&DMA1_Channel4_IRQHandler,
&DMA1_Channel5_IRQHandler,
&DMA1_Channel6_IRQHandler,
&DMA1_Channel7_IRQHandler,
&ADC1_2_IRQHandler,
&USB_HP_CAN1_TX_IRQHandler,
&USB_LP_CAN1_RX0_IRQHandler,
&CAN1_RX1_IRQHandler,
&CAN1_SCE_IRQHandler,
&EXTI9_5_IRQHandler,
&TIM1_BRK_IRQHandler,
&TIM1_UP_IRQHandler,
&TIM1_TRG_COM_IRQHandler,
&TIM1_CC_IRQHandler,
&TIM2_IRQHandler,
&TIM3_IRQHandler,
&TIM4_IRQHandler,
&I2C1_EV_IRQHandler,
&I2C1_ER_IRQHandler,
&I2C2_EV_IRQHandler,
&I2C2_ER_IRQHandler,
&SPI1_IRQHandler,
&SPI2_IRQHandler,
&USART1_IRQHandler,
&USART2_IRQHandler,
&USART3_IRQHandler,
&EXTI15_10_IRQHandler,
&RTCAlarm_IRQHandler,
&USBWakeUp_IRQHandler,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
BootRAM
};

void SystemInit();
void __libc_init_array();
void main();

extern void *_sidata, *_sdata, *_edata;
extern void *_sbss, *_ebss;

#include "stm32f10x.h"

void __attribute__((naked, noreturn)) Reset_Handler()
{
SCB->VTOR = (uint32_t)&g_pfnVectors;
//Normally the CPU should will setup the based on the value from the first entry in the vector table.
//If you encounter problems with accessing stack variables during initialization, ensure
//asm ("ldr sp, =_estack");

void **pSource, **pDest;
for (pSource = &_sidata, pDest = &_sdata; pDest != &_edata; pSource++, pDest++)
*pDest = *pSource;

for (pDest = &_sbss; pDest != &_ebss; pDest++)
*pDest = 0;

SystemInit();
__libc_init_array();
main();
for (;;) ;
}

void __attribute__((naked, noreturn)) Default_Handler()
{
//If we ended up here, an unexpected interrupt has happened (we did not defined the XXX_Handler function for it).
//See the definition of g_pfnVectors above for interrupt handler names.
for (;;) ;
}
5
I looked closely to the startup code and the g_pfnVectors array is initialized properly (there are non-null address where should be), however all of them point to DefaultHandler.

There are also definitions for the aliases in the startup code like this:
void SysTick_Handler()            __attribute__ ((weak, alias ("Default_Handler")));

It seems like the aliases doesn't change when the library is linked.

To be clear: I am trying to use your library with GNU toolchain using Visual Studio and VisualGDB plugin, so I setup the project from scratch. It is possible, that I have ommited some steps necessary for the aliases to work. I attach the configuration of the project (the startup code and linker script are generated by VisualGDB).
6
Reset_Handler executes main. Even the pin is set high. However after several cycles in MillisecondTimer::delay the Default_Handler is triggered. It seems to me like the interrupt for SysTick was not defined.
7
Hello,
I am also trying to use your great-looking library for STM32F103C8. I tried to use the F1_HD settings with linker script from VisualGDB. The blink example hangs in Default_Handler. It seems like no handlers were defined - when I look inside the g_pfnVectors, all vectors have defined Default_Handler.

Could you please take a look at it?