/*******************************************************************************
 * @fn          Main
 *
 * @brief       Application Main
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.
 */
int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  RegisterAssertCback(AssertHandler);

  PIN_init(BoardGpioInitTable);

#ifdef CC1350_LAUNCHXL
  // Enable 2.4GHz Radio
  radCtrlHandle = PIN_open(&radCtrlState, radCtrlCfg);

#ifdef POWER_SAVING
  Power_registerNotify(&rFSwitchPowerNotifyObj, 
                       PowerCC26XX_ENTERING_STANDBY | PowerCC26XX_AWAKE_STANDBY,
                       (Power_NotifyFxn) rFSwitchNotifyCb, NULL);
#endif //POWER_SAVING
#endif //CC1350_LAUNCHXL
  
  // Enable iCache prefetching
  VIMSConfigure(VIMS_BASE, TRUE, TRUE);

  // Enable cache
  VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);

#ifndef POWER_SAVING
  /* Set constraints for Standby, powerdown and idle mode */
  Power_setConstraint(PowerCC26XX_SB_DISALLOW);
  Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING

  /* Initialize ICall module */
  ICall_init();

  /* Start tasks of external images */
  ICall_createRemoteTasks();

  /* Kick off application */
  HostTestApp_createTask();

  /* Kick off NPI */
  NPITask_createTask(ICALL_SERVICE_CLASS_BLE);

  /* enable interrupts and start SYS/BIOS */
  BIOS_start();

  return 0;
}
Exemplo n.º 2
0
/*******************************************************************************
 * @fn          Main
 *
 * @brief       Application Main
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * @param       None.
 *
 * @return      None.   
 */
int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  RegisterAssertCback(AssertHandler);

  PIN_init(BoardGpioInitTable);

#ifdef CC1350_LAUNCHXL
  // Enable 2.4GHz Radio
  radCtrlHandle = PIN_open(&radCtrlState, radCtrlCfg);
  
#ifdef POWER_SAVING
  Power_registerNotify(&rFSwitchPowerNotifyObj, 
                       PowerCC26XX_ENTERING_STANDBY | PowerCC26XX_AWAKE_STANDBY,
                       (Power_NotifyFxn) rFSwitchNotifyCb, NULL);
#endif //POWER_SAVING
#endif //CC1350_LAUNCHXL

#ifndef POWER_SAVING
  /* Set constraints for Standby, powerdown and idle mode */
  Power_setConstraint(PowerCC26XX_SB_DISALLOW);
  Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING

  /* Initialize ICall module */
  ICall_init();

  /* Start tasks of external images - Priority 5 */
  ICall_createRemoteTasks();

  /* Kick off profile - Priority 3 */
  GAPCentralRole_createTask();

  /* SDI UART Example Task - Priority 2 */
  SDITask_createTask();    
    
  /* Kick off application - Priority 1 */
  SPPBLEClient_createTask();

  /* enable interrupts and start SYS/BIOS */
  BIOS_start();

  return 0;
}
/**************************************************************************************************
 * @fn          macBackoffSetupPwrMgmt
 *
 * @brief       Intializes backoff timer power management logic.
 *              Note that this function must be called only once.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffSetupPwrMgmt(void)
{
#ifdef USE_ICALL
  /* Register power transition notification */
  if (ICall_pwrRegisterNotify(macBackoffTimerICallPwrNotify,
                              &macBackoffTimerICallPwrNotifyData) !=
      ICALL_ERRNO_SUCCESS)
  {
    MAC_ASSERT(0);
  }
#endif /* USE_ICALL */
#ifdef OSAL_PORT2TIRTOS
  /* Register power transition notification */
  Power_registerNotify(&macBackoffPwrNotifyObj,
                       (Power_ENTERING_STANDBY |
                        Power_ENTERING_SHUTDOWN |
                        Power_AWAKE_STANDBY),
                       (xdc_Fxn) macBackoffTimerPwrNotify,
                       (UArg) NULL, 0);
#endif /* OSAL_PORT2TIRTOS */
}
/*
 *  ======== WatchdogCC26XX_open ========
 */
Watchdog_Handle WatchdogCC26XX_open(Watchdog_Handle handle, Watchdog_Params *params)
{
    unsigned int                   key;
    Hwi_Params                     hwiParams;
    Watchdog_Params                watchdogParams;
    WatchdogCC26XX_HWAttrs const  *hwAttrs;
    WatchdogCC26XX_Object         *object;
    Types_FreqHz                   freq;

    /* get the pointer to the object and hwAttrs */
    object = handle->object;
    hwAttrs = handle->hwAttrs;

    /* disable preemption while checking if the WatchDog is open. */
    key = Hwi_disable();

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

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

    /* if params are NULL use defaults. */
    if (params == NULL) {
        Watchdog_Params_init(&watchdogParams);
        params = &watchdogParams;
    }

    /* initialize the Watchdog object */
    object->debugStallMode = params->debugStallMode;
    object->resetMode      = params->resetMode;

    /* 1 second period at default CPU clock frequency */
    BIOS_getCpuFreq(&freq);
    object->reloadValue = freq.lo/2;

    /* Construct Hwi object for Watchdog */
    Hwi_Params_init(&hwiParams);
    hwiParams.arg = (UArg)handle;

    /* setup callback function if defined */
    if (params->callbackFxn != NULL) {
        Hwi_construct(&(object->hwi), hwAttrs->intNum, params->callbackFxn,
                      &hwiParams, NULL);
    }

    /* initialize the watchdog hardware */
    // WatchdogIntClear();
    WatchdogCC26XX_initHw(handle);

    Log_print1(Diags_USER1, "Watchdog: handle %x opened" ,(UArg)handle);

    /* register notification functions */
    Power_registerNotify(&object->watchdogPreObj, PowerCC26XX_ENTERING_STANDBY, (Fxn)watchdogPreNotify, (uint32_t)handle);
    Power_registerNotify(&object->watchdogPostObj, PowerCC26XX_AWAKE_STANDBY, (Fxn)watchdogPostNotify, (uint32_t)handle);

    /* return handle of the Watchdog object */
    return (handle);
}
Exemplo n.º 5
0
/*!
 *  @brief  Function to initialize the CC26XX SPI peripheral specified by the
 *          particular handle. The parameter specifies which mode the SPI
 *          will operate.
 *
 *  The function will set a dependency on it power domain, i.e. power up the
 *  module and enable the clock. The IOs are allocated. Neither the SPI nor UDMA module
 *  will be enabled.
 *
 *  @pre    SPI controller has been initialized.
 *          Calling context: Task
 *
 *  @param  handle        A SPI_Handle
 *
 *  @param  params        Pointer to a parameter block, if NULL it will use
 *                        default values
 *
 *  @return A SPI_Handle on success or a NULL on an error or if it has been
 *          already opened
 *
 *  @sa     SPICC26XXDMA_close()
 */
SPI_Handle SPICC26XXDMA_open(SPI_Handle handle, SPI_Params *params)
{
    /* Use union to save on stack allocation */
    union {
        Semaphore_Params semParams;
        Hwi_Params hwiParams;
    } paramsUnion;
    SPI_Params               defaultParams;
    SPICC26XX_Object         *object;
    SPICC26XX_HWAttrs const  *hwAttrs;
    unsigned int             key;

    /* Get the pointer to the object and hwAttrs */
    object = handle->object;
    hwAttrs = handle->hwAttrs;

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

    /* Check if the SPI is open already with the base addr. */
    if (object->isOpen == true) {
        Hwi_restore(key);

        Log_warning1("SPI:(%p) already in use.", hwAttrs->baseAddr);

        return (NULL);
    }

    /* Mark the handle as being used */
    object->isOpen = true;
    Hwi_restore(key);

    /* If params are NULL use defaults */
    if (params == NULL) {
        /* No params passed in, so use the defaults */
        SPI_Params_init(&defaultParams);
        params = &defaultParams;
    }

    Assert_isTrue((params->dataSize >= 4) &&
                  (params->dataSize <= 16), NULL);

    /* Initialize the SPI object */
    object->currentTransaction = NULL;
    object->bitRate            = params->bitRate;
    object->dataSize           = params->dataSize;
    object->frameFormat        = params->frameFormat;
    object->mode               = params->mode;
    object->transferMode       = params->transferMode;
    object->transferTimeout    = params->transferTimeout;
    object->returnPartial      = false;
#ifdef SPICC26XXDMA_WAKEUP_ENABLED
    object->wakeupCallbackFxn  = NULL;
#endif

    /* Determine if we need to use an 8-bit or 16-bit framesize for the DMA */
    object->frameSize = (params->dataSize < 9) ? SPICC26XXDMA_8bit : SPICC26XXDMA_16bit;

    Log_print2(Diags_USER2,"SPI:(%p) DMA buffer incrementation size: %s",
                            hwAttrs->baseAddr,
                           (object->frameSize) ? (UArg)"16-bit" : (UArg)"8-bit");

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

    /* Configure the hardware module */
    SPICC26XXDMA_initHw(handle);

    /* CSN is initialized using hwAttrs initially, but can be re-configured later */
    object->csnPin = hwAttrs->csnPin;

    /* Configure IOs after hardware has been initialized so that IOs aren't */
    /* toggled unnecessary and make sure it was successful */
    if (!SPICC26XXDMA_initIO(handle)) {
        /* Trying to use SPI driver when some other driver or application
        *  has already allocated these pins, error! */
        Log_warning0("Could not allocate SPI pins, already in use.");

        /* Release power dependency - i.e. potentially power down serial domain. */
        Power_releaseDependency(hwAttrs->powerMngrId);

        /* Mark the module as available */
        key = Hwi_disable();
        object->isOpen = false;
        Hwi_restore(key);

        /* Signal back to application that SPI driver was not succesfully opened */
        return (NULL);
    }

    /* Create the Hwi for this SPI peripheral. */
    Hwi_Params_init(&paramsUnion.hwiParams);
    paramsUnion.hwiParams.arg = (UArg) handle;
    Hwi_construct(&(object->hwi), (int) hwAttrs->intNum, SPICC26XXDMA_hwiFxn, &paramsUnion.hwiParams, NULL);

    /* Check the transfer mode */
    if (object->transferMode == SPI_MODE_BLOCKING) {
        Log_print1(Diags_USER2, "SPI DMA:(%p) in SPI_MODE_BLOCKING mode",
                                 hwAttrs->baseAddr);

        /* Create a semaphore to block task execution for the duration of the
         * SPI transfer */
        Semaphore_Params_init(&paramsUnion.semParams);
        paramsUnion.semParams.mode = Semaphore_Mode_BINARY;
        Semaphore_construct(&(object->transferComplete), 0, &paramsUnion.semParams);

        /* Store internal callback function */
        object->transferCallbackFxn = SPICC26XXDMA_transferCallback;
    }
    else {
        Log_print1(Diags_USER2, "SPI DMA:(%p) in SPI_MODE_CALLBACK mode", hwAttrs->baseAddr);

        /* Check to see if a callback function was defined for async mode */
        Assert_isTrue(params->transferCallbackFxn != NULL, NULL);

        /* Save the callback function pointer */
        object->transferCallbackFxn = params->transferCallbackFxn;
    }

    /* Declare the dependency on the UDMA driver */
    object->udmaHandle = UDMACC26XX_open();

    /* Configure PIN driver for CSN callback in optional RETURN_PARTIAL slave mode */
    /* and/or optional wake up on CSN assert slave mode */
    if (object->mode == SPI_SLAVE) {
        PIN_registerIntCb(object->pinHandle, SPICC26XXDMA_csnCallback);
        PIN_setUserArg(object->pinHandle, (UArg) handle);
    }

    Log_print1(Diags_USER1, "SPI:(%p) opened", hwAttrs->baseAddr);

    /* Register notification functions */
#ifdef SPICC26XXDMA_WAKEUP_ENABLED
    Power_registerNotify(&object->spiPreObj, Power_ENTERING_STANDBY, (Fxn)spiPreNotify, (UInt32)handle, NULL );
#endif
    Power_registerNotify(&object->spiPostObj, Power_AWAKE_STANDBY, (Fxn)spiPostNotify, (UInt32)handle, NULL );

    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);
}
/*!
 *  @brief Function to initialize a given I2C CC26XX peripheral specified by the
 *         particular handle. The parameter specifies which mode the I2C
 *         will operate.
 *
 *  After calling the open function, the I2C is enabled. If there is no active
 *  I2C transactions, the device can enter standby.
 *
 *  @pre    The I2CCC26XX_Config structure must exist and be persistent before this
 *          function can be called. I2CCC26XX has been initialized with I2CCC26XX_init().
 *          Calling context: Task
 *
 *  @param  handle   An I2C_Handle
 *
 *  @param  params   Pointer to a parameter block, if NULL it will use default values.
 *
 *  @return A I2C_Handle on success, or a NULL on an error or if it has been
 *          already opened.
 *
 *  @note  The generic I2C API should be used when accessing the I2CCC26XX.
 *
 *  @sa     I2CCC26XX_close(), I2CCC26XX_init(), I2C_open(), I2C_init()
 */
I2C_Handle I2CCC26XX_open(I2C_Handle handle, I2C_Params *params)
{
    union {
        Hwi_Params              hwiParams;
        Semaphore_Params        semParams;
    } paramsUnion;
    UInt                        key;
    I2C_Params                  i2cParams;
    I2CCC26XX_Object             *object;
    I2CCC26XX_HWAttrs const      *hwAttrs;

    /* Get the pointer to the object and hwAttrs */
    object = handle->object;
    hwAttrs = handle->hwAttrs;

    /* Determine if the device index was already opened */
    key = Hwi_disable();
    if(object->isOpen == true){
        Hwi_restore(key);
        return (NULL);
    }

    /* Mark the handle as being used */
    object->isOpen = true;
    Hwi_restore(key);

    /* Store the I2C parameters */
    if (params == NULL) {
        /* No params passed in, so use the defaults */
        I2C_Params_init(&i2cParams);
        params = &i2cParams;
    }

    /* Configure the IOs early to ensure allocation is allowed (PIN driver and IO config setup only).*/
    if (I2CCC26XX_initIO(handle, params->custom)) {
      /* If initialization and allocation of IOs failed, log error and return NULL pointer */
      Log_print1(Diags_USER1, "I2C: Pin allocation failed, open did not succeed (baseAddr:0x%x)", hwAttrs->baseAddr);
      return (NULL);
    }

    /* Save parameters */
    object->transferMode = params->transferMode;
    object->transferCallbackFxn = params->transferCallbackFxn;
    object->bitRate = params->bitRate;

    /* Create Hwi object for this I2C peripheral */
    Hwi_Params_init(&paramsUnion.hwiParams);
    paramsUnion.hwiParams.arg = (UArg)handle;
    Hwi_construct(&(object->hwi), hwAttrs->intNum, I2CCC26XX_hwiFxn,
                  &paramsUnion.hwiParams, NULL);

    /*
     * Create thread safe handles for this I2C peripheral
     * Semaphore to provide exclusive access to the I2C peripheral
     */
    Semaphore_Params_init(&paramsUnion.semParams);
    paramsUnion.semParams.mode = Semaphore_Mode_BINARY;
    Semaphore_construct(&(object->mutex), 1, &paramsUnion.semParams);

    /*
     * Store a callback function that posts the transfer complete
     * semaphore for synchronous mode
     */
    if (object->transferMode == I2C_MODE_BLOCKING) {
        /*
         * Semaphore to cause the waiting task to block for the I2C
         * to finish
         */
        Semaphore_construct(&(object->transferComplete), 0, &paramsUnion.semParams);

        /* Store internal callback function */
        object->transferCallbackFxn = I2CCC26XX_blockingCallback;
    }
    else {
        /* Check to see if a callback function was defined for async mode */
        Assert_isTrue(object->transferCallbackFxn != NULL, NULL);
    }

    /* Specify the idle state for this I2C peripheral */
    object->mode = I2CCC26XX_IDLE_MODE;

    /* Clear the head pointer */
    object->headPtr = NULL;
    object->tailPtr = NULL;

    /* Power on the I2C module */
    Power_setDependency(hwAttrs->powerMngrId);

    /* Initialize the I2C hardware module */
    I2CCC26XX_initHw(handle);

    /* Register notification functions */
    Power_registerNotify(&object->i2cPostObj, Power_AWAKE_STANDBY, (Fxn)i2cPostNotify, (UInt32)handle, NULL );

    Log_print1(Diags_USER1, "I2C: Object created 0x%x", hwAttrs->baseAddr);

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