biradarajinkya wrote on Monday, January 28, 2013:
Hello all,
I am using** STR912 comstick **with freeRTOS to generate a variable width PWM using TIM1.
Generation of variable width PWM is done.
Now I have two tasks both generating PWM but of different variable widths.
I want to switch between these two tasks on some event - high or low on a GPIO.
For that I need binary semaphore since I have one resource to share i.e TIM1.
If we use no semaphore with only one task it works fine.
When I use binary semaphore it dose not work .
//global variables
xSemaphoreHandle xSemaphore = NULL;
const unsigned long ONArrayOC2R = {0x94CA,0x1982,0x0CBC,0x0CBC,0x0CBC,0x1982,0x0CBC,0x0CBC,0x0CBC,
0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,
0x0CBC,0x1982,0x1982,0x0CBC,0x1982,0x0CBC,0x0CBC,0x0CBC,0x1982,
0x1982,0x1982,0xCBC};
const unsigned long ArrayOC1R = {0x64C3,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,
0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,
0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,0x075D,
0x075D,0x075D,0x75D};
const unsigned long OFFArrayOC2R = {0x94CA,0x1982,0x0CBC,0x0CBC,0x0CBC,0x1982,0x0CBC,0x0CBC,0x0CBC,
0x1982,0x1982,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x0CBC,
0x0CBC,0x0CBC,0x0CBC,0x0CBC,0x1982,0x0CBC,0x1982,0x0CBC,0x0CBC,
0x0CBC,0x1982,0x0CBC};
static unsigned int PulseCount=0, RepeatSignal=0, ON_OFF_Flag;
My main is -
void main( void )
{
#ifdef DEBUG
debug();
#endif
/* Setup any hardware that has not already been configured by the low
level init routines. */
prvSetupHardware();
vSemaphoreCreateBinary( xSemaphore ); // create binary semaphore
/* Start either the uIP TCP/IP stack or the lwIP TCP/IP stack. */
#ifdef STACK_UIP
/* Finally, create the WEB server task. */
//xTaskCreate( vuIP_Task, “uIP”, configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY - 1, NULL );
xTaskCreate( vPWM_ON_Task, “PWM_AC_ON”, configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY - 1,NULL);
xTaskCreate( vPWM_OFF_Task, “PWM_AC_OFF”, configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY - 2,NULL);
#endif
#ifdef STACK_LWIP_130
vStartEthernetTasks(mainNET_TASK_BASE_PRIORITY);
#endif
/* Start the scheduler.
NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
The processor MUST be in supervisor mode when vTaskStartScheduler is
called. The demo applications included in the FreeRTOS.org download switch
to supervisor mode prior to main being called. If you are not using one of
these demo application projects then ensure Supervisor mode is used here. */
//portBASE_TYPE xHigherPriorityTaskWoken = 0;
vTaskStartScheduler();
/* We should never get here as control is now taken by the scheduler. */
for( ;; );
}
then I have the task definitions as -
void vPWM_ON_Task(void)
{
TIM_DeInit(TIM1);
VIC_DeInit();
TIM_ClearFlag(TIM1,TIM_FLAG_OC2);
portENTER_CRITICAL();
{
VIC_Config(TIM1_ITLine,VIC_IRQ, 0);
VIC_ITCmd(TIM1_ITLine,ENABLE);
VIC_InitDefaultVectors();
TIM1->SR &= 0x0000;
VIC0->FSR = 0x0000;
}
portEXIT_CRITICAL();
if(GPIO_ReadBit(GPIO4,GPIO_Pin_7)!= Bit_RESET) //this is the event for loading particular array of variable widths in ISR
{
ON_OFF_Flag = 1;
gpio9_led_on();
}
/*************************************************/
TIM1->OC1R = 0x00FF;
TIM1->CR2 = 0x0810; //set prescaler and interrupt enable
TIM1->CR1 = 0x8250; //start the timer
TIM1->OC2R = 0x0FFF;
/*************************************************/
xSemaphoreTake( xSemaphore, configTICK_RATE_HZ / 2 );
}
The ISR is -
void PWM_TIM1_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = 0;
/* Give the semaphore in case the uIP task needs waking. */
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
/* Clear the interrupt. */
TIM1->SR = 0x0000;
VIC0->FSR = 0x0000;
if(ON_OFF_Flag ==0)
TIM1->OC2R = OFFArrayOC2R; //first array
else
TIM1->OC2R = ONArrayOC2R; //second array
TIM1->OC1R = ArrayOC1R;
PulseCount++ ;
if(PulseCount >= 30)
{
RepeatSignal++;
PulseCount = 0 ;
}
VIC0->VAR = 0;
asm(“SUBS pc,lr,#4”); //returning from ISR
}
Second task is-
void vPWM_OFF_Task(void)
{
TIM_DeInit(TIM1);
VIC_DeInit();
TIM_ClearFlag(TIM1,TIM_FLAG_OC2);
portENTER_CRITICAL();
{
VIC_Config(TIM1_ITLine,VIC_IRQ, 0);
VIC_ITCmd(TIM1_ITLine,ENABLE);
VIC_InitDefaultVectors();
TIM1->SR &= 0x0000;
VIC0->FSR = 0x0000;
}
portEXIT_CRITICAL();
if(GPIO_ReadBit(GPIO4,GPIO_Pin_7)== Bit_RESET)
{
ON_OFF_Flag = 0;
gpio9_led_on();
}
/*************************************************/
TIM1->OC1R = 0x00FF;
TIM1->CR2 = 0x0810;
TIM1->CR1 = 0x8250;
TIM1->OC2R = 0x0FFF;
/*************************************************/
xSemaphoreTake( xSemaphore, configTICK_RATE_HZ / 2 );
}
Is there something that I am doing wrong?
How to make use of binary semaphores to get it working