GPIO as PWM output
Risposta
01/09/16 13.28

Hello all,

I want to operate a electrical valve using a PWM signal. Frequency shall be about 10Hz and the duty cycle shall be variable. Is there an example how to setup a PWM signal on a GPIO?

 

Best regards,

Michael

0 (0 Voti)
RE: GPIO as PWM output
Risposta
02/09/16 12.45 come risposta a Michael Walter.

Hello Michael,

Unfortunately we don’t provide any PWM examples right now. But an example of this kind is currently in development.

So for the moment, feel free to try it on your own.
You can find the related PWM interface TIM_timer_ih.h in SDK/xdk110/Platform/Peripherals/includes.

I hope this helps you to make some progress.

Kind regards,
Manuel

0 (0 Voti)
RE: GPIO as PWM output
Risposta
01/12/16 9.48 come risposta a Manuel Cerny.

Hey there,

I've got a further question to PWM. Which GPIO Ports are possible to use as PWM ports? Are those the pin connectors A1, A2 and A3 corresponding to the timer enum

typedef enum TIM_port_e
{
    TIM_CC0, /**< Corresponds to the Timer Channel 0 */
    TIM_CC1, /**< Corresponds to the Timer Channel 1 */
    TIM_CC2, /**< Corresponds to the Timer Channel 2 */
    TIM_CC_MAX /**< Defines the Total number of Timer Channels */
} TIM_port_t;

?

The problem is, that I want to change my actual setting, a motor at GPIO B3 pin, to a brushless motor, needing a PWM signal for setting the motor speed, without resoldering my conductor board.

If it is not possible to set any GPIO port with the predefined PWM function, then I will code my own PWM function for any GPIO port, just setting the port on/off in the right pulsing... or is there any protest against my workaround?

Thanks in advance

Markus

0 (0 Voti)
RE: GPIO as PWM output
Risposta
01/12/16 13.22 come risposta a Markus Thäter.

Hello Markus,

the pins A1, A2 and A3 on the extension board are indeed corresponding to the timer enums and can be configured as PWM ports.
You can also configure the GPIO pin A13 on the extension board as TIM0_CC1 and use it as PWM port. For more information about the pin configuration on the extension board please refer to table 13 on page 49 in the XDK general information guide.

Therefore a workaround to implement an own PWM functionality is not required.

Please don't hesitate to ask if you have further questions.

Kind regards,
Manuel

+1 (1 Voto)
RE: GPIO as PWM output
Risposta
12/12/16 15.04 come risposta a Manuel Cerny.

Hi Manuel,

thanks for your answer. I decided to test the included PWM Timer and failed \-:

My appInitSystem() looks something like this:

void appInitSystem(xTimerHandle xTimer)
{
	(void) xTimer;

	printf("GPIO initializazion\r\n");
	fflush(stdout);
	PTD_portInit();

	setPinStructToValue(&PA0_HandleInfo, GPIO_HANDLE_MAGIC_WORD, gpioPortA, 0, GPIO_DIRECTION_OUTPUT, true, false);
	setPinStructToValue(&PC0_HandleInfo, GPIO_HANDLE_MAGIC_WORD, gpioPortC, 0, GPIO_DIRECTION_OUTPUT, true, false);
	setPinStructToValue(&PC1_HandleInfo, GPIO_HANDLE_MAGIC_WORD, gpioPortC, 1, GPIO_DIRECTION_OUTPUT, true, false);

	//GPIO_init( (GPIO_handle_tp) &PA0_HandleInfo, GPIO_DIRECTION_OUTPUT, GPIO_STATE_ON);
	//GPIO_init( (GPIO_handle_tp) &PC0_HandleInfo, GPIO_DIRECTION_OUTPUT, GPIO_STATE_ON);
	//GPIO_init( (GPIO_handle_tp) &PC1_HandleInfo, GPIO_DIRECTION_OUTPUT, GPIO_STATE_ON);

	printf("TIM enabling\r\n");
	fflush(stdout);
	TIM_enable(PA0Name);

	printf("TIM initialization\r\n");
	fflush(stdout);

	TIMER3_IRQHandler();
	TIM_init(PA0Name);

	//irqHandlerTimer3(PA0Port);

	printf("TIM setting PWM to A0 = %hu%%; C0 = %hu%%; C1 = %hu%% \r\n", loadA0, loadC0, loadC1);
	fflush(stdout);
	TIM_pwmAlterDutyCycle(PA0Name, PA0Port, (uint8_t) loadA0);
	TIM_pwmAlterDutyCycle(PA0Name, PC0Port, (uint8_t) loadC0);
	TIM_pwmAlterDutyCycle(PA0Name, PC1Port, (uint8_t) loadC1);

	TIM_pwmAlterDutyCycle(PA0Name, PA0Port, (uint8_t) loadA0);
	TIM_pwmAlterDutyCycle(PA0Name, PC0Port, (uint8_t) loadC0);
	TIM_pwmAlterDutyCycle(PA0Name, PC1Port, (uint8_t) loadC1);

	printf("Starting timer\r\n");
	fflush(stdout);

	pwmTimer = xTimerCreate( (const char * const ) "PwmTimerTest", ticks, OS_AUTORELOAD_ON,
				NULL, &pwmTimerTest);
	xTimerStart(pwmTimer, UINT32_MAX);

	printf("appInitSystem finished!\r\n");
	fflush(stdout);

The setPinStructToValue() function is

return_t setPinStructToValue(GPIO_handleInfo_t * pin,
		uint16_t magicW,
		GPIO_Port_TypeDef prt,
		uint8_t bitInd,
		GPIO_pinDirections_t Dir,
		_Bool lockDir,
		_Bool initD)
{
	return_t retValue = FAILURE;

	pin->magicWord = magicW;
	pin->port = prt;
	pin->bitIndex = bitInd;
	pin->Direction = Dir;
	pin->initDone = initD;
	pin->lockDirection = lockDir;

	if (pin != NULL)
		retValue = SUCCESS;

	return retValue;
}

To set the struct lying behind the GPIO pins.

Has someone some experience with the PWM timer? My approach doesn't lead to success.

 

Thanks,

Markus

0 (0 Voti)
RE: GPIO as PWM output
Risposta
12/12/16 22.31 come risposta a Markus Thäter.

Hello Markus,

I will try to help you as good as I can. To do so I would ask you to post one missing code snippet which contains the function pwmTimerTest. This is necessary to find a suitable solution for your issue. Otherwise I can only test the initialisation code you provided, without the timer task.

Kind regards,
Manuel

0 (0 Voti)
RE: GPIO as PWM output
Risposta
13/12/16 7.25 come risposta a Manuel Cerny.

The pwmTimerTest() is just there to keep the timer running. I thougt the TIM_pwmAlterDutyCycle() function sets the ports to the needed PWM ,,value'' (as far as it can be called a value).

static void pwmTimerTest(xTimerHandle pxTimer)
{
	(void) pxTimer;
	//printf("ticks = %lu; A0 load = %hu; C0; load = %hu; C1 load = %hu", ticks, loadA0, loadC0, loadC1);
	fflush(stdout);

}

Do I have to do something in my timed function to start the PWM signal?

The timer reload btw is set to 5000ms.

 

Kind regards,

Markus

 

0 (0 Voti)
RE: GPIO as PWM output
Risposta
13/12/16 18.17 come risposta a Markus Thäter.

Hello Markus,

thank you for the missing code snippet. Unfortunately I was not able to make any conclustions why your code is not running as it should. I also spend some time to setup a pwm on my own and faced some difficulties. To solve this I contacted  the second level support to get some advide of the developer perspective.

Unfortunately I need to ask you for patience. I will keep you posted about the progress in this thread.

In the meantime please feel free to open new thread for any other issues.

Kind regards,
Manuel

0 (0 Voti)
RE: GPIO as PWM output
Risposta
14/12/16 16.27 come risposta a Manuel Cerny.

Hello Markus,

I got a very fast response from the development team. I am very sorry to tell you that we currently cannot provide any example code or documentation other than the interface that is already included in the XDK and thus I cannot solve your issue.

Nevertheless please do not hesitate to ask if I can help you with anything else.

Kind regards,
Manuel

0 (0 Voti)
RE: GPIO as PWM output
Risposta
15/12/16 15.37 come risposta a Manuel Cerny.

Hey Manuel,

thanks for your efford. That's kind of sad, that there is no further documentation, 'cause this means in fact that the PWM functionality is not given by now. -sigh-

I am trying to fetch a BLDC controller which is able to process with an analog signal.

 

Kind regards,

Markus

0 (0 Voti)
RE: GPIO as PWM output
Risposta
16/12/16 17.31 come risposta a Markus Thäter.

Markus,

Accessing a BLDC controller sounds like a great application.

Due to my personal experience it should be possible to send PWM signals with the documentation that is available in the XDK-SDK. I am truly certain that this will take some implementation time.

Regardless please do not hesitate to ask if we can support you with anything else. 

We will keep you posted about upcoming XDK features in this community.

Kind regards,
Manuel

0 (0 Voti)
RE: GPIO as PWM output
Risposta
02/06/17 14.27 come risposta a Manuel Cerny.

Hi

I quite sure I am replying too late. I am also facing the same issue.

When I checked, In XDK TIM library is configured for TIMER3, and the pins associated with it are PE0, PE1 and PE2 and NOT PA0, PC0 and PC1 as in the cod snippet. These pins are configured to TIMER0.

Only PE2 is available in the XDK gateway.

I have not done the entire PWM implementation, but I have just initialised it and PWM are generated. Will update once I have complete running code.

static TIMER_InitCC_TypeDef TIM_timerChannelInit = TIMER_INITCC_DEFAULT;

static TIMER_Init_TypeDef TIM_timerInit;


void init(void)
{

	GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 0);
	GPIO_PinModeSet(gpioPortC, 0, gpioModePushPull, 0);
	GPIO_PinModeSet(gpioPortC, 1, gpioModePushPull, 0);
	setupTimer0();
}

static void setupTimer0(void) //Copied from TIM_timer_cc.C and modified for TIMER0
{
    /* Enable  CMU clock for TIMER0 */
    CMU_ClockEnable(TIM_TIMER_CLOCK, true);

    /* Select CC channel parameters */
    TIM_timerChannelInit.eventCtrl = timerEventEveryEdge; /* PRS output pulse, interrupt flag and DMA request set on every capture */
    TIM_timerChannelInit.edge = timerEdgeBoth; /* Input capture edge selected to detect */
    TIM_timerChannelInit.prsSel = timerPRSSELCh0; /* Peripheral reflex system trigger selection set on PRS channel 0 */
    TIM_timerChannelInit.cufoa = timerOutputActionNone; /* Counter underflow output action disabled */
    TIM_timerChannelInit.cofoa = timerOutputActionNone; /* Counter overflow output action disabled */
    TIM_timerChannelInit.cmoa = timerOutputActionToggle; /* Counter match output action set to Toggle on event */
    TIM_timerChannelInit.mode = timerCCModePWM; /* Compare/capture channel mode set for Pulse-Width modulation */
    TIM_timerChannelInit.filter = false; /* digital filter Disabled */
    TIM_timerChannelInit.prsInput = false; /* Select TIMERnCCx */
    TIM_timerChannelInit.coist = false; /* Compare output initial state disabled */
    TIM_timerChannelInit.outInvert = true; /* Invert output from compare/capture channel enabled */

    /* Configure CC channel 0 */
    TIMER_InitCC(TIM_TIMER_TYPE, TIM_CC0, &TIM_timerChannelInit);

    /* Configure CC channel 1 */
    TIMER_InitCC(TIM_TIMER_TYPE, TIM_CC1, &TIM_timerChannelInit);

    /* Configure CC channel 2 */
    TIMER_InitCC(TIM_TIMER_TYPE, TIM_CC2, &TIM_timerChannelInit);

    /* Route CC0 to location 4 (PA0),
     * Route CC1 to location 4 (PC0),
     * Route CC2 to location 4 (PC1)
     * and enable pin */
    TIM_TIMER_TYPE->ROUTE |= (TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC1PEN | TIMER_ROUTE_CC2PEN | TIMER_ROUTE_LOCATION_LOC4);

    /* Set Top Value */
    TIMER_TopSet(TIM_TIMER_TYPE, TIM_TIMER_FREQ_TOP_SET_VALUE);

    /* Set compare value starting at 0 for CC0 - it will be utilised in the interrupt handler */
    TIMER_CompareBufSet(TIM_TIMER_TYPE, TIM_CC0, 0.5*TIM_TIMER_FREQ_TOP_SET_VALUE);

    /* Set compare value starting at 0 for CC1 - it will be utilised in the interrupt handler */
    TIMER_CompareBufSet(TIM_TIMER_TYPE, TIM_CC1, .4*TIM_TIMER_FREQ_TOP_SET_VALUE);

    /* Set compare value starting at 0 for CC2 - it will be utilised in the interrupt handler */
    TIMER_CompareBufSet(TIM_TIMER_TYPE, TIM_CC2, 20);

    /* Select timer parameters */
    TIM_timerInit.enable = true; /* Do not Start counting when init completed */
    TIM_timerInit.debugRun = true; /* Counter shall keep running during debug halt */
    TIM_timerInit.prescale = TIM_TIMER_PRESCALAR_VALUE; /* Prescaling factor, for HFPER clock set as 2*/
    TIM_timerInit.clkSel = timerClkSelHFPerClk; /* Clock selection - Prescaled HFPER*/
    TIM_timerInit.fallAction = timerInputActionNone; /* Action on falling input edge disabled */
    TIM_timerInit.riseAction = timerInputActionNone; /* Action on rising input edge disabled */
    TIM_timerInit.mode = timerModeUp; /* Counting mode - Up-counting*/
    TIM_timerInit.dmaClrAct = false; /* DMA request clear on active disabled */
    TIM_timerInit.quadModeX4 = false; /* Select X2 quadrature decode mode */
    TIM_timerInit.oneShot = false; /* Determines as only counting up once */
    TIM_timerInit.sync = false; /* Timer start/stop/reload by other timers disabled */
}

 

 

 

0 (0 Voti)
RE: GPIO as PWM output
Risposta
06/06/17 15.24 come risposta a Gowrishankar Murali.

Hello Gowrishankar,

first I'd like to welcome you to the XDK community.
Your implementation looks very interesting on the first glance. But I would like to clarify some things first.
Your post indicates that you are facing the same issue as the previous user before, but as you go more into detail, it seems that you are on a way to solve it. Thus, you don't need help right now.

Is that correct?

Kind regards,
Franjo

0 (0 Voti)
RE: GPIO as PWM output
Risposta
07/06/17 18.38 come risposta a Franjo Stjepandic.

Hello Franjo,

Thank You.

Yes I dont need help right now. I have just started developing.

I just think the PWM implementation in the SDK are routed to pins that are not available on the extension bus. They are mapped if, I am not wrong, to LOCATION0 of TIMER3 which corresponds to pin PE14,PE15 and PA15 which are not available on the bus and hence the mentioned solution did not work.

When I changed them to TIMER0 and LOCATION4, they correspond to the pins mentioned in example and in macro naming in TIM library and PWM wa sucessfully generated.

May be I am using an old SDK or I am completely wrong in which case, please correct it. I just posted because this was the only useful thread about PWM implementation in the community.

Thank You

Best Regards

Gowri

0 (0 Voti)
RE: GPIO as PWM output
Risposta
08/06/17 14.45 come risposta a Gowrishankar Murali.

Hello Gowrishankar,

I took a look at the timer3 implementation, too. The timer3 implementation is connected to the corresponding pins of timer3 of the EFM32GG micro controller of the XDK. Unfortunately, as you already mentioned these pins are not available on the extension bus of the XDK. Thus you are correct with your assumptions regarding the SDK of the XDK.

But I am curious, did you use your timer configuration with the variable TIMER_ROUTE_LOCATION_LOC2 to generate a PWM with the available pins for timer2 too?

In any case, I am looking forward to see the complete implementation of yours.

Kind regards,
Franjo

0 (0 Voti)