Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:59

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2020 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_flexio.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexio"
0018 #endif
0019 
0020 /*< @brief user configurable flexio handle count. */
0021 #define FLEXIO_HANDLE_COUNT 2
0022 
0023 /*******************************************************************************
0024  * Variables
0025  ******************************************************************************/
0026 /*! @brief Pointers to flexio bases for each instance. */
0027 FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
0028 
0029 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0030 /*! @brief Pointers to flexio clocks for each instance. */
0031 const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
0032 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0033 
0034 /*< @brief pointer to array of FLEXIO handle. */
0035 static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
0036 
0037 /*< @brief pointer to array of FLEXIO IP types. */
0038 static void *s_flexioType[FLEXIO_HANDLE_COUNT];
0039 
0040 /*< @brief pointer to array of FLEXIO Isr. */
0041 static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
0042 
0043 /* FlexIO common IRQ Handler. */
0044 static void FLEXIO_CommonIRQHandler(void);
0045 
0046 /*******************************************************************************
0047  * Codes
0048  ******************************************************************************/
0049 
0050 /*!
0051  * brief Get instance number for FLEXIO module.
0052  *
0053  * param base FLEXIO peripheral base address.
0054  */
0055 uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
0056 {
0057     uint32_t instance;
0058 
0059     /* Find the instance index from base address mappings. */
0060     for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
0061     {
0062         if (s_flexioBases[instance] == base)
0063         {
0064             break;
0065         }
0066     }
0067 
0068     assert(instance < ARRAY_SIZE(s_flexioBases));
0069 
0070     return instance;
0071 }
0072 
0073 /*!
0074  * brief Configures the FlexIO with a FlexIO configuration. The configuration structure
0075  * can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig().
0076  *
0077  * Example
0078    code
0079    flexio_config_t config = {
0080    .enableFlexio = true,
0081    .enableInDoze = false,
0082    .enableInDebug = true,
0083    .enableFastAccess = false
0084    };
0085    FLEXIO_Configure(base, &config);
0086    endcode
0087  *
0088  * param base FlexIO peripheral base address
0089  * param userConfig pointer to flexio_config_t structure
0090 */
0091 void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
0092 {
0093     uint32_t ctrlReg = 0;
0094 
0095 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0096     CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
0097 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0098 
0099     FLEXIO_Reset(base);
0100 
0101     ctrlReg = base->CTRL;
0102     ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
0103     ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
0104                 FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
0105     if (!userConfig->enableInDoze)
0106     {
0107         ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
0108     }
0109 
0110     base->CTRL = ctrlReg;
0111 }
0112 
0113 /*!
0114  * brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
0115  *
0116  * note After calling this API, call the FLEXO_Init to use the FlexIO module.
0117  *
0118  * param base FlexIO peripheral base address
0119  */
0120 void FLEXIO_Deinit(FLEXIO_Type *base)
0121 {
0122     FLEXIO_Enable(base, false);
0123 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0124     CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
0125 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0126 }
0127 
0128 /*!
0129  * brief Gets the default configuration to configure the FlexIO module. The configuration
0130  * can used directly to call the FLEXIO_Configure().
0131  *
0132  * Example:
0133    code
0134    flexio_config_t config;
0135    FLEXIO_GetDefaultConfig(&config);
0136    endcode
0137  *
0138  * param userConfig pointer to flexio_config_t structure
0139 */
0140 void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
0141 {
0142     assert(userConfig != NULL);
0143 
0144     /* Initializes the configure structure to zero. */
0145     (void)memset(userConfig, 0, sizeof(*userConfig));
0146 
0147     userConfig->enableFlexio     = true;
0148     userConfig->enableInDoze     = false;
0149     userConfig->enableInDebug    = true;
0150     userConfig->enableFastAccess = false;
0151 }
0152 
0153 /*!
0154  * brief Resets the FlexIO module.
0155  *
0156  * param base FlexIO peripheral base address
0157  */
0158 void FLEXIO_Reset(FLEXIO_Type *base)
0159 {
0160     /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
0161     base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
0162     base->CTRL = 0;
0163 }
0164 
0165 /*!
0166  * brief Gets the shifter buffer address for the DMA transfer usage.
0167  *
0168  * param base FlexIO peripheral base address
0169  * param type Shifter type of flexio_shifter_buffer_type_t
0170  * param index Shifter index
0171  * return Corresponding shifter buffer index
0172  */
0173 uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
0174 {
0175     assert(index < FLEXIO_SHIFTBUF_COUNT);
0176 
0177     uint32_t address = 0;
0178 
0179     switch (type)
0180     {
0181         case kFLEXIO_ShifterBuffer:
0182             address = (uint32_t) & (base->SHIFTBUF[index]);
0183             break;
0184 
0185         case kFLEXIO_ShifterBufferBitSwapped:
0186             address = (uint32_t) & (base->SHIFTBUFBIS[index]);
0187             break;
0188 
0189         case kFLEXIO_ShifterBufferByteSwapped:
0190             address = (uint32_t) & (base->SHIFTBUFBYS[index]);
0191             break;
0192 
0193         case kFLEXIO_ShifterBufferBitByteSwapped:
0194             address = (uint32_t) & (base->SHIFTBUFBBS[index]);
0195             break;
0196 
0197 #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
0198         case kFLEXIO_ShifterBufferNibbleByteSwapped:
0199             address = (uint32_t) & (base->SHIFTBUFNBS[index]);
0200             break;
0201 
0202 #endif
0203 #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
0204         case kFLEXIO_ShifterBufferHalfWordSwapped:
0205             address = (uint32_t) & (base->SHIFTBUFHWS[index]);
0206             break;
0207 
0208 #endif
0209 #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
0210         case kFLEXIO_ShifterBufferNibbleSwapped:
0211             address = (uint32_t) & (base->SHIFTBUFNIS[index]);
0212             break;
0213 
0214 #endif
0215         default:
0216             address = (uint32_t) & (base->SHIFTBUF[index]);
0217             break;
0218     }
0219     return address;
0220 }
0221 
0222 /*!
0223  * brief Configures the shifter with the shifter configuration. The configuration structure
0224  * covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
0225  * mode, select which timer controls the shifter to shift, whether to generate start bit/stop
0226  *  bit, and the polarity of start bit and stop bit.
0227  *
0228  * Example
0229    code
0230    flexio_shifter_config_t config = {
0231    .timerSelect = 0,
0232    .timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
0233    .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
0234    .pinPolarity = kFLEXIO_PinActiveLow,
0235    .shifterMode = kFLEXIO_ShifterModeTransmit,
0236    .inputSource = kFLEXIO_ShifterInputFromPin,
0237    .shifterStop = kFLEXIO_ShifterStopBitHigh,
0238    .shifterStart = kFLEXIO_ShifterStartBitLow
0239    };
0240    FLEXIO_SetShifterConfig(base, &config);
0241    endcode
0242  *
0243  * param base FlexIO peripheral base address
0244  * param index Shifter index
0245  * param shifterConfig Pointer to flexio_shifter_config_t structure
0246 */
0247 void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
0248 {
0249     base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
0250 #if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
0251                             | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
0252 #endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
0253                             | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
0254                             FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
0255 
0256     base->SHIFTCTL[index] =
0257         FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
0258         FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
0259         FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
0260 }
0261 
0262 /*!
0263  * brief Configures the timer with the timer configuration. The configuration structure
0264  * covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
0265  * mode, select trigger source for timer and the timer pin output and the timing for timer.
0266  *
0267  * Example
0268    code
0269    flexio_timer_config_t config = {
0270    .triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
0271    .triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
0272    .triggerSource = kFLEXIO_TimerTriggerSourceInternal,
0273    .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
0274    .pinSelect = 0,
0275    .pinPolarity = kFLEXIO_PinActiveHigh,
0276    .timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
0277    .timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
0278    .timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
0279    .timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
0280    .timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
0281    .timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
0282    .timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
0283    .timerStart = kFLEXIO_TimerStartBitEnabled
0284    };
0285    FLEXIO_SetTimerConfig(base, &config);
0286    endcode
0287  *
0288  * param base FlexIO peripheral base address
0289  * param index Timer index
0290  * param timerConfig Pointer to the flexio_timer_config_t structure
0291 */
0292 void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
0293 {
0294     base->TIMCFG[index] =
0295         FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
0296         FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
0297         FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
0298         FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
0299 
0300     base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
0301 
0302     base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
0303                           FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
0304                           FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
0305                           FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
0306                           FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
0307 }
0308 
0309 /*!
0310  * brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
0311  *
0312  * param base Pointer to the FlexIO simulated peripheral type.
0313  * param handle Pointer to the handler for FlexIO simulated peripheral.
0314  * param isr FlexIO simulated peripheral interrupt handler.
0315  * retval kStatus_Success Successfully create the handle.
0316  * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
0317  */
0318 status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
0319 {
0320     assert(base != NULL);
0321     assert(handle != NULL);
0322     assert(isr != NULL);
0323 
0324     uint8_t index;
0325 
0326     /* Find the an empty handle pointer to store the handle. */
0327     for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
0328     {
0329         if (s_flexioHandle[index] == NULL)
0330         {
0331             /* Register FLEXIO simulated driver base, handle and isr. */
0332             s_flexioType[index]   = base;
0333             s_flexioHandle[index] = handle;
0334             s_flexioIsr[index]    = isr;
0335             break;
0336         }
0337     }
0338 
0339     if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
0340     {
0341         return kStatus_OutOfRange;
0342     }
0343     else
0344     {
0345         return kStatus_Success;
0346     }
0347 }
0348 
0349 /*!
0350  * brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
0351  *
0352  * param base Pointer to the FlexIO simulated peripheral type.
0353  * retval kStatus_Success Successfully create the handle.
0354  * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
0355  */
0356 status_t FLEXIO_UnregisterHandleIRQ(void *base)
0357 {
0358     assert(base != NULL);
0359 
0360     uint8_t index;
0361 
0362     /* Find the index from base address mappings. */
0363     for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
0364     {
0365         if (s_flexioType[index] == base)
0366         {
0367             /* Unregister FLEXIO simulated driver handle and isr. */
0368             s_flexioType[index]   = NULL;
0369             s_flexioHandle[index] = NULL;
0370             s_flexioIsr[index]    = NULL;
0371             break;
0372         }
0373     }
0374 
0375     if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
0376     {
0377         return kStatus_OutOfRange;
0378     }
0379     else
0380     {
0381         return kStatus_Success;
0382     }
0383 }
0384 
0385 static void FLEXIO_CommonIRQHandler(void)
0386 {
0387     uint8_t index;
0388 
0389     for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
0390     {
0391         if (s_flexioHandle[index] != NULL)
0392         {
0393             s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
0394         }
0395     }
0396     SDK_ISR_EXIT_BARRIER;
0397 }
0398 
0399 void FLEXIO_DriverIRQHandler(void);
0400 void FLEXIO_DriverIRQHandler(void)
0401 {
0402     FLEXIO_CommonIRQHandler();
0403 }
0404 
0405 void FLEXIO0_DriverIRQHandler(void);
0406 void FLEXIO0_DriverIRQHandler(void)
0407 {
0408     FLEXIO_CommonIRQHandler();
0409 }
0410 
0411 void FLEXIO1_DriverIRQHandler(void);
0412 void FLEXIO1_DriverIRQHandler(void)
0413 {
0414     FLEXIO_CommonIRQHandler();
0415 }
0416 
0417 void UART2_FLEXIO_DriverIRQHandler(void);
0418 void UART2_FLEXIO_DriverIRQHandler(void)
0419 {
0420     FLEXIO_CommonIRQHandler();
0421 }
0422 
0423 void FLEXIO2_DriverIRQHandler(void);
0424 void FLEXIO2_DriverIRQHandler(void)
0425 {
0426     FLEXIO_CommonIRQHandler();
0427 }
0428 
0429 void FLEXIO3_DriverIRQHandler(void);
0430 void FLEXIO3_DriverIRQHandler(void)
0431 {
0432     FLEXIO_CommonIRQHandler();
0433 }