/*
*  ======== SPICC3200DMA_hwiFxn ========
*  ISR for the SPI when we use the DMA is used.
*/
void SPICC3200DMA_hwiFxn(uintptr_t arg)
{
    SPI_Transaction            *msg;
    SPICC3200DMA_Object        *object = ((SPI_Handle)arg)->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = ((SPI_Handle)arg)->hwAttrs;
    uint32_t                    intCode = 0;

    DebugP_log1("SPI:(%p) interrupt context start", hwAttrs->baseAddr);

    intCode = MAP_SPIIntStatus(hwAttrs->baseAddr, false);
    if (intCode & SPI_INT_DMATX) {
        /* DMA finished transfering; clear & disable interrupt */
        MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMATX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMATX);
    }

    /* Determine if the TX & RX DMA channels have completed */
    if ((object->transaction) &&
            (MAP_uDMAChannelIsEnabled(hwAttrs->rxChannelIndex) == false) &&
            (MAP_uDMAIntStatus() & (1 << hwAttrs->rxChannelIndex))) {

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

        MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMARX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_EOW);

        /*
         * Clear any pending interrupt
         * As the TX DMA channel interrupt gets service, it may be possible
         * that the RX DMA channel finished in the meantime, which means
         * the IRQ for RX DMA channel is still pending...
         */
        HwiP_clearInterrupt(hwAttrs->intNum);

        /*
         * Use a temporary transaction pointer in case the callback function
         * attempts to perform another SPI_transfer call
         */
        msg = object->transaction;

        /* Indicate we are done with this transfer */
        object->transaction = NULL;

        /* Release constraint since transaction is done */
        Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);

        DebugP_log2("SPI:(%p) DMA transaction: %p complete",
                    hwAttrs->baseAddr, (uintptr_t)msg);

        object->transferCallbackFxn((SPI_Handle)arg, msg);
    }

    DebugP_log1("SPI:(%p) interrupt context end", hwAttrs->baseAddr);
}
/*
 *  ======== 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);
}
Esempio n. 3
0
/*
 *  ======== dmaErrorHwi ========
 */
static void dmaErrorHwi(uintptr_t arg)
{
    DebugP_log1("DMA error code: %d\n", MAP_DMA_getErrorStatus());
    MAP_DMA_clearErrorStatus();
    DebugP_log0("DMA error!!\n");
    while(1);
}
/*
 *  ======== readIsrTextBlocking ========
 *  Function that is called by the ISR
 */
static bool readIsrTextBlocking(UART_Handle handle)
{
    int                       readIn;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    readIn = MAP_UART_receiveData(hwAttrs->baseAddr);

    if (readIn == '\r') {
        /* Echo character if enabled. */
        if (object->state.readEcho) {
            MAP_UART_transmitData(hwAttrs->baseAddr, '\r');
        }
        readIn = '\n';
    }

    if (RingBuf_put(&object->ringBuffer, (unsigned char) readIn) == -1) {
        DebugP_log1("UART:(%p) Ring buffer full!!", hwAttrs->baseAddr);
        return (false);
    }

    DebugP_log2("UART:(%p) buffered '0x%02x'", hwAttrs->baseAddr,
        (unsigned char) readIn);

    if (object->state.readEcho) {
        MAP_UART_transmitData(hwAttrs->baseAddr, (unsigned char) readIn);
    }
    if (object->state.callCallback) {
        object->state.callCallback = false;
        object->readCallback(handle, NULL, 0);
    }

    return (true);
}
/*
 *  ======== readIsrBinaryCallback ========
 */
static bool readIsrBinaryCallback(UART_Handle handle)
{
    int                       readIn;
    bool                      ret = true;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    readIn = MAP_UART_receiveData(hwAttrs->baseAddr);

    if (RingBuf_put(&object->ringBuffer, (unsigned char)readIn) == -1) {
        DebugP_log1("UART:(%p) Ring buffer full!!", hwAttrs->baseAddr);
        ret = false;
    }
    DebugP_log2("UART:(%p) buffered '0x%02x'", hwAttrs->baseAddr,
        (unsigned char) readIn);

    /*
     * Check and see if a UART_read in callback mode told use to continue
     * servicing the user buffer...
     */
    if (object->state.drainByISR) {
        readTaskCallback(handle);
    }

    return (ret);
}
/*
 *  ======== 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);
}
/*
 *  ======== SPICC3200DMA_transferCallback ========
 *  Callback function for when the SPI is in SPI_MODE_BLOCKING
 *
 *  @pre    Function assumes that the handle is not NULL
 */
static void SPICC3200DMA_transferCallback(SPI_Handle handle,
                                          SPI_Transaction *transaction)
{
    SPICC3200DMA_Object *object = handle->object;

    DebugP_log1("SPI:(%p) posting transferComplete semaphore",
                ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr);

    SemaphoreP_post(object->transferComplete);
}
/*
 *  ======== errorCallback ========
 *  Generic log function for when unexpected events occur.
 */
static void errorCallback(UART_Handle handle, uintptr_t error)
{
    if (error & EUSCI_A_UART_OVERRUN_ERROR) {
        DebugP_log1("UART:(%p): OVERRUN ERROR",
            ((UARTMSP432_HWAttrs const *)handle->hwAttrs)->baseAddr);
    }
    if (error & EUSCI_A_UART_BREAK_DETECT) {
        DebugP_log1("UART:(%p): BREAK ERROR",
            ((UARTMSP432_HWAttrs const *)handle->hwAttrs)->baseAddr);
    }
    if (error & EUSCI_A_UART_PARITY_ERROR) {
        DebugP_log1("UART:(%p): PARITY ERROR",
            ((UARTMSP432_HWAttrs const *)handle->hwAttrs)->baseAddr);
    }
    if (error & EUSCI_A_UART_FRAMING_ERROR) {
        DebugP_log1("UART:(%p): FRAMING ERROR",
            ((UARTMSP432_HWAttrs const *)handle->hwAttrs)->baseAddr);
    }
}
/*
 *  ======== 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);
}
/*
 *  ======== CameraCC3200DMA_configDMA ========
 */
static void CameraCC3200DMA_configDMA(Camera_Handle handle)
{
    CameraCC3200DMA_Object           *object = handle->object;
    CameraCC3200DMA_HWAttrs const    *hwAttrs = handle->hwAttrs;
    unsigned long **bufferPtr = (unsigned long**)&object->captureBuf;


    /* Setup ping-pong transfer */
    MAP_uDMAChannelControlSet(hwAttrs->channelIndex,
              UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);
    MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex,UDMA_ATTR_USEBURST);
    MAP_uDMAChannelTransferSet(hwAttrs->channelIndex, UDMA_MODE_PINGPONG,
                               (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr,
                               CameraCC3200DMA_DMA_TRANSFER_SIZE);
    MAP_uDMAChannelEnable(hwAttrs->channelIndex);

    /* Pong Buffer */
    *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
    MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
              UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);
    MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                                                       UDMA_ATTR_USEBURST);
    MAP_uDMAChannelTransferSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                                UDMA_MODE_PINGPONG,
                               (void *)CAM_BUFFER_ADDR,
                               (void *)*bufferPtr,
                               CameraCC3200DMA_DMA_TRANSFER_SIZE);
    MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT);

    /*  Ping Buffer */
    *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;

    DebugP_log1("Camera:(%p) DMA transfer enabled", hwAttrs->baseAddr);

    /* Set mode to Ping buffer initially */
    object->cameraDMA_PingPongMode = 0;

    /* Clear any pending interrupt */
    MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA);

    /* DMA Interrupt unmask from apps config */
    MAP_CameraIntEnable(hwAttrs->baseAddr, CAM_INT_DMA);

    DebugP_log3("Camera:(%p) DMA receive, "
                   "CaptureBuf: %p; Count: %d",
                    hwAttrs->baseAddr,
                    (uintptr_t)*bufferPtr,
                    (uintptr_t)object->bufferlength);
}
/*
 *  ======== readIsrTextCallback ========
 */
static bool readIsrTextCallback(UART_Handle handle)
{
    int                       readIn;
    bool                      ret = true;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    readIn = MAP_UART_receiveData(hwAttrs->baseAddr);

    if (readIn == '\r') {
        /* Echo character if enabled. */
        if (object->state.readEcho) {
            /* Wait until TX is ready */
            while (!MAP_UART_getInterruptStatus(hwAttrs->baseAddr,
                EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG)) {}
            MAP_UART_transmitData(hwAttrs->baseAddr, '\r');
        }
        readIn = '\n';
    }
    if (RingBuf_put(&object->ringBuffer, (unsigned char) readIn) == -1) {
        DebugP_log1("UART:(%p) Ring buffer full!!", hwAttrs->baseAddr);
        ret = false;
    }
    DebugP_log2("UART:(%p) buffered '0x%02x'", hwAttrs->baseAddr,
        (unsigned char) readIn);

    if (object->state.readEcho) {
        /* Wait until TX is ready */
        while (!MAP_UART_getInterruptStatus(hwAttrs->baseAddr,
            EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG)) {}
        MAP_UART_transmitData(hwAttrs->baseAddr, (unsigned char)readIn);
    }

    /*
     * Check and see if a UART_read in callback mode told use to continue
     * servicing the user buffer...
     */
    if (object->state.drainByISR) {
        readTaskCallback(handle);
    }

    return (ret);
}
/*
 *  ======== UARTMSP432_close ========
 */
void UARTMSP432_close(UART_Handle handle)
{
    unsigned int              i;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    MAP_UART_disableInterrupt(hwAttrs->baseAddr,
        EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT);
    MAP_UART_disableInterrupt(hwAttrs->baseAddr,
        EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT |
        EUSCI_A_UART_BREAKCHAR_INTERRUPT);
    MAP_UART_disableModule(hwAttrs->baseAddr);

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

    /* Remove power constraints */
    for (i = 0; object->perfConstraintMask; i++) {
        if (object->perfConstraintMask & 0x01) {
            Power_releaseConstraint(PowerMSP432_DISALLOW_PERFLEVEL_0 + i);
        }
        object->perfConstraintMask >>= 1;
    }
    if (object->state.rxEnabled) {
        Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
        Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
    }
    Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0);
    Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1);
    Power_unregisterNotify(&object->perfChangeNotify);

    object->state.opened = false;

    DebugP_log1("UART:(%p) closed", hwAttrs->baseAddr);
}
/*
 *  ======== readIsrBinaryBlocking ========
 *  Function that is called by the ISR
 */
static bool readIsrBinaryBlocking(UART_Handle handle)
{
    int                       readIn;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    readIn = MAP_UART_receiveData(hwAttrs->baseAddr);

    if (RingBuf_put(&object->ringBuffer, (unsigned char) readIn) == -1) {
        DebugP_log1("UART:(%p) Ring buffer full!!", hwAttrs->baseAddr);
        return (false);
    }
    DebugP_log2("UART:(%p) buffered '0x%02x'", hwAttrs->baseAddr,
        (unsigned char) readIn);

    if (object->state.callCallback) {
        object->state.callCallback = false;
        object->readCallback(handle, NULL, 0);
    }
    return (true);
}
/*
 *  ======== CameraCC3200DMA_close ========
 */
void CameraCC3200DMA_close(Camera_Handle handle)
{
    CameraCC3200DMA_Object           *object = handle->object;
    CameraCC3200DMA_HWAttrs const    *hwAttrs = handle->hwAttrs;

    /* Disable Camera and interrupts. */
    MAP_CameraIntDisable(hwAttrs->baseAddr,CAM_INT_FE);
    MAP_CameraDMADisable(hwAttrs->baseAddr);

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

    Power_releaseDependency(PowerCC3200_PERIPH_CAMERA);
    Power_releaseDependency(PowerCC3200_PERIPH_UDMA);

    object->opened = false;

    DebugP_log1("Camera:(%p) closed", hwAttrs->baseAddr);
}
/*
 *  ======== 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));
}
/*
 *  ======== 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);
}
/*
 *  ======== UARTMSP432_control ========
 *  @pre    Function assumes that the handle is not NULL
 */
int UARTMSP432_control(UART_Handle handle, unsigned int cmd, void *arg)
{
    int                       bufferCount;
    unsigned char             data;
    UARTMSP432_Object        *object = handle->object;
    UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs;

    bufferCount = RingBuf_peek(&object->ringBuffer, &data);

    switch (cmd) {
        /* Common UART CMDs */
        case (UART_CMD_PEEK):
            *(int *)arg = (bufferCount) ? data : UART_ERROR;
            DebugP_log2("UART:(%p) UART_CMD_PEEK: %d", hwAttrs->baseAddr,
                *(uintptr_t*)arg);
            return (UART_STATUS_SUCCESS);

        case (UART_CMD_ISAVAILABLE):
            *(bool *)arg = (bufferCount != 0);
            DebugP_log2("UART:(%p) UART_CMD_ISAVAILABLE: %d", hwAttrs->baseAddr,
                *(uintptr_t*)arg);
            return (UART_STATUS_SUCCESS);

        case (UART_CMD_GETRXCOUNT):
            *(int *)arg = bufferCount;
            DebugP_log2("UART:(%p) UART_CMD_GETRXCOUNT: %d", hwAttrs->baseAddr,
                *(uintptr_t*)arg);
            return (UART_STATUS_SUCCESS);

        case (UART_CMD_RXENABLE):
            if (!object->state.rxEnabled) {
                /*
                 * Set power constraints to keep peripheral active receiving
                 * RX interrupts and prevent a performance level change.
                 */
                Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
                Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
                MAP_UART_enableInterrupt(hwAttrs->baseAddr,
                    EUSCI_A_UART_RECEIVE_INTERRUPT);
                object->state.rxEnabled = true;
                DebugP_log1("UART:(%p) UART_CMD_RXENABLE: Enabled",
                    hwAttrs->baseAddr);
                DebugP_log1("UART:(%p) UART_control set read power constraint",
                    hwAttrs->baseAddr);
                return (UART_STATUS_SUCCESS);
            }
            DebugP_log1("UART:(%p) UART_CMD_RXENABLE: Already enabled",
                hwAttrs->baseAddr);
            return (UART_STATUS_ERROR);

        case (UART_CMD_RXDISABLE):
            if (object->state.rxEnabled) {
                MAP_UART_disableInterrupt(hwAttrs->baseAddr,
                    EUSCI_A_UART_RECEIVE_INTERRUPT);
                /*
                 * Remove constraints, this will allow the device to enter
                 * LPM3 and higher as well as allow performance level changes
                 * by the application.
                 */
                Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
                Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES);
                object->state.rxEnabled = false;
                DebugP_log1("UART:(%p) UART_CMD_RXDISABLE: Disabled",
                    hwAttrs->baseAddr);
                DebugP_log1("UART:(%p) UART_control released read power "
                    "constraint", hwAttrs->baseAddr);
                return (UART_STATUS_SUCCESS);
            }
            DebugP_log1("UART:(%p) UART_CMD_RXDISABLE: Already disabled",
                hwAttrs->baseAddr);
            return (UART_STATUS_ERROR);

        default:
            DebugP_log2("UART:(%p) UART CMD undefined: %d",
                hwAttrs->baseAddr, cmd);
            return (UART_STATUS_UNDEFINEDCMD);
    }
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}