📄 pwm.c
字号:
/*******************************************************************************************
函数名称: PWM_GetFrequency
描 述: 获取定时器 0 和 1 输出的 PWM 频率
输入参数: DWORD t_num: 定时器编号: 0 或 1
输出参数: DWORD *frequency: PWM 的输出频率
返 回: TRUE: 成功; FALSE: 失败
********************************************************************************************/
const BYTE MUX_Tbl[4] = {2, 4, 8, 16};
BOOL PWM_GetFrequency(DWORD t_num, DWORD *frequency)
{
DWORD freq;
DWORD t_Mux;
if (t_num > 1) return FALSE;
freq = m_s3c2410_pclk / ((v_PWMregs->TCFG0 & 0xFF) + 1); /* 预分频 */
if (t_num == 0)
{
t_Mux = v_PWMregs->TCFG1 & 0x0F; /* [3:0]位 */
if (t_Mux <= 3)
freq = freq / MUX_Tbl[t_Mux];
else
return FALSE;
freq = freq / v_PWMregs->TCNTB0;
}
else
{
t_Mux = (v_PWMregs->TCFG1 & 0xF0) << 4; /* [7:4]位 */
if (t_Mux <= 3)
freq = freq / MUX_Tbl[t_Mux];
else
return FALSE;
freq = freq / v_PWMregs->TCNTB1;
}
*frequency = freq;
return TRUE;
}
/*******************************************************************************************
函数名称: PWM_Init
描 述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置
输出参数: 无
返 回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD PWM_Init(DWORD dwContext)
{
PROCESSOR_INFO procInfo;
DWORD dwBytesReturned;
// 取得相关寄存器的虚拟地址空间
PWM_InitializeAddresses();
/* get the information of the device */
if (!KernelIoControl(IOCTL_PROCESSOR_INFORMATION, NULL, 0, &procInfo, sizeof(PROCESSOR_INFO), &dwBytesReturned))
{
m_s3c2410_pclk = DEFAULT_S3C2410X_PCLK;
RETAILMSG(TRUE, (TEXT("WARNING: DAC_Init:: failed to obtain processor frequency - using default value (%d).\r\n"), m_s3c2410_pclk));
}
else
{
m_s3c2410_pclk = procInfo.dwClockSpeed;
RETAILMSG(TRUE, (TEXT("INFO: DAC_Init:: using processor frequency reported by the OAL (%d).\r\n"), m_s3c2410_pclk));
}
#if 0
RETAILMSG(TRUE, (TEXT("v_pIOPregs->GPBCON is 0x%x).\r\n"), v_pIOPregs->GPBCON));
RETAILMSG(TRUE, (TEXT("v_PWMregs->TCFG0 is 0x%x).\r\n"), v_PWMregs->TCFG0));
RETAILMSG(TRUE, (TEXT("v_PWMregs->TCFG1 is 0x%x).\r\n"), v_PWMregs->TCFG1));
RETAILMSG(TRUE, (TEXT("v_PWMregs->TCMPB0 is 0x%x).\r\n"), v_PWMregs->TCMPB0));
RETAILMSG(TRUE, (TEXT("v_PWMregs->TCNTB0 is 0x%x).\r\n"), v_PWMregs->TCNTB0));
RETAILMSG(TRUE, (TEXT("v_PWMregs->TCON is 0x%x).\r\n"), v_PWMregs->TCON));
#endif
RETAILMSG(1, (TEXT("::: PWM_Init Sucessfully. \r\n")));
return (DWORD)1;
}
/*******************************************************************************************
函数名称: DllEntry
描 述: 驱动程序动态库入口
输入参数:
输出参数:
返 回:
*******************************************************************************************/
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("PWM: DLL_PROCESS_ATTACH\r\n")));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("PWM: DLL_PROCESS_DETACH\r\n")));
break;
}
return (TRUE);
}
/*******************************************************************************************
函数名称: PWM_Close
描 述: 驱动程序关闭函数
输入参数: DWORD Handle: 驱动程序引用事例句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL PWM_Close(DWORD Handle)
{
if (g_OpenCount > 0)
{
PWM_ConfigPWMDefault(0); /* 恢复 PWM 相关硬件为默认值 */
PWM_ConfigPWMDefault(1);
}
g_OpenCount = 0;
return TRUE;
} // PWM_Close
/*******************************************************************************************
函数名称: PWM_Deinit
描 述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL PWM_Deinit(DWORD dwContext)
{
PWM_ConfigPWMDefault(0); /* 恢复 PWM 相关硬件为默认值 */
PWM_ConfigPWMDefault(1);
// 释放申请的虚拟空间
if (v_pIOPregs)
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
if (v_PWMregs)
VirtualFree((PVOID) v_PWMregs, 0, MEM_RELEASE);
g_OpenCount = 0;
return TRUE;
} // PWM_Deinit
/*******************************************************************************************
函数名称: PWM_Open
描 述: 打开驱动程序
输入参数: DWORD dwData : 设备驱动程序句柄
DWORD dwAccess : 访问请求代码,是读和写的组合
DWORD dwShareMode: 共享模式
输出参数:
返 回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD PWM_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
if (g_OpenCount > 0)
return 0;
PWM_ConfigPWMDefault(0); /* 恢复 PWM 相关硬件为默认值 */
PWM_ConfigPWMDefault(1);
g_OpenCount++;
return g_OpenCount;
} // PWM_Open
/*******************************************************************************************
函数名称: PWM_IOControl
描 述: 驱动程序 I/O 请求
输入参数:
输出参数:
返 回: TRUE: 成功 FALSE: 失败
*******************************************************************************************/
BOOL
PWM_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
BOOL bErr = FALSE;
switch (dwIoControlCode)
{
case IOCTL_PWM_SET_PRESCALER: /* 设置预分频值 */
if (nInBufSize >= 2) /* 需要2个字节缓冲区 */
{
PWM_SetPrescaler(pInBuf[0], pInBuf[1]);
bErr = TRUE;
}
break;
case IOCTL_PWM_SET_DIVIDER:
if (nInBufSize >= 2) /* 需要2个字节缓冲区 */
bErr = PWM_SetDivider(pInBuf[0], pInBuf[1]);
// 设置分频值 (定时器编号, 分频值)
break;
case IOCTL_PWM_START:
if (nInBufSize >= 3) /* 需要3个字缓冲区 */
{
DWORD t_num = *((DWORD *)pInBuf);
DWORD cycle = *((DWORD *)(pInBuf + 4));
DWORD duty = *((DWORD *)(pInBuf + 8));
#if 0
RETAILMSG(TRUE, (TEXT("t_num is 0x%x).\r\n"), t_num));
RETAILMSG(TRUE, (TEXT("cycle is 0x%x).\r\n"), cycle));
RETAILMSG(TRUE, (TEXT("duty is 0x%x).\r\n"), duty));
#endif
bErr = PWM_StartPWM(t_num, cycle, duty);
}
break;
case IOCTL_PWM_GET_FREQUENCY:
if ((nInBufSize >= 0) && (nOutBufSize > 0))
{
DWORD t_num = *((DWORD *)pInBuf);
bErr = PWM_GetFrequency(t_num, (DWORD *)pOutBuf);
*pBytesReturned = 1;
}
break;
default:
break;
}
return bErr;
} // PWM_IOControl
/*******************************************************************************************
函数名称: PWM_Read
描 述: 从 IIC 从机读取数据
输入参数: DWORD Handle : 驱动程序引用事例句柄
LPVOID pBuffer : 接收缓冲区
DWORD dwNumBytes: 要读的字节数
输出参数: 无
返 回: 实际读到字节数
*******************************************************************************************/
DWORD PWM_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
/*******************************************************************************************
函数名称: PWM_Write
描 述: 向 IIC 从机发送数据
输入参数:
输出参数:
返 回: 成功发送的字节数
*******************************************************************************************/
DWORD PWM_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
return 0;
}
/*******************************************************************************************
函数名称: PWM_Seek
描 述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数:
输出参数:
返 回:
*******************************************************************************************/
DWORD PWM_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
return 0;
}
/*******************************************************************************************
函数名称: PWM_PowerUp
描 述: 电源上电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void PWM_PowerUp(void)
{
return;
}
/*******************************************************************************************
函数名称: PWM_PowerDown
描 述: 电源下电驱动处理函数
输入参数:
输出参数:
返 回: 无
*******************************************************************************************/
void PWM_PowerDown(void)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -