Page 1 of 2

[SOLVED] Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Tue Jun 13, 2017 8:06 pm
by thanhvu94
I need to generate the PWM signal to the pin IO1 (PB8, using TIMER10), and I have modify the main.c in the Eclipse project workspace on the Virtual Machine of Crazyflie like below. The clean and build doesn't give any error, but I cannot see any PWM output signal with the oscilloscope:

Code: Select all

/* Personal configs */
#include "FreeRTOSConfig.h"
#include <stdint.h>

/* FreeRtos includes */
#include "FreeRTOS.h"
#include "task.h"
#include <stdint.h>

/* Project includes */
#include "config.h"
#include "platform.h"
#include "system.h"
#include "usec_time.h"

#include "led.h"

/* ST includes */
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"

/*Predefined macros*/
#define IR_TX_CARRIER_FREQ			56000
#define IR_TX_CARRIER_PWM_PERIOD	(SystemCoreClock/IR_TX_CARRIER_FREQ)
#define IR_TX_DELAY_PRESCALER		(84-1)
#define ENABLE 		1
#define IR_TX_CARRIER_TIMER                   TIM10
#define IR_TX_CARRIER_TIMER_RCC               RCC_APB2Periph_TIM10
#define IR_TX_CARRIER_TIMER_CH_Init           TIM_OC1Init
#define IR_TX_CARRIER_TIMER_CH_PreloadConfig  TIM_OC1PreloadConfig
#define IR_TX_CARRIER_TIMER_CH_SetCompare     TIM_SetCompare1
#define IR_TX_CARRIER_RCC                     RCC_AHB1Periph_GPIOB
#define IR_TX_CARRIER_PORT                    GPIOB
#define IR_TX_CARRIER_PIN                     GPIO_Pin_8

void irTxInit(void);

int main()
{
  //Initialize the platform.
  platformInit();

  //Launch the system task that will initialize and start everything
  systemLaunch();

  //Start the FreeRTOS scheduler
  vTaskStartScheduler();

  //PWM
  irTxInit();
  TIM10->CCR1 = 50*(65535/100);
  GPIO_SetBits(GPIOB,GPIO_Pin_5);

  //TODO: Move to platform launch failed
  ledInit();
  ledSet(0, 1);
  ledSet(1, 1);

  //Should never reach this point!
  while(1);

  return 0;
}


void irTxInit(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(IR_TX_CARRIER_RCC, ENABLE);
  RCC_APB2PeriphClockCmd(IR_TX_CARRIER_TIMER_RCC, ENABLE);

  // Configure the GPIO for the timer output
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Pin = IR_TX_CARRIER_PIN;
  GPIO_Init(IR_TX_CARRIER_PORT, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM10);

  // Time base configuration
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(IR_TX_CARRIER_TIMER, &TIM_TimeBaseStructure);

  // PWM channel configuration
  TIM_OCStructInit(&TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  // Configure Output Compare for PWM
  IR_TX_CARRIER_TIMER_CH_Init(IR_TX_CARRIER_TIMER, &TIM_OCInitStructure);
  IR_TX_CARRIER_TIMER_CH_PreloadConfig(IR_TX_CARRIER_TIMER,     TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(IR_TX_CARRIER_TIMER, ENABLE);
  TIM_Cmd(IR_TX_CARRIER_TIMER, ENABLE);
}
When I flash to the STM32F4 using CrazyRadio, the console is like this and it seems normal:

Code: Select all

17:24:21 **** Build of configuration Default for project crazyflie-firmware ****
make cload 
python3 -m cfloader  flash  cf2.bin stm32-fw
Restart the Crazyflie you want to bootload in the next
 10 seconds ...
 done!
Connected to bootloader on Crazyflie 2.0 (version=0x10)
Target info: nrf51 (0xFE)
Flash pages: 232 | Page size: 1024 | Buffer pages: 1 | Start page: 88
144 KBytes of flash available for firmware image.
Target info: stm32 (0xFF)
Flash pages: 1024 | Page size: 1024 | Buffer pages: 10 | Start page: 16
1008 KBytes of flash available for firmware image.

Flashing 1 of 1 to stm32 (fw): 184595 bytes (181 pages) ..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10..........10.1
Reset in firmware mode ...

17:25:16 Build Finished (took 54s.83ms)
Is there anything wrong with the code? I did use quite the same code on STM32F4 Discovery for PWM generation and it worked, so I think the code is correct.

The only thing I'm doubted about is that there are some bug signs in some lines of code just like in the image attached. When I click in the bug, it says:

Code: Select all

Symbol .... could not be resolved, return 0
The .... is a name of a variable in #define part. I don't know there these bugs come from. I don't think it is because I haven't defined the path or the preprocessor for the project, because when I right click a variable/macro "See the Definition" or "See the Declaration", it shows up the source file where that variable/macro is defined.

I will appreciate any help. Please tell me if you see any problem.

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 8:04 am
by tobias
The reason why it is not working is because it is in the main.c file and after the FreeRTOS scheduler has started so the code will never be executed. I think the easiest way to run you code is to create a deck driver as described in the wiki.

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 8:44 am
by thanhvu94
tobias wrote:The reason why it is not working is because it is in the main.c file and after the FreeRTOS scheduler has started so the code will never be executed. I think the easiest way to run you code is to create a deck driver as described in the wiki.
Thank you so much for yuor hint. However, when I look into the code, I'm not familiar with it. Is it possible to create a .c file in deck and write in C as usual (just like what I wrote above for PWM)?

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 8:51 am
by arnaud
There is a howto page on the wiki that explains step by step how to add code in the Crazyflie as a deck driver: https://wiki.bitcraze.io/doc:crazyflie: ... deck:howto

Once you have done it, you will have a C file with an init function where you can write your code to be run when the Crazylfie starts.

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 10:00 am
by thanhvu94
I followed what you told me to do with Deck Drivers but I'm still not successful, there is nothing new printed in the console after I load the program into Crazyflie. Here is my pwm_irled.c created in crazyflie-firmware/src/deck/driver/src :

Code: Select all

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "deck.h"
#include "debug.h"
#include "deck_core.h"

/* ST includes */
#include "stm32f4xx.h"
#include "FreeRTOS.h"

/*Predefined macros*/
#define IR_TX_CARRIER_FREQ			56000
#define IR_TX_CARRIER_PWM_PERIOD	(SystemCoreClock/IR_TX_CARRIER_FREQ)
#define IR_TX_DELAY_PRESCALER		(84-1)
#define ENABLE 		1
#define IR_TX_CARRIER_TIMER                   TIM10
#define IR_TX_CARRIER_TIMER_RCC               RCC_APB2Periph_TIM10
#define IR_TX_CARRIER_TIMER_CH_Init           TIM_OC1Init
#define IR_TX_CARRIER_TIMER_CH_PreloadConfig  TIM_OC1PreloadConfig
#define IR_TX_CARRIER_TIMER_CH_SetCompare     TIM_SetCompare1
#define IR_TX_CARRIER_RCC                     RCC_AHB1Periph_GPIOB
#define IR_TX_CARRIER_PORT                    GPIOB
#define IR_TX_CARRIER_PIN                     GPIO_Pin_8

static void pwmInit(DeckInfo *info)
{
	  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	  TIM_OCInitTypeDef  TIM_OCInitStructure;
	  GPIO_InitTypeDef GPIO_InitStructure;

	  RCC_AHB1PeriphClockCmd(IR_TX_CARRIER_RCC, ENABLE);
	  RCC_APB2PeriphClockCmd(IR_TX_CARRIER_TIMER_RCC, ENABLE);

	  // Configure the GPIO for the timer output
	  GPIO_StructInit(&GPIO_InitStructure);
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	  GPIO_InitStructure.GPIO_Pin = IR_TX_CARRIER_PIN;
	  GPIO_Init(IR_TX_CARRIER_PORT, &GPIO_InitStructure);

	  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM10);

	  // Time base configuration
	  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
	  TIM_TimeBaseStructure.TIM_Prescaler = 0;
	  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	  TIM_TimeBaseInit(IR_TX_CARRIER_TIMER, &TIM_TimeBaseStructure);

	  // PWM channel configuration
	  TIM_OCStructInit(&TIM_OCInitStructure);
	  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	  TIM_OCInitStructure.TIM_Pulse = 0;
	  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	  //TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

	  // Configure Output Compare for PWM
	  IR_TX_CARRIER_TIMER_CH_Init(IR_TX_CARRIER_TIMER, &TIM_OCInitStructure);
	  IR_TX_CARRIER_TIMER_CH_PreloadConfig(IR_TX_CARRIER_TIMER, TIM_OCPreload_Enable);

	  TIM_ARRPreloadConfig(IR_TX_CARRIER_TIMER, ENABLE);
	  TIM_Cmd(IR_TX_CARRIER_TIMER, ENABLE);

	  TIM10->CCR1 = 50*(65535/100);
	  DEBUG_PRINT("PWM Inited.\n");
}

static bool pwmTest()
{
	DEBUG_PRINT("PWM initlized successfully. \n");
	return true;
}

static const DeckDriver pwm_ir = {
	//.usedPeriph = DECK_USING_TIMER10,
	.usedGpio = DECK_USING_IO_1,
	.name = "myPWM",
	.init = pwmInit,
	.test = pwmTest,
};

DEC_DRIVER(pwm_ir);
I want to use Timer10 tto output PWM to IO1 using .usedPeriph = DECK_USING_TIMER10, but there is no macro defined for TIM10 in deck.h file.

Here is my config.mk file in crazyflie-firmware/tools/make/:

Code: Select all

# Load a deck driver that has no OW memory
CFLAGS += -DDECK_FORCE=myPWM

DEBUG=1
Also, there are some warnings about DEC_DRIVER when I compile, but I still can flash/load into the memory:

Code: Select all

bitcraze@bitcraze-vm:~/projects/crazyflie-firmware$ make
  CLEAN_VERSION
  VTMPL version.c
  CC    version.o
  CC    pwm_irled.o
src/deck/drivers/src/pwm_irled.c:105:1: warning: data definition has no type or storage class
 DEC_DRIVER(pwm_ir);
 ^
src/deck/drivers/src/pwm_irled.c:105:1: warning: type defaults to 'int' in declaration of 'DEC_DRIVER'
src/deck/drivers/src/pwm_irled.c:105:1: warning: parameter names (without types) in function declaration
  LD    cf2.elf
  COPY  cf2.hex
  COPY  cf2.bin
  DFUse cf2.dfu
Crazyflie 2.0 build!
Build 0:df11f2550b81 (2017.05) MODIFIED
Version extracted from git
Crazyloader build!
   text	   data	    bss	    dec	    hex	filename
 123928	   2392	  58576	 184896	  2d240	cf2.elf
Can you tell me where is the problem?

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 11:39 am
by tobias
I think I found one problem and the clue is DEC_DRIVER(pwm_ir); ;)

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Wed Jun 14, 2017 9:20 pm
by thanhvu94
tobias wrote:I think I found one problem and the clue is DEC_DRIVER(pwm_ir); ;)
I have tried to blink the LED exactly like this tutorial (https://wiki.bitcraze.io/doc:crazyflie: ... mware:deck). There is no error when make and make cload, but the IO1 (PB8) pin is still not high when I measure by oscilloscope. I don't know what is happening. The only thing that seems to be strange to me is there are some bug signs in some lines of the code, and on the left, some source file have red x like there is some errors (although those source files are cloned from github of crazyflie and I didn't modify anything).

Should I delete the VM Crazyflie and reinstall/add the new VM Crazyflie again? May it help?

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Thu Jun 15, 2017 7:50 am
by tobias
Maybe I didn't give enough information. You are missing the K en DECK_DRIVER(pwm_ir).

Edit: Also check out the howto if you haven't already.

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Thu Jun 15, 2017 12:48 pm
by thanhvu94
tobias wrote:Maybe I didn't give enough information. You are missing the K en DECK_DRIVER(pwm_ir).

Edit: Also check out the howto if you haven't already.
I succeed in the LED and DEBUG_PRINT example. However, still struggle to make PWM works. I will use pin IO1 and TIMER10. Do I need to declare
.usedGpio = DECK_USING_IO_1 and .usedPeriph or not? I notice that there is no macro for TIM10 (just like DECK_USING_TIMER3).

Re: Cannot generate the PWM signal to the breakout board of the STM32F405 microcontroller

Posted: Thu Jun 15, 2017 5:01 pm
by thanhvu94
I have just succeeded in generating the PWM anyway. Thank you so much for your help