📄 pwmpdd.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on
// your install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//-----------------------------------------------------------------------------
//
// File: pwmpdd.c
//
// Implementation of PWM Driver Platform Device Driver
//
// This file implements the device specific functions for PWM.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include "csp.h"
#include "pwmdefs.h"
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
extern UINT32 BSPSetPWMClockSource(void);
extern void BSPPwmIomuxSetPin(void);
extern BOOL BSPPwmSetClockGatingMode(BOOL);
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
#define PWMPRESCALER_VAL 0 // divide by 1
#define PWMWATERMARK_VAL 0 // FIFO empty flag is set when there are
// more than or equal to 1 empty slots in FIFO
#define PWMOUTCONFIG_VAL 0 // output pin is set at rollover and cleared at comparsion
#define PWMSAMPLEREPEAT_VAL 0 // use each sample once
#define UPPER_LIMIT 65535 // upper limit of 16bits register
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
static PCSP_PWM_REG g_pPwm;
static CRITICAL_SECTION g_hPwmLock;
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
static void Reset(void);
//------------------------------------------------------------------------------
//
// Function: PwmStart
//
// This function is used to start the Pwm. It will set the enable
// bit in pwm control register. This function should be called to
// enable the pwm after configuring the pwm.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void PwmStart(void)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmStart\r\n")));
// Enable the pwm
INSREG32(&g_pPwm->PWM_CR, CSP_BITFMASK(PWM_CR_EN), CSP_BITFVAL(PWM_CR_EN, PWM_CR_EN_ENABLE));
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmStart\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: PwmStop
//
// This function stops the Pwm. It will
// clear the enable bit in Pwm control register.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void PwmStop(void)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmStop\r\n")));
// Disable the pwm
INSREG32(&g_pPwm->PWM_CR, CSP_BITFMASK(PWM_CR_EN),CSP_BITFVAL(PWM_CR_EN, PWM_CR_EN_DISABLE));
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmStop\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: PwmPlaySample
//
// This function is used to play the pwm sample
//
// Parameters:
// SampleBuffer
// [in] pwm sample conform to pwmSample_t structure
//
// SampleSize
// [in] Size of the pwmSample_t structure
// Returns:
// TRUE - If success.
//
// FALSE - If failed
//
//------------------------------------------------------------------------------
BOOL PwmPlaySample(LPCVOID SampleBuffer, int SampleSize )
{
pPwmSample_t PwmSampleBuffer;
DWORD dwStartTime, dwElapsedTime;
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmPlaySample\r\n")));
PwmSampleBuffer = (pPwmSample_t)SampleBuffer;
// check for the limits of the sample and period
if(PwmSampleBuffer->sample > UPPER_LIMIT || PwmSampleBuffer->period > UPPER_LIMIT)
return FALSE;
if(SampleSize != sizeof(PwmSample_t))
return FALSE;
EnterCriticalSection(&g_hPwmLock);
OUTREG32(&g_pPwm->PWM_SAR, PwmSampleBuffer->sample);
OUTREG32(&g_pPwm->PWM_PR, PwmSampleBuffer->period);
PwmStart();
dwStartTime = GetTickCount();
do{
dwElapsedTime = GetTickCount() - dwStartTime;
}while(dwElapsedTime < PwmSampleBuffer->duration);
PwmStop();
LeaveCriticalSection(&g_hPwmLock);
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmPlaySample\r\n")));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: PwmDeinit
//
// Frees up the register space and deletes critical
// section for deinitialization.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void PwmDeinit(void)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmRelease\r\n")));;
// free the virtual space allocated for PWM memory map
if (g_pPwm != NULL)
{
VirtualFree((void *) g_pPwm, 0, MEM_RELEASE);
g_pPwm = NULL;
}
// Delete the critical section
DeleteCriticalSection(&g_hPwmLock);
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmRelease\r\n")));;
return;
}
//------------------------------------------------------------------------------
//
// Function: PwmInitialize
//
// This function will allocate mapping for PWM registers, initialize critical section,
// reset the PWM, and initialize of PWM control register
//
// Parameters:
// None
//
// Returns:
// TRUE - If success
//
// FALSE - If failure
//
//------------------------------------------------------------------------------
BOOL PwmInitialize(void)
{
PHYSICAL_ADDRESS phyAddr;
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmInitialize\r\n")));;
phyAddr.QuadPart = CSP_BASE_REG_PA_PWM;
g_pPwm = (PCSP_PWM_REG) MmMapIoSpace(phyAddr, sizeof(CSP_PWM_REG), FALSE);
// check if Map Virtual Address failed
if (g_pPwm == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PwmInitialize: MmMapIoSpace failed!\r\n")));
goto Error;
}
// Initialize PWM critical section
InitializeCriticalSection(&g_hPwmLock);
BSPPwmIomuxSetPin();
BSPPwmSetClockGatingMode(TRUE);
Reset();
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmInitialize\r\n")));;
return TRUE;
Error:
PwmDeinit();
return FALSE;
}
//------------------------------------------------------------------------------
//
// Function: PwmReset
//
// This function will reset PWM.
//
// Parameters:
// None
//
// Returns:
// None
//
//------------------------------------------------------------------------------
void PwmReset(void)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmReset\r\n")));
EnterCriticalSection(&g_hPwmLock);
Reset();
LeaveCriticalSection(&g_hPwmLock);
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmReset\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: PwmReadRegister
//
// This function is used to read the current values of all PWM registers
//
// Parameters:
// readBuf
// [in] pwm sample conform to pwmSample_t structure
//
// Count
// [in] number of uint32 to be read
//
// Returns:
// TRUE - If success.
//
// FALSE - If the Pwm is not allocated.
//
//------------------------------------------------------------------------------
BOOL PwmReadRegister(UINT32* readBuf, DWORD Count)
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("++PwmReadRegister\r\n")));
EnterCriticalSection(&g_hPwmLock);
if(Count < (6 * sizeof(UINT32)))
return FALSE;
readBuf[0] = INREG32(&g_pPwm->PWM_CR);
readBuf[1] = INREG32(&g_pPwm->PWM_SR);
readBuf[2] = INREG32(&g_pPwm->PWM_IR);
readBuf[3] = INREG32(&g_pPwm->PWM_SAR);
readBuf[4] = INREG32(&g_pPwm->PWM_PR);
readBuf[5] = INREG32(&g_pPwm->PWM_CNR);
LeaveCriticalSection(&g_hPwmLock);
DEBUGMSG(ZONE_FUNCTION, (TEXT("--PwmReadRegister\r\n")));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: Reset
//
// This function is used to trigger a reset in PWM Control Register,
// and load preset value in Control Register
//
// Parameters:
// none.
//
// Returns:
// none.
//
//------------------------------------------------------------------------------
static void Reset(void)
{
UINT32 clkSrc;
// Disable PWM and clear all configuration bits
OUTREG32(&g_pPwm->PWM_CR, 0);
// Assert software reset for the timer
INSREG32BF(&g_pPwm->PWM_CR, PWM_CR_SWR, PWM_CR_SWR_RESET);
// Wait for the software reset to complete
while(EXTREG32BF(&g_pPwm->PWM_CR, PWM_CR_SWR));
// Get BSP-specific clock source
clkSrc = BSPSetPWMClockSource();
OUTREG32(&g_pPwm->PWM_CR,
(CSP_BITFVAL(PWM_CR_EN, PWM_CR_EN_DISABLE)) | // disables the PWM
(CSP_BITFVAL(PWM_CR_REPEAT, PWMSAMPLEREPEAT_VAL)) | // use sample with no repeat
(CSP_BITFVAL(PWM_CR_SWR, PWM_CR_SWR_NORESET)) | // no SW reset
(CSP_BITFVAL(PWM_CR_PRESCALER, PWMPRESCALER_VAL)) | // prescaler value of 1
(CSP_BITFVAL(PWM_CR_CLKSRC, clkSrc)) | // bsp set clock source
(CSP_BITFVAL(PWM_CR_POUTC, PWMOUTCONFIG_VAL)) | // PWM output configuration
(CSP_BITFVAL(PWM_CR_HCTR, PWM_CR_HCTR_DISABLE)) | // no half-word data swap
(CSP_BITFVAL(PWM_CR_BCTR, PWM_CR_BCTR_DISABLE)) | // no byte data swap
(CSP_BITFVAL(PWM_CR_DBGEN, PWM_CR_DBGEN_INACTIVE)) | // pwm inactive in debug mode
(CSP_BITFVAL(PWM_CR_WAITEN, PWM_CR_WAITEN_INACTIVE)) | // pwm inactive in wait mode
(CSP_BITFVAL(PWM_CR_DOZEN, PWM_CR_DOZEN_INACTIVE)) | // pwm inactive in doze mode
(CSP_BITFVAL(PWM_CR_STOPEN, PWM_CR_STOPEN_INACTIVE)) | // pwm inactive in stop mode
(CSP_BITFVAL(PWM_CR_FWM, PWMWATERMARK_VAL))); // FIFO empty flag set condition
// disable all interrupts
OUTREG32(&g_pPwm->PWM_IR,
(CSP_BITFVAL(PWM_IR_FIE, PWM_IR_FIE_DISABLE)) |
(CSP_BITFVAL(PWM_IR_RIE, PWM_IR_RIE_DISABLE)) |
(CSP_BITFVAL(PWM_IR_CIE, PWM_IR_CIE_DISABLE)));
// Clear Interrupt Status Bits
INSREG32(&g_pPwm->PWM_SR, CSP_BITFMASK(PWM_SR_CMP), CSP_BITFVAL(PWM_SR_CMP, PWM_SR_CMP_STATUS_CLEAR));
}
//------------------------------------------------------------------------------
//
// Function: SetPwmPower
//
// This function is to initiailize the power management for PWM driver.
//
// Parameters:
// power
// [in] pointer to POWER_CAPABILITIES structure
//
// Returns:
// none.
//
//------------------------------------------------------------------------------
void SetPwmPower(PPOWER_CAPABILITIES power)
{
power->DeviceDx = 0x15; // D0, D2 & D4
// supported power & latency info
power->Power[D0] = PwrDeviceUnspecified; // mW
power->Power[D2] = PwrDeviceUnspecified; // mW
power->Power[D4] = PwrDeviceUnspecified; // mW
power->Latency[D0] = 0; // mSec
power->Latency[D2] = 0; // mSec
power->Latency[D4] = 0; // mSec
power->WakeFromDx = 0; // no device wake
power->InrushDx = 0; // no inrush
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -