text:
                                  (CLASS_IS_FURY && REVISION_IS_A2) ||        \
                                  (CLASS_IS_DUSTDEVIL && REVISION_IS_A0)) ?   \
                                 16 : 8)

//*****************************************************************************
//
// A mapping of UART base address to interupt number.
//
//*****************************************************************************
static const unsigned long g_ppulUARTIntMap[][2] =
{
    { UART0_BASE, INT_UART0 },
    { UART1_BASE, INT_UART1 },
    { UART2_BASE, INT_UART2 },
    { UART3_BASE, INT_UART3 },
    { UART4_BASE, INT_UART4 },
    { UART5_BASE, INT_UART5 },
    { UART6_BASE, INT_UART6 },
    { UART7_BASE, INT_UART7 },
};

//*****************************************************************************
//
//! \internal
//! Checks a UART base address.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function determines if a UART port base address is valid.
//!
//! \return Returns \b true if the base address is valid and \b false
//! otherwise.
//
//*****************************************************************************
#ifdef DEBUG
static tBoolean
UARTBaseValid(unsigned long ulBase)
{
    return((ulBase == UART0_BASE) || (ulBase == UART1_BASE) ||
           (ulBase == UART2_BASE) || (ulBase == UART3_BASE) ||
           (ulBase == UART4_BASE) || (ulBase == UART5_BASE) ||
           (ulBase == UART6_BASE) || (ulBase == UART7_BASE));
}
#endif

//*****************************************************************************
//
//! \internal
//! Gets the UART interrupt number.
//!
//! \param ulBase is the base address of the UART port.
//!
//! Given a UART base address, this function returns the corresponding
//! interrupt number.
//!
//! \return Returns a UART interrupt number, or -1 if \e ulBase is invalid.
//
//*****************************************************************************
static long
UARTIntNumberGet(unsigned long ulBase)
{
    unsigned long ulIdx;

    //
    // Loop through the table that maps UART base addresses to interrupt
    // numbers.
    //
    for(ulIdx = 0; ulIdx < (sizeof(g_ppulUARTIntMap) /
                            sizeof(g_ppulUARTIntMap[0])); ulIdx++)
    {
        //
        // See if this base address matches.
        //
        if(g_ppulUARTIntMap[ulIdx][0] == ulBase)
        {
            //
            // Return the corresponding interrupt number.
            //
            return(g_ppulUARTIntMap[ulIdx][1]);
        }
    }

    //
    // The base address could not be found, so return an error.
    //
    return(-1);
}

//*****************************************************************************
//
//! Sets the type of parity.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulParity specifies the type of parity to use.
//!
//! This function configures the type of parity to use for transmitting and
//! expect when receiving.  The \e ulParity parameter must be one of
//! \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD,
//! \b UART_CONFIG_PAR_ONE, or \b UART_CONFIG_PAR_ZERO.  The last two
//! parameters allow direct control of the parity bit; it is always either one
//! or zero based on the mode.
//!
//! \return None.
//
//*****************************************************************************
void
UARTParityModeSet(unsigned long ulBase, unsigned long ulParity)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));
    ASSERT((ulParity == UART_CONFIG_PAR_NONE) ||
           (ulParity == UART_CONFIG_PAR_EVEN) ||
           (ulParity == UART_CONFIG_PAR_ODD) ||
           (ulParity == UART_CONFIG_PAR_ONE) ||
           (ulParity == UART_CONFIG_PAR_ZERO));

    //
    // Set the parity mode.
    //
    HWREG(ulBase + UART_O_LCRH) = ((HWREG(ulBase + UART_O_LCRH) &
                                    ~(UART_LCRH_SPS | UART_LCRH_EPS |
                                      UART_LCRH_PEN)) | ulParity);
}

//*****************************************************************************
//
//! Gets the type of parity currently being used.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function gets the type of parity used for transmitting data and
//! expected when receiving data.
//!
//! \return Returns the current parity settings, specified as one of
//! \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN, \b UART_CONFIG_PAR_ODD,
//! \b UART_CONFIG_PAR_ONE, or \b UART_CONFIG_PAR_ZERO.
//
//*****************************************************************************
unsigned long
UARTParityModeGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the current parity setting.
    //
    return(HWREG(ulBase + UART_O_LCRH) &
           (UART_LCRH_SPS | UART_LCRH_EPS | UART_LCRH_PEN));
}

//*****************************************************************************
//
//! Sets the FIFO level at which interrupts are generated.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulTxLevel is the transmit FIFO interrupt level, specified as one of
//! \b UART_FIFO_TX1_8, \b UART_FIFO_TX2_8, \b UART_FIFO_TX4_8,
//! \b UART_FIFO_TX6_8, or \b UART_FIFO_TX7_8.
//! \param ulRxLevel is the receive FIFO interrupt level, specified as one of
//! \b UART_FIFO_RX1_8, \b UART_FIFO_RX2_8, \b UART_FIFO_RX4_8,
//! \b UART_FIFO_RX6_8, or \b UART_FIFO_RX7_8.
//!
//! This function configures the FIFO level at which transmit and receive
//! interrupts are generated.
//!
//! \return None.
//
//*****************************************************************************
void
UARTFIFOLevelSet(unsigned long ulBase, unsigned long ulTxLevel,
                 unsigned long ulRxLevel)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));
    ASSERT((ulTxLevel == UART_FIFO_TX1_8) ||
           (ulTxLevel == UART_FIFO_TX2_8) ||
           (ulTxLevel == UART_FIFO_TX4_8) ||
           (ulTxLevel == UART_FIFO_TX6_8) ||
           (ulTxLevel == UART_FIFO_TX7_8));
    ASSERT((ulRxLevel == UART_FIFO_RX1_8) ||
           (ulRxLevel == UART_FIFO_RX2_8) ||
           (ulRxLevel == UART_FIFO_RX4_8) ||
           (ulRxLevel == UART_FIFO_RX6_8) ||
           (ulRxLevel == UART_FIFO_RX7_8));

    //
    // Set the FIFO interrupt levels.
    //
    HWREG(ulBase + UART_O_IFLS) = ulTxLevel | ulRxLevel;
}

//*****************************************************************************
//
//! Gets the FIFO level at which interrupts are generated.
//!
//! \param ulBase is the base address of the UART port.
//! \param pulTxLevel is a pointer to storage for the transmit FIFO level,
//! returned as one of \b UART_FIFO_TX1_8, \b UART_FIFO_TX2_8,
//! \b UART_FIFO_TX4_8, \b UART_FIFO_TX6_8, or \b UART_FIFO_TX7_8.
//! \param pulRxLevel is a pointer to storage for the receive FIFO level,
//! returned as one of \b UART_FIFO_RX1_8, \b UART_FIFO_RX2_8,
//! \b UART_FIFO_RX4_8, \b UART_FIFO_RX6_8, or \b UART_FIFO_RX7_8.
//!
//! This function gets the FIFO level at which transmit and receive interrupts
//! are generated.
//!
//! \return None.
//
//*****************************************************************************
void
UARTFIFOLevelGet(unsigned long ulBase, unsigned long *pulTxLevel,
                 unsigned long *pulRxLevel)
{
    unsigned long ulTemp;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Read the FIFO level register.
    //
    ulTemp = HWREG(ulBase + UART_O_IFLS);

    //
    // Extract the transmit and receive FIFO levels.
    //
    *pulTxLevel = ulTemp & UART_IFLS_TX_M;
    *pulRxLevel = ulTemp & UART_IFLS_RX_M;
}

//*****************************************************************************
//
//! Sets the configuration of a UART.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulUARTClk is the rate of the clock supplied to the UART module.
//! \param ulBaud is the desired baud rate.
//! \param ulConfig is the data format for the port (number of data bits,
//! number of stop bits, and parity).
//!
//! This function configures the UART for operation in the specified data
//! format.  The baud rate is provided in the \e ulBaud parameter and the data
//! format in the \e ulConfig parameter.
//!
//! The \e ulConfig parameter is the logical OR of three values: the number of
//! data bits, the number of stop bits, and the parity.  \b UART_CONFIG_WLEN_8,
//! \b UART_CONFIG_WLEN_7, \b UART_CONFIG_WLEN_6, and \b UART_CONFIG_WLEN_5
//! select from eight to five data bits per byte (respectively).
//! \b UART_CONFIG_STOP_ONE and \b UART_CONFIG_STOP_TWO select one or two stop
//! bits (respectively).  \b UART_CONFIG_PAR_NONE, \b UART_CONFIG_PAR_EVEN,
//! \b UART_CONFIG_PAR_ODD, \b UART_CONFIG_PAR_ONE, and \b UART_CONFIG_PAR_ZERO
//! select the parity mode (no parity bit, even parity bit, odd parity bit,
//! parity bit always one, and parity bit always zero, respectively).
//!
//! The peripheral clock is the same as the processor clock.  The frequency of
//! the system clock is the value returned by SysCtlClockGet(), or it can be
//! explicitly hard coded if it is constant and known (to save the
//! code/execution overhead of a call to SysCtlClockGet()).
//!
//! For Stellaris parts that have the ability to specify the UART baud clock
//! source (via UARTClockSourceSet()), the peripheral clock can be changed to
//! PIOSC.  In this case, the peripheral clock should be specified as
//! 16,000,000 (the nominal rate of PIOSC).
//!
//! This function replaces the original UARTConfigSet() API and performs the
//! same actions.  A macro is provided in <tt>uart.h</tt> to map the original
//! API to this API.
//!
//! \return None.
//
//*****************************************************************************
void
UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk,
                    unsigned long ulBaud, unsigned long ulConfig)
{
    unsigned long ulDiv;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));
    ASSERT(ulBaud != 0);
    ASSERT(ulUARTClk >= (ulBaud * UART_CLK_DIVIDER));

    //
    // Stop the UART.
    //
    UARTDisable(ulBase);

    //
    // Is the required baud rate greater than the maximum rate supported
    // without the use of high speed mode?
    //
    if((ulBaud * 16) > ulUARTClk)
    {
        //
        // Enable high speed mode.
        //
        HWREG(ulBase + UART_O_CTL) |= UART_CTL_HSE;

        //
        // Half the supplied baud rate to compensate for enabling high speed
        // mode.  This allows the following code to be common to both cases.
        //
        ulBaud /= 2;
    }
    else
    {
        //
        // Disable high speed mode.
        //
        HWREG(ulBase + UART_O_CTL) &= ~(UART_CTL_HSE);
    }

    //
    // Compute the fractional baud rate divider.
    //
    ulDiv = (((ulUARTClk * 8) / ulBaud) + 1) / 2;

    //
    // Set the baud rate.
    //
    HWREG(ulBase + UART_O_IBRD) = ulDiv / 64;
    HWREG(ulBase + UART_O_FBRD) = ulDiv % 64;

    //
    // Set parity, data length, and number of stop bits.
    //
    HWREG(ulBase + UART_O_LCRH) = ulConfig;

    //
    // Clear the flags register.
    //
    HWREG(ulBase + UART_O_FR) = 0;

    //
    // Start the UART.
    //
    UARTEnable(ulBase);
}

//*****************************************************************************
//
//! Gets the current configuration of a UART.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulUARTClk is the rate of the clock supplied to the UART module.
//! \param pulBaud is a pointer to storage for the baud rate.
//! \param pulConfig is a pointer to storage for the data format.
//!
//! This function determines the baud rate and data format for the UART, given
//! an explicitly provided peripheral clock (hence the ExpClk suffix).  The
//! returned baud rate is the actual baud rate; it may not be the exact baud
//! rate requested or an ``official'' baud rate.  The data format returned in
//! \e pulConfig is enumerated the same as the \e ulConfig parameter of
//! UARTConfigSetExpClk().
//!
//! The peripheral clock is the same as the processor clock.  The frequency of
//! the system clock is the value returned by SysCtlClockGet(), or it can be
//! explicitly hard coded if it is constant and known (to save the
//! code/execution overhead of a call to SysCtlClockGet()).
//!
//! For Stellaris parts that have the ability to specify the UART baud clock
//! source (via UARTClockSourceSet()), the peripheral clock can be changed to
//! PIOSC.  In this case, the peripheral clock should be specified as
//! 16,000,000 (the nominal rate of PIOSC).
//!
//! This function replaces the original UARTConfigGet() API and performs the
//! same actions.  A macro is provided in <tt>uart.h</tt> to map the original
//! API to this API.
//!
//! \return None.
//
//*****************************************************************************
void
UARTConfigGetExpClk(unsigned long ulBase, unsigned long ulUARTClk,
                    unsigned long *pulBaud, unsigned long *pulConfig)
{
    unsigned long ulInt, ulFrac;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Compute the baud rate.
    //
    ulInt = HWREG(ulBase + UART_O_IBRD);
    ulFrac = HWREG(ulBase + UART_O_FBRD);
    *pulBaud = (ulUARTClk * 4) / ((64 * ulInt) + ulFrac);

    //
    // See if high speed mode enabled.
    //
    if(HWREG(ulBase + UART_O_CTL) & UART_CTL_HSE)
    {
        //
        // High speed mode is enabled so the actual baud rate is actually
        // double what was just calculated.
        //
        *pulBaud *= 2;
    }

    //
    // Get the parity, data length, and number of stop bits.
    //
    *pulConfig = (HWREG(ulBase + UART_O_LCRH) &
                  (UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 |
                   UART_LCRH_EPS | UART_LCRH_PEN));
}

//*****************************************************************************
//
//! Enables transmitting and receiving.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function sets the UARTEN, TXE, and RXE bits and enables the transmit
//! and receive FIFOs.
//!
//! \return None.
//
//*****************************************************************************
void
UARTEnable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Enable the FIFO.
    //
    HWREG(ulBase + UART_O_LCRH) |= UART_LCRH_FEN;

    //
    // Enable RX, TX, and the UART.
    //
    HWREG(ulBase + UART_O_CTL) |= (UART_CTL_UARTEN | UART_CTL_TXE |
                                   UART_CTL_RXE);
}

//*****************************************************************************
//
//! Disables transmitting and receiving.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function clears the UARTEN, TXE, and RXE bits, waits for the end of
//! transmission of the current character, and flushes the transmit FIFO.
//!
//! \return None.
//
//*****************************************************************************
void
UARTDisable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait for end of TX.
    //
    while(HWREG(ulBase + UART_O_FR) & UART_FR_BUSY)
    {
    }

    //
    // Disable the FIFO.
    //
    HWREG(ulBase + UART_O_LCRH) &= ~(UART_LCRH_FEN);

    //
    // Disable the UART.
    //
    HWREG(ulBase + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE |
                                    UART_CTL_RXE);
}

//*****************************************************************************
//
//! Enables the transmit and receive FIFOs.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This functions enables the transmit and receive FIFOs in the UART.
//!
//! \return None.
//
//*****************************************************************************
void
UARTFIFOEnable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Enable the FIFO.
    //
    HWREG(ulBase + UART_O_LCRH) |= UART_LCRH_FEN;
}

//*****************************************************************************
//
//! Disables the transmit and receive FIFOs.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function disables the transmit and receive FIFOs in the UART.
//!
//! \return None.
//
//*****************************************************************************
void
UARTFIFODisable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Disable the FIFO.
    //
    HWREG(ulBase + UART_O_LCRH) &= ~(UART_LCRH_FEN);
}

//*****************************************************************************
//
//! Enables SIR (IrDA) mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//! \param bLowPower indicates if SIR Low Power Mode is to be used.
//!
//! This function enables the SIREN control bit for IrDA mode on the UART.  If
//! the \e bLowPower flag is set, then SIRLP bit is also set.  This
//! function only has an effect if the UART has not been enabled
//! by a call to UARTEnable().  The call UARTEnableSIR() must be made before
//! a call to UARTConfigSetExpClk() because the UARTConfigSetExpClk() function
//! calls the UARTEnable() function.  Another option is to call UARTDisable()
//! followed by UARTEnableSIR() and then enable the UART by calling
//! UARTEnable().
//!
//! \note The availability of SIR (IrDA) operation varies with the Stellaris
//! part in use.  Please consult the datasheet for the part you are using to
//! determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTEnableSIR(unsigned long ulBase, tBoolean bLowPower)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Enable SIR and SIRLP (if appropriate).
    //
    if(bLowPower)
    {
        HWREG(ulBase + UART_O_CTL) |= (UART_CTL_SIREN | UART_CTL_SIRLP);
    }
    else
    {
        HWREG(ulBase + UART_O_CTL) |= (UART_CTL_SIREN);
    }
}

//*****************************************************************************
//
//! Disables SIR (IrDA) mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function clears the SIREN (IrDA) and SIRLP (Low Power) bits.  This
//! function only has an effect if the UART has not been enabled by a
//! call to UARTEnable().  The call UARTEnableSIR() must be made before
//! a call to UARTConfigSetExpClk() because the UARTConfigSetExpClk() function
//! calls the UARTEnable() function.  Another option is to call UARTDisable()
//! followed by UARTEnableSIR() and then enable the UART by calling
//! UARTEnable().
//!
//! \note The availability of SIR (IrDA) operation varies with the Stellaris
//! part in use.  Please consult the datasheet for the part you are using to
//! determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTDisableSIR(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Disable SIR and SIRLP (if appropriate).
    //
    HWREG(ulBase + UART_O_CTL) &= ~(UART_CTL_SIREN | UART_CTL_SIRLP);
}

//*****************************************************************************
//
//! Enables ISO7816 smart card mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function enables the SMART control bit for the ISO7816 smart card mode
//! on the UART.  This call also sets 8-bit word length and even parity as
//! required by ISO7816.
//!
//! \note The availability of SIR (IrDA) operation varies with the Stellaris
//! part in use.  Please consult the datasheet for the part you are using to
//! determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTSmartCardEnable(unsigned long ulBase)
{
    unsigned long ulVal;

    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(UARTBaseValid(ulBase));

    //
    // Set 8-bit word length, even parity, 2 stop bits (note that although the
    // STP2 bit is ignored when in smartcard mode, this code lets the caller
    // read back the actual setting in use).
    //
    ulVal = HWREG(ulBase + UART_O_LCRH);
    ulVal &= ~(UART_LCRH_SPS | UART_LCRH_EPS | UART_LCRH_PEN |
               UART_LCRH_WLEN_M);
    ulVal |= UART_LCRH_WLEN_8 | UART_LCRH_PEN | UART_LCRH_EPS | UART_LCRH_STP2;
    HWREG(ulBase + UART_O_LCRH) = ulVal;

    //
    // Enable SMART mode.
    //
    HWREG(ulBase + UART_O_CTL) |= UART_CTL_SMART;
}

//*****************************************************************************
//
//! Disables ISO7816 smart card mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function clears the SMART (ISO7816 smart card) bit in the UART
//! control register.
//!
//! \note The availability of ISO7816 smart card mode varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTSmartCardDisable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(UARTBaseValid(ulBase));

    //
    // Disable the SMART bit.
    //
    HWREG(ulBase + UART_O_CTL) &= ~UART_CTL_SMART;
}

//*****************************************************************************
//
//! Sets the states of the DTR and/or RTS modem control signals.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulControl is a bit-mapped flag indicating which modem control bits
//! should be set.
//!
//! This function configures the states of the DTR or RTS modem handshake
//! outputs from the UART.
//!
//! The \e ulControl parameter is the logical OR of any of the following:
//!
//! - \b UART_OUTPUT_DTR - The Modem Control DTR signal
//! - \b UART_OUTPUT_RTS - The Modem Control RTS signal
//!
//! \note The availability of ISO7816 smart card mode varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTModemControlSet(unsigned long ulBase, unsigned long ulControl)
{
    unsigned long ulTemp;

    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(ulBase == UART1_BASE);
    ASSERT((ulControl & ~(UART_OUTPUT_RTS | UART_OUTPUT_DTR)) == 0);

    //
    // Set the appropriate modem control output bits.
    //
    ulTemp = HWREG(ulBase + UART_O_CTL);
    ulTemp |= (ulControl & (UART_OUTPUT_RTS | UART_OUTPUT_DTR));
    HWREG(ulBase + UART_O_CTL) = ulTemp;
}

//*****************************************************************************
//
//! Clears the states of the DTR and/or RTS modem control signals.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulControl is a bit-mapped flag indicating which modem control bits
//! should be set.
//!
//! This function clears the states of the DTR or RTS modem handshake outputs
//! from the UART.
//!
//! The \e ulControl parameter is the logical OR of any of the following:
//!
//! - \b UART_OUTPUT_DTR - The Modem Control DTR signal
//! - \b UART_OUTPUT_RTS - The Modem Control RTS signal
//!
//! \note The availability of hardware modem handshake signals varies with the
//! Stellaris part and UART in use.  Please consult the datasheet for the part
//! you are using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTModemControlClear(unsigned long ulBase, unsigned long ulControl)
{
    unsigned long ulTemp;

    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(ulBase == UART1_BASE);
    ASSERT((ulControl & ~(UART_OUTPUT_RTS | UART_OUTPUT_DTR)) == 0);

    //
    // Set the appropriate modem control output bits.
    //
    ulTemp = HWREG(ulBase + UART_O_CTL);
    ulTemp &= ~(ulControl & (UART_OUTPUT_RTS | UART_OUTPUT_DTR));
    HWREG(ulBase + UART_O_CTL) = ulTemp;
}

//*****************************************************************************
//
//! Gets the states of the DTR and RTS modem control signals.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the current states of each of the two UART modem
//! control signals, DTR and RTS.
//!
//! \note The availability of hardware modem handshake signals varies with the
//! Stellaris part and UART in use.  Please consult the datasheet for the part
//! you are using to determine whether this support is available.
//!
//! \return Returns the states of the handshake output signals.  This value is
//! a logical OR combination of values \b UART_OUTPUT_RTS and
//! \b UART_OUTPUT_DTR where the presence of each flag indicates that the
//! associated signal is asserted.
//
//*****************************************************************************
unsigned long
UARTModemControlGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(ulBase == UART1_BASE);

    return(HWREG(ulBase + UART_O_CTL) & (UART_OUTPUT_RTS | UART_OUTPUT_DTR));
}

//*****************************************************************************
//
//! Gets the states of the RI, DCD, DSR and CTS modem status signals.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the current states of each of the four UART modem
//! status signals, RI, DCD, DSR and CTS.
//!
//! \note The availability of hardware modem handshake signals varies with the
//! Stellaris part and UART in use.  Please consult the datasheet for the part
//! you are using to determine whether this support is available.
//!
//! \return Returns the states of the handshake output signals.  This value
//! is a logical OR combination of values \b UART_INPUT_RI,
//! \b UART_INPUT_DCD, \b UART_INPUT_CTS and \b UART_INPUT_DSR where the
//! presence of each flag indicates that the associated signal is asserted.
//
//*****************************************************************************
unsigned long
UARTModemStatusGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(ulBase == UART1_BASE);

    return(HWREG(ulBase + UART_O_FR) & (UART_INPUT_RI | UART_INPUT_DCD |
           UART_INPUT_CTS | UART_INPUT_DSR));
}

//*****************************************************************************
//
//! Sets the UART hardware flow control mode to be used.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulMode indicates the flow control modes to be used.  This parameter
//! is a logical OR combination of values \b UART_FLOWCONTROL_TX and
//! \b UART_FLOWCONTROL_RX to enable hardware transmit (CTS) and receive (RTS)
//! flow control or \b UART_FLOWCONTROL_NONE to disable hardware flow control.
//!
//! This function configures the required hardware flow control modes.  If
//! \e ulMode contains flag \b UART_FLOWCONTROL_TX, data is only transmitted
//! if the incoming CTS signal is asserted. If \e ulMode contains flag
//! \b UART_FLOWCONTROL_RX, the RTS output is controlled by the hardware and is
//! asserted only when there is space available in the receive FIFO.  If no
//! hardware flow control is required, \b UART_FLOWCONTROL_NONE should be
//! passed.
//!
//! \note The availability of hardware flow control varies with the Stellaris
//! part and UART in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTFlowControlSet(unsigned long ulBase, unsigned long ulMode)
{
    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(UARTBaseValid(ulBase));
    ASSERT((ulMode & ~(UART_FLOWCONTROL_TX | UART_FLOWCONTROL_RX)) == 0);

    //
    // Set the flow control mode as requested.
    //
    HWREG(ulBase + UART_O_CTL) = ((HWREG(ulBase + UART_O_CTL) &
                                 ~(UART_FLOWCONTROL_TX |
                                   UART_FLOWCONTROL_RX)) | ulMode);
}

//*****************************************************************************
//
//! Returns the UART hardware flow control mode currently in use.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the current hardware flow control mode.
//!
//! \note The availability of hardware flow control varies with the Stellaris
//! part and UART in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return Returns the current flow control mode in use.  This value is a
//! logical OR combination of values \b UART_FLOWCONTROL_TX if transmit
//! (CTS) flow control is enabled and \b UART_FLOWCONTROL_RX if receive (RTS)
//! flow control is in use.  If hardware flow control is disabled,
//! \b UART_FLOWCONTROL_NONE is returned.
//
//*****************************************************************************
unsigned long
UARTFlowControlGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(!CLASS_IS_SANDSTORM && !CLASS_IS_FURY && !CLASS_IS_DUSTDEVIL);
    ASSERT(UARTBaseValid(ulBase));

    return(HWREG(ulBase + UART_O_CTL) & (UART_FLOWCONTROL_TX |
                                         UART_FLOWCONTROL_RX));
}

//*****************************************************************************
//
//! Sets the operating mode for the UART transmit interrupt.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulMode is the operating mode for the transmit interrupt.  It may be
//! \b UART_TXINT_MODE_EOT to trigger interrupts when the transmitter is idle
//! or \b UART_TXINT_MODE_FIFO to trigger based on the current transmit FIFO
//! level.
//!
//! This function allows the mode of the UART transmit interrupt to be set.  By
//! default, the transmit interrupt is asserted when the FIFO level falls past
//! a threshold set via a call to UARTFIFOLevelSet().  Alternatively, if this
//! function is called with \e ulMode set to \b UART_TXINT_MODE_EOT, the
//! transmit interrupt is asserted once the transmitter is completely idle -
//! the transmit FIFO is empty and all bits, including any stop bits, have
//! cleared the transmitter.
//!
//! \note The availability of end-of-transmission mode varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTTxIntModeSet(unsigned long ulBase, unsigned long ulMode)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));
    ASSERT((ulMode == UART_TXINT_MODE_EOT) ||
           (ulMode == UART_TXINT_MODE_FIFO));

    //
    // Set or clear the EOT bit of the UART control register as appropriate.
    //
    HWREG(ulBase + UART_O_CTL) = ((HWREG(ulBase + UART_O_CTL) &
                                 ~(UART_TXINT_MODE_EOT |
                                   UART_TXINT_MODE_FIFO)) | ulMode);
}

//*****************************************************************************
//
//! Returns the current operating mode for the UART transmit interrupt.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the current operating mode for the UART transmit
//! interrupt.  The return value is \b UART_TXINT_MODE_EOT if the transmit
//! interrupt is currently configured to be asserted once the transmitter is
//! completely idle - the transmit FIFO is empty and all bits, including any
//! stop bits, have cleared the transmitter.  The return value is
//! \b UART_TXINT_MODE_FIFO if the interrupt is configured to be asserted based
//! on the level of the transmit FIFO.
//!
//! \note The availability of end-of-transmission mode varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return Returns \b UART_TXINT_MODE_FIFO or \b UART_TXINT_MODE_EOT.
//
//*****************************************************************************
unsigned long
UARTTxIntModeGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the current transmit interrupt mode.
    //
    return(HWREG(ulBase + UART_O_CTL) & (UART_TXINT_MODE_EOT |
                                         UART_TXINT_MODE_FIFO));
}

//*****************************************************************************
//
//! Determines if there are any characters in the receive FIFO.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns a flag indicating whether or not there is data
//! available in the receive FIFO.
//!
//! \return Returns \b true if there is data in the receive FIFO or \b false
//! if there is no data in the receive FIFO.
//
//*****************************************************************************
tBoolean
UARTCharsAvail(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the availability of characters.
    //
    return((HWREG(ulBase + UART_O_FR) & UART_FR_RXFE) ? false : true);
}

//*****************************************************************************
//
//! Determines if there is any space in the transmit FIFO.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns a flag indicating whether or not there is space
//! available in the transmit FIFO.
//!
//! \return Returns \b true if there is space available in the transmit FIFO
//! or \b false if there is no space available in the transmit FIFO.
//
//*****************************************************************************
tBoolean
UARTSpaceAvail(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the availability of space.
    //
    return((HWREG(ulBase + UART_O_FR) & UART_FR_TXFF) ? false : true);
}

//*****************************************************************************
//
//! Receives a character from the specified port.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function gets a character from the receive FIFO for the specified
//! port.
//!
//! This function replaces the original UARTCharNonBlockingGet() API and
//! performs the same actions.  A macro is provided in <tt>uart.h</tt> to map
//! the original API to this API.
//!
//! \return Returns the character read from the specified port, cast as a
//! \e long.  A \b -1 is returned if there are no characters present in the
//! receive FIFO.  The UARTCharsAvail() function should be called before
//! attempting to call this function.
//
//*****************************************************************************
long
UARTCharGetNonBlocking(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // See if there are any characters in the receive FIFO.
    //
    if(!(HWREG(ulBase + UART_O_FR) & UART_FR_RXFE))
    {
        //
        // Read and return the next character.
        //
        return(HWREG(ulBase + UART_O_DR));
    }
    else
    {
        //
        // There are no characters, so return a failure.
        //
        return(-1);
    }
}

//*****************************************************************************
//
//! Waits for a character from the specified port.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function gets a character from the receive FIFO for the specified
//! port.  If there are no characters available, this function waits until a
//! character is received before returning.
//!
//! \return Returns the character read from the specified port, cast as a
//! \e long.
//
//*****************************************************************************
long
UARTCharGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait until a char is available.
    //
    while(HWREG(ulBase + UART_O_FR) & UART_FR_RXFE)
    {
    }

    //
    // Now get the char.
    //
    return(HWREG(ulBase + UART_O_DR));
}

//*****************************************************************************
//
//! Sends a character to the specified port.
//!
//! \param ulBase is the base address of the UART port.
//! \param ucData is the character to be transmitted.
//!
//! This function writes the character \e ucData to the transmit FIFO for the
//! specified port.  This function does not block, so if there is no space
//! available, then a \b false is returned and the application must retry the
//! function later.
//!
//! This function replaces the original UARTCharNonBlockingPut() API and
//! performs the same actions.  A macro is provided in <tt>uart.h</tt> to map
//! the original API to this API.
//!
//! \return Returns \b true if the character was successfully placed in the
//! transmit FIFO or \b false if there was no space available in the transmit
//! FIFO.
//
//*****************************************************************************
tBoolean
UARTCharPutNonBlocking(unsigned long ulBase, unsigned char ucData)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // See if there is space in the transmit FIFO.
    //
    if(!(HWREG(ulBase + UART_O_FR) & UART_FR_TXFF))
    {
        //
        // Write this character to the transmit FIFO.
        //
        HWREG(ulBase + UART_O_DR) = ucData;

        //
        // Success.
        //
        return(true);
    }
    else
    {
        //
        // There is no space in the transmit FIFO, so return a failure.
        //
        return(false);
    }
}

//*****************************************************************************
//
//! Waits to send a character from the specified port.
//!
//! \param ulBase is the base address of the UART port.
//! \param ucData is the character to be transmitted.
//!
//! This function sends the character \e ucData to the transmit FIFO for the
//! specified port.  If there is no space available in the transmit FIFO, this
//! function waits until there is space available before returning.
//!
//! \return None.
//
//*****************************************************************************
void
UARTCharPut(unsigned long ulBase, unsigned char ucData)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait until space is available.
    //
    while(HWREG(ulBase + UART_O_FR) & UART_FR_TXFF)
    {
    }

    //
    // Send the char.
    //
    HWREG(ulBase + UART_O_DR) = ucData;
}

//*****************************************************************************
//
//! Causes a BREAK to be sent.
//!
//! \param ulBase is the base address of the UART port.
//! \param bBreakState controls the output level.
//!
//! Calling this function with \e bBreakState set to \b true asserts a break
//! condition on the UART.  Calling this function with \e bBreakState set to
//! \b false removes the break condition.  For proper transmission of a break
//! command, the break must be asserted for at least two complete frames.
//!
//! \return None.
//
//*****************************************************************************
void
UARTBreakCtl(unsigned long ulBase, tBoolean bBreakState)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Set the break condition as requested.
    //
    HWREG(ulBase + UART_O_LCRH) =
        (bBreakState ?
         (HWREG(ulBase + UART_O_LCRH) | UART_LCRH_BRK) :
         (HWREG(ulBase + UART_O_LCRH) & ~(UART_LCRH_BRK)));
}

//*****************************************************************************
//
//! Determines whether the UART transmitter is busy or not.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function allows the caller to determine whether all transmitted bytes
//! have cleared the transmitter hardware.  If \b false is returned, the
//! transmit FIFO is empty and all bits of the last transmitted character,
//! including all stop bits, have left the hardware shift register.
//!
//! \return Returns \b true if the UART is transmitting or \b false if all
//! transmissions are complete.
//
//*****************************************************************************
tBoolean
UARTBusy(unsigned long ulBase)
{
    //
    // Check the argument.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Determine if the UART is busy.
    //
    return((HWREG(ulBase + UART_O_FR) & UART_FR_BUSY) ? true : false);
}

//*****************************************************************************
//
//! Registers an interrupt handler for a UART interrupt.
//!
//! \param ulBase is the base address of the UART port.
//! \param pfnHandler is a pointer to the function to be called when the
//! UART interrupt occurs.
//!
//! This function does the actual registering of the interrupt handler.  This
//! function enables the global interrupt in the interrupt controller; specific
//! UART interrupts must be enabled via UARTIntEnable().  It is the interrupt
//! handler's responsibility to clear the interrupt source.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
{
    unsigned long ulInt;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Determine the interrupt number based on the UART port.
    //
    ulInt = UARTIntNumberGet(ulBase);

    //
    // Register the interrupt handler.
    //
    IntRegister(ulInt, pfnHandler);

    //
    // Enable the UART interrupt.
    //
    IntEnable(ulInt);
}

//*****************************************************************************
//
//! Unregisters an interrupt handler for a UART interrupt.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function does the actual unregistering of the interrupt handler.  It
//! clears the handler to be called when a UART interrupt occurs.  This
//! function also masks off the interrupt in the interrupt controller so that
//! the interrupt handler no longer is called.
//!
//! \sa IntRegister() for important information about registering interrupt
//! handlers.
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntUnregister(unsigned long ulBase)
{
    unsigned long ulInt;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Determine the interrupt number based on the UART port.
    //
    ulInt = UARTIntNumberGet(ulBase);

    //
    // Disable the interrupt.
    //
    IntDisable(ulInt);

    //
    // Unregister the interrupt handler.
    //
    IntUnregister(ulInt);
}

//*****************************************************************************
//
//! Enables individual UART interrupt sources.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
//!
//! This function enables the indicated UART interrupt sources.  Only the
//! sources that are enabled can be reflected to the processor interrupt;
//! disabled sources have no effect on the processor.
//!
//! The \e ulIntFlags parameter is the logical OR of any of the following:
//!
//! - \b UART_INT_9BIT - 9-bit Address Match interrupt
//! - \b UART_INT_OE - Overrun Error interrupt
//! - \b UART_INT_BE - Break Error interrupt
//! - \b UART_INT_PE - Parity Error interrupt
//! - \b UART_INT_FE - Framing Error interrupt
//! - \b UART_INT_RT - Receive Timeout interrupt
//! - \b UART_INT_TX - Transmit interrupt
//! - \b UART_INT_RX - Receive interrupt
//! - \b UART_INT_DSR - DSR interrupt
//! - \b UART_INT_DCD - DCD interrupt
//! - \b UART_INT_CTS - CTS interrupt
//! - \b UART_INT_RI - RI interrupt
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Enable the specified interrupts.
    //
    HWREG(ulBase + UART_O_IM) |= ulIntFlags;
}

//*****************************************************************************
//
//! Disables individual UART interrupt sources.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
//!
//! This function disables the indicated UART interrupt sources.  Only the
//! sources that are enabled can be reflected to the processor interrupt;
//! disabled sources have no effect on the processor.
//!
//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
//! parameter to UARTIntEnable().
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Disable the specified interrupts.
    //
    HWREG(ulBase + UART_O_IM) &= ~(ulIntFlags);
}

//*****************************************************************************
//
//! Gets the current interrupt status.
//!
//! \param ulBase is the base address of the UART port.
//! \param bMasked is \b false if the raw interrupt status is required and
//! \b true if the masked interrupt status is required.
//!
//! This function returns the interrupt status for the specified UART.  Either
//! the raw interrupt status or the status of interrupts that are allowed to
//! reflect to the processor can be returned.
//!
//! \return Returns the current interrupt status, enumerated as a bit field of
//! values described in UARTIntEnable().
//
//*****************************************************************************
unsigned long
UARTIntStatus(unsigned long ulBase, tBoolean bMasked)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return either the interrupt status or the raw interrupt status as
    // requested.
    //
    if(bMasked)
    {
        return(HWREG(ulBase + UART_O_MIS));
    }
    else
    {
        return(HWREG(ulBase + UART_O_RIS));
    }
}

//*****************************************************************************
//
//! Clears UART interrupt sources.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
//!
//! The specified UART interrupt sources are cleared, so that they no longer
//! assert.  This function must be called in the interrupt handler to keep the
//! interrupt from being triggered again immediately upon exit.
//!
//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
//! parameter to UARTIntEnable().
//!
//! \note Because there is a write buffer in the Cortex-M processor, it may
//! take several clock cycles before the interrupt source is actually cleared.
//! Therefore, it is recommended that the interrupt source be cleared early in
//! the interrupt handler (as opposed to the very last action) to avoid
//! returning from the interrupt handler before the interrupt source is
//! actually cleared.  Failure to do so may result in the interrupt handler
//! being immediately reentered (because the interrupt controller still sees
//! the interrupt source asserted).
//!
//! \return None.
//
//*****************************************************************************
void
UARTIntClear(unsigned long ulBase, unsigned long ulIntFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Clear the requested interrupt sources.
    //
    HWREG(ulBase + UART_O_ICR) = ulIntFlags;
}

//*****************************************************************************
//
//! Enable UART DMA operation.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulDMAFlags is a bit mask of the DMA features to enable.
//!
//! The specified UART DMA features are enabled.  The UART can be
//! configured to use DMA for transmit or receive and to disable
//! receive if an error occurs.  The \e ulDMAFlags parameter is the
//! logical OR of any of the following values:
//!
//! - UART_DMA_RX - enable DMA for receive
//! - UART_DMA_TX - enable DMA for transmit
//! - UART_DMA_ERR_RXSTOP - disable DMA receive on UART error
//!
//! \note The uDMA controller must also be set up before DMA can be used
//! with the UART.
//!
//! \return None.
//
//*****************************************************************************
void
UARTDMAEnable(unsigned long ulBase, unsigned long ulDMAFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Set the requested bits in the UART DMA control register.
    //
    HWREG(ulBase + UART_O_DMACTL) |= ulDMAFlags;
}

//*****************************************************************************
//
//! Disable UART DMA operation.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulDMAFlags is a bit mask of the DMA features to disable.
//!
//! This function is used to disable UART DMA features that were enabled
//! by UARTDMAEnable().  The specified UART DMA features are disabled.  The
//! \e ulDMAFlags parameter is the logical OR of any of the following values:
//!
//! - UART_DMA_RX - disable DMA for receive
//! - UART_DMA_TX - disable DMA for transmit
//! - UART_DMA_ERR_RXSTOP - do not disable DMA receive on UART error
//!
//! \return None.
//
//*****************************************************************************
void
UARTDMADisable(unsigned long ulBase, unsigned long ulDMAFlags)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Clear the requested bits in the UART DMA control register.
    //
    HWREG(ulBase + UART_O_DMACTL) &= ~ulDMAFlags;
}

//*****************************************************************************
//
//! Gets current receiver errors.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the current state of each of the 4 receiver error
//! sources.  The returned errors are equivalent to the four error bits
//! returned via the previous call to UARTCharGet() or UARTCharGetNonBlocking()
//! with the exception that the overrun error is set immediately when the
//! overrun occurs rather than when a character is next read.
//!
//! \return Returns a logical OR combination of the receiver error flags,
//! \b UART_RXERROR_FRAMING, \b UART_RXERROR_PARITY, \b UART_RXERROR_BREAK
//! and \b UART_RXERROR_OVERRUN.
//
//*****************************************************************************
unsigned long
UARTRxErrorGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the current value of the receive status register.
    //
    return(HWREG(ulBase + UART_O_RSR) & 0x0000000F);
}

//*****************************************************************************
//
//! Clears all reported receiver errors.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function is used to clear all receiver error conditions reported via
//! UARTRxErrorGet().  If using the overrun, framing error, parity error or
//! break interrupts, this function must be called after clearing the interrupt
//! to ensure that later errors of the same type trigger another interrupt.
//!
//! \return None.
//
//*****************************************************************************
void
UARTRxErrorClear(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Any write to the Error Clear Register clears all bits which are
    // currently set.
    //
    HWREG(ulBase + UART_O_ECR) = 0;
}

//*****************************************************************************
//
//! Sets the baud clock source for the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//! \param ulSource is the baud clock source for the UART.
//!
//! This function allows the baud clock source for the UART to be selected.
//! The possible clock source are the system clock (\b UART_CLOCK_SYSTEM) or
//! the precision internal oscillator (\b UART_CLOCK_PIOSC).
//!
//! Changing the baud clock source changes the baud rate generated by the
//! UART.  Therefore, the baud rate should be reconfigured after any change to
//! the baud clock source.
//!
//! \note The ability to specify the UART baud clock source varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UARTClockSourceSet(unsigned long ulBase, unsigned long ulSource)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));
    ASSERT((ulSource == UART_CLOCK_SYSTEM) || (ulSource == UART_CLOCK_PIOSC));

    //
    // Set the UART clock source.
    //
    HWREG(ulBase + UART_O_CC) = ulSource;
}

//*****************************************************************************
//
//! Gets the baud clock source for the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function returns the baud clock source for the specified UART.  The
//! possible baud clock source are the system clock (\b UART_CLOCK_SYSTEM) or
//! the precision internal oscillator (\b UART_CLOCK_PIOSC).
//!
//! \note The ability to specify the UART baud clock source varies with the
//! Stellaris part in use.  Please consult the datasheet for the part you are
//! using to determine whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
unsigned long
UARTClockSourceGet(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Return the UART clock source.
    //
    return(HWREG(ulBase + UART_O_CC));
}

//*****************************************************************************
//
//! Enables 9-bit mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function enables the 9-bit operational mode of the UART.
//!
//! \note The availability of 9-bit mode varies with the Stellaris part in use.
//! Please consult the datasheet for the part you are using to determine
//! whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UART9BitEnable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Enable 9-bit mode.
    //
    HWREG(ulBase + UART_O_9BITADDR) |= UART_9BITADDR_9BITEN;
}

//*****************************************************************************
//
//! Disables 9-bit mode on the specified UART.
//!
//! \param ulBase is the base address of the UART port.
//!
//! This function disables the 9-bit operational mode of the UART.
//!
//! \note The availability of 9-bit mode varies with the Stellaris part in use.
//! Please consult the datasheet for the part you are using to determine
//! whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UART9BitDisable(unsigned long ulBase)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Disable 9-bit mode.
    //
    HWREG(ulBase + UART_O_9BITADDR) &= ~UART_9BITADDR_9BITEN;
}

//*****************************************************************************
//
//! Sets the device address(es) for 9-bit mode.
//!
//! \param ulBase is the base address of the UART port.
//! \param ucAddr is the device address.
//! \param ucMask is the device address mask.
//!
//! This function configures the device address or range of device addresses
//! that respond to requests on the 9-bit UART port.  The received address is
//! masked with the mask and then compared against the given address, allowing
//! either a single address (if \b ucMask is 0xff) or a set of addresses to be
//! matched.
//!
//! \note The availability of 9-bit mode varies with the Stellaris part in use.
//! Please consult the datasheet for the part you are using to determine
//! whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UART9BitAddrSet(unsigned long ulBase, unsigned char ucAddr,
                unsigned char ucMask)
{
    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Set the address and mask.
    //
    HWREG(ulBase + UART_O_9BITADDR) = ucAddr << UART_9BITADDR_ADDR_S;
    HWREG(ulBase + UART_O_9BITAMASK) = ucMask << UART_9BITAMASK_MASK_S;
}

//*****************************************************************************
//
//! Sends an address character from the specified port when operating in 9-bit
//! mode.
//!
//! \param ulBase is the base address of the UART port.
//! \param ucAddr is the address to be transmitted.
//!
//! This function waits until all data has been sent from the specified port
//! and then sends the given address as an address byte.  It then waits until
//! the address byte has been transmitted before returning.
//!
//! The normal data functions (UARTCharPut(), UARTCharPutNonBlocking(),
//! UARTCharGet(), and UARTCharGetNonBlocking()) are used to send and receive
//! data characters in 9-bit mode.
//!
//! \note The availability of 9-bit mode varies with the Stellaris part in use.
//! Please consult the datasheet for the part you are using to determine
//! whether this support is available.
//!
//! \return None.
//
//*****************************************************************************
void
UART9BitAddrSend(unsigned long ulBase, unsigned char ucAddr)
{
    unsigned long ulLCRH;

    //
    // Check the arguments.
    //
    ASSERT(UARTBaseValid(ulBase));

    //
    // Wait until the FIFO is empty and the UART is not busy.
    //
    while(HWREG(ulBase + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY))
    {
    }

    //
    // Force the address/data bit to 1 to indicate this is an address byte.
    //
    ulLCRH = HWREG(ulBase + UART_O_LCRH);
    HWREG(ulBase + UART_O_LCRH) = ((ulLCRH & ~UART_LCRH_EPS) | UART_LCRH_SPS |
                                   UART_LCRH_PEN);

    //
    // Send the address.
    //
    HWREG(ulBase + UART_O_DR) = ucAddr;

    //
    // Wait until the address has been sent.
    //
    while(HWREG(ulBase + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY))
    {
    }

    //
    // Restore the address/data setting.
    //
    HWREG(ulBase + UART_O_LCRH) = ulLCRH;
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************


The Opus is a high end condominium launch by renowned developer City Developments Limited. The Opus land was bought through an enbloc sales, previously names Amber Park.
The Opus condo will consist of an appproximate of 600 plus units from 1 bedroom to 4 bedrooms. Units on the high floors will have an unblocked view of the East Coast Beach and the borderless sea.
The Opus price will be expected to be an average of $2,800 - $3,000 psf when they are launching. With a perfect address in Amber Road, coupled with a excellent District 15, this freehold development is expected to be well sort after by the rich.


text:
in Pune, Water management
This Simple Plan by Punekars Can Save 1600 Cr Litres of Water in 3 Years. Here's How
In an exclusive interview, the Indian Plumbing Association (IPA) explains how this simple solution can save massive quantities of wasted water in Ahmedabad, Bengaluru, Chennai, Delhi and Mumbai too.
by Tanvi Patel March 5, 2019, 4:10 pm
The 'I Save Water' campaign by the Indian Plumbing Association (IPA) is all set to save over 1600 crore litres of water in three years!
The ambitious plan has already seen great success in Pune, and now, the city chapter of the association aims to replicate it in five more cities.
This will be done through simple but effective techniques which will reduce the use of water and recycle a large portion of the used water.
The Better India spoke to Rahul Dhadphale, the National Joint Secretary of IPA about the campaign to understand how they plan on undertaking the seemingly humongous task to save precious water from going waste.
But first, we need to understand why it is crucial for us to make individual efforts towards this aim.
Representative image. Source: Nithi Anand/ Flickr.
One does not need to be briefed about water scarcity; it is a global crisis. However, when you calculate the amount of water used for minor activities like brushing our teeth or flushing, it really puts things into perspective.
A tap left open for a full minute lets out over 9 litres of water. That is over Rs 300 spent on a soft drink, or Rs 180 spent on bottles of mineral water of the same quantity, gone down the drain.
A shower consumes about 37 litres of water while every flush takes about 18 litres of water.
Now, of course, we cannot stop bathing or using the toilet. The former can be unhygienic and compromising on the latter is downright disgusting.
But what solutions do we have to use the water that needs to be used while not wasting it too much?
"A tap running at an optimum capacity lets out between 8 to 10 litres, but we do not more than 2.5 litres to wash our hands or for brushing," says Dhadphale.
"So, the IPA is trying to bring technical solutions, which are already available in the market, to the attention of the public.
For example, a pressure compensating aerator is fixed inside a tap so that it lets out water is such a flow that we get the satisfaction of using the water, but the extra 6 litres or so is not wasted," he adds.
Examples of the aerators. Courtesy: Rahul Dhadphale.
The aerator is a device fixed inside taps to add air to the water which increases its volume. This way, the flow remains as usual, but less water is let out and consequently, restricting wastage.
The ISW campaign was implemented in Pune three years ago when the IPA approached the Pune airport to fit its water outlets with the aerators.
The result? Over 15 lakh litres of water saved at the airport which sees a massive passenger footfall every day. In addition to the airport, the experiment targeted hotels and residential societies as well.
You may also like: Pune Students Give Free Meals to Juniors – For a Reason That'll Touch Your Heart
Speaking to The Hindu, Gurmeet Singh, the national president of IPA had said, "We went to residential societies and hotel groups. Hotels on an average have 1,500 rooms with high water consumption.
There is a lot of wastage in hotels as people use water without thinking, as it is free of cost. We saved 20 [lakh] litres of water through the project. The airport and railway stations in Pune are now saving water."
Taking the project to the next level, the IPA is pitching Rs 5-7 lakh to install about 1000 aerators which cost between Rs 350-1000, prioritising public spaces. Plumbers will be hired to install the devices in taps.
While the aerator has spelt success with the 10,000 people that installed it through the ISW campaign in Pune, Dhadphale says that rainwater harvesting and recycling of grey water are also on the agenda to ensure that water is saved not just on an individual level, but also on household and housing society levels.
Reducing the usage of water (through aerators), reusing it (greywater harvesting) and recycling (rainwater harvesting) are three excellent methods to conserve water.
You may also like: 20-YO Farmer's Son Is Using Fruit Peels to Help Rajasthan Beat Water Scarcity!
As mentioned at the start of this article, the project will be replicated in Ahmedabad, Bengaluru, Chennai, Delhi and Mumbai. "We are targeting this segment to save 100 crore-litres of water in the first year, 500 crore litres in the second and 1,000 crore litres in 2021," Singh told TH.
It is the need of the hour today to really scrutinise how much water we need and how much of it goes waste.
While groundwater levels are depleting in several parts of India and drought-like situations are frequent in central and southern India, it is up to us to conserve the water at our disposal and save it in the process.
Find Out What's Good Today – Sign Up Now!

redpajama_set_name: RedPajamaCommonCrawl


text:
Staff Council wants limits on retiree hiring
Career growth hindered by common practice, members say
By Cynthia Pasquale
Concerned that some retirees returning to work for the university might be in jobs that could be filled by unemployed or underemployed workers or those who might be promoted, the University of Colorado Staff Council asked administration officials to place a cap on the time a retiree can work for CU.
During their May 23 meeting at 1800 Grant St. in Denver, many council members said that while they understand the necessity to rehire retirees with specialized skills, they would like to see a more definitive limit placed on how long a retiree can work for the university. Some council members said they personally knew of retirees who continued to work for the university for as long as 10 years.
Administrative Policy Statement 5054, "Hiring Working Retirees into Staff Positions," currently is under review and is scheduled to take effect July 31. The current policy draft states, "Retirees can be hired into staff (university staff or university classified staff) positions limited to a 12-month, a defined project period or to be reviewed at the end of each year."
Council members also said departments should do a better job of training current employees so open positions can be filled by non-retirees.
Departments are not "giving staff an opportunity to move up in the system because they don't have good succession planning," said Deserae Frisk, chair of the University of Colorado Denver Staff Council. "Staff members aren't given the skills to be competitive" in the hiring process.
"Jobs that go on for years might be getting in the way for hope for a career path, and that is a very real concern," said E. Jill Pollock, vice president for employee and information services. "But some jobs require a high degree of specialization and will never be a full-time position. The campus consensus is that jobs that will never be full-time and are erratic" can be filled by a retiree.
Pollock said that one reason APS 5054 includes a "yearly review" is to ensure departments justify their reasons for hiring retirees. Pollock said the APS has received intense scrutiny. Originally, the policy only addressed PERA retirees, but it now includes Optional Retirement Plan (OPR) members.
To read the draft policy, visit https://www.cu.edu/policies/PUR/5054Draft.pdf.
Pollock also gave council members updates on Be Colorado Move and compensation system planning.
Be Colorado Move offers paid incentive to participants who exercise at least 30 minutes 12 times per month. Enrollees can earn $25 per month paid quarterly. At the end of April, the first month of the program, 1,201 employees – or about 7.8 percent of those who qualified – were enrolled. Pollock said the program's goal was to register 6 percent to 10 percent. "Of those enrolled, 40 percent met their goal, which is a nice start," Pollock said.
A number of devices and a downloaded app can be used to track and report exercise. For more information about the program, visit http://becolorado.org/programs/be-colorado-move/
The total rewards project for officers and exempt personnel (now referred to as university staff) is a three-phase compensation structure that officials currently are preparing. Last year, Pollock said, a team was put together to examine titles and job families and to review salaries as they related to market pay in order to make the university competitive. The team found that many employees are paid under market rates.
Officials also are identifying other elements important to employees in order to keep the university competitive. Those elements are benefits, environment (the culture of the organization and physical work environment), the work/life balance, and development opportunities.
Pollock said a compensation program must be equitable and consistent, market competitive, transparent, and reward high performance. She said the university has a strong desire to pay for performance, not effort or longevity, and to significantly differentiate rewards for high-level performers.
Among current university staff, Pollock said, almost 82 percent earn "exceed expectations" or "outstanding" on performance reviews. "There's hardly any differentiation from top to bottom until you get to "below expectations," she said. The university is rethinking its evaluation structure so high performers are rewarded appropriately. In addition, she said, supervisors must be trained to administer reviews in a way that differentiates employees, Pollock said.
Pollock said the first phase of the program is scheduled to begin in fiscal year 2015.
The council also was presented with an update on the President's Task Force on Efficiency (PTFE) by Leonard Dinegar, senior vice president and chief of staff, and Dan Montez, director of the Office of Policy and Efficiency.
When the task force was formed in 2008, there were 210 System Administration Policy Statements; those now have been pared to 85. In addition, the PTFE recently conducted an employee survey to assess its progress.
Montez said PTFE tried to identify a list of Top 10 issues important to employees and asked whether the issue had improved or gotten worse since 2009. Respondents said two areas had not improved: The administrative burden on campus (58.6 percent) and hiring processes, which were deemed too cumbersome (53.4). Results were nearly split on a third issue: Just over 48 percent said there is still a perception of mistrust of employees and a low tolerance for mistakes.
Respondents saw improvement in other issues, including reliance on paper and manual processes (80.2 percent), procurement and travel processes (63.9 percent), amount and delivery of training (64.7 percent), and the new financial reporting system (65.1 percent).
Montez said employees like the website and the president's communique. He said the office will continue to improve communications efforts so that information reaches all levels of the university.
Be Colorado, Denver Staff Council, Office of Policy and Efficiency, Staff Council
Staff Council reflects on year's progress, elects officers
Staff Council celebrates contributions of those who go above and beyond
2 min 55 sec ago


We appreciate the importance of your wedding day. It would be an honor to preside over your sacred ceremony.
There are many ways to personalize your ceremony from writing vows to exchanging flowers to lighting a unity candle. Whatever form of ceremony you choose, Center for Spiritual Living, Redding, is here to help. Your wedding may be traditional, spiritual or a combination of the two, and we offer wedding coordination, music arrangement, photography and audio/video recordings to preserve your memories.
The ministers of Center for Spiritual Living, Redding, are happy to officiate at your wedding onsite or at another location of your choosing. Within Center for Spiritual Living, Redding, the Sanctuary, Meditation Pavilion, LightSource Village, Labyrinth and Gardens are all available for your use. Offsite locations are also available. These include,and are not limited to, Whiskeytown Lake, Shasta Lake, Castle Lake, the Coastal Redwoods or a private residence of your choosing.
The basic fee for one of our ministers to officiate at your wedding is $200. This includes a one-hour, premarital counseling session, attendance at the rehearsal (if applicable), and officiating at your ceremony in the greater Redding, California area. Travel outside of the greater Redding area is $50 per half-hour, plus any expenses incurred.


text:
HomeAudiobooksPop Culture
Seven Deadly Sins: Settling the Argument Between Born Bad and Damaged Good
Written by Corey Taylor
Narrated by Corey Taylor
For the first time, Slipknot and Stone Sour frontman Corey Taylor speaks directly to his fans and shares his worldview about life as a sinner. And Taylor knows how to sin. As a small-town hero in the early '90s, he threw himself into a fierce-drinking, drug-abusing, hard-loving, live-for-the-moment life. Soon Taylor's music exploded, and he found himself rich, wanted, and on the road.
His new and ever-more-extreme lifestyle had an unexpected effect, however; for the first time, he began to actively think about what it meant to sin and whether sinning could-or should-be recast in a different light. Seven Deadly Sins is Taylor's personal story, but it's also a larger discussion of what it means to be seen as either a "good" person or a "bad" one. Yes, Corey Taylor has broken the law and hurt people, but, if sin is what makes us human, how wrong can it be?
Publisher: Tantor AudioReleased: Sep 27, 2011ISBN: 9781452604459Format: audiobook
More Audiobooks By Corey Taylor
You're Making Me Hate You: A Cantankerous Look at the Common Misconception That Humans Have Any Common Sense Left
A Funny Thing Happened on the Way to Heaven: Or, How I Made Peace With the Paranormal and Stigmatized Zealots and Cynics in the Process
Linger
Barrel Fever and Other Stories
So That Happened: A Memoir
Whatever You Say I Am: The Life and Times of Eminem
Anthony Bozza
Sabriel: The Old Kingdom, Book 1
I Hope They Serve Beer in Hell
Tucker Max
My Horizontal Life: A Collection of One-night Stands
Nerd Do Well: A Small Boy's Journey to Becoming a Big Kid
Sharon Osbourne Extreme: My Autobiography
Wonderful Tonight: George Harrison, Eric Clapton, and Me
The Girl Who Played with Fire: Millennium
Daughter of Smoke & Bone
There Is No F*cking Secret: Letters From a Badass Bitch
Tough Sh*t: Life Advice from a Fat, Lazy Slob Who Did Good
Three Weeks with My Brother
Micah Sparks
Light & Shade: Conversations With Jimmy Page
Brad Tolinski
Double Dexter: A Novel
Jeff Lindsay
Battle Hymn of the Tiger Mother
Amy Chua
Let's Take the Long Way Home: A Memoir of Friendship
Gail Caldwell
Beer Drinkers and Hell Raisers: The Rise of Motörhead
Martin Popoff
Van Halen Rising: How a Southern California Backyard Party Band Saved Heavy Metal
Greg Renoff
The Silent Cry: Alone, there is nothing Kim can do as her mother's mental health spirals out of control
Cathy Glass
Thanks a Lot, Mr. Kibblewhite: My Story
The Lords of Salem
Hell's Angel: The Life and Times of Sonny Barger and the Hell's Angels Motorcycle Club
Dexter in the Dark
Angry Optimist: The Life and Times of Jon Stewart
Lisa Rogak


text:
Q: protractor angular app browser.wait does not wait for element I'm checking wrong log in message. I'm using async spec with browser.wait to wait for element to appear in DOM.
But it does not work as expected.
I would expect it to wait for given timeout if element is not present.
But the spec fail quickly with message that element does not exist.
It makes no sense. If it really does not exist it should wait for it and fail after timeout.
it("reports wrong login",  async () => {
    browser.waitForAngularEnabled(false);
    await username.clear(); //clear as it may be filled already with something
    await password.clear(); //clear as it may be filled already with something
    await username.sendKeys("wrongemail");
    await password.sendKeys("wrongpass");
    await submitButton.click();

    let errorTextElement = element(by.css(".has-remote-error > small"));
    let until = protractor.ExpectedConditions;
    browser.wait(until.presenceOf(errorTextElement), 5000, "error message element not found in DOM");
    let errorText = await errorTextElement.getText();

    //CHECKS
    expect(errorText).toEqual("Your email address or password is incorrect!");

})

I tired several ways to do this I found. This seems to be the correct way to do it. Why is this not working?
here is the fail test message:
Failed: No element found using locator: By(css selector, .has-remote-error > small)

usign protractor version 5.4.3 direct connect chrome 80.0.3987.149 on Mac OS X
actually here is config
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/docs/referenceConf.js

const HtmlReporter = require('protractor-beautiful-reporter');

exports.config = {
    allScriptsTimeout: 30000,
    specs: [
        './e2eTests/**/*.e2e-spec.ts'
    ],
    capabilities: {
        'browserName': 'chrome'
    },
    directConnect: true,
    baseUrl: 'http://localhost:4200/',
    framework: 'jasmine',
    SELENIUM_PROMISE_MANAGER: false,
    // Options to be passed to Jasmine.
    jasmineNodeOpts: {
        showColors: true,
        defaultTimeoutInterval: 30000,
        print: function() {}
    },
    useAllAngular2AppRoots: true,
    beforeLaunch: function() {

    },
    onPrepare: function() {
        require('ts-node').register({ project: 'e2eTests/tsconfig.e2e.json' });

        // Add a screenshot reporter:
        jasmine.getEnv().addReporter(new HtmlReporter({
            preserveDirectory: false,
            takeScreenShotsOnlyForFailedSpecs: true,
            screenshotsSubfolder: 'images',
            jsonsSubfolder: 'jsons',
            baseDirectory: 'e2eTests/reports',
            clientDefaults:{
                useAjax:false,
                totalDurationFormat:'hms',
                showTotalDurationIn: 'header'
            }
        }).getJasmine2Reporter());

    }
};

A: Set waitForAngularEnabled to true and then try

it("reports wrong login",  async () => {
    browser.waitForAngularEnabled(true);
    await username.clear(); //clear as it may be filled already with something
    await password.clear(); //clear as it may be filled already with something
    await username.sendKeys("wrongemail");
    await password.sendKeys("wrongpass");
    await submitButton.click();

    let errorTextElement = element(by.css(".has-remote-error > small"));
    let until = protractor.ExpectedConditions;
    browser.wait(until.presenceOf(errorTextElement), 5000, "error message element not found in DOM");
    let errorText = await errorTextElement.getText();

    //CHECKS
    expect(errorText).toEqual("Your email address or password is incorrect!");

})

redpajama_set_name: RedPajamaStackExchange


The Victorian Local Jobs First Bill will be introduced to Parliament next year. The Bill will mandate the use of local content and local apprentices on Victoria's most significant public projects – from road and rail projects to schools and hospitals – ensuring every major contractor is held to account.
In addition, a Victorian Local Jobs First Commissioner will advocate for local content and oversee compliance of local workforce and content targets. And a new regime will be developed to target non-compliance.
As Victoria's advocate for local content, the Local Jobs First Commissioner will work closely with industry and departments to open-up opportunities for small and medium firms on government projects.
There will also be a new requirement on all government agencies to buy local uniforms and locally-manufactured personal protective equipment – such as high-vis vests, hard hats and safety goggles – where possible, instead of importing gear from overseas.
To help create local jobs across the supply chain, local content targets have been set on major government works including 100 per cent local steel on level crossings and 50 per cent local content on rolling stock.


text:
GrasshopperHerder
Grasshopper Herder
Fear and the Sandbox, Part II: Nurturing Innovation in the Workplace
UnLearning to Lead Part II: How to Get the Best Out of Everyone
Lean Tools: How TenTune Harnessed the Power of the Pencil
What Metrics Should Innovation Programs Measure?
Innovation Portfolio Management – Principles Before Tools
Innovation Ecosystem
User Experience & Research
By: Tristan Kromer
When Vladimir Horbovanu met Yiyo Guerra in 2012 at Hackers and Founders in Monterey, Mexico, he found a kindred spirit. Guerra, a music producer, wanted to bring unheard music to new ears, and connect unknown artists to audiences and concert promoters without the need for middlemen and expensive marketing campaigns.
Yiyo enlisted Vlad, a software developer, to help create a music-listening app that capitalized on the enormous number of indie artists out there trying to build an audience.
Their concept couldn't have been simpler: by pushing a "play" button on the app, the user could tap into a library of music samples lasting ten seconds each, giving them a hard-and-fast sampling of a half-dozen artists per minute — basically a Tindr for music fans. If the listener liked a tune, they would click the heart icon and connect to the band.
But we are getting ahead of ourselves. Long before they visualized the end-result and coded their MVP, they mapped everything out with pencil and paper (remember those?), iterating in small chunks, step by step, carefully documenting everything along the way.
And the first thing they had to do was find their customers.
Step 1: Who needs your service?
Describing their creation as "music blind tasting," the duo set out to discover the two personas key to their plan: the artist and the consumer. They sketched out these personas on a sheet of paper, knowing that understanding the relationship between the artist "Alex" and the listener "Mario" was crucial to a viable product.
Artist Persona: Alex
– single, 28 years old, holds a day job, makes $15k(MXN)/month
– collaborates with three bandmates, has lots of musician friends and contacts
– spends $40-50k/year making his music, plays 6 gigs/year for audience of 200, has no online promo tools
– wants industry contacts and a big break, willing to pay for exposure
Customer Persona: Mario
– hipster, 25 years old, college educated, makes $15k/month
– uses online playlists, influenced by music recommenders, doesn't buy much music or attend concerts, active on social media
– music connoisseur, enjoys recommending, doesn't care if the artist is famous
Step 2: Storyboard
Now that they had the personas laid out, they had to zero in on that relationship. Understanding how a listener finds new tunes can make or break a music delivery service, so they interviewed musicians and fans to get a handle on what might make someone use their website.
The team drew up a series of storyboards visualizing a seven-step process that would bring Mario into their website, where he could become a member and discover new music.
Mario's friend Juan likes a song on social media. Mario likes music, trusts Juan's taste, and is intrigued by the song's artwork/description, so he clicks on the link, taking him to the app to hear a 3-minute sample of the song.
Mario is intrigued by the app's layout, which includes Play and Discover buttons, and promises "your next favorite song" in three minutes.
After hearing the first song, Mario begins listening to 15-second samples from the Discover feature, clicking Like on the ones he finds interesting, and having fun engaging with the platform. When each sample ends, he decides whether or not he likes it enough to add it to his playlist.
Mario enjoys the One More Minute button, and keeps clicking on it, hearing new samples, until he gets bored.
Mario is redirected to a Facebook login button, which he uses because he's curious about the app and has already invested time listening to a batch of song samples.
After logging in, Mario can see the details of the first song he liked. He can play the whole song, and either keep it on his playlist or delete it. The app includes Next and Previous buttons so he can listen again or skip ahead.
Mario can see his list of favorites, and has the option of buying the songs/albums and learning more about the artists, or he can "roll again" to hear more samples.
Step 3: Wireframes
With a loose idea of how their users would be guided to their site, they set out to translate this process into wireframes. They knew they needed to beware of a bulky, obtrusive experience, so they focused on keeping the UI simple, clear, and elegant to create a site that flows seamlessly from one step to the next.
Initially songs were set to play for one minute, and the first version of the product was called "Bandemia," the name of a music compilation project Yiyo had produced that they planned to use for their initial content. (They would later rename the project "TenTune," a play on their eventual decision to limit the song samples to ten seconds.)
Step 4: Test Early
Despite having the technical abilities to build a prototype, that could have potentially taken months. Instead, Vlad look a lean approach and decided not to code right away. Vlad and Yiyo realized that what they needed most was to make their experience as engaging as possible to the end users.
They needed as much data from listeners as possible. If users wouldn't come and listen to several songs in a row, then Bandemia would need a massive amount of users to get enough data to tell which songs were more popular than others. For a website like this, acquiring users can be very expensive. Bandemia needed to go viral.
So instead of building a product, they built a paper prototype to simulate an experience that was close enough to their vision, hoping to get some real data on how useful and engaging the experience was.
They showed ten people this hand-drawn mockup of the site, and asked them to essentially treat it like an analog iPod. If they wanted to play the music, they'd press the play button. Vlad then gave them a set of headphones that he plugged into his MP3 player, and played them ten seconds of music to simulate the experience customers would have on the site. The test subjects would pick the songs they liked and list them to save for later.
Paramount to the experiment was the intuitive nature of the product, and their primary goal was achieved: the listeners weren't confused by the process. It didn't seem to matter to the listeners that the prototype was written in English and being tested in a Spanish-speaking country (prototyping was done in English so Vlad would not have to later revise his coding for internationalization of the app). It was clear to the customer that they just needed to push the play button. The product made sense to the listener, which to Vlad and Yiyo, was a validation of their vision.
Step 5: A Working Product
With the successful coffeeshop test, Vlad went into developer mode, quickly coding a working (but still minimal) website.
They pressed on, slowly iterating and increasing fidelity as they published the app and honed in on their market with live usability testing and promotion through Twitter and Facebook. They tracked everything, from feedback on social media, to how long it took someone to click next, to how many songs they listened to before leaving.
At the beginning they didn't see a lot of likes, so they made the Like button more prominent by having it replace the Play button after it was pushed.
In the first month, they saw people listened to an average of ten clips before leaving the site, 25% of users were liking a song, 22% went to the Facebook Connect page, and of those, 41% actually registered.
Along the way, they learned a number of useful tidbits that allowed them to modify the experience based on the data — the most significant being the amount of time a user needed to hear a song. Early iterations ranged from 1-3 minutes, but the coffee-house MVP demonstrated that listeners only needed ten seconds, which was validated by the metrics after the project was scaled up and coded. Out of 3,029 people, 47.24% skipped a song after only listening for 1-2 seconds – they knew right away that they didn't like it.
The paper prototype found the same key insight in a day that would have taken a month of quantitative data, revealing something many modern entrepreneurs wouldn't suspect:
Paper can be a useful, low-tech tool in reaching a conclusion before coding begins, saving valuable time between iterations. Click To Tweet
The team spent weeks between each version (their biggest design challenge was to give everything a round shape in CSS), working in small increments from iteration to iteration. Eventually they settled on a production-ready version, with the front page just a single, orange Play button, based on what they considered the most positive experience from the paper prototype.
Step 6: The Other Side of the Market
The hard part, of course, was monetization. The music they were working with was from Yiyo's Bandemia compilation albums, and they added some international bands to expand the sample list. But at some point they would need to charge bands to be listed, creating a two-sided market where bands were paying for exposure to listeners, plus data on those listeners.
Of course indie bands are not the richest people in the world, and neither Vlad nor Yiyo were sales-oriented, so it was difficult to enlist bands to use the platform if they had to pay for the service.
Having great user engagement is one thing, but that's not enough for a business model. Tentune.me needed to engage the paying side of the market.
TenTune ultimately suffered the most common fate of startups — failure to gather enough paying customers to make the product viable. Despite positive user-engagement feedback, Vlad and Yiyo's lack of a business model left them long on product and short on customers.
TenTune applied the same rapid testing to the other side of the market that was critical for their business – the paying customers – the musicians.
While listeners may love the service and find it addictive, TenTune's model was that the musicians would pay for this exposure. Unfortunately, most small-venue musicians are broke, and don't have the luxury of spending money on anything that doesn't have the name Fender or Marshall on it.
By rapidly testing musician demand with a landing page, they quickly found that the musicians couldn't support the business model. Even though they had personal relationships with most of these early-testers, indie artists didn't sign up for a paid plan. If anything, the personal relationship should have biased the test towards a false positive, with indie artists signing up out of feelings of personal obligation. But they just didn't care enough to spend what little money they had, a clear signal that the value proposition wasn't compelling enough.
"One of our errors was probably focusing mostly on the end users and assuming we had the artists' side covered and understood," Vlad later told me. "When the come join pitch turned into come pay, it became obvious they wouldn't. Most were performing as a hobby and were already on very tight budgets. What they wanted were gigs, and it wasn't clear if TenTune would help them get those."
In retrospect, maybe that was the side of the market they should have started with. Looking back at Alex's proto persona, perhaps TenTune's riskiest assumption was that Alex was willing to pay for exposure — maybe they could have saved some time by starting with the musicians.
In a two-sided market, testing the riskier side first can save a lot of time and heartache. Click To Tweet
With the speed and intentionally low fidelity of their testing, they invalidated their business model for a fraction of what a waterfall or "build it and they will come" approach would cost.
Ultimately, the decision they made was not to pivot to another business model (e.g. trying to make record companies or band promoters pay for the data) but to stop work and move on to the next idea.
Despite TenTune's ultimate demise, the project garnered Vlad a host of new skills to launch a new venture in real estate (and, we assume, many future ventures down the road). And while Vlad gained a deeper understanding of lean startup culture, the rest of us benefited from an unusually robust (and robustly documented) sample of how far an entrepreneur can go with a pencil, a piece of paper, and a good idea.
Download our customer persona framework here.
You don't need to build a website to test your idea. Low-tech = high-value.
You don't just build one MVP — each MVP is a new test and chance to learn.
Even a great experience requires a business model.
Test the riskiest side of the business model first.
A successful leader makes sure their teammates are capable in their position and clear on their mission. Continue reading...
Free Resources for Startups
The Real Startup Book
Learn S.M.A.R.T Template
Product/Market Fit Storyboard
Tristan Kromer
I help product teams go fast. My team at Kromatic and I coach teams on an ongoing basis and help design Innovation Ecosystems.
Sign Up for my Free Office Hours
Copyright © GrasshopperHerder.com 2019
Thoughts from a Lean Startup Coach & Innovation Ecosystem Designer
Get the latest tips and tricks on Lean Startup and Innovation Ecosystems from real practitioners.


text:
Q: how to transform JSON array in ramda js? Input JSON
{
  'abc': [{
    'stores':[{
      'myproperty':true
    }],
    'list':[{
      'listname':'mylist',
      'listid': 'list1'
    }],
    'address': {
      'name':'george street'
    }
  }]
}

Output JSON
{
  'abc': [
    {
      myproperty: true,
      listname: 'mylist',
      listid: 'list1',
      address: 'george street'
    }
  ]
}

Need to consider only the first object in the array.
const transformArray = R.pipe(R.identity, R.applySpec({
    abc: R.pipe(R.prop('abc'), R.map(x => {
        return x.stores[0].myproperty
    }))
}));

New to Ramdajs, trying the build the functional code

A: Use R.evolve transform the abc property, and then use R.applySpec with R.path to generate the internal object:

const { evolve, applySpec, path } = R

const fn = evolve({
  abc: [applySpec({
    myproperty: path(['stores', 0, 'myproperty']),
    listname: path(['list', 0, 'listname']),
    listid: path(['list', 0, 'listid']),
    address: path(['address', 'name']),
  })]
})

const obj = {
  'abc': [{
    'stores':[{
      'myproperty':true
    }],
    'list':[{
      'listname':'mylist',
      'listid': 'list1'
    }],
    'address': {
      'name':'george street'
    }
  }]
}

const result = fn(obj)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

If there might be multiple items in the abc array, use R.map as well:

const { evolve, map, applySpec, path } = R

const fn = evolve({
  abc: map(applySpec({
    myproperty: path(['stores', 0, 'myproperty']),
    listname: path(['list', 0, 'listname']),
    listid: path(['list', 0, 'listid']),
    address: path(['address', 'name']),
  }))
})

const obj = {
  'abc': [{
    'stores':[{
      'myproperty':true
    }],
    'list':[{
      'listname':'mylist',
      'listid': 'list1'
    }],
    'address': {
      'name':'george street'
    }
  }]
}

const result = fn(obj)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

A: We can write this fairly simply using a few Ramda functions:

const convert = map (compose (mergeAll, flatten, chain (values)))

const input = {abc: [{stores: [{myproperty: true }], list: [{listname:'mylist', listid: 'list1'}], address: {name:'george street'}}]}

console .log (convert (input))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {map, compose, mergeAll, flatten, chain, values} = R      </script>

The composed bit goes through these three steps:
// after `chain (values)`
[[{myproperty: true}], [{listname: "mylist", listid: "list1"}], {name: "george street"}]

// after `flatten`
[{myproperty: true}, {listname: "mylist", listid: "list1"}, {name: "george street"}]

// after `mergeAll`
{myproperty: true, listname: "mylist", listid: "list1", name: "george street"}

Then we apply that to all properties of our input object with map.


Be special! The new KBL 7000 extraSun ensures an extravagant tanning experience. Nothing like anything in its class, this will be sure to wow any client who steps foot in your salon. The new modern sleek design will fit perfectly in any room and take your class to a whole new level. The KBL 7000 pureSunlight and extraSunlight lamps provide intensive sunlight with a higher percentage of UVB for increased pigment development along with enhanced illumination features. The Intelligent Control System lets you adjust many settings instantly, without having to call a technician. Your customers will benefit as well as they are able to preset the individual comfort features with just the simple touch of the all new preselection display screen. The pureFacials provide an intense amount of sunlight just for the face. All of the well known comfort features such as aquaCool, airCon, aroma, Bluetooth etc. are available as well.