cancel
Showing results for 
Search instead for 
Did you mean: 

STR91x library - timer example doesn't work?

pontus
Associate II
Posted on June 25, 2008 at 05:42

STR91x library - timer example doesn't work?

7 REPLIES 7
pontus
Associate II
Posted on May 17, 2011 at 09:52

Hi

I am using the Hitex STR912 eval board (HiTOP + GCC toolchain) and I want to set up a timer that toggles a GPIO pin (I want to make a software pwm later on). The original timer interrupt toggles GPIO 4.1, but I want to toggle 6.0. This shouldn't make any difference I think? The software doesn't toggle 6.0 anyway (nor does it work with the original code, GPIO 4.1). Any hints as to what is going on?

This is my code (I have also attached all my project files as a zip archive):

/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************

* File Name : main.c

* Author : MCD Application Team

* Version : V2.0

* Date : 12/07/2007

* Description : Program using the TIM peripheral.

* Shows TIM1 configured in Output Compare mode with interrupt

* generation.

********************************************************************************

* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH

* CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS

* A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT

* OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT

* OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION

* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.

*******************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include ''91x_lib.h''

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

TIM_InitTypeDef TIM_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

/* Private function prototypes -----------------------------------------------*/

void SCU_Configuration(void);

/* Private functions ---------------------------------------------------------*/

/*******************************************************************************

* Function Name : main

* Description : Main program

* Input : None

* Output : None

* Return : None

*******************************************************************************/

int main(void)

{

#ifdef DEBUG

debug();

#endif

/* Configure the system clocks */

SCU_Configuration();

/* Init VIC */

VIC_DeInit();

/* initialize VICs default vector registers*/

VIC_InitDefaultVectors();

/* GPIO P6.0 configuration */

GPIO_DeInit(GPIO6);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;

GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;

GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt1;

GPIO_Init(GPIO6,&GPIO_InitStructure);

/* TIM1 Structure Initialization */

TIM_StructInit(&TIM_InitStructure);

/* TIM1 Configuration in Output Compare Mode */

TIM_DeInit(TIM1); /* TIM1 Deinitialization */

TIM_InitStructure.TIM_Mode = TIM_OCM_CHANNEL_1;

TIM_InitStructure.TIM_OC1_Modes = TIM_TIMING;

TIM_InitStructure.TIM_Clock_Source = TIM_CLK_APB;

TIM_InitStructure.TIM_Clock_Edge = TIM_CLK_EDGE_FALLING;

TIM_InitStructure.TIM_Prescaler = 0x20;

TIM_InitStructure.TIM_Pulse_Length_1 = 0x100;

TIM_Init (TIM1, &TIM_InitStructure);

/*Enable TIM1 Output Compare1 interrupt*/

TIM_ITConfig(TIM1, TIM_IT_OC1, ENABLE);

/*Configure TIM1 interrupt in VIC*/

VIC_Config(TIM1_ITLine, VIC_IRQ, 0);

VIC_ITCmd(TIM1_ITLine, ENABLE);

/* Start the counter of TIM1 */

TIM_CounterCmd(TIM1, TIM_START);

while(1);

}

/*******************************************************************************

* Function Name : SCU_Configuration

* Description : Configures the Master clock @96MHz and the Main system

* configuration and Clocks (FMI,PLL,RCLK,HCLK,PCLK ,MCLK )

* and enable clocks for peripherals.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void SCU_Configuration(void)

{

SCU_MCLKSourceConfig(SCU_MCLK_OSC); /* Default configuration */

/*wait state insertion :This function should be executed from SRAM when*/

/*booting from bank1 to avoid Read-While-Write from the Same Bank.*/

FMI_Config(FMI_READ_WAIT_STATE_2, FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE,

FMI_LVD_ENABLE, FMI_FREQ_HIGH);/*Insert 2 Wait States for read*/

SCU_PLLFactorsConfig(192, 25, 2); /* PLL factors Configuration based on*/

/* a OSC/Crystal value = 25Mhz*/

SCU_PLLCmd(ENABLE); /* PLL Enable and wait for Locking*/

SCU_RCLKDivisorConfig(SCU_RCLK_Div1); /* RCLK @96Mhz */

SCU_HCLKDivisorConfig(SCU_HCLK_Div1); /* AHB @96Mhz */

SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);/* FMI @96Mhz */

SCU_PCLKDivisorConfig(SCU_PCLK_Div2); /* APB @48Mhz */

SCU_MCLKSourceConfig(SCU_MCLK_PLL); /* MCLK @96Mhz */

SCU_APBPeriphClockConfig(__TIM01, ENABLE); /*Enable the clock for TIM0 and TIM1*/

SCU_AHBPeriphClockConfig(__VIC,ENABLE); /*Enable the clock for VIC*/

SCU_APBPeriphClockConfig(__GPIO4, ENABLE); /* Enable the clock for GPIO4 */

}

/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/

and in 91x_it.c:

void TIM1_IRQHandler(void)

{

/* clear Output Compare 1 flag*/

TIM_ClearFlag(TIM1, TIM_FLAG_OC1);

/* Reset TIM1 Counter*/

TIM_CounterCmd(TIM1, TIM_CLEAR);

/*toggle GPIO P4.1*/

flag ^=1;

if (flag) GPIO_WriteBit(GPIO6,GPIO_Pin_0,Bit_SET);

else GPIO_WriteBit(GPIO6,GPIO_Pin_0,Bit_RESET);

/*write any value to VIC0 VAR*/

VIC0->VAR = 0xFF;

}

rgreenthal
Associate II
Posted on May 17, 2011 at 09:52

Hi

Look at the New FW Lib, note the reinit of the registers for the timer.

The silicon doesn't do this properly for you. I had the same problem ST Micro needs to put this in their Errata. I noted other areas that look like the Soft/Warm Reset doesn't reinit the registers properly & just scrambles them, so check on this.

I am also new to the STR series, but used the Intel Xscale ARM9 (PAX290)

void TIM_DeInit(TIM_TypeDef *TIMx)

{

if((TIMx == TIM0)||(TIMx == TIM1))

{

SCU_APBPeriphReset(__TIM01, DISABLE); /* TIM0 & TIM1 Reset's off */

}

else

{

SCU_APBPeriphReset(__TIM23, DISABLE); /* TIM2 & TIM3 Reset's off */

}

/* Set all the TIMx registers to thier default values */

TIMx->OC1R = 0x8000;

TIMx->OC2R = 0x8000;

TIMx->CR1 = 0x0;

TIMx->CR2 = 0x1;

TIMx->CNTR = 0x1234;

TIMx->SR = 0x0;

}

Good luck

Ralph

amira1
Associate II
Posted on May 17, 2011 at 09:52

Hello all,

There is no problem with reinit of the registers for the timer.

pontus.froessander,

The timer example of our library works fine. It's normal that the GPIO6 is not toggled in your code since you are not enabling its clock as I see. In fact, please try to add this line :

SCU_APBPeriphClockConfig(__GPIO6, ENABLE);

in the SCU_Configuration function.

Best regards,

mirou.

pontus
Associate II
Posted on May 17, 2011 at 09:52

Thank you for your replies

I changed the code to

SCU_APBPeriphClockConfig(__GPIO6, ENABLE);

but no change.

rgreenthal:

What do you mean? I have the latest revision of the library and the codes in the 91x_tim.c matches your code exactly.

I am running out of ideas soon :). Any more tips?

mattb
Associate II
Posted on May 17, 2011 at 09:52

I too am seeing the same issue with the ''TIM example 2'' sample. Note that I am using the new version 2 of the firmware library. A couple of notes:

- The timer rate in the sample is too fast to see the LED...try the following lines:

TIM_InitStructure.TIM_Prescaler = 0xFF;

TIM_InitStructure.TIM_Pulse_Length_1 = 0xFFFB;

- If you do this, you will see that the IRQ handler actually fires off twice in a row (the LED will quickly light and then go out). It fires off at the correct frequency, but then gets two right together. Therefore it toggles it on and then right away toggles it off (or vice-versa depending on the intial state of the ''flag'' variable).

Any thoughts on why it fires twice in a row for each interrupt?

mattb
Associate II
Posted on May 17, 2011 at 09:52

So I figured it out. I seems that you must reset the counter _before_ you clear the OC1 flag. So change your ISR to be:

void TIM1_IRQHandler(void)

{

/* Reset TIM1 Counter*/

TIM_CounterCmd(TIM1, TIM_CLEAR);

/* clear Output Compare 1 flag*/

TIM_ClearFlag(TIM1, TIM_FLAG_OC1);

...

}

Maybe resetting the counter takes longer and if you've cleared the flag before hand it queues up another interrupt incorrectly. If this is the case, the ST samples should be changed.

- Matt

pontus
Associate II
Posted on May 17, 2011 at 09:52

Ah nice. I will try this. Thanks a lot!