Ejemplo n.º 1
0
/*
 *  ======== MSP_EXP432P401R_initDMA ========
 */
void MSP_EXP432P401R_initDMA(void)
{
    HwiP_Params hwiParams;
    HwiP_Handle dmaErrorHwiHandle;

    if (!dmaInitialized) {
        HwiP_Params_init(&hwiParams);
        dmaErrorHwiHandle = HwiP_create(INT_DMA_ERR, dmaErrorHwi, &hwiParams);
        if (dmaErrorHwiHandle == NULL) {
            DebugP_log0("Failed to create DMA error Hwi!!\n");
            while (1);
        }

        MAP_DMA_enableModule();
        MAP_DMA_setControlBase(dmaControlTable);

        dmaInitialized = true;
    }
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}
/*
 *  ======== 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);
}