📄 pit.c
字号:
/* * File: pit.c * Purpose: Driver for the Programmable Interrupt Timer */#include "common.h"#include "pit.h"/* * Initialize Variables */pit_isr pit_example_isr[4];static uint32 pow(uint8 u8Pow2);static void pit_countdown_isr(void);uint8 u8PITSemaphore = PIT_IDLE;uint8 u8CountdownPIT = 0;/********************************************************************//* * Initialize PIT * * 1. Disable PIT Module * 2. Set Prescaler * 3. Set Modulus * 4. Set Reload according to mode */int8 PITInit(uint8 u8Prescaler, uint16 u16Modulus, uint8 u8PITModule){ MCF_PIT_PCSR(u8PITModule) = 0x00 | MCF_PIT_PCSR_PRE(u8Prescaler); MCF_PIT_PMR(u8PITModule) = u16Modulus; /* Enable reload for periodic mode */ MCF_PIT_PCSR(u8PITModule) |= MCF_PIT_PCSR_RLD; /* Enable Interrupts for PIT0 (55) and PIT1(56) */ MCF_INTC1_CIMR = MCF_INTC_CIMR_CIMR(43); MCF_INTC1_CIMR = MCF_INTC_CIMR_CIMR(44); MCF_INTC1_CIMR = MCF_INTC_CIMR_CIMR(45); MCF_INTC1_CIMR = MCF_INTC_CIMR_CIMR(46); MCF_INTC1_ICR43 = MCF_INTC_ICR_IL(3); MCF_INTC1_ICR44 = MCF_INTC_ICR_IL(3); MCF_INTC1_ICR45 = MCF_INTC_ICR_IL(3); MCF_INTC1_ICR46 = MCF_INTC_ICR_IL(3); /* Set the interrupt handlers in the vector table */ mcf5xxx_set_handler(128 + 43, (ADDRESS)pit0_isr); mcf5xxx_set_handler(128 + 44, (ADDRESS)pit1_isr); mcf5xxx_set_handler(128 + 45, (ADDRESS)pit2_isr); mcf5xxx_set_handler(128 + 46, (ADDRESS)pit3_isr); return 0; }/********************************************************************//* * Enable PIT Interrupts and set ISR */void PIT_EnableInts(pit_isr pit_isr_ptr, uint8 u8PITModule){ MCF_PIT_PCSR(u8PITModule) |= MCF_PIT_PCSR_PIE; pit_example_isr[u8PITModule] = pit_isr_ptr;}/********************************************************************//* * Disable PIT Interrupts */void PIT_DisableInts(uint8 u8PITModule){ MCF_PIT_PCSR(u8PITModule) &= ~MCF_PIT_PCSR_PIE;}/********************************************************************//* * Enable PIT */void PIT_Start(uint8 u8PITModule){ PIT_ENABLE(u8PITModule);}/********************************************************************//* * Stop PIT */void PIT_Stop(uint8 u8PITModule){ PIT_DISABLE(u8PITModule);}/********************************************************************//* * PIT Countdown * Takes a time in milliseconds, and then creates a countdown timer * to execute pit_countdown_isr when the counter reaches zero. * * Parameters: * u32Period Time in milliseconds to countdown * u8PITModule The PIT module (0 or 1) to use * * Return Values: * 0 for OK */int8 PIT_CountDown(uint32 u32Period, uint8 u8PITModule){ pit_isr pit_temp_isr; /* Backup the ISR */ pit_temp_isr = pit_example_isr[u8PITModule]; /* Disable reloading of the PIT */ MCF_PIT_PCSR(u8PITModule) &= ~MCF_PIT_PCSR_RLD; /* Enable overwrite */ MCF_PIT_PCSR(u8PITModule) |= MCF_PIT_PCSR_OVW; if ( PIT_SetPeriod (u32Period,u8PITModule) == -1){ return -1; } PIT_EnableInts(pit_countdown_isr, u8PITModule); u8CountdownPIT = u8PITModule; u8PITSemaphore = PIT_COUNTING; PIT_Start(u8PITModule); /* Wait until countdown finishes */ while (u8PITSemaphore != PIT_DONE) ; u8PITSemaphore = PIT_IDLE; /* Reload the original ISR */ pit_example_isr[u8PITModule] = pit_temp_isr; return 0; }/********************************************************************//* * PIT Countdown ISR */static void pit_countdown_isr(void){ u8PITSemaphore = PIT_DONE; MCF_PIT_PCSR(u8CountdownPIT) &= ~MCF_PIT_PCSR_EN;}/********************************************************************//* * Set PIT Frequency in Hz */uint32 PIT_SetFreq (uint32 u32FreqHz, uint8 u8PITModule) { uint8 i; uint32 u32Modulus; for (i=0; i < 16; i++){ u32Modulus = (FSYS_KHZ/2*1000) / (u32FreqHz*pow(i)); if (u32Modulus < 65535){ /* Try to find a good prescaler */ MCF_PIT_PCSR(u8PITModule) &= ~MCF_PIT_PCSR_PRE(0x0F); MCF_PIT_PCSR(u8PITModule) |= MCF_PIT_PCSR_PRE(i); MCF_PIT_PMR(u8PITModule) = u32Modulus; return ((FSYS_KHZ/2*1000) / (pow(i)*u32Modulus)); } } return -1;}/********************************************************************//* * Set PIT Period in milliseconds */uint32 PIT_SetPeriod (uint32 u32Periodms, uint8 u8PITModule) { uint8 i; uint32 u32Modulus; for (i=0; i < 16; i++){ u32Modulus = ((FSYS_KHZ/2) * u32Periodms) / pow(i); if (u32Modulus < 65535){ /* Try to find a good prescaler */ MCF_PIT_PCSR(u8PITModule) &= ~MCF_PIT_PCSR_PRE(0x0F); MCF_PIT_PCSR(u8PITModule) |= MCF_PIT_PCSR_PRE(i); MCF_PIT_PMR(u8PITModule) = u32Modulus; return ((pow(i)*u32Modulus) / (FSYS_KHZ/2)); } } return -1; }/********************************************************************//* * PIT0 ISR */__interrupt__ void pit0_isr(){ MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF; pit_example_isr[0]();}/********************************************************************//* * PIT1 ISR */__interrupt__ void pit1_isr(){ MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; pit_example_isr[1]();}/********************************************************************//* * PIT2 ISR */__interrupt__ void pit2_isr(){ MCF_PIT2_PCSR |= MCF_PIT_PCSR_PIF; pit_example_isr[2]();}/********************************************************************//* * PIT1 ISR */__interrupt__ void pit3_isr(){ MCF_PIT3_PCSR |= MCF_PIT_PCSR_PIF; pit_example_isr[3]();}/********************************************************************//* * Recursively calculate value to the power of 2 */static uint32 pow(uint8 u8Pow2){ if (!u8Pow2){ return 1; } else{ return (2*pow(u8Pow2-1)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -