Beispiel #1
0
/**
 * Initializes a UART controller.
 * It is enabled for transmission (Tx) only, receive must be enabled separately.
 * By default all IRQ sources are disabled (masked out).
 *
 * Nothing is done if 'nr' is invalid (equal or greater than 3).
 *
 * @param nr - number of the UART (between 0 and 2)
 */
void uart_init(uint8_t nr)
{
    /* Sanity check */
    if ( nr >= BSP_NR_UARTS )
    {
        return;
    }

    /*
     * Registers' reserved bits should not be modified.
     * For that reason, the registers are set in two steps:
     * - the appropriate bit masks of 1-bits are bitwise or'ed to the register
     * - zero complements of the appropriate bit masks of 0-bits are bitwise and'ed to the register
     */


    /*
     * Whatever the current state, as suggested on page 3-16 of the DDI0183, the UART
     * should be disabled first:
     */
    HWREG_CLEAR_BITS( pReg[nr]->UARTCR, CTL_UARTEN );

    /* Set Control Register's TXE to 1: */
    HWREG_SET_BITS( pReg[nr]->UARTCR, CTL_TXE );

    /*
     * Set all other bits (except UARTEN) of the Control Register to 0:
     * - SIREN
     * - SIRLP
     * - LBE
     * - RXE
     * - DTR
     * - RTS
     * - Out1
     * - Out2
     * - RTSEn
     * - CTSEn
     */
    HWREG_CLEAR_BITS( pReg[nr]->UARTCR, (CTL_SIREN | CTL_SIRLP | CTL_LBE | CTL_RXE | CTL_DTR) );
    HWREG_CLEAR_BITS( pReg[nr]->UARTCR, ( CTL_RTS | CTL_OUT1 | CTL_OUT2 | CTL_RTSEn | CTL_CTSEn ) );


    /* By default, all interrupts are masked out (i.e. cleared to 0): */
    HWREG_CLEAR_BITS( pReg[nr]->UARTIMSC, ( INT_RIMIM | INT_CTSMIM | INT_DCDMIM | INT_DSRMIM | INT_RXIM | INT_TXIM ) );
    HWREG_CLEAR_BITS( pReg[nr]->UARTIMSC, ( INT_RTIM | INT_FEIM | INT_PEIM | INT_BEIM | INT_OEIM ) );

    /* TODO: line control... */

    /* Finally enable the UART: */
    HWREG_SET_BITS( pReg[nr]->UARTCR, CTL_UARTEN );

    /* reserved bits remained unmodified */
}
/*
 * Assigns the selected register a 32-bit reload value.
 *
 * Nothing is done if 'wd' is greater than 1.
 *
 * @param wd - watchdog timer to be loaded (between 0 and 1)
 * @param ex - exception type
 */
static void __wd_setLoadValue(uint8_t wd, uint32_t value)
{
    /*
     * See page 779 of the Data Sheet for more details.
     */

    if ( wd < BSP_NR_WATCHDOGS )
    {
        /* store the value for reusing it by wd_reload() */
        __wdSettings[wd].loadVal = value;

        /*
         * There is a hardware bug in both watchdog timers.
         * If the STALL bit of the WDTTEST register is set,
         * the WTDLOAD register cannot be changed.
         * See page 68 of the Silicon Errata for more details.
         *
         * For that reason the STALL bit will be cleared first
         * and set again later.
         */
        HWREG_CLEAR_BITS( pReg[wd]->WD_TEST, TST_STALL );
        __waitWd1(wd);

        pReg[wd]->WD_LOAD = value;
        __waitWd1(wd);

        /* Set the STALL bit again. */
        HWREG_SET_BITS( pReg[wd]->WD_TEST, TST_STALL );
        __waitWd1(wd);
    }
}
/*
 * Configures an exception that is triggered when the watchdog's
 * counter reaches 0.
 *
 * Nothing is done if 'wd' is greater than 1 or
 * 'ex' is invalid.
 *
 * @param wd - watchdog timer to be configured (between 0 and 1)
 * @param ex - exception type (any valid value of WatchdogException)
 */
static void __wd_setExceptionType(uint8_t wd, WatchdogException ex)
{
    /*
     * Exception type is configured via relevant bits
     * of the WDTCTL register.
     * See the Data Sheet, pp. 781 - 782, for more details.
     */

    if ( wd >= BSP_NR_WATCHDOGS )
    {
        return;
    }

    __wdSettings[wd].exType = ex;

    /* Clear the RESEN flag. It will be reenabled if necessary */
    HWREG_CLEAR_BITS( pReg[wd]->WD_CTL, CTL_RESEN );
    __waitWd1(wd);

    switch (ex)
    {
    case WDEX_NMI:
        HWREG_SET_BITS( pReg[wd]->WD_CTL, CTL_INTTYPE );
        break;

    case WDEX_IRQ:
        HWREG_CLEAR_BITS( pReg[wd]->WD_CTL, CTL_INTTYPE );
        break;

    case WDEX_NMI_RESET:
        HWREG_SET_BITS( pReg[wd]->WD_CTL, CTL_INTTYPE );
        __waitWd1(wd);
        HWREG_SET_BITS( pReg[wd]->WD_CTL, CTL_RESEN );
        break;

    case WDEX_IRQ_RESET:
        HWREG_CLEAR_BITS( pReg[wd]->WD_CTL, CTL_INTTYPE );
        __waitWd1(wd);
        HWREG_SET_BITS( pReg[wd]->WD_CTL, CTL_RESEN );
        break;

    }

    __waitWd1(wd);
}
Beispiel #4
0
/**
 * Disables the specified UART controller.
 *
 * Nothing is done if 'nr' is invalid (equal or greater than 3).
 *
 * @param nr - number of the UART (between 0 and 2)
 */
void uart_disableUart(uint8_t nr)
{
    /* Sanity check */
    if ( nr >= BSP_NR_UARTS )
    {
        return;
    }

    HWREG_CLEAR_BITS( pReg[nr]->UARTCR, CTL_UARTEN );
}
Beispiel #5
0
/**
 * Disables the interrupt triggering by the specified UART when a character is received.
 *
 * Nothing is done if 'nr' is invalid (equal or greater than 3).
 *
 * @param nr - number of the UART (between 0 and 2)
 */
void uart_disableRxInterrupt(uint8_t nr)
{
    /* Sanity check */
    if ( nr >= BSP_NR_UARTS )
    {
        return;
    }

    /* Clear bit 4 of the IMSC register: */
    HWREG_CLEAR_BITS( pReg[nr]->UARTIMSC, INT_RXIM );
}
/**
 * Sets the SysTick's source clock.
 * The SysTick runs either on the system clock or on the
 * precision internal oscillator (PIOSC), whose frequency
 * is divided by 4.
 *
 * @param systemClock - 'true' for the system clock; 'false' for PIOSC/4
 */
void systick_setSource(bool systemClock)
{
    if ( true == systemClock)
    {
        HWREG_SET_BITS( pReg->SYSTICK_STCTRL, CLKSRC_MASK );
    }
    else
    {
        HWREG_CLEAR_BITS( pReg->SYSTICK_STCTRL, CLKSRC_MASK );
    }
}
Beispiel #7
0
/**
 * Disables the timer's interrupt triggering (when the counter reaches 0).
 *
 * Nothing is done if either 'timerNr' or 'counterNr' is invalid.
 *
 * @param timerNr - timer number (between 0 and 1)
 * @param counterNr - counter number of the selected timer (between 0 and 1)
 */
void timer_disableInterrupt(uint8_t timerNr, uint8_t counterNr)
{

    /* sanity check: */
    if ( timerNr >= BSP_NR_TIMERS || counterNr >= NR_COUNTERS )
    {
        return;
    }

    /* Set bit 5 of the Control Register to 0, do not modify other bits */
    HWREG_CLEAR_BITS( pReg[timerNr]->CNTR[counterNr].CONTROL, CTL_INTR );
}
Beispiel #8
0
/*
 * Sets or clears a bit of the Control Register. This function is short and
 * used by other functions, this is why it is implemented as an inline function.
 *
 * Nothing is done if 'nr' is invalid (equal or greater than 3).
 *
 * @param nr - number of the UART (between 0 and 2)
 * @param set - true: bitmask's bit(s) are set to 1;  false: bits are cleared to 0
 * @param bitmask - bitmask of 1-bits that will be set or cleared
 */
static inline void __setCrBit(uint8_t nr, bool set, uint32_t bitmask)
{
    uint32_t enabled;

    /* Sanity check */
    if ( nr >= BSP_NR_UARTS )
    {
        return;
    }

    /* Store UART's enable status (UARTEN) */
    enabled = HWREG_READ_BITS( pReg[nr]->UARTCR, CTL_UARTEN );

    /*
     * As suggested on page 3-16 of the DDI0183, the UART should be disabled
     * prior to any modification of the Control Register
     */
    HWREG_CLEAR_BITS( pReg[nr]->UARTCR, CTL_UARTEN );

    /* Depending on 'set'... */
    if (set)
    {
        /* Set bitmask's bits to 1 using bitwise OR */
        HWREG_SET_BITS( pReg[nr]->UARTCR, bitmask );
    }
    else
    {
        /* Clear bitmask's bits to 0 using bitwise AND */
        HWREG_CLEAR_BITS( pReg[nr]->UARTCR, bitmask );
    }

    /* Reenable the UART if it was been enabled before */
    if (enabled)
    {
        HWREG_SET_BITS( pReg[nr]->UARTCR, CTL_UARTEN );
    }
}
Beispiel #9
0
/**
 * Initializes the specified timer's counter controller.
 * The following parameters are set:
 * - periodic mode (when the counter reaches 0, it is wrapped to the value of the Load Register)
 * - 32-bit counter length
 * - prescale = 1
 *
 * This function does not enable interrupt triggering and does not start the counter!
 *
 * Nothing is done if either 'timerNr' or 'counterNr' is invalid.
 *
 * @param timerNr - timer number (between 0 and 1)
 * @param counterNr - counter number of the selected timer (between 0 and 1)
 */
void timer_init(uint8_t timerNr, uint8_t counterNr)
{

    /* sanity check: */
    if ( timerNr >= BSP_NR_TIMERS || counterNr >= NR_COUNTERS )
    {
        return;
    }


    /*
     * DDI0271 does not recommend modifying reserved bits of the Control Register (see page 3-5).
     * For that reason, the register is set in two steps:
     * - the appropriate bit masks of 1-bits are bitwise or'ed to the CTL
     * - zero complements of the appropriate bit masks of 0-bits are bitwise and'ed to the CTL
     */


    /*
     * The following bits will be set to 1:
     * - timer mode (periodic)
     * - counter length (32-bit)
     */

    HWREG_SET_BITS( pReg[timerNr]->CNTR[counterNr].CONTROL, ( CTL_MODE | CTL_CTRLEN ) );

    /*
     * The following bits are will be to 0:
     * - enable bit (disabled, i.e. timer not running)
     * - interrupt bit (disabled)
     * - both prescale bits (00 = 1)
     * - oneshot bit (wrapping mode)
     */

    HWREG_CLEAR_BITS( pReg[timerNr]->CNTR[counterNr].CONTROL,
    		( CTL_ENABLE | CTL_INTR | CTL_PRESCALE_1 | CTL_PRESCALE_2 | CTL_ONESHOT ) );

    /* reserved bits remained unmodified */
}
/**
 * Reloads the selected watchdog's counter to the
 * load value, specified by wd_config().
 *
 * Nothing is done if 'wd' is greater than 1.
 *
 * @param wd - watchdog timer (between 0 and 1)
 */
void wd_reload(uint8_t wd)
{
    /*
     * For more details about the WDTLOAD register,
     * see page 779 of the Data Sheet
     */

    if ( wd >= BSP_NR_WATCHDOGS )
    {
        return;
    }

    if ( 1==wd && (6==sysctl_mcu_revision || 7==sysctl_mcu_revision) )
    {
        /*
         * According to page 64 of the Silicon Errata,
         * reloading the WDTLOAD of the watchdog 1 will not
         * restart the counter. As a workaround it is
         * suggested to reset, reconfigure and restart
         * the watchdog.
         */

        wd_reset(wd);
        wd_config(wd, __wdSettings[wd].loadVal, __wdSettings[wd].exType);

        /* Set the STALL bit if necessary */
        HWREG_SET_BITS( pReg[wd]->WD_TEST, TST_STALL );
        __waitWd1(wd);

        wd_start(wd);
    }
    else
    {
        /*
         * At other watchdogs, no workaround is necessary.
         * Reloading the WDTLOAD register will also
         * restart the counter.
         * Note: __waitWd1() is still preserved in the code.
         */

        /*
         * There is a hardware bug in both watchdog timers.
         * If the STALL bit of the WDTTEST register is set,
         * the WTDLOAD register cannot be changed.
         * See page 68 of the Silicon Errata for more details.
         *
         * For that reason the STALL bit will be cleared first
         * and set again later.
         */
        HWREG_CLEAR_BITS( pReg[wd]->WD_TEST, TST_STALL );
        __waitWd1(wd);

        pReg[wd]->WD_LOAD = __wdSettings[wd].loadVal;
        __waitWd1(wd);

        /* Set the STALL bit again. */
        HWREG_SET_BITS( pReg[wd]->WD_TEST, TST_STALL );
        __waitWd1(wd);

    }
}
/**
 * Stops the SysTick timer.
 */
void systick_disable(void)
{
    HWREG_CLEAR_BITS( pReg->SYSTICK_STCTRL, ENABLE_MASK );
}
/**
 * Disables SysTick interrupt triggering.
 */
void systick_disableInterrupt(void)
{
    HWREG_CLEAR_BITS( pReg->SYSTICK_STCTRL, INTR_MASK );
}