/****************************************************************************
* *
* Copyright (c) 2008 Nuvoton Electronics Corp. All rights reserved. *
* *
*****************************************************************************/
/****************************************************************************
* FILENAME
* pwm_demo.c
*
* VERSION
* 1.0
*
* DESCRIPTION
* The PWM test program of Nuvoton NUC900 MCU
*
* DATA STRUCTURES
* None
*
* FUNCTIONS
* PWM_Item
* PWM_Timer
* PWM_TimerDZ
*
* HISTORY
* 2007-11-23 Ver 1.0 Created
*
* REMARK
* None
****************************************************************************/
#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "kapi.h"
#include "diag.h"
#include "wbio.h"
#else
#include "wblib.h"
#endif
#include "NUC900_pwm.h"
#ifdef ECOS
#define MSG diag_printf
#define GETCH diag_getc
#else
#define MSG sysprintf
#define GETCH sysGetChar
#endif
#ifdef ECOS
static cyg_handle_t thread_handle;
static cyg_thread thread;
#define STACKSIZE (128*1024)
#define Successful 0
#define Fail -1
static UINT8 _Statck[STACKSIZE];
#endif
VOID PWM_Item(VOID);
INT PWM_Timer(INT timer_num);
INT PWM_TimerDZ(INT dz_num);
#ifdef ECOS
VOID PWM_Sample (cyg_addrword_t tdata);
#else
VOID PWM_Sample (VOID);
#endif
int main (VOID)
{
//int i;
#ifdef ECOS
cyg_thread_create(22, PWM_Sample, 0, "pwm_smpl", _Statck, STACKSIZE, &thread_handle, &thread);
cyg_thread_resume(thread_handle);
#else
PWM_Sample();
#endif
return 0;
}
#ifdef ECOS
void PWM_Sample (cyg_addrword_t tdata)
#else
void PWM_Sample (VOID)
#endif
{
INT item;
do
{
PWM_Item();// Show menu
item = GETCH();// Get user key
switch(item)
{
case '0': PWM_Timer(PWM_TIMER0); break;
case '1': PWM_Timer(PWM_TIMER1); break;
case '2': PWM_Timer(PWM_TIMER2); break;
case '3': PWM_Timer(PWM_TIMER3); break;
case '4': PWM_TimerDZ(PWM_TIMER0); break;
case '5': PWM_TimerDZ(PWM_TIMER2); break;
default: break;
}
}while (item != 27);//do until user press ESC
}
VOID PWM_Item(VOID)
{
MSG("\n\n\n");
MSG("+------------------------------------------------------+\n");
MSG("| Nuvoton PWM Diagnostic Code |\n");
MSG("+------------------------------------------------------+\n");
MSG("| PWM Timer0 test - [0] |\n");
MSG("| PWM Timer1 test - [1] |\n");
MSG("| PWM Timer2 test - [2] |\n");
MSG("| PWM Timer3 test - [3] |\n");
MSG("| PWM Dead zone 0 test - [4] |\n");
MSG("| PWM Dead zone 1 test - [5] |\n");
MSG("+------------------------------------------------------+\n");
MSG("| Quit - [ESC] |\n");
MSG("+------------------------------------------------------+\n");
MSG("Please Select : \r\n");
}
INT PWM_Timer(INT timer_num)
{
typeTIMERVALUE timervalue;
typePWMSTATUS PWMSTATUS;
INT nLoop=0;
INT nStatus=0;
INT nInterruptInterval=0;
PWMSTATUS.PDR=0;
PWMSTATUS.InterruptFlag=FALSE;
pwmInit();
pwmOpen(timer_num);
// Change PWM Timer setting
pwmIoctl(timer_num, SET_CSR, 0, CSRD16);
pwmIoctl(timer_num, SET_CP, 0, 249);
pwmIoctl(timer_num, SET_DZI, 0, 0);
pwmIoctl(timer_num, SET_INVERTER, 0, PWM_INVOFF);
pwmIoctl(timer_num, SET_MODE, 0, PWM_ONESHOT);
pwmIoctl(timer_num, DISABLE_DZ_GENERATOR, 0, 0);
pwmIoctl(timer_num, ENABLE_PWMGPIOOUTPUT, 0, 0);
timervalue.field.cnr=59999;
timervalue.field.cmr=4999;
pwmWrite(timer_num, (PUCHAR)(&timervalue), sizeof(timervalue));
MSG("PWM Timer%d one shot mode test\nPWM. Timer interrupt will occure soon.", timer_num);
//Start PWM Timer
pwmIoctl(timer_num, START_PWMTIMER, 0, 0);
while(1)
{
nLoop++;
if(nLoop%100000 == 0)
{
MSG(".");
}
nStatus=pwmRead(timer_num, (PUCHAR)&PWMSTATUS, sizeof(PWMSTATUS));
if(nStatus != Successful)
{
MSG("PWM read error, ERR CODE:%d",nStatus);
pwmClose(timer_num);
return Fail;
}
if(PWMSTATUS.InterruptFlag==TRUE)
{
MSG("\n\nPWM Timer interrupt occurred!\n\n");
break;
}
}
// Change PWM Timer setting
pwmIoctl(timer_num, SET_CSR, 0, CSRD16);
pwmIoctl(timer_num, SET_CP, 0, 255);
pwmIoctl(timer_num, SET_DZI, 0, 0);
pwmIoctl(timer_num, SET_INVERTER, 0, PWM_INVOFF);
pwmIoctl(timer_num, SET_MODE, 0, PWM_TOGGLE);
pwmIoctl(timer_num, DISABLE_DZ_GENERATOR, 0, 0);
pwmIoctl(timer_num, ENABLE_PWMGPIOOUTPUT, 0, 0);
nInterruptInterval=30000;
timervalue.field.cnr=nInterruptInterval;
timervalue.field.cmr=4999;
pwmWrite(timer_num, (PUCHAR)(&timervalue), sizeof(timervalue));
MSG("PWM Timer%d toggle mode test\nPWM Timer interrupt interval will decrease gradually\n", timer_num);
//Start PWM Timer
pwmIoctl(timer_num, START_PWMTIMER, 0, 0);
nLoop=0;
while(1)
{
nStatus=pwmRead(timer_num, (PUCHAR)&PWMSTATUS, sizeof(PWMSTATUS));
if(nStatus != Successful)
{
MSG("PWM read error, ERR CODE:%d",nStatus);
pwmClose(timer_num);
return Fail;
}
if(PWMSTATUS.InterruptFlag==TRUE)
{
MSG("PWM Timer interrupt [%d], CNR:%d\n",nLoop,nInterruptInterval);
nInterruptInterval/=2;
timervalue.field.cnr=nInterruptInterval;
timervalue.field.cmr=4999;
pwmWrite(timer_num, (PUCHAR)(&timervalue), sizeof(timervalue));
nLoop++;
if(nLoop==10)
{
break;
}
}
}
pwmIoctl(timer_num, STOP_PWMTIMER, 0, 0);
pwmClose(timer_num);
MSG("\nPWM Timer %d test finish\nPress any key to continue....", timer_num);
GETCH();
return Successful;
}
INT PWM_TimerDZ(INT timer_num)
{
typePWMSTATUS PWMSTATUS0;
typePWMSTATUS PWMSTATUS1;
INT nLoop=0;
INT nStatus0=0,nStatus1=0;
PWMSTATUS0.PDR=0;
PWMSTATUS0.InterruptFlag=FALSE;
PWMSTATUS1.PDR=0;
PWMSTATUS1.InterruptFlag=FALSE;
pwmInit();
pwmOpen(timer_num);
pwmOpen(timer_num+1);
pwmIoctl(timer_num, ENABLE_PWMGPIOOUTPUT, 0, 0);
pwmIoctl(timer_num, SET_DZI, 0, 0x50);
pwmIoctl(timer_num, ENABLE_DZ_GENERATOR, 0, 0);
pwmIoctl(timer_num, START_PWMTIMER, 0, 0);
pwmIoctl(timer_num+1, START_PWMTIMER, 0, 0);
nLoop=0;
while(1)
{
nStatus0=pwmRead(timer_num, (PUCHAR)&PWMSTATUS0, sizeof(PWMSTATUS0));
nStatus1=pwmRead(timer_num+1, (PUCHAR)&PWMSTATUS1, sizeof(PWMSTATUS1));
if(nStatus0 != Successful || nStatus1 != Successful)
{
MSG("PWM read error, ERR CODE:%d %d",nStatus0,nStatus1);
pwmClose(timer_num);
pwmClose(timer_num+1);
return Fail;
}
if(PWMSTATUS0.InterruptFlag==TRUE && PWMSTATUS1.InterruptFlag==TRUE)
{
nLoop++;
if(nLoop==10)
{
break;
}
}
}
pwmIoctl(timer_num, STOP_PWMTIMER, 0, 0);
pwmIoctl(timer_num+1, STOP_PWMTIMER, 0, 0);
pwmClose(timer_num);
pwmClose(timer_num+1);
MSG("PWM Dead zone test finish\nPress any key to continue....");
GETCH();
return Successful;
}