RIT (Repetitive Interrupt Timer) Library.

Dependents:   ORTP-L_SensorTest ORTP-L_V01 ORTP-L_V01 RIT_Demo

RIT.cpp

Committer:
wvd_vegt
Date:
2011-03-11
Revision:
4:64198265f56f
Parent:
0:af45bc81d34c

File content as of revision 4:64198265f56f:

/* mbed Repetitive Interrupt Timer Library
 * Copyright (c) 2011 wvd_vegt
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "LPC17xx.h"
#include "RIT.h"
#include "mbed.h"

//Note: Code Ideas taken from BLDC and ADC Library.

//TODO Document RIT.h
//TODO Publish as Library

RIT *RIT::instance;

//------------------------------------------------------------------------------
//Public Stuff.
//------------------------------------------------------------------------------

RIT::RIT(uint32_t ms) {
    //Default NULL global custom isr
    _rit_g_isr = NULL;

    // Set RIT interrupt priority
    NVIC_SetPriority(RIT_IRQn, 11);

    // Power the RIT
    power_enable();

    // Select perhiperal clk
    select_clk();

    // Set Clock
    setup_ms(ms);

    // Set counter clear/reset after interrupt
    LPC_RIT->RICTRL |= (2L); //RITENCLR

    // Connect the RIT interrupt to the interrupt handler
    instance = this;
    NVIC_SetVector(RIT_IRQn, (uint32_t)&_ritisr);

    // Disable the RIT interrupt
    disable();
}

//Setup Timing in ms.
void RIT::setup_ms(uint32_t ms) {
    LPC_RIT->RICOMPVAL = (uint32_t)(((SYSCLK / ONEMHZ) * ms * 1000)-1);
    LPC_RIT->RICOUNTER = 0;
}

//Setup Timing in us.
void RIT::setup_us(uint32_t us) {
    LPC_RIT->RICOMPVAL = (uint32_t)(((SYSCLK / ONEMHZ) * us)-1);
    LPC_RIT->RICOUNTER = 0;
}

//Attach custom interrupt handler replacing default
void RIT::attach(void(*fptr)(void)) {
    //* Attach IRQ
    NVIC_SetVector(ADC_IRQn, (uint32_t)fptr);
}

//Restore default interrupt handler
void RIT::detach(void) {
    //* Attach IRQ
    instance = this;

    NVIC_SetVector(ADC_IRQn, (uint32_t)&_ritisr);
}

//Unappend global interrupt handler to function isr
void RIT::append(void(*fptr)()) {
    _rit_g_isr = fptr;
}

//Detach global interrupt handler to function isr
void RIT::unappend() {
    _rit_g_isr = NULL;
}

void RIT::enable(void) {
    // Enable RIT interrupt
    NVIC_EnableIRQ(RIT_IRQn);

    // Enable the RIT
    LPC_RIT->RICTRL |= (8L); //RITEN;
}

void RIT::disable(void) {
    // Disable RIT interrupt
    NVIC_DisableIRQ(RIT_IRQn);

    // Disable the RIT
    LPC_RIT->RICTRL &= ~(8L); //RITEN;
}

void RIT::power_enable(void) {
    // Power the TRIT
    LPC_SC->PCONP |= (1L<<16); //PCRIT
}

void RIT::power_disable(void) {
    // Powerdown the RIT
    LPC_SC->PCONP &= ~(1L<<16); //PCRIT
}
//------------------------------------------------------------------------------
//Private Stuff.
//------------------------------------------------------------------------------

void RIT::_ritisr(void) {
    instance->ritisr();
}

void RIT::ritisr(void) {
    // RIT interrupt occured
    if ((LPC_RIT->RICTRL & 1L) == 1L) //RITINT
        // Clear the RIT interrupt
        LPC_RIT->RICTRL |= 1L;
    
    //Call User defined interrupt handlers if any
    if (_rit_g_isr != NULL)
        _rit_g_isr();
}

void RIT::select_clk(void) {
    // Timer0 perhiperal clock select (01: PCLK Peripheral = CCLK)
    LPC_SC->PCLKSEL1 &= ~(3L << 26); // Clear PCLK_RIT bits;
    LPC_SC->PCLKSEL1 |=  (1L << 26); // Set PCLK_RIT bits to 0x01;
}