/*
 *  ======== UARTMSP432_writeCancel ========
 */
void UARTMSP432_writeCancel(UART_Handle handle)
{
    uintptr_t                 key;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;
    unsigned int              written;

    key = HwiP_disable();

    /* Return if there is no write. */
    if (!object->writeCount) {
        HwiP_restore(key);
        return;
    }

    /* Set size = 0 to prevent writing and restore interrupts. */
    MAP_UART_disableInterrupt(hwAttrs->baseAddr, EUSCI_A_UART_TRANSMIT_INTERRUPT);
    written = object->writeCount;
    object->writeCount = 0;

    HwiP_restore(key);

    /* Remove constraints set during write */
    Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
    Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);

    /* Reset the write buffer so we can pass it back */
    object->writeCallback(handle, (void *)object->writeBuf,
        object->writeSize - written);

    DebugP_log2("UART:(%p) Write canceled, %d bytes written",
        hwAttrs->baseAddr, object->writeSize - written);
}
/*
 *  ======== UARTMSP432_write ========
 */
int UARTMSP432_write(UART_Handle handle, const void *buffer, size_t size)
{
    uintptr_t                 key;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    if (!size) {
        return 0;
    }

    key = HwiP_disable();

    if (object->writeCount) {
        HwiP_restore(key);
        DebugP_log1("UART:(%p) Could not write data, uart in use.",
            hwAttrs->baseAddr);

        return (UART_ERROR);
    }

    /* Save the data to be written and restore interrupts. */
    object->writeBuf = buffer;
    object->writeSize = size;
    object->writeCount = size;

    HwiP_restore(key);

    /*
     * Set power constraint to keep peripheral active during transfer and
     * to prevent a performance level change
     */
    Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
    Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);

    /* Enabling TX interrupt will trigger the Hwi which will handle the write */
    MAP_UART_enableInterrupt(hwAttrs->baseAddr, EUSCI_A_UART_TRANSMIT_INTERRUPT);

    /* If writeMode is blocking, block and get the state. */
    if (object->state.writeMode == UART_MODE_BLOCKING) {
        /* Pend on semaphore and wait for Hwi to finish. */
        if (SemaphoreP_pend(object->writeSem, object->writeTimeout) !=
                SemaphoreP_OK) {
            /* Semaphore timed out, make the write empty and log the write. */
            MAP_UART_disableInterrupt(hwAttrs->baseAddr,
                EUSCI_A_UART_TRANSMIT_INTERRUPT);
            object->writeCount = 0;

            DebugP_log2("UART:(%p) Write timed out, %d bytes written",
                hwAttrs->baseAddr, object->writeCount);
        }
        return (object->writeSize - object->writeCount);
    }

    return (0);
}
int CameraCC3200DMA_capture(Camera_Handle handle, void *buffer,
                                        unsigned int bufferlen)
{
   CameraCC3200DMA_Object        *object = handle->object;
   CameraCC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;
   uintptr_t                      key;

   key = HwiP_disable();
   if (object->inUse) {
       HwiP_restore(key);
       DebugP_log1("Camera:(%p) Could not capture data, camera in use.",
                      ((CameraCC3200DMA_HWAttrs const *)
                          (handle->hwAttrs))->baseAddr);

       return (CAMERA_STATUS_UNDEFINEDCMD);
   }

   object->captureBuf             = buffer;
   object->bufferlength           = bufferlen;
   object->frameLength            = 0;
   object->cameraDMAxIntrRcvd     = 0;
   object->inUse                  = 1;
   object->cameraDMA_PingPongMode = 0;

   HwiP_restore(key);

   /* Set constraints to guarantee transaction */
   Power_setConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);

   /* Start the DMA transfer */
   CameraCC3200DMA_configDMA(handle);
   MAP_CameraCaptureStart(hwAttrs->baseAddr);

   /* If operationMode is blocking, block and get the status. */
   if (object->operationMode == Camera_MODE_BLOCKING) {
       /* Pend on semaphore and wait for Hwi to finish. */
       if (SemaphoreP_pend(object->captureSem, object->captureTimeout)
                                                        != SemaphoreP_OK) {

           DebugP_log2("Camera:(%p) Capture timed out, %d bytes captured",
                          ((CameraCC3200DMA_HWAttrs const *)
                          (handle->hwAttrs))->baseAddr,
                          object->frameLength);
       }
       else {
           MAP_CameraCaptureStop(hwAttrs->baseAddr, true);
           return (object->frameLength);
       }
   }

    return (0);
}
/*
 *  ======== SPICC3200DMA_close ========
 *  @pre    Function assumes that the handle is not NULL
 */
void SPICC3200DMA_close(SPI_Handle handle)
{
    uintptr_t                    key;
    SPICC3200DMA_Object         *object = handle->object;
    SPICC3200DMA_HWAttrs const  *hwAttrs = handle->hwAttrs;

    MAP_SPIDisable(hwAttrs->baseAddr);
    MAP_SPICSDisable(hwAttrs->baseAddr);

    MAP_SPIDmaDisable(hwAttrs->baseAddr, SPI_RX_DMA | SPI_TX_DMA);
    MAP_SPIFIFODisable(hwAttrs->baseAddr, SPI_RX_FIFO | SPI_TX_FIFO);

    /* Release power dependency on SPI. */
    Power_releaseDependency(getPowerMgrId(hwAttrs->baseAddr));
    Power_releaseDependency(PowerCC3200_PERIPH_UDMA);

    Power_unregisterNotify(&(object->notifyObj));

    if (object->hwiHandle) {
        HwiP_delete(object->hwiHandle);
    }
    if (object->transferComplete) {
        SemaphoreP_delete(object->transferComplete);
    }

    DebugP_log1("SPI:(%p) closed", hwAttrs->baseAddr);

    key = HwiP_disable();
    object->isOpen = false;
    HwiP_restore(key);
}
/*
 *  ======== PWMTimerMSP432_close ========
 *  @pre    Function assumes that the handle is not NULL
 */
void PWMTimerMSP432_close(PWM_Handle handle)
{
    uintptr_t                     key;
    PWMTimerMSP432_Object        *object = handle->object;
    PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    MAP_Timer_A_setCompareValue(hwAttrs->baseAddr, hwAttrs->compareRegister, 0);

    key = HwiP_disable();

    /* Mark the output as unused */
    (object->pwmTimerStatus)->activeOutputsMask &= ~(object->pwmCompareOutputBit);

    /* Stop timer & clear all status if no other PWM instances are being used */
    if ((object->pwmTimerStatus)->activeOutputsMask == 0) {
        MAP_Timer_A_stopTimer(hwAttrs->baseAddr);
        (object->pwmTimerStatus)->cyclesPerMicroSec = 0;
        (object->pwmTimerStatus)->period = 0;
        (object->pwmTimerStatus)->prescalar = 0;
    }

    object->isOpen = false;

    HwiP_restore(key);

    /* Remove power constraints */
    Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
    Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
    Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0);
    Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1);

    DebugP_log1("PWM: (%p) closed", (uintptr_t) handle);
}
/*
 *  ======== SPICC3200DMA_transfer ========
 *  @pre    Function assumes that handle and transaction is not NULL
 */
bool SPICC3200DMA_transfer(SPI_Handle handle, SPI_Transaction *transaction)
{
    uintptr_t                   key;
    SPICC3200DMA_Object        *object = handle->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;

    /* This is a limitation by the micro DMA controller */
    if ((transaction->count == 0) || (transaction->count > 1024) ||
        !(transaction->rxBuf || transaction->txBuf) ||
        (!(transaction->rxBuf && transaction->txBuf) && !hwAttrs->scratchBufPtr)) {
        return (false);
    }

    /* Check if a transfer is in progress */
    key = HwiP_disable();
    if (object->transaction) {
        HwiP_restore(key);
        DebugP_log1("SPI:(%p) ERROR! Transaction still in progress",
                    ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr);

        return (false);
    }
    else {
        object->transaction = transaction;
        HwiP_restore(key);
    }

    /* Set constraints to guarantee transaction */
    Power_setConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);

    SPICC3200DMA_configDMA(handle, transaction);
    MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW);
    MAP_SPIIntEnable(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW);

    MAP_SPIEnable(hwAttrs->baseAddr);
    MAP_SPICSEnable(hwAttrs->baseAddr);

    if (object->transferMode == SPI_MODE_BLOCKING) {
        DebugP_log1("SPI:(%p) transfer pending on transferComplete semaphore",
                    ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr);

        SemaphoreP_pend(object->transferComplete, SemaphoreP_WAIT_FOREVER);
    }

    return (true);
}
/*
 *  ======== PWMTimerMSP432_control ========
 *  @pre    Function assumes that the handle is not NULL
 */
int PWMTimerMSP432_control(PWM_Handle handle, unsigned int cmd, void *arg)
{
    uintptr_t                     key;
    uint32_t                      period;
    uint8_t                       prescalar;
    PWMTimerMSP432_Object        *object = handle->object;
    PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    switch(cmd) {
        case PWMTimerMSP432_CHANGE_PERIOD:
            DebugP_assert((uint32_t *) arg != NULL);

            key = HwiP_disable();

            /* Calculate period in PWM timer counts */
            period = (*(uint32_t *) arg) *
                (object->pwmTimerStatus)->cyclesPerMicroSec;
            prescalar = PWMTimerMSP432_calculatePrescalar(period);

            /* Ensure new period can be generated with current prescalar */
            if (prescalar != (object->pwmTimerStatus)->prescalar) {
                HwiP_restore(key);
                return (-1);
            }

            MAP_Timer_A_setCompareValue(hwAttrs->baseAddr,
                TIMER_A_CAPTURECOMPARE_REGISTER_0, period/prescalar);

            /* Update PWM status with new period */
            (object->pwmTimerStatus)->period = *((uint32_t *) arg);

            HwiP_restore(key);

            return (PWMTimerMSP432_CHANGE_PERIOD);

        default:
            /* No implementation yet */
            return (PWM_STATUS_UNDEFINEDCMD);
    }
}
/*
 *  ======== PWMTimerMSP432_getPeriodMicroSecs ========
 *  @pre    Function assumes that handle is not NULL
 */
unsigned int PWMTimerMSP432_getPeriodMicroSecs(PWM_Handle handle)
{
    uintptr_t              key;
    unsigned int           period;
    PWMTimerMSP432_Object *object = handle->object;

    key = HwiP_disable();

    period = (object->pwmTimerStatus)->period;

    HwiP_restore(key);

    return period;
}
/*
 *  ======== readTaskCallback ========
 *  This function is called the first time by the UART_read task and tries to
 *  get all the data it can get from the ringBuffer. If it finished, it will
 *  perform the user supplied callback. If it didn't finish, the ISR must handle
 *  the remaining data. By setting the drainByISR flag, the UART_read function
 *  handed over the responsibility to get the remaining data to the ISR.
 */
static int readTaskCallback(UART_Handle handle)
{
    bool               makeCallback = false;
    unsigned char      readIn;
    unsigned char     *bufferEnd;
    uintptr_t          key;
    UARTMSP432_Object *object = handle->object;

    object->state.drainByISR = false;
    bufferEnd = (unsigned char*) object->readBuf + object->readSize;

    while (object->readCount) {
        if (RingBuf_get(&object->ringBuffer, &readIn) < 0) {
            break;
        }

        DebugP_log2("UART:(%p) read '0x%02x'",
            ((UARTMSP432_HWAttrs const *)(handle->hwAttrs))->baseAddr,
            (unsigned char) readIn);

        *(unsigned char *) (bufferEnd - object->readCount *
            sizeof(unsigned char)) = readIn;

        key = HwiP_disable();

        object->readCount--;

        HwiP_restore(key);

        if (object->state.readDataMode == UART_DATA_TEXT &&
                object->state.readReturnMode == UART_RETURN_NEWLINE &&
                readIn == '\n') {
            makeCallback = true;
            break;
        }
    }

    if (!object->readCount || makeCallback) {
        /* Nested UART_reads from within callbacks are NOT supported!!! */
        object->readCallback(handle, object->readBuf,
            object->readSize - object->readCount);
        object->readSize = 0;
    }
    else {
        object->state.drainByISR = true;
    }

    return (0);
}
/*
 *  ======== UARTMSP432_read ========
 */
int UARTMSP432_read(UART_Handle handle, void *buffer, size_t size)
{
    uintptr_t          key;
    UARTMSP432_Object *object = handle->object;

    key = HwiP_disable();

    if ((object->state.readMode == UART_MODE_CALLBACK) && object->readSize) {
        HwiP_restore(key);

        DebugP_log1("UART:(%p) Could not read data, uart in use.",
            ((UARTMSP432_HWAttrs const *)(handle->hwAttrs))->baseAddr);
        return (UART_ERROR);
    }

    /* Save the data to be read and restore interrupts. */
    object->readBuf = buffer;
    object->readSize = size;
    object->readCount = size;

    HwiP_restore(key);

    return (object->readFxns.readTaskFxn(handle));
}
Esempio n. 11
0
/*
 *  ======== List_putHead ========
 */
void List_putHead(List_List *list, List_Elem *elem)
{
    uintptr_t key;

    key = HwiP_disable();

    elem->next = list->head;
    elem->prev = NULL;
    if (list->head != NULL) {
        list->head->prev = elem;
    }
    else {
        list->tail = elem;
    }

    list->head = elem;

    HwiP_restore(key);
}
Esempio n. 12
0
/*
 *  ======== List_get ========
 */
List_Elem *List_get(List_List *list)
{
    List_Elem *elem;
    uintptr_t key;

    key = HwiP_disable();

    elem = list->head;

    /* See if the List was empty */
    if (elem != NULL) {
        list->head = elem->next;
        if (elem->next != NULL) {
            elem->next->prev = NULL;
        }
        else {
            list->tail = NULL;
        }
    }

    HwiP_restore(key);

    return (elem);
}
/*
 *  ======== UARTMSP432_readCancel ========
 */
void UARTMSP432_readCancel(UART_Handle handle)
{
    uintptr_t          key;
    UARTMSP432_Object *object = handle->object;

    if ((object->state.readMode != UART_MODE_CALLBACK) ||
        (object->readSize == 0)) {
        return;
    }

    key = HwiP_disable();

    object->state.drainByISR = false;
    /*
     * Indicate that what we've currently received is what we asked for so that
     * the existing logic handles the completion.
     */
    object->readSize -= object->readCount;
    object->readCount = 0;

    HwiP_restore(key);

    object->readFxns.readTaskFxn(handle);
}
/*
 *  ======== UARTMSP432_open ========
 */
UART_Handle UARTMSP432_open(UART_Handle handle, UART_Params *params)
{
    unsigned int              i;
    uintptr_t                 key;
    uint32_t                  clockFreq;
    uint8_t                   numPerfLevels;
    int32_t                   baudrateIndex;
    union {
        ClockP_Params         clockParams;
        HwiP_Params           hwiParams;
        SemaphoreP_Params     semParams;
    } portsParams;
    PowerMSP432_Freqs         powerFreqs;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    if (params == NULL) {
        params = (UART_Params *) &UART_defaultParams;
    }

    /* Check that a callback is set */
    DebugP_assert((params->readMode != UART_MODE_CALLBACK) ||
        (params->readCallback != NULL));
    DebugP_assert((params->writeMode != UART_MODE_CALLBACK) ||
        (params->writeCallback != NULL));

    key = HwiP_disable();

    if (object->state.opened) {
        HwiP_restore(key);
        DebugP_log1("UART:(%p) already in use.", hwAttrs->baseAddr);
        return (NULL);
    }
    object->state.opened = true;

    HwiP_restore(key);

    /* Ensure a supported clock source is used */
    if (hwAttrs->clockSource != EUSCI_A_UART_CLOCKSOURCE_ACLK &&
        hwAttrs->clockSource != EUSCI_A_UART_CLOCKSOURCE_SMCLK) {
        DebugP_log1("UART:(%p) Error! Using unsupported clock source.",
            hwAttrs->baseAddr);
        object->state.opened = false;
        return (NULL);
    }

    /*
     * Add power management support - Disable performance transitions while
     * opening the driver is open.  This constraint remains active until a
     * UART_control() disables receive interrupts.  Afterwards performance
     * levels can be changed by the application.  A UART_control() call can
     * enable RX interrupts again and set the pertinent constraints.
     */
    Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);

    /*
     * Verify that the driver can be opened at current performance level and
     * set constraints for other performance levels.
     */
    numPerfLevels = PowerMSP432_getNumPerfLevels();
    PowerMSP432_getFreqs(Power_getPerformanceLevel(), &powerFreqs);
    if (hwAttrs->clockSource == EUSCI_A_UART_CLOCKSOURCE_ACLK) {
        /*
         * Verify if driver can be opened with ACLK; ACLK does not change
         * in any performance level.
         */
        baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT,
            hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.ACLK);
        if (baudrateIndex == -1) {
            DebugP_log3("UART:(%p) unable to find a valid buadrate %d "
                "configuration at clock input clock freq %d", hwAttrs->baseAddr,
                params->baudRate, powerFreqs.ACLK);
            Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
            object->state.opened = false;
            return (NULL);
        }
        clockFreq = powerFreqs.ACLK;
    }
    else {    /* hwAttrs->clockSource == EUSCI_A_UART_CLOCKSOURCE_SMCLK */
        baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT,
            hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.SMCLK);
        if (baudrateIndex == -1) {
            DebugP_log3("UART:(%p) unable to find a valid buadrate %d "
                "configuration at clock input clock freq %d", hwAttrs->baseAddr,
                params->baudRate, powerFreqs.SMCLK);
            Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
            object->state.opened = false;
            return (NULL);
        }
        clockFreq = powerFreqs.SMCLK;

        /*
         * SMCLK changes with performance levels.  Set constraints for
         * unsupported performance levels.
         */
        for (i = 0; i < numPerfLevels; i++) {
            PowerMSP432_getFreqs(i, &powerFreqs);
            baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT,
                hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.SMCLK);
            if (baudrateIndex == -1) {
                /* Set constraint and keep track of it in perfConstraintMask */
                object->perfConstraintMask |= (1 << i);
                Power_setConstraint(PowerMSP432_DISALLOW_PERFLEVEL_0 + i);
            }
        }
    }

    /*
     * Shutdown not supported while driver is open.  The DEEPSLEEP_0 constraint
     * keeps stops the device from going into LPM3 or higher.  This is done
     * to keep the UART peripheral receiving in the background and storing data
     * in the internal ring buff.
     */
    Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
    Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0);
    Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1);

    /* Register function to reconfigure peripheral on perf level changes */
    Power_registerNotify(&object->perfChangeNotify,
        PowerMSP432_START_CHANGE_PERF_LEVEL | PowerMSP432_DONE_CHANGE_PERF_LEVEL,
        perfChangeNotifyFxn, (uintptr_t) handle);

    /* Create the Hwi for this UART peripheral */
    HwiP_Params_init(&(portsParams.hwiParams));
    portsParams.hwiParams.arg = (uintptr_t) handle;
    portsParams.hwiParams.priority = hwAttrs->intPriority;
    object->hwiHandle = HwiP_create(hwAttrs->intNum, UARTMSP432_hwiIntFxn,
        &(portsParams.hwiParams));
    if (object->hwiHandle == NULL) {
        DebugP_log1("UART:(%p) HwiP_create() failed", hwAttrs->baseAddr);
        UARTMSP432_close(handle);
        return (NULL);
    }

    SemaphoreP_Params_init(&(portsParams.semParams));
    portsParams.semParams.mode = SemaphoreP_Mode_BINARY;

    if (params->writeMode == UART_MODE_BLOCKING) {
        /* If write mode is blocking create a semaphore and set callback. */
        object->writeSem = SemaphoreP_create(0, &(portsParams.semParams));
        if (object->writeSem == NULL) {
            DebugP_log1("UART:(%p) SemaphoreP_create() failed.",
                hwAttrs->baseAddr);
            UARTMSP432_close(handle);
            return (NULL);
        }
        object->writeCallback = &writeSemCallback;
    }
    else {
        /* UART_MODE_CALLBACK - Store application callback */
        object->writeCallback = params->writeCallback;
    }

    if (params->readMode == UART_MODE_BLOCKING) {
        /* If read mode is blocking create a semaphore and set callback. */
        object->readSem = SemaphoreP_create(0, &(portsParams.semParams));
        if (object->readSem == NULL) {
            DebugP_log1("UART:(%p) SemaphoreP_create() failed.",
                hwAttrs->baseAddr);
            UARTMSP432_close(handle);
            return (NULL);
        }
        object->readCallback = &readSemCallback;

        ClockP_Params_init(&(portsParams.clockParams));
        portsParams.clockParams.arg = (uintptr_t) handle;
        object->timeoutClk = ClockP_create((ClockP_Fxn) &readBlockingTimeout,
            &(portsParams.clockParams));
        if (object->timeoutClk == NULL) {
            DebugP_log1("UART:(%p) ClockP_create() failed.", hwAttrs->baseAddr);
            UARTMSP432_close(handle);
            return (NULL);
        }
    }
    else {
        object->state.drainByISR = false;
        object->readCallback = params->readCallback;
    }

    /*
     * Initialize UART read buffer - will store received bytes until
     * UART_read is invoked.
     */
    RingBuf_construct(&object->ringBuffer, hwAttrs->ringBufPtr,
        hwAttrs->ringBufSize);
    /*
     * Store UART parameters & initialize peripheral.  These are used to
     * re/initialize the peripheral when opened or changing performance level.
     */
    object->state.readMode       = params->readMode;
    object->state.writeMode      = params->writeMode;
    object->state.readReturnMode = params->readReturnMode;
    object->state.readDataMode   = params->readDataMode;
    object->state.writeDataMode  = params->writeDataMode;
    object->state.readEcho       = params->readEcho;
    object->readTimeout          = params->readTimeout;
    object->writeTimeout         = params->writeTimeout;
    object->baudRate             = params->baudRate;
    object->stopBits             = params->stopBits;
    object->parityType           = params->parityType;
    object->readFxns =
        staticFxnTable[object->state.readMode][object->state.readDataMode];
    object->writeBuf             = NULL;
    object->readBuf              = NULL;
    object->writeCount           = 0;
    object->readCount            = 0;
    object->writeSize            = 0;
    object->readSize             = 0;
    object->state.writeCR        = false;
    object->state.txEnabled      = false;
    object->state.rxEnabled      = true;
    initHw(object, hwAttrs, clockFreq);

    DebugP_log1("UART:(%p) opened", hwAttrs->baseAddr);

    /* Return the handle */
    return (handle);
}
/*
 *  ======== WatchdogMSP432_open ========
 */
Watchdog_Handle WatchdogMSP432_open(Watchdog_Handle handle,
    Watchdog_Params *params)
{
    uintptr_t                     key;
    HwiP_Params                   hwiParams;
    WatchdogMSP432_Object        *object = handle->object;
    WatchdogMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    /* If params are NULL use defaults. */
    if (params == NULL) {
        params = (Watchdog_Params *) &Watchdog_defaultParams;
    }

    /* Ensure a callbackFxn is specified if using watchdog in interval mode */
    DebugP_assert((params->resetMode == Watchdog_RESET_ON) ||
        (params->callbackFxn != NULL));

    /* Don't allow preemption */
    key = HwiP_disable();

    /* Check if the Watchdog is open already with the HWAttrs */
    if (object->isOpen) {
        HwiP_restore(key);
        DebugP_log1("Watchdog: Handle %x already in use.", (uintptr_t) handle);
        return (NULL);
    }
    object->isOpen = true;
    HwiP_restore(key);

    /*
     * Add power management support - Disable performance transitions while
     * opening the driver.
     */
    Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
    if (params->resetMode == Watchdog_RESET_ON ||
        hwAttrs->clockSource == WDT_A_CLOCKSOURCE_SMCLK ||
        hwAttrs->clockSource == WDT_A_CLOCKSOURCE_ACLK) {
        /*
         * Do not support power modes lower than LPM0 if in watchdog mode or
         * in interval mode and using SMCLK or ACLK as clock sources.
         * Additionally, LPM3.5 cannot be reached.
         */
        Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
        Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0);
    }
    else {
        /*
         * Interval mode and not using SMCLK and ACLK as clock sources.  Can
         * be configured as a LPM3.5 wake up source, so we do not set the
         * SHUTDOWN_0 constraint.
         */
        Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1);
    }

    /* SHUTDOWN_1 (LPM4.5) not supported while driver is open */
    Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1);

    /* Construct Hwi object for watchdog */
    if (params->callbackFxn) {
        HwiP_Params_init(&hwiParams);
        hwiParams.arg = (uintptr_t) handle;
        hwiParams.priority = hwAttrs->intPriority;
        object->hwiHandle = HwiP_create(hwAttrs->intNum, params->callbackFxn,
                               &hwiParams);
        if (!object->hwiHandle) {
            DebugP_log0("Watchdog: HwiP_create() failed");
            Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
            WatchdogMSP432_close(handle);
            return (NULL);
        }
    }

    /* Configure and initialize WDT */
    object->resetMode = params->resetMode;
    if (object->resetMode == Watchdog_RESET_ON) {
        MAP_WDT_A_initWatchdogTimer(hwAttrs->clockSource, hwAttrs->clockDivider);
    }
    else {
        MAP_WDT_A_initIntervalTimer(hwAttrs->clockSource, hwAttrs->clockDivider);
    }
    MAP_WDT_A_startTimer();

    /* Allow performance level changes  */
    Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);

    DebugP_log1("Watchdog: (0x%x) opened and enabled.", (uintptr_t) handle);

    /* Return handle of the Watchdog object */
    return (handle);
}
/*
 *  ======== PWMTimerMSP432_setDuty ========
 *  @pre    Function assumes that handle is not NULL
 */
void PWMTimerMSP432_setDuty(PWM_Handle handle, uint32_t duty)
{
    uintptr_t                     key;
    uint16_t                      period;
    uint32_t                      newDuty;
    PWMTimerMSP432_Object        *object = handle->object;
    PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    key = HwiP_disable();

    period = MAP_Timer_A_getCaptureCompareCount(hwAttrs->baseAddr,
        TIMER_A_CAPTURECOMPARE_REGISTER_0);

    switch(object->dutyMode) {
        case PWM_DUTY_COUNTS:
            /* Duty specified as PWM timer counts */
            DebugP_assert(duty <= period);

            newDuty = duty;
            break;

        case PWM_DUTY_TIME:
            /* Duty is specified in microseconds */
            DebugP_assert(duty <= (object->pwmTimerStatus)->period);

            newDuty = (duty * (object->pwmTimerStatus)->cyclesPerMicroSec) /
                (object->pwmTimerStatus)->prescalar;
            break;

        case PWM_DUTY_SCALAR:
            /* Duty specified as a number [0 - 65535] scaled to the period */
            DebugP_assert(duty <= maxDutyValue);

            if (duty >= maxDutyValue) {
                newDuty = period;
            }
            else {
                newDuty = (period * 100) / maxDutyValue;
                newDuty = (newDuty * duty) / 100;
            }
            break;

        default:
            DebugP_log1("PWM: (%p) unsupported PWM duty mode; duty unchanged",
                (uintptr_t) handle);
            return;
    }

    /*
     * This condition ensures that the output will remain active if the newDuty
     * is greater or equal to the period.
     */
    if (newDuty >= period) {
        newDuty = (period + 1);
    }

    MAP_Timer_A_setCompareValue(hwAttrs->baseAddr, hwAttrs->compareRegister,
        newDuty);

    HwiP_restore(key);

    DebugP_log2("PWM: (%p) duty set to: %d", (uintptr_t) handle, duty);
}
/*
 *  ======== PWMTimerMSP432_open ========
 *  @pre    Function assumes that the handle is not NULL
 */
PWM_Handle PWMTimerMSP432_open(PWM_Handle handle, PWM_Params *params)
{
    uintptr_t                     key;
    bool                          timerIsRunning;
    uint8_t                       cyclesPerMicroSec;
    uint32_t                      clockFreq;
    uint32_t                      tempPeriod;
    Timer_A_PWMConfig             pwmConfig;
    PowerMSP432_Freqs             powerFreqs;
    PWMTimerMSP432_Object        *object = handle->object;
    PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    if(params == NULL) {
        params = (PWM_Params *) &PWM_defaultParams;
    }

    key = HwiP_disable();

    /*
     * Before opening the PWM instance, we must verify that the Timer is not
     * already open or being used by another source (possibly the Kernel).
     * Additionally, the Timer peripheral could have already been initialized
     * by another PWM instance, so we must verify if any other PWM driver
     * (on the same Timer) is initialized.
     */
    timerIsRunning =
        (TIMER_A_CMSIS(hwAttrs->baseAddr)->rCTL.b.bMC != TIMER_A_STOP_MODE);
    if (object->isOpen ||
        (timerIsRunning && (object->pwmTimerStatus)->activeOutputsMask == 0)) {
        /* Timer already opened or used by source other than PWM driver */
        HwiP_restore(key);
        DebugP_log1("PWM:(%p) timer used by another source.",
            (uintptr_t) handle);
        return (NULL);
    }

    /*
     * Timer capture/compare register 0 is used as the period.  It cannot be
     * used to generate PWM output.
     */
    DebugP_assert(hwAttrs->compareRegister != TIMER_A_CAPTURECOMPARE_REGISTER_0);

    /*
     * Add power management support - PWM driver does not allow performance
     * level changes, low power modes or shutdown while open.
     */
    Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
    Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
    Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0);
    Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1);

    PowerMSP432_getFreqs(Power_getPerformanceLevel(), &powerFreqs);
    clockFreq = powerFreqs.SMCLK;
    cyclesPerMicroSec = clockFreq / 1000000;

    /* Assert if period is too large for peripheral */
    tempPeriod = params->period * cyclesPerMicroSec;
    DebugP_assert(tempPeriod <= maxPrescalarValue * maxDutyValue);

    /*
     * Verify if timer has been initialized by another PWM instance.  If so,
     * make sure PWM periods are the same, do not open driver if otherwise.
     */
    if ((object->pwmTimerStatus)->period &&
        (object->pwmTimerStatus)->period != params->period) {
        HwiP_restore(key);
        DebugP_log1("PWM:(%p) differing PWM periods, cannot open driver.",
            (uintptr_t) handle);
        PWMTimerMSP432_close(handle);
        return (NULL);
    }
    else {
        /* PWM timer has not been initialized */
        (object->pwmTimerStatus)->cyclesPerMicroSec = cyclesPerMicroSec;
        (object->pwmTimerStatus)->prescalar =
            PWMTimerMSP432_calculatePrescalar(tempPeriod);
        (object->pwmTimerStatus)->period = params->period;
    }

    /* Mark driver as being used */
    object->isOpen = true;
    (object->pwmTimerStatus)->activeOutputsMask |= object->pwmCompareOutputBit;

    HwiP_restore(key);

    /* Store PWM instance parameters */
    object->dutyMode = params->dutyMode;

    /* Configure PWM output & start timer */
    pwmConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
    pwmConfig.clockSourceDivider = (object->pwmTimerStatus)->prescalar;
    pwmConfig.timerPeriod = tempPeriod / (object->pwmTimerStatus)->prescalar;
    pwmConfig.compareRegister = hwAttrs->compareRegister;
    pwmConfig.compareOutputMode = outputPolarity[params->polarity];
    pwmConfig.dutyCycle = 0;
    MAP_Timer_A_generatePWM(hwAttrs->baseAddr, &pwmConfig);
    MAP_Timer_A_startCounter(hwAttrs->baseAddr, TIMER_A_UP_MODE);

    DebugP_log2("PWM:(%p) opened; period set to: %d", (uintptr_t) handle,
        params->period);

    return (handle);
}
/*
 *  ======== SPICC3200DMA_configDMA ========
 *  This functions configures the transmit and receive DMA channels for a given
 *  SPI_Handle and SPI_Transaction
 *
 *  @pre    Function assumes that the handle and transaction is not NULL
 */
static void SPICC3200DMA_configDMA(SPI_Handle handle, SPI_Transaction *transaction)
{
    uintptr_t                   key;
    SPIDataType                 dummy;
    void                       *buf;
    uint32_t                    channelControlOptions;
    SPICC3200DMA_Object        *object = handle->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;

    /* Clear out the FIFO */
    while (MAP_SPIDataGetNonBlocking(hwAttrs->baseAddr, &dummy)) {}

    /* Configure DMA for RX */
    MAP_uDMAChannelAssign(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->rxChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->rxBuf) {
        channelControlOptions = dmaRxConfig[object->frameSize];
        buf = transaction->rxBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_RX0),
                               buf,
                               transaction->count);

    /* Configure DMA for TX */
    MAP_uDMAChannelAssign(hwAttrs->txChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->txChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->txBuf) {
        channelControlOptions = dmaTxConfig[object->frameSize];
        buf = transaction->txBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue;
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               buf,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_TX0),
                               transaction->count);

    DebugP_log1("SPI:(%p) DMA transfer enabled", hwAttrs->baseAddr);
    DebugP_log4("SPI:   DMA transaction: %p, rxBuf: %p; txBuf: %p; Count: %d",
                (uintptr_t)transaction, (uintptr_t)transaction->rxBuf,
                (uintptr_t)transaction->txBuf, (uintptr_t)transaction->count);

    key = HwiP_disable();
    MAP_uDMAChannelEnable(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelEnable(hwAttrs->txChannelIndex);
    HwiP_restore(key);

    MAP_SPIWordCountSet(hwAttrs->baseAddr, transaction->count);
}
/*
 *  ======== SPICC3200DMA_open ========
 *  @pre    Function assumes that the handle is not NULL
 */
SPI_Handle SPICC3200DMA_open(SPI_Handle handle, SPI_Params *params)
{
    uintptr_t                   key;
    SPICC3200DMA_Object        *object = handle->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;
    SemaphoreP_Params           semParams;
    HwiP_Params                 hwiParams;

    key = HwiP_disable();
    if(object->isOpen == true) {
        HwiP_restore(key);
        return (NULL);
    }

    object->isOpen = true;
    HwiP_restore(key);

    if (params == NULL) {
        params = (SPI_Params *) &SPI_defaultParams;
    }

    DebugP_assert((params->dataSize >= 4) && (params->dataSize <= 32));

    /* Determine if we need to use an 8, 16 or 32-bit frameSize for the DMA */
    if (params->dataSize <= 8) {
        object->frameSize = SPICC3200DMA_8bit;
    }
    else if (params->dataSize <= 16) {
        object->frameSize = SPICC3200DMA_16bit;
    }
    else {
        object->frameSize = SPICC3200DMA_32bit;
    }

    /* Store SPI mode of operation */
    object->spiMode = params->mode;
    object->transferMode = params->transferMode;
    object->transaction = NULL;
    object->rxFifoTrigger = (1 << object->frameSize);
    object->txFifoTrigger = (1 << object->frameSize);
    object->bitRate = params->bitRate;
    object->frameFormat = params->frameFormat;
    object->dataSize = params->dataSize;

    /* Register power dependency - i.e. power up and enable clock for SPI. */
    Power_setDependency(getPowerMgrId(hwAttrs->baseAddr));
    Power_setDependency(PowerCC3200_PERIPH_UDMA);

    Power_registerNotify(&(object->notifyObj), PowerCC3200_AWAKE_LPDS,
            SPICC3200DMA_postNotify, (uintptr_t)handle);

    HwiP_Params_init(&hwiParams);
    hwiParams.arg = (uintptr_t)handle;
    hwiParams.priority = hwAttrs->intPriority;
    object->hwiHandle = HwiP_create(hwAttrs->intNum,
                                    SPICC3200DMA_hwiFxn,
                                    &hwiParams);
    if (object->hwiHandle == NULL) {
        SPICC3200DMA_close(handle);
        return (NULL);
    }

    if (object->transferMode == SPI_MODE_BLOCKING) {
        DebugP_log1("SPI:(%p) in SPI_MODE_BLOCKING mode", hwAttrs->baseAddr);

        SemaphoreP_Params_init(&semParams);
        semParams.mode = SemaphoreP_Mode_BINARY;
        object->transferComplete = SemaphoreP_create(0, &semParams);
        if (object->transferComplete == NULL) {
            SPICC3200DMA_close(handle);
            return (NULL);
        }

        object->transferCallbackFxn = SPICC3200DMA_transferCallback;
    }
    else {
        DebugP_log1("SPI:(%p) in SPI_MODE_CALLBACK mode", hwAttrs->baseAddr);

        DebugP_assert(params->transferCallbackFxn != NULL);
        object->transferCallbackFxn = params->transferCallbackFxn;
    }

    if (uDMAControlBase == NULL) {
        uDMAControlBase = MAP_uDMAControlBaseGet();
    }

    SPICC3200DMA_initHw(handle);

    DebugP_log3("SPI:(%p) CPU freq: %d; SPI freq to %d",
                hwAttrs->baseAddr, PRCMPeripheralClockGet(hwAttrs->spiPRCM),
                params->bitRate);
    DebugP_log1("SPI:(%p) opened", hwAttrs->baseAddr);

    return (handle);
}
/*
 *  ======== CameraCC3200DMA_open ========
 */
Camera_Handle CameraCC3200DMA_open(Camera_Handle handle, Camera_Params *params)
{
    uintptr_t                      key;
    CameraCC3200DMA_Object        *object = handle->object;
    CameraCC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;
    unsigned long                  hSyncPolarityConfig;
    unsigned long                  vSyncPolarityConfig;
    unsigned long                  byteOrderConfig;
    unsigned long                  interfaceSync;
    unsigned long                  pixelClkConfig;
    HwiP_Params                    hwiParams;
    SemaphoreP_Params              semParams;

    /* If params are NULL use defaults. */
    if (params == NULL) {
        params = (Camera_Params *) &Camera_defaultParams;
    }

    /* Timeouts cannot be 0 */
    DebugP_assert((params->captureTimeout != 0));

    /* Check that a callback is set */
    DebugP_assert((params->captureMode != Camera_MODE_CALLBACK) ||
                  (params->captureCallback != NULL));

    /* Disable preemption while checking if the Camera is open. */
    key = HwiP_disable();

    /* Check if the Camera is open already with the base addr. */
    if (object->opened == true) {
        HwiP_restore(key);

        DebugP_log1("Camera:(%p) already in use.", hwAttrs->baseAddr);
        return (NULL);
    }

    object->opened = true;
    HwiP_restore(key);

    object->operationMode    = params->captureMode;
    object->captureCallback  = params->captureCallback;
    object->captureTimeout   = params->captureTimeout;

    /* Set Camera variables to defaults. */
    object->captureBuf = NULL;
    object->bufferlength = 0;
    object->frameLength  = 0;
    object->inUse        = 0;

    /*
     *  Register power dependency. Keeps the clock running in SLP
     *  and DSLP modes.
     */
    Power_setDependency(PowerCC3200_PERIPH_CAMERA);
    Power_setDependency(PowerCC3200_PERIPH_UDMA);

    /* Disable the Camera interrupt. */
    MAP_CameraIntDisable(hwAttrs->baseAddr, (CAM_INT_FE | CAM_INT_DMA));

    HwiP_clearInterrupt(hwAttrs->intNum);

    /* Create Hwi object for the Camera peripheral. */
    /* Register the interrupt for this Camera peripheral. */
    HwiP_Params_init(&hwiParams);
    hwiParams.arg = (uintptr_t)handle;
    hwiParams.priority = hwAttrs->intPriority;
    object->hwiHandle = HwiP_create(hwAttrs->intNum, CameraCC3200DMA_hwiIntFxn,
                                    &hwiParams);
    if (object->hwiHandle == NULL) {
        CameraCC3200DMA_close(handle);
        return (NULL);
    }

    MAP_IntEnable(INT_CAMERA);

    SemaphoreP_Params_init(&semParams);
    semParams.mode = SemaphoreP_Mode_BINARY;

    /* If capture is blocking create a semaphore and set callback. */
    if (object->operationMode == Camera_MODE_BLOCKING) {
        object->captureSem = SemaphoreP_create(0, &semParams);
        if (object->captureSem) {
            CameraCC3200DMA_close(handle);
            return (NULL);
        }
        object->captureCallback = &captureSemCallback;
    }

    MAP_CameraReset(hwAttrs->baseAddr);

    if (params->hsyncPolarity == Camera_HSYNC_POLARITY_HIGH) {
        hSyncPolarityConfig = CAM_HS_POL_HI;
    }
    else {
        hSyncPolarityConfig = CAM_HS_POL_LO;
    }

    if (params->vsyncPolarity == Camera_VSYNC_POLARITY_HIGH) {
        vSyncPolarityConfig = CAM_VS_POL_HI;
    }
    else {
        vSyncPolarityConfig = CAM_VS_POL_LO;
    }

    if (params->byteOrder == Camera_BYTE_ORDER_SWAP) {
        byteOrderConfig = CAM_ORDERCAM_SWAP;
    }
    else {
        byteOrderConfig = 0;
    }

    if (params->interfaceSync == Camera_INTERFACE_SYNC_OFF) {
        interfaceSync = CAM_NOBT_SYNCHRO;
    }
    else {
        interfaceSync = CAM_NOBT_SYNCHRO | CAM_IF_SYNCHRO | CAM_BT_CORRECT_EN;
    }

    if (params->pixelClkConfig == Camera_PCLK_CONFIG_RISING_EDGE) {
        pixelClkConfig = CAM_PCLK_RISE_EDGE;
    }
    else {
        pixelClkConfig = CAM_PCLK_FALL_EDGE;
    }

    MAP_CameraParamsConfig(hwAttrs->baseAddr, hSyncPolarityConfig,
                           vSyncPolarityConfig,
                           byteOrderConfig | interfaceSync | pixelClkConfig);

    /*Set the clock divider based on the output clock */
    MAP_CameraXClkConfig(hwAttrs->baseAddr,
                         PRCMPeripheralClockGet(PRCM_CAMERA),
                         params->outputClock);

    /*Setting the FIFO threshold for a DMA request */
    MAP_CameraThresholdSet(hwAttrs->baseAddr, 8);

    MAP_CameraIntEnable(hwAttrs->baseAddr, (CAM_INT_FE | CAM_INT_DMA));
    MAP_CameraDMAEnable(hwAttrs->baseAddr);

    DebugP_log1("Camera:(%p) opened", hwAttrs->baseAddr);

    /* Return the handle */
    return (handle);
}