Hi,
I would like to control the display backlight brightness with the PWM signal and as such configured the GPMC_nCS7 PAD in pad config file as
OUTREG16(&pConfig->CONTROL_PADCONF_GPMC_nCS7, (INPUT_DISABLE | PULL_INACTIVE | MUX_MODE_3));
and written my first stream interface driver PWM. I cannot see any signal generating on pad. Am I doing something wrong ?
#include <omap35xx.h>
#include <ceddk.h>
#define MAX_BRIGHT 255
PHYSICAL_ADDRESS PhysAddr;
OMAP_PRCM_PER_CM_REGS *pClkBase;
OMAP_GPTIMER_REGS *pTimerBase8;
static int round_down = 0;
static int duty_max = 0;
static int duty_min = 0;
static int frequency = 200;
DWORD tldr;
DWORD l;
DWORD tmar;
void timer_set_pwm()
{
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR); //wait until pending bit cleared
l = pTimerBase8->TCLR;
l &= ~(GPTIMER_TLCR_GPO_CFG | GPTIMER_TLCR_SCPWM | GPTIMER_TLCR_PT | (0x03 << 10));
l |= GPTIMER_TLCR_PT;
l |= GPTIMER_TCLR_TRG_OVERFLOWMATCH;
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR);
pTimerBase8->TCLR = l;
}
void timer_set_load()
{
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR);
l = pTimerBase8->TCLR;
l |= GPTIMER_TLCR_AR;
while((pTimerBase8->TWPS & 0xFF) & (GPTIMER_TWPS_TCLR));
pTimerBase8->TCLR = l;
while((pTimerBase8->TWPS & 0xFF) & (GPTIMER_TWPS_TLDR));
pTimerBase8->TLDR = tldr;
while((pTimerBase8->TWPS & 0xFF) & (GPTIMER_TWPS_TTGR));
pTimerBase8->TTGR = 0;
}
void timer_set_match(DWORD t_mar)
{
while((pTimerBase8->TWPS & 0xFF) & (GPTIMER_TWPS_TCLR));
l = pTimerBase8->TCLR;
l |= GPTIMER_TLCR_CE;
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR);
pTimerBase8->TCLR = l;
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TMAR);
pTimerBase8->TMAR = t_mar;
}
void timer_set_start()
{
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR);
l = pTimerBase8->TCLR;
l |= GPTIMER_TLCR_ST;
while((pTimerBase8->TWPS & 0xFF) & GPTIMER_TWPS_TCLR);
pTimerBase8->TCLR = l;
}
DWORD PWM_Init(DWORD dwContext)
{
pTimerBase8 = NULL;
pClkBase = NULL;
if(pTimerBase8 == NULL)
{
PhysAddr.LowPart = OMAP_GPTIMER8_REGS_PA;
PhysAddr.HighPart = 0;
pTimerBase8 = (OMAP_GPTIMER_REGS*)MmMapIoSpace(PhysAddr, sizeof(OMAP_GPTIMER_REGS), FALSE);
if(pTimerBase8 == NULL)
{
OutputDebugString(L"TIMERBASE cannot match to Physical address %d\r\n");
return FALSE;
}
}
if(pClkBase == NULL)
{
PhysAddr.LowPart = OMAP_PRCM_PER_CM_REGS_PA;
PhysAddr.HighPart = 0;
pClkBase = (OMAP_PRCM_PER_CM_REGS*)MmMapIoSpace(PhysAddr, sizeof(OMAP_PRCM_PER_CM_REGS), FALSE);
if(pClkBase == NULL)
{
OutputDebugString(L"TIMECLKBASE cannot match to Physical address %d\r\n");
return FALSE;
}
}
OutputDebugString(L"PWM - Driver Version 1.00 started++\r\n");
//Enable the clocks
pClkBase->CM_FCLKEN_PER |= CM_CLKEN_GPT8;
pClkBase->CM_ICLKEN_PER |= CM_CLKEN_GPT8;
l = pTimerBase8->TIOCP;
l |= 0x02 << 3; // Set to smart-idle mode
l |= 0x2 << 8; // Set clock activity to perserve f-clock on idle
pTimerBase8->TIOCP = l;
//Match hardware reset default of posted mode
pTimerBase8->TSICR = GPTIMER_TSICR_POSTED;
timer_set_pwm();
tldr = 0xFFFFFFFF - 26000000 / frequency - 1;
tmar = tldr + 26000000 / frequency;
timer_set_load();
timer_set_match(tmar);
timer_set_start();
OutputDebugString(L"PWM - Driver Version 1.00 Finished--\r\n");
return TRUE;
}
I would like to call driver by passing the brightness intensity as parameter
DWORD PWM_Write(DWORD dwData, PBYTE pBuf, DWORD Len)
{
int div = 0;
div = pBuf[0];
OutputDebugString(L"PWM-Write Operation++++\r\n");
if(div - round_down < 0)
{
div = 0;
}
if(div + round_down > MAX_BRIGHT)
{
div = MAX_BRIGHT;
}
div = div * div / MAX_BRIGHT;
div = div * (duty_max - duty_min) / 100 + duty_min * MAX_BRIGHT / 100;
tmar = tldr + 26000000 / frequency * div /255;
timer_set_match(tmar);
OutputDebugString(L"PWM-Write Operation----\r\n");
return 1;
}