SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By biradarajinkya
#155200
Hello Guys,
I am using STR912 comstick, ported freeRTOS on it and trying to generate IR remote control signal.
This kit has provided port-4 for user usage, which provides one Vcc and GND pin.
One of port 4 GPIO pin i am configuring for PWM(pin 2) out and one as switch(pin 7).

I am flashing the .out file using openocd+telnet.
After flashing We need to reset the kit to start the flashed program.
When i reset it will start polling GPIO on state change it is expected to get a Pulse sequence.
on state change it enters in ConfigurePWMfor_AC_ON() for generating pulse sequence which I am able to see on oscilloscope. after that control should return and should start polling GPIO but program counter is stuck on 0x0000 002C when i say "halt" in telnet debug.
As .map file says this location is some ".invec" section.
----------------------------------------------------------------------------------------------
"A1": place at 0x00000000 { ro section .intvec };
Section Kind Address Size Object
------- ---- ------- ---- ------
"A1": 0x198
.intvec ro code 0x00000000 0x198 91x_vect.o [1]
- 0x00000198 0x198
-----------------------------------------------------------------------------------------------
I am putting my code here to get some solution/bug and for reference also.
I am not getting what is happening here.

//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------Initialization--------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void ConfigurePWMfor_AC_ON(void);
int PollGPIO(void);
void vAC_ON_OFF_Task(void *pvParameters);
void vPWM_ON_Task(void *pvParameters);
void vPWM_OFF_Task(void *pvParameters);
xTaskHandle vAcOnOffPoll_Handle, xPWM_ON_Task_Handle, xPWM_OFF_Task_Handle;

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};
typedef enum
{
POLL_INPUT_GPIO,
INPUT_GPIO_ASSERTED,
SW_AC_ON2OFF,
SW_AC_OFF2ON,
PWM_DONE
//AC_CNTRL_NEEDED
}CNTRL_STATES;

typedef enum
{
ON,
OFF
}AC_STATES ;

static unsigned long *ptrONArrayOC2R = &ONArrayOC2R[0];
static unsigned long *ptrOFFArrayOC2R = &OFFArrayOC2R[0];

static unsigned int OFFArrayPulseCount=0,ONArrayPulseCount=0, PulseCountOC2R=0, PulseCountOC1R=0, PulseCount=0,RepeatSignal=0, ON_OFF_Flag=0;
static unsigned int OverFlag=0, PassArray=0;
AC_STATES PreviousState = OFF;
AC_STATES RequestedState = ON ;
static int PWMBusy=0;
CNTRL_STATES CntrlState = INPUT_GPIO_ASSERTED ;
//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------void main-------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void main( void )
{
#ifdef DEBUG
debug();
#endif

/* Setup any hardware that has not already been configured by the low
level init routines. */
prvSetupHardware();

xTaskCreate( vAC_ON_OFF_Task, "AC_ON_OFF_Poll", configMINIMAL_STACK_SIZE * 3, NULL, mainCHECK_TASK_PRIORITY - 1, NULL);

/* 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. */

vTaskStartScheduler();

/* We should never get here as control is now taken by the scheduler. */
for( ;; );
}

//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------Task defination----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void vAC_ON_OFF_Task(void *pvParameters)
{
while(1)
{
static int BusyFlag =0;
while(!PWMBusy)
{
BusyFlag = PollGPIO();
}
if (BusyFlag)
{
ConfigurePWMfor_AC_ON();
}

for(int i=0; i>4000; i++)
for(int i=0; i>5000; i++)
{}
}
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------PollGPIO function----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
int PollGPIO(void)
{
static int GPIOBitSatus ;
GPIOBitSatus = GPIO_ReadBit(GPIO4,GPIO_Pin_7) ;

switch (GPIOBitSatus) {

case Bit_RESET:
RequestedState = OFF;
GPIO_WriteBit(GPIO4, GPIO_Pin_0, Bit_RESET);
if(PreviousState != RequestedState) {
PWMBusy=1;
CntrlState = SW_AC_OFF2ON;
PreviousState = OFF;
}
break;
case Bit_SET :
RequestedState = ON;
GPIO_WriteBit(GPIO4, GPIO_Pin_0, Bit_SET);
if(PreviousState != RequestedState) {
PWMBusy=1;
CntrlState = SW_AC_ON2OFF;
PreviousState = ON;
}
break;
default: break;
}
return PWMBusy;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------ ConfigurePWMfor_AC_ON function -----------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void ConfigurePWMfor_AC_ON(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();

TIM1->OC1R = 0x00FF;
TIM1->CR2 = 0x0810;
TIM1->CR1 = 0x8250;
TIM1->OC2R = 0x0FFF;
if(PulseCount >= 30)
{
TIM_DeInit(TIM1);
PulseCount=0;
}
PWMBusy =0;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------ PWM_TIM1_IRQHandler routine -----------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void PWM_TIM1_IRQHandler(void)
{
/* Clear the interrupt. */
TIM1->SR = 0x0000;
VIC0->FSR = 0x0000;

TIM1->OC2R = OFFArrayOC2R[PulseCount];

TIM1->OC1R = ArrayOC1R[PulseCount];

if(PulseCount < 30)
PulseCount++;
else
TIM1->CR1 &= 0x7FFF; //STOP timer counter so next interrupt will not occur

VIC0->VAR = 0;
asm("SUBS pc,lr,#4");
}