//************************************************************************ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) { // uint32_t tonePeriod; uint8_t port; // Should have an error check here for pin number out of range. //* there is no standard on the number of pins. Since we want this to work on all versions of the PIC32 //* I have set it to 112 for now which is the largest I/O pin count on a pic32 if ((frequency > 0) && (_pin < (NUM_DIGITAL_PINS))) { // If a tone is currently playing on a different pin, the function is // documented to have no effect. If playing on the same pin, change // the frequency. If not currently playing, initialize the timer. // This is currently hard coded to use timer1. if (tone_pin == 255) { // No tone currently playing. Init the timer. T1CON = TACON_PS_256; setIntVector(_TIMER_1_VECTOR, Timer1Handler); clearIntFlag(_TIMER_1_IRQ); setIntPriority(_TIMER_1_VECTOR, _T1_IPL_IPC, _T1_SPL_IPC); setIntEnable(_TIMER_1_IRQ); } else if (_pin != tone_pin) { // Tone currently playing on another pin. ignore this call. return; } // Determine which port and bit are requested. tone_pin = _pin; port = digitalPinToPort(_pin); tone_pin_port = (p32_ioport *)portRegisters(port); tone_pin_mask = digitalPinToBitMask(_pin); // Ensure that the pin is a digital output pinMode(_pin, OUTPUT); // Duration 0 means to play forever until stopped. Other values // mean to play for that many milliseconds. if (duration > 0) { timer1_toggle_count = (2 * frequency * duration) / 1000; } else { timer1_toggle_count = -1; } TMR1 = 0; PR1 = ((__PIC32_pbClk / 256) / 2 / frequency); T1CONSET = TACON_ON; } }
void RTCCClass::begin() { setIntVector(_RTCC_VECTOR, __RTCCInterrupt); setIntPriority(_RTCC_VECTOR, 3, 0); clearIntFlag(_RTCC_IRQ); setIntEnable(_RTCC_IRQ); /*Ensure the secondary oscillator is enabled and ready, i.e. OSCCON<1>=1, OSCCON<22>=1, and RTCC write is enabled i.e. RTCWREN (RTCCON<3>) =1;*/ UNLOCK RTCCONbits.RTCWREN = 1; RTCCONbits.ON = 1; OSCCONSET = 0x00400002; LOCK _validity = RTCC_VAL_NOT; // 0: very unsure! }
void LowPower_::snooze(unsigned long ms) { uint32_t f_pb = getPeripheralClock(); if (switchToLPRC()) { f_pb = 31250; } float baseclock = f_pb; uint8_t ps = 0; float f = 1.0 / (ms / 1000.0); if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 2; ps = 1; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 4; ps = 2; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 8; ps = 3; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 8; ps = 3; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 16; ps = 4; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 32; ps = 5; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 64; ps = 6; } if (baseclock / f > 0xFFFFFFFF) { baseclock = f_pb / 256; ps = 7; } uint32_t tcon4 = T4CON; uint32_t tpr4 = PR4; uint32_t tmr4 = TMR4; uint32_t tcon5 = T5CON; uint32_t tpr5 = PR5; uint32_t tmr5 = TMR5; int ipl; int spl; T4CON = 0; T5CON = 0; T4CONbits.TCKPS = ps; T4CONbits.T32 = 1; uint32_t pr = baseclock / f; PR4 = pr & 0xFFFF; PR5 = pr >> 16; isrFunc origIsr = setIntVector(_TIMER_5_VECTOR, _timerWakeup); getIntPriority(_TIMER_5_VECTOR, &ipl, &spl); setIntPriority(_TIMER_5_VECTOR, 5, 0); int en = setIntEnable(_TIMER_5_IRQ); clearIntFlag(_TIMER_5_IRQ); TMR4 = 0; TMR5 = 0; // If we're going to do this we need to ensure the two timers are enabled! enableTimer4(); enableTimer5(); int cten = clearIntEnable(_CORE_TIMER_IRQ); T4CONbits.TON = 1; enterIdleMode(); restoreIntEnable(_CORE_TIMER_IRQ, cten); T4CONbits.TON = 0; setIntPriority(_TIMER_5_VECTOR, ipl, spl); setIntVector(_TIMER_5_VECTOR, origIsr); restoreIntEnable(_TIMER_5_IRQ, en); T5CON = tcon5; PR5 = tpr5; TMR5 = tmr5; T4CON = tcon4; PR4 = tpr4; TMR4 = tmr4; restoreSystemClock(); }
void VGA::initializeDevice() { _vgaDevice = this; if (_hsync_pin == 0 || _vsync_pin == 0) { return; } memset((void *)_buffer0, 0, ((Width/8)+1) * Height); #if VGA_USE_DOUBLE_BUFFER memset((void *)_buffer1, 0, ((Width/8)+1) * Height); bufferNumber = 0; activeBuffer = _buffer0; vgaBuffer = _buffer1; #else bufferNumber = 0; activeBuffer = _buffer0; vgaBuffer = _buffer0; #endif _hsync_port->tris.clr = _hsync_pin; _vsync_port->tris.clr = _vsync_pin; // First we need to set up a timer that will trigger at the different times. T2CONbits.TCKPS = 0; // No prescaler PR2 = 0xFFFF; setIntVector(_TIMER_2_VECTOR, vgaProcess); setIntPriority(_TIMER_2_VECTOR, 6, 0); clearIntFlag(_TIMER_2_IRQ); setIntEnable(_TIMER_2_IRQ); // Now congfigure SPI4 for display data transmission. SPI4CON = 0; SPI4CONbits.MSTEN = 1; SPI4CONbits.STXISEL = 0b11; // Interrupt when one byte in buffer #if VGA_USE_HI_RES SPI4BRG = 0; // This will set how big each pixel is. #else SPI4BRG = 1; // This will set how big each pixel is. #endif SPI4CONbits.ON = 1; // And now a DMA channel for transferring the data DCH0SSA = ((unsigned int)vgaBuffer) & 0x1FFFFFFF; DCH0DSA = ((unsigned int)&SPI4BUF) & 0x1FFFFFFF; DCH0SSIZ = (Width / 8) + 1; DCH0DSIZ = 1; DCH0CSIZ = 1; DCH0ECONbits.SIRQEN = 1; DCH0ECONbits.CHSIRQ = _SPI4_TX_IRQ; DCH0CONbits.CHAEN = 0; DCH0CONbits.CHEN = 0; DCH0CONbits.CHPRI = 3; vgaVsyncPort = _vsync_port; vgaHsyncPort = _hsync_port; vgaVsyncMask = _vsync_pin; vgaHsyncMask = _hsync_pin; vgaWidth = (Width/8) + 1; vgaHeight = Height; vgaBufSize = vgaWidth * vgaHeight; clearIntEnable(_CORE_TIMER_IRQ); // setIntPriority(_CORE_TIMER_VECTOR, 5, 0); VSYNC_OFF HSYNC_OFF DMACONbits.ON = 1; T2CONbits.ON = 1; // Turn on the timer }