| 
在线时间3 小时
UID3912890
注册时间2023-4-11
NXP金币33 
 该用户从未签到 新手上路 
 
 
	积分27 
最后登录2025-10-26 | 
 
| #include "fsl_flexio.h" #include "fsl_edma.h"
 #include "fsl_dmamux.h"
 #include "fsl_iomuxc.h"
 #include "fsl_clock.h"
 #include "fsl_gpio.h"
 #include "fsl_common.h"
 
 #define FLEXIO_BASE        FLEXIO2
 #define FLEXIO_CLOCK_NAME  kCLOCK_Flexio2
 #define LED_PIN            7
 #define DMA_CHANNEL        0
 #define FLEXIO_SHIFTER     0
 #define FLEXIO_DMA_REQUEST kDmaRequestMuxFlexIO2Request0Request1
 
 #define NUM_LEDS           1
 #define DATA_SIZE          (NUM_LEDS * 24)
 
 AT_NONCACHEABLE_SECTION(volatile uint32_t ws2812_buffer[DATA_SIZE]);
 
 static edma_handle_t dmaHandle;
 static volatile bool dmaTransferDone = false;
 
 static uint16_t TIMCMP_0 = 0;
 static uint16_t TIMCMP_1 = 0;
 
 void EDMA_Callback(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
 {
 if (transferDone)
 {
 dmaTransferDone = true;
 }
 }
 
 uint32_t WS2812_GetFlexIO2Clock(void) {
 uint32_t clockFreq = 0;
 uint32_t mux = (CCM->CSCMR2 & CCM_CSCMR2_FLEXIO2_CLK_SEL_MASK) >> CCM_CSCMR2_FLEXIO2_CLK_SEL_SHIFT;
 uint32_t div = ((CCM->CS1CDR & CCM_CS1CDR_FLEXIO2_CLK_PODF_MASK) >> CCM_CS1CDR_FLEXIO2_CLK_PODF_SHIFT) + 1;
 
 switch (mux) {
 case 3:
 clockFreq = CLOCK_GetFreq(kCLOCK_Usb1PllClk);
 break;
 case 2:
 clockFreq = CLOCK_GetFreq(kCLOCK_SysPllClk);
 break;
 case 1:
 clockFreq = 24000000;
 break;
 default:
 clockFreq = 0;
 break;
 }
 return clockFreq / div;
 }
 
 void WS2812_FlexIO_Init(void)
 {
 CLOCK_EnableClock(kCLOCK_Iomuxc);
 CLOCK_EnableClock(kCLOCK_Flexio2);
 
 IOMUXC_SetPinMux(IOMUXC_GPIO_B0_07_FLEXIO2_FLEXIO07, 1);
 IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_07_FLEXIO2_FLEXIO07, 0x10B0U);
 
 flexio_config_t flexioConfig;
 FLEXIO_GetDefaultConfig(&flexioConfig);
 FLEXIO_Init(FLEXIO_BASE, &flexioConfig);
 
 flexio_timer_config_t timerConfig;
 timerConfig.triggerSelect   = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0);
 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
 timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceInternal;
 timerConfig.pinConfig       = kFLEXIO_PinConfigOutput;
 timerConfig.pinSelect       = LED_PIN;
 timerConfig.timerMode       = kFLEXIO_TimerModeDual8BitPWM;
 timerConfig.timerOutput     = kFLEXIO_TimerOutputOneNotAffectedByReset;
 timerConfig.timerDecrement  = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
 timerConfig.timerDisable    = kFLEXIO_TimerDisableOnTimerCompare;
 timerConfig.timerEnable     = kFLEXIO_TimerEnableOnTriggerRisingEdge;
 
 uint32_t flexioClock = WS2812_GetFlexIO2Clock();
 uint32_t timerDiv = (flexioClock / 800000) - 1;
 
 uint32_t T0H = (flexioClock / 1000000 * 270) / 1000;
 uint32_t T0L = timerDiv - T0H;
 uint32_t T1H = (flexioClock / 1000000 * 930) / 1000;
 uint32_t T1L = timerDiv - T1H;
 TIMCMP_0 = ((T0H << 8) | T0L);
 TIMCMP_1 = ((T1H << 8) | T1L);
 
 timerConfig.timerCompare = TIMCMP_1;
 FLEXIO_SetTimerConfig(FLEXIO_BASE, 0, &timerConfig);
 
 flexio_shifter_config_t shifterConfig;
 shifterConfig.timerSelect   = 0;
 shifterConfig.pinConfig     = kFLEXIO_PinConfigOutput;
 shifterConfig.pinSelect     = LED_PIN;
 shifterConfig.shifterMode   = kFLEXIO_ShifterModeTransmit;
 shifterConfig.pinPolarity   = kFLEXIO_PinActiveLow;
 shifterConfig.inputSource   = kFLEXIO_ShifterInputFromPin;
 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
 shifterConfig.shifterStart  = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
 shifterConfig.shifterStop   = kFLEXIO_ShifterStopBitDisable;
 FLEXIO_SetShifterConfig(FLEXIO_BASE, FLEXIO_SHIFTER, &shifterConfig);
 
 FLEXIO_EnableShifterStatusDMA(FLEXIO_BASE, (1U << FLEXIO_SHIFTER), true);
 FLEXIO_BASE->SHIFTSTAT = 0xFF;
 
 for (int i = 0; i < 4; i++)
 {
 FLEXIO_BASE->SHIFTBUF[FLEXIO_SHIFTER] = TIMCMP_0;
 }
 }
 
 void WS2812_DMA_Init(void)
 {
 edma_config_t edmaConfig;
 
 DMAMUX_Init(DMAMUX);
 DMAMUX_SetSource(DMAMUX, DMA_CHANNEL, FLEXIO_DMA_REQUEST);
 DMAMUX_EnableChannel(DMAMUX, DMA_CHANNEL);
 
 NVIC_SetPriority(DMA0_DMA16_IRQn, 2);
 NVIC_EnableIRQ(DMA0_DMA16_IRQn);
 
 EDMA_GetDefaultConfig(&edmaConfig);
 EDMA_Init(DMA0, &edmaConfig);
 
 EDMA_CreateHandle(&dmaHandle, DMA0, DMA_CHANNEL);
 EDMA_SetCallback(&dmaHandle, EDMA_Callback, NULL);
 
 dmaTransferDone = false;
 }
 
 void WS2812_PrepareData(uint8_t *led_data) {
 uint32_t index = 0;
 for (int i = 0; i < NUM_LEDS; i++) {
 for (int j = 0; j < 3; j++) {
 uint8_t byte = led_data[i * 3 + j];
 for (int bit = 7; bit >= 0; bit--) {
 ws2812_buffer[index++] = (byte & (1 << bit)) ? TIMCMP_1 : TIMCMP_0;
 }
 }
 }
 }
 
 void WS2812_SendData(uint8_t *led_data) {
 WS2812_PrepareData(led_data);
 
 edma_transfer_config_t transferConfig;
 EDMA_PrepareTransfer(&transferConfig,
 (void *)ws2812_buffer,
 sizeof(uint32_t),
 (void *)&FLEXIO_BASE->SHIFTBUF[FLEXIO_SHIFTER],
 sizeof(uint32_t),
 sizeof(uint32_t),
 sizeof(ws2812_buffer),
 kEDMA_MemoryToPeripheral);
 
 dmaTransferDone = false;
 FLEXIO_BASE->SHIFTSTAT = 0xFF;
 DMA0->TCD[DMA_CHANNEL].SADDR = (uint32_t)&ws2812_buffer[0];
 
 if (!(DMA0->ERQ & (1 << DMA_CHANNEL))) {
 EDMA_EnableChannelRequest(DMA0, DMA_CHANNEL);
 }
 EDMA_SubmitTransfer(&dmaHandle, &transferConfig);
 EDMA_StartTransfer(&dmaHandle);
 
 while (!dmaTransferDone) {
 __NOP();
 }
 
 SDK_DelayAtLeastUs(300, CLOCK_GetFreq(kCLOCK_CpuClk));
 }
 
 int main(void)
 {
 BOARD_BootClockRUN();
 init_after_reset();
 SCB_DisableDCache();
 
 if (!(CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK)) {
 CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_ENABLE_MASK;
 CCM_ANALOG->PLL_USB1_CLR = CCM_ANALOG_PLL_USB1_POWER_MASK;
 CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_POWER_MASK;
 CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
 }
 
 CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 0);
 CLOCK_SetDiv(kCLOCK_Flexio2Div, 0);
 
 CLOCK_EnableClock(kCLOCK_Iomuxc);
 
 WS2812_FlexIO_Init();
 WS2812_DMA_Init();
 
 uint8_t led_data[NUM_LEDS * 3];
 
 while (1)
 {
 for (int i = 0; i < NUM_LEDS; i++) {
 led_data[i * 3 + 0] = 0;
 led_data[i * 3 + 1] = 255;
 led_data[i * 3 + 2] = 0;
 }
 WS2812_SendData(led_data);
 SDK_DelayAtLeastUs(500000, CLOCK_GetFreq(kCLOCK_CpuClk));
 
 for (int i = 0; i < NUM_LEDS; i++) {
 led_data[i * 3 + 0] = 0;
 led_data[i * 3 + 1] = 0;
 led_data[i * 3 + 2] = 255;
 }
 WS2812_SendData(led_data);
 SDK_DelayAtLeastUs(500000, CLOCK_GetFreq(kCLOCK_CpuClk));
 }
 }
 
 
 
 | 
 |