void _wd_intHandler(void) { /* * Poll both WDTMIS registers to find the watchdog * that triggered the interrupt * For more details about the WDTMIS register, * see page 785 of the Data Sheet. * * WARNING: registers of a watchdog, not enabled in SYSCTL, * must not be accessed or a bus fault may occur! * For that reason, __enabled MUST be checked for each 'wd' first. * The if statement also checks if __intrIsr is equal to NULL. * If this is the case, this handler would not do anything anyway. */ uint8_t wd; for ( wd=0; wd<BSP_NR_WATCHDOGS; ++wd ) { if ( true == __wdSettings[wd].enabled && NULL != __wdSettings[wd].intrIsr && 0 != HWREG_READ_BITS( pReg[wd]->WD_MIS, MIS_MASK ) ) { ( *(__wdSettings[wd].intrIsr) )(); /* * The interrupt request source is deliberately * not cleared, this enables reset (if configured so) * on the second time out. */ } /* if */ } /* for wd */ }
/* * Outputs a character to the specified UART. This short function is used by other functions, * that is why it is implemented as an inline function. * * As the function is "private", it trusts its caller functions, that 'nr' * is valid (between 0 and 2). * * @param nr - number of the UART (between 0 and 2) * @param ch - character to be sent to the UART */ static inline void __printCh(uint8_t nr, char ch) { /* * Qemu ignores other UART's registers, anyway the Flag Register is checked * to better emulate a "real" UART controller. * See description of the register on page 3-8 of DDI0183 for more details. */ /* * Poll the Flag Register's TXFF bit until the Transmit FIFO is not full. * When the TXFF bit is set to 1, the controller's internal Transmit FIFO is full. * In this case, wait until some "waiting" characters have been transmitted and * the TXFF is set to 0, indicating the Transmit FIFO can accept additional characters. */ while ( 0 != HWREG_READ_BITS( pReg[nr]->UARTFR, FR_TXFF ) ); /* * The Data Register is a 32-bit word, however only the least significant 8 bits * can be assigned the character to be sent, while other bits represent various flags * and should not be set to 0. For that reason, the following trick is introduced: * * Casting the Data Register's address to char* effectively turns the word into an array * of (four) 8-bit characters. Now, dereferencing the first character of this array affects * only the desired character itself, not the whole word. */ *( (char*) &(pReg[nr]->UARTDR) ) = ch; }
/* * The Watchdog 1 is clocked by an independent source and * its registers must be written with a time gap between * accesses. If the WRC bit of the WDTCTL register is set to 1, * this indicates that the timing gap has elapsed. There are no * such restrictions for the Watchdog 0. * * See pages 777 and 781 of the Data Shhet for more details. * * @param wd - watchdog timer */ static inline void __waitWd1(uint8_t wd) { if ( 1 == wd ) { while ( 0 == HWREG_READ_BITS(pReg[wd]->WD_CTL, CTL_WRC) ); } }
/** * Checks whether the specified timer's counter is enabled, i.e. running. * * If it is enabled, a nonzero value, typically 1, is returned, * otherwise a zero value is returned. * * If either 'timerNr' or 'counterNr' is invalid, a zero is returned * (as an invalid timer/counter cannot be enabled). * * @param timerNr - timer number (between 0 and 1) * @param counterNr - counter number of the selected timer (between 0 and 1) * * @return a zero value if the timer is disabled, a nonzero if it is enabled */ int8_t timer_isEnabled(uint8_t timerNr, uint8_t counterNr) { /* sanity check: */ if ( timerNr >= BSP_NR_TIMERS || counterNr >= NR_COUNTERS ) { return 0; } /* just check the enable bit of the timer's Control Register */ return ( 0!=HWREG_READ_BITS( pReg[timerNr]->CNTR[counterNr].CONTROL, CTL_ENABLE ) ); }
/** * Reads a character that was received by the specified UART. * The function may block until a character appears in the UART's receive buffer. * It is recommended that the function is called, when the caller is sure that a * character has actually been received, e.g. by notification via an interrupt. * * A zero is returned immediately if 'nr' is invalid (equal or greater than 3). * * @param nr - number of the UART (between 0 and 2) * * @return character received at the UART */ char uart_readChar(uint8_t nr) { /* Sanity check */ if ( nr >= BSP_NR_UARTS ) { return (char) 0; } /* Wait until the receiving FIFO is not empty */ while ( 0 != HWREG_READ_BITS( pReg[nr]->UARTFR, FR_RXFE ) ); /* * UART DR is a 32-bit register and only the least significant byte must be returned. * Casting its address to char* effectively turns the word into an array * of (four) 8-bit characters. Now, dereferencing the first character of this array affects * only the desired character itself, not the whole word. */ return *( (char*) &(pReg[nr]->UARTDR) ); }
/* * 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 ); } }
/** * @return current value of the SysTick counter */ uint32_t systick_getCurrentValue(void) { return ( HWREG_READ_BITS( pReg->SYSTICK_STCURRENT, B24BIT_MASK ) ); }
/** * Has the counter already wrapped (reached 0)? * Note that the count flag is automatically cleared * after its status has been read. * * @return 'true' if the counter reached 0; 'false' if not */ bool systick_countSet(void) { return ( HWREG_READ_BITS( pReg->SYSTICK_STCTRL, COUNT_MASK ) ? true : false ); }