|
- #include "config.h"
- #include "timer.h"
-
- /* Setup a 16-bit timer to overflow at the specified frequency
- timer = 1-9
- freq = Hz, or 0 to disable the timer.
- interrupt = 1 to enable interrupt, 0 to disable
- */
- int timer_setup_16bit(int timer, uint32_t freq, int ie)
- {
- uint32_t period;
- uint16_t prescale;
-
- if (timer < 1 || timer > 9)
- return -1;
-
- if (freq == 0) {
- switch(timer) {
- case 1: T1CONbits.TON = 0; return 0;
- case 2: T2CONbits.TON = 0; return 0;
- case 3: T3CONbits.TON = 0; return 0;
- case 4: T4CONbits.TON = 0; return 0;
- case 5: T5CONbits.TON = 0; return 0;
- case 6: T6CONbits.TON = 0; return 0;
- case 7: T7CONbits.TON = 0; return 0;
- case 8: T8CONbits.TON = 0; return 0;
- case 9: T9CONbits.TON = 0; return 0;
- }
- }
-
- /* Figure out timer prescaler and period values. Max period
- is 65535 (PRx = 65534) so we can still attain 100% duty
- cycle when using a timer for PWM. */
- if ((period = FCY / (freq * 1L)) <= 65535)
- prescale = 0;
- else if ((period = FCY / (freq * 8L)) <= 65535)
- prescale = 1;
- else if ((period = FCY / (freq * 64L)) <= 65535)
- prescale = 2;
- else if ((period = FCY / (freq * 256L)) <= 65535)
- prescale = 3;
- else
- prescale = 3, period = 65535;
- if (period > 0)
- period -= 1;
-
- switch (timer) {
- #define __timer_setup_case(x) \
- case x: \
- T##x##CONbits.TON = 0; \
- T##x##CONbits.TCKPS = prescale; \
- PR##x = period; \
- T##x##CONbits.TON = 1; \
- break
- __timer_setup_case(1);
- __timer_setup_case(2);
- __timer_setup_case(3);
- __timer_setup_case(4);
- __timer_setup_case(5);
- __timer_setup_case(6);
- __timer_setup_case(7);
- __timer_setup_case(8);
- __timer_setup_case(9);
- #undef __timer_setup_case
- }
-
- /* Enable interrupt if requested */
- timer_clear_txif(timer);
- switch (timer) {
- case 1: IEC0bits.T1IE = ie; break;
- case 2: IEC0bits.T2IE = ie; break;
- case 3: IEC0bits.T3IE = ie; break;
- case 4: IEC1bits.T4IE = ie; break;
- case 5: IEC1bits.T5IE = ie; break;
- case 6: IEC2bits.T6IE = ie; break;
- case 7: IEC3bits.T7IE = ie; break;
- case 8: IEC3bits.T8IE = ie; break;
- case 9: IEC3bits.T9IE = ie; break;
- }
-
- return 0;
- }
-
- /* sleep for between "ms" and "ms+1" milliseconds */
- void msleep(int ms)
- {
- static int initialized = 0;
-
- if (!initialized) {
- timer_setup_16bit(1, 1000, 0);
- initialized = 1;
- }
-
- /* Very basic, assumes timer1 is set up at 1 khz */
- while (ms-- >= 0) {
- IFS0bits.T1IF = 0;
- while(IFS0bits.T1IF == 0)
- continue;
- }
- }
|