打印
[DemoCode下载]

使用 PSIO 实现 ARGB2 LED 灯效

[复制链接]
614|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ps, RGB, LED, IO, GB
en-us--EC_M252_PSIO_ARGB2_LED_Control_V1.00.zip (2.52 MB)
使用M252 PSIO实现ARGB2 LED时序并实现彩虹灯、跑马灯等灯效
PSIO (Programmable Serial I/O) 提供简易的方法达到各种串行传输的接收与传送,例如: HDQ、DMX512、1-wire、IR、PS/2、Microwire、Wiegand、LED等。本文描述如何使用PSIO实现ARGB2 LED灯效,并演示ARGB2 LED彩虹灯、跑马灯效果,此范例代码使用一组Timer来定时更新ARGB2 LED彩虹灯、跑马灯的颜色,一组UART来选择执行模式;其内容包含PSIO与ARGB2 LED的基本介绍、范例程序的说明以及运行结果。

丰富的操作技术下载附件观看吧。

使用特权

评论回复
沙发
小灵通2018|  楼主 | 2024-5-20 21:35 | 只看该作者
/******************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url]     PSIO_ARGB2_Driver.h
* [url=home.php?mod=space&uid=247401]@brief[/url]    Nuvoton ARGB2 strip basic setting header file
*
* @note
* Copyright (C) 2022 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#ifndef _PSIO_ARGB2_STRIP_H_
#define _PSIO_ARGB2_STRIP_H_

//------------------------------------------------------------------------------
#include <stdint.h>

//------------------------------------------------------------------------------
#define PIXEL_NUM                       30         //LED's number in ARGB2 strip
#define GRB                             24         //Total bits of RGB


//Th20 SET Mode Setting
#define TH20_24bits                     0xDF1F1F

//------------------------------------------------------------------------------
// Don't remove
//------------------------------------------------------------------------------
#define BIT1_HIGH                       1        //Denote BIT1
#define BIT0_LOW                        0        //Denote BIT0

//------------------------------------------------------------------------------
typedef struct
{
    uint8_t u8SlotCtrl;
    uint8_t u8DataPin;
    uint8_t u8Brightness;
    uint8_t u8Reserved;
    uint16_t u16PulseCnt;
    uint8_t au8PixelBuffer[PIXEL_NUM][GRB];
} S_PSIO_ARGB2_STRIP_CFG_T;

//------------------------------------------------------------------------------
void Delay_Init(void);

void PSIO_StripInit(uint8_t u8Slot, uint8_t u8DataPin);
void PSIO_StripClear(void);
void PSIO_StripReset(void);
void PSIO_StripShow(void);

void PSIO_StripSetRGBColor(uint8_t u8Red, uint8_t u8Green, uint8_t u8Blue);
void PSIO_StripSetBrightness(uint8_t u8Brightness);
uint32_t PSIO_StripWheel(uint8_t u8WheelPos);
void PSIO_StripSetPixelColor(uint16_t u16Num, uint32_t u32RGBColor);
uint16_t PSIO_StripFeedBackMode(void);
void PSIO_StripHighLevelSetup(void);

void PSIO_StripWakeupMode(void);
void PSIO_StripSleepMode(void);

void PSIO_SetStripID(uint8_t u8ID);
void PSIO_ClearStripID(uint8_t u8ID);
void PSIO_CheckStripkID(uint8_t u8ID);
void PSIO_SpecifyStripID(uint8_t u8ID);

#endif /* _PSIO_ARGB2_STRIP_H_ */

/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/

使用特权

评论回复
板凳
小灵通2018|  楼主 | 2024-5-20 21:35 | 只看该作者
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "NuMicro.h"
#include "PSIO_ARGB2_Driver.h"

//------------------------------------------------------------------------------
// Global variable
//------------------------------------------------------------------------------
static S_PSIO_ARGB2_STRIP_CFG_T gsPSIO_ARGB2_Cfg = {0};
static uint32_t u32TimeoutUs = 0;
static uint32_t multipliter = 0;

//------------------------------------------------------------------------------
// Define functions prototype
//------------------------------------------------------------------------------
static void PSIO_Strip_OpenInput(uint32_t u32Switch);
static void PSIO_Strip_OpenOutput(uint32_t u32Switch);

//------------------------------------------------------------------------------
void Delay_Init(void)
{
    /* while loop takes 3 ~ 4 cycles */
    /* for 1 us delay, we need to divide with 3M */
    multipliter = (CLK_GetCPUFreq() / 12000000);
}

uint32_t TimeoutUsInit(uint32_t micros)
{
    return (u32TimeoutUs = ((multipliter * (micros + 16)) - 10));
}

void DelayUs(uint32_t micros)
{
    /* multiply micro with multipliter */
    micros = ((multipliter * (micros + 16)) - 10);

    /* 4 cycles for one loop */
    while (micros--);
}

void DelayMs(uint32_t mills)
{
    /* multiply mills with multipliter */
    mills = multipliter * mills * 1100 - 10;

    /* 4 cycles for one loop */
    while (mills--);
}

void DelayS(uint32_t mills)
{
    /* multiply mills with multipliter */
    mills = multipliter * mills * 1100000 - 10;

    /* 4 cycles for one loop */
    while (mills--);
}

/**
  * @brief  Clear PSIO SLOT setting.
  * @param  None
  * @retval None
  */
void PSIO_ResetAllSlotSetting(void)
{
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT1SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT2SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT1ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT2ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot tick count */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT3, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT4, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT5, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT6, 0);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT7, 0);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);
}

/**
  * @brief  Send BIT0 and BIT1 to complete burst data transfer
  * @param  None
  * @retval None
  */
void PSIO_StripSendBurstData(uint32_t u32DataSize,
                             uint32_t *u32Data,
                             uint32_t u32DataCount)
{
    uint32_t u32i = 0;
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_OUT_BUFFER;
    sDataConfig.CKPT2ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot count */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 1);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 2);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 1);

    /* Enable repeat slot0 ~ slot2 u32DataSize - 1 times */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT2, u32DataSize - 1, PSIO_REPEAT_DISABLE);

    /* Set out data width as u32DataSize bit */
    PSIO_SET_WIDTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, 0, u32DataSize);

    /* Set out data depth as 1 */
    PSIO_SET_OUTPUT_DEPTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, PSIO_DEPTH1);

    for (u32i = 0; u32i < u32DataCount; u32i++)
    {
        /* Set output data to buffer */
        PSIO_SET_OUTPUT_DATA(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, u32Data[u32i]);

        /* Trigger slot controller */
        PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

        /* Wait for slot controller is not busy */
        while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));
    }

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

/**
  * @brief  Send BIT0 and BIT1 to complete the data transfer
  * @param  None
  * @retval None
  */
void PSIO_SendDataWithSize(uint32_t u32DataSize, uint32_t u32Data)
{
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_OUT_BUFFER;
    sDataConfig.CKPT2ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot count */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 1);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 2);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 1);

    /* Enable repeat slot0 ~ slot2 u32DataSize - 1 times */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT2, u32DataSize - 1, PSIO_REPEAT_DISABLE);

    /* Set out data width as u32DataSize bit */
    PSIO_SET_WIDTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, 0, u32DataSize);

    /* Set out data depth as 1 */
    PSIO_SET_OUTPUT_DEPTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, PSIO_DEPTH1);

    /* Set output data to buffer */
    PSIO_SET_OUTPUT_DATA(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, u32Data);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

void PSIO_StripSetupID(uint32_t u32DataSize, uint32_t u32Data)
{
    S_PSIO_CP_CONFIG sCmdConfig = {0};
    S_PSIO_CP_CONFIG sDataConfig = {0};

    //--------------------------------------------------------------------------
    // Enable strip setup ID control
    //--------------------------------------------------------------------------
    /* Slot 0 ~ 7 */
    sCmdConfig.CKPT0SLT = PSIO_SLOT0;
    sCmdConfig.CKPT1SLT = PSIO_SLOT1;
    sCmdConfig.CKPT2SLT = PSIO_SLOT2;
    sCmdConfig.CKPT3SLT = PSIO_SLOT3;
    sCmdConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sCmdConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sCmdConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sCmdConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sCmdConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sCmdConfig.CKPT1ACT = PSIO_OUT_HIGH;
    sCmdConfig.CKPT2ACT = PSIO_OUT_HIGH;
    sCmdConfig.CKPT3ACT = PSIO_OUT_LOW;
    sCmdConfig.CKPT4ACT = PSIO_NO_ACTION;
    sCmdConfig.CKPT5ACT = PSIO_NO_ACTION;
    sCmdConfig.CKPT6ACT = PSIO_NO_ACTION;
    sCmdConfig.CKPT7ACT = PSIO_NO_ACTION;

    //--------------------------------------------------------------------------
    // send strip setup command and ID
    //--------------------------------------------------------------------------
    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_OUT_BUFFER;
    sDataConfig.CKPT2ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    //first reset
    PSIO_StripReset();

    /* Set out data width as u32DataSize bit */
    PSIO_SET_WIDTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, 0, u32DataSize);

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sCmdConfig);

    /* Set slot 0 tick count as 4, slot 1 tick count as 4, slot 2 tick count as 7 */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 4);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 4);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 7);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT3, 12);

    /* Enable repeat slot 0 ~ slot 2 u32DataSize - 1 times*/
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT2, u32DataSize - 1, PSIO_REPEAT_DISABLE);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot count */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 1);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 2);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 1);

    /* Set output data to buffer */
    PSIO_SET_OUTPUT_DATA(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, u32Data);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

/**
  * @brief Receive response pulse for Y-Cable check ID function
  * @param  None
  * @retval None
  */
uint16_t PSIO_StripCheckIDFeedback(uint16_t u16WaitTime)
{
    uint16_t u16LEDCnt = 0;
    uint32_t u32BitIndex = 0;
    int32_t i32UsTimeout = 0;
    S_PSIO_CP_CONFIG sDataConfig = {0};

    i32UsTimeout = TimeoutUsInit(u16WaitTime);

    PSIO_Strip_OpenInput(PSIO_PIN_ENABLE);

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_IN_BUFFER;
    sDataConfig.CKPT2ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 3);

    /* Enable repeat slot0 ~ slot0 26 times */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT2, 63, PSIO_REPEAT_DISABLE);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait data buffer is full */
    while ((!PSIO_GET_TRANSFER_STATUS(PSIO, PSIO_TRANSTS_INFULL0_Msk)) && (i32UsTimeout-- >= 0));

    if (i32UsTimeout <= 0)
    {
        /* Stop slot controller */
        PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

        /* Disable repeat slot0 ~ slot0 */
        PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);

        PSIO_Strip_OpenOutput(PSIO_PIN_ENABLE);
        return 0;
    }

    /* Read data from device */
    u16LEDCnt = PSIO_GET_INPUT_DATA(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin);

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot0 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);

    PSIO_Strip_OpenOutput(PSIO_PIN_ENABLE);

    return u16LEDCnt;
}

void PSIO_SpecifyStripID(uint8_t u8ID)
{
    uint8_t u8Cmd = (0x40 | (u8ID & 0x0F));

    PSIO_StripSetupID(8, u8Cmd);

    PSIO_StripReset();
}

void PSIO_CheckStripkID(uint8_t u8ID)
{
    uint8_t u8GetPulse = 0;
    uint8_t u8Cmd = (0x30 | (u8ID & 0x0F));

    PSIO_StripSetupID(8, u8Cmd);

    u8GetPulse = PSIO_StripCheckIDFeedback(160);

    if (u8GetPulse != 0)
    {
        printf("Get %d strip ID\r\n", u8ID);
    }
    else
    {
        printf("Not get %d strip ID\r\n", u8ID);
    }

    PSIO_StripReset();
}

void PSIO_ClearStripID(uint8_t u8ID)
{
    uint8_t u8Cmd = (0x20 | (u8ID & 0x0F));

    PSIO_StripSetupID(8, u8Cmd);

    PSIO_StripReset();
}

void PSIO_SetStripID(uint8_t u8ID)
{
    uint8_t u8Cmd = (0x10 | (u8ID & 0x0F));

    PSIO_StripSetupID(8, u8Cmd);

    PSIO_StripReset();
}

void PSIO_StripWakeupMode(void)
{
    uint8_t u8StripCnt = 0;

    PSIO_StripReset();

    for (u8StripCnt = 0; u8StripCnt < PIXEL_NUM; u8StripCnt++)
    {
        PSIO_SendDataWithSize(24, TH20_24bits);
        DelayMs(1);
    }
}

void PSIO_StripSleepMode(void)
{
    uint8_t u8StripCnt = 0;

    for (u8StripCnt = 0; u8StripCnt < PIXEL_NUM; u8StripCnt++)
    {
        PSIO_SendDataWithSize(24, 0x000000);
    }

    PSIO_SendDataWithSize(8, 0x5A);

    PSIO_StripReset();
}

void PSIO_StripHighLevelCMDTh20(void)
{
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT2SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT2ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot 0 tick count as 15, slot 1 tick count as 15 */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 15);

    /* Enable repeat slot 0 ~ slot 2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT0, 3, PSIO_REPEAT_DISABLE);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot0 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

void PSIO_StripHighLevelSetup(void)
{
    uint8_t u8StripCnt = 0;
    uint32_t u32Data[PIXEL_NUM] = {TH20_24bits};

    for (u8StripCnt = 0; u8StripCnt < PIXEL_NUM; u8StripCnt++)
    {
        u32Data[u8StripCnt] = TH20_24bits;
    }

    PSIO_StripHighLevelCMDTh20();

    PSIO_StripReset();

    PSIO_StripSendBurstData(24, &u32Data[0], PIXEL_NUM);

    PSIO_StripReset();
}

/**
  * @brief  Send Trst
  * @param  None
  * @retval None
  */
uint16_t PSIO_StripReadFeedBack(uint16_t u16WaitTime)
{
    uint16_t u16LEDCnt = 0;
    uint32_t u32BitIndex = 0;
    int32_t i32UsTimeout = 0;
    S_PSIO_CP_CONFIG sDataConfig = {0};

    PSIO_Strip_OpenInput(PSIO_PIN_ENABLE);

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT1ACT = PSIO_IN_BUFFER;
    sDataConfig.CKPT2ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot 0 tick count as 15, slot 1 tick count as 15, slot 2 tick count as 3*/
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 9);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 7);

    /* Enable repeat slot0 ~ slot2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT2, 63, PSIO_REPEAT_DISABLE);

    for (u32BitIndex = 0; u32BitIndex < 512; u32BitIndex++)
    {
        /* Set wait pulse timeout counter */
        i32UsTimeout = TimeoutUsInit(u16WaitTime);

        /* Trigger slot controller */
        PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

        /* Wait data buffer is full */
        while ((!PSIO_GET_TRANSFER_STATUS(PSIO, PSIO_TRANSTS_INFULL0_Msk)) && (i32UsTimeout-- >= 0));

        if (i32UsTimeout <= 0)
        {
            break;
        }

        /* Read data from device */
        u16LEDCnt += PSIO_GET_INPUT_DATA(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin);
    }

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot2 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);

    PSIO_Strip_OpenOutput(PSIO_PIN_ENABLE);

    return u16LEDCnt;
}

/**
  * @brief  Send Trst
  * @param  None
  * @retval None
  */
void PSIO_StripFeedBackCMDTh50(void)
{
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT1;
    sDataConfig.CKPT2SLT = PSIO_SLOT2;
    sDataConfig.CKPT3SLT = PSIO_SLOT3;
    sDataConfig.CKPT4SLT = PSIO_SLOT4;
    sDataConfig.CKPT5SLT = PSIO_SLOT5;
    sDataConfig.CKPT6SLT = PSIO_SLOT6;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT1ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT2ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT3ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT4ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT5ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT6ACT = PSIO_OUT_HIGH;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot tick count */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT1, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT2, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT3, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT4, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT5, 15);
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT6, 15);

    /* Enable repeat slot6 ~ slot7 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT6, PSIO_SLOT6, 9, PSIO_REPEAT_DISABLE);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot0 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

/**
  * @brief  Send Trst
  * @param  None
  * @retval None
  */
uint16_t PSIO_StripFeedBackMode(void)
{
    uint16_t u16LEDCnt = 0;
    uint32_t u32BitIndex = 0;
    uint32_t u32DelayCnt = 0;

    PSIO_StripReset();

    PSIO_StripFeedBackCMDTh50();

    u16LEDCnt = PSIO_StripReadFeedBack(160);

    PSIO_StripReset();
    PSIO_ResetAllSlotSetting();
    return u16LEDCnt;
}

/**
  * @brief  Send Trst
  * @param  None
  * @retval None
  */
void PSIO_StripReset(void)
{
    S_PSIO_CP_CONFIG sDataConfig = {0};

    /* Slot 0 ~ 7 */
    sDataConfig.CKPT0SLT = PSIO_SLOT0;
    sDataConfig.CKPT1SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT2SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT3SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT4SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT5SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT6SLT = PSIO_SLOT_DISABLE;
    sDataConfig.CKPT7SLT = PSIO_SLOT_DISABLE;

    /* Actions 0 ~ 7 */
    sDataConfig.CKPT0ACT = PSIO_OUT_LOW;
    sDataConfig.CKPT1ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT2ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT3ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT4ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT5ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT6ACT = PSIO_NO_ACTION;
    sDataConfig.CKPT7ACT = PSIO_NO_ACTION;

    /* Set check point configuration */
    PSIO_SET_CP_CONFIG(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, &sDataConfig);

    /* Set slot 0 tick count as 15, slot 1 tick count as 15 */
    PSIO_SCSLOT_SET_SLOT(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, 15);

    /* Enable repeat slot1 ~ slot1 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT0, PSIO_SLOT0, 47, PSIO_REPEAT_DISABLE);

    /* Trigger slot controller */
    PSIO_START_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Wait for slot controller is not busy */
    while (PSIO_GET_BUSY_FLAG(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl));

    /* Stop slot controller */
    PSIO_STOP_SC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl);

    /* Disable repeat slot0 ~ slot0 */
    PSIO_SET_SCCTL(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SLOT_DISABLE, PSIO_SLOT_DISABLE, 0, PSIO_REPEAT_DISABLE);
}

static void PSIO_Strip_OpenInput(uint32_t u32Switch)
{
    /* PSIO UART TX PIN general setting */
    PSIO_SET_GENCTL(PSIO,
                    gsPSIO_ARGB2_Cfg.u8DataPin,
                    u32Switch,//PSIO_PIN_ENABLE,
                    gsPSIO_ARGB2_Cfg.u8SlotCtrl,
                    PSIO_INPUT_MODE,
                    PSIO_LOW_LEVEL,
                    PSIO_LOW_LEVEL);

    /* Set output data buffer width as 8 bit, input data width as 1 bit*/
    PSIO_SET_WIDTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, 1, 8);

    /* Set input data buffer depth as 1 */
    PSIO_SET_INPUT_DEPTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, PSIO_DEPTH1);
}

static void PSIO_Strip_OpenOutput(uint32_t u32Switch)
{
    /* PSIO UART TX PIN general setting */
    PSIO_SET_GENCTL(PSIO,
                    gsPSIO_ARGB2_Cfg.u8DataPin,
                    u32Switch, //PSIO_PIN_ENABLE
                    gsPSIO_ARGB2_Cfg.u8SlotCtrl,
                    PSIO_OUTPUT_MODE,
                    PSIO_LOW_LEVEL,
                    PSIO_LOW_LEVEL);

    /* Set data order ad MSB */
    PSIO_SET_ORDER(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, PSIO_MSB);

    /* Set output data buffer width as 8 bit, input data width as 1 bit*/
    PSIO_SET_WIDTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, 1, 8);

    /* Set output data buffer depth as 1 */
    PSIO_SET_OUTPUT_DEPTH(PSIO, gsPSIO_ARGB2_Cfg.u8DataPin, PSIO_DEPTH1);

    /* Set slot controller trigger source as software trigger */
    PSIO_SET_TRIGSRC(PSIO, gsPSIO_ARGB2_Cfg.u8SlotCtrl, PSIO_SW_TRIGGER);
}

/**
  * @brief  initialize ARGB2 PSIO PIN
  * @param  None
  * @retval None
  */
void PSIO_StripInit(uint8_t u8SlotCtrl, uint8_t u8DataPin)
{
    gsPSIO_ARGB2_Cfg.u8SlotCtrl = u8SlotCtrl;
    gsPSIO_ARGB2_Cfg.u8DataPin = u8DataPin;

    PSIO_Strip_OpenOutput(PSIO_PIN_ENABLE);
}

//------------------------------------------------------------------------------
/**
  * @brief  Fill ALL LEDs with (0,0,0)
    * @param  24 bits data (Range: 0x000000 to 0xffffff)
  * @retval None
  */
void PSIO_StripClear(void)
{
    uint8_t u8i = 0;

    for (u8i = 0; u8i < PIXEL_NUM; u8i++)
    {
        PSIO_SendDataWithSize(24, 0x000000);
    }
}

/**
  * @brief  Digital output to all LED which in ARGB2 strip
  * @param  None
  * @retval None
  */
void PSIO_StripShow(void)
{
    uint16_t i, j;
    int32_t i32Data[PIXEL_NUM] = {0};
    S_PSIO_CP_CONFIG sDataConfig = {0};

    for (i = 0; i < PIXEL_NUM; ++i)
    {
        for (j = 0; j < GRB; ++j)
        {
            i32Data[i] |= (gsPSIO_ARGB2_Cfg.au8PixelBuffer[i][j] << (23 - j));
            //if (gsPSIO_ARGB2_Cfg.au8PixelBuffer[i][j] == BIT1_HIGH) {
            //    PSIO_SendStripBit1();
            //} else {
            //    PSIO_SendStripBit0();
            //}
        }
    }

    for (i = 0; i < PIXEL_NUM; ++i)
    {
        PSIO_SendDataWithSize(24, i32Data[i]);
    }
}

/**
  * @brief  RGB color bitwise operation
  * @param  red     0-255
    *                   green   0-255
    *                   blue    0-255
  * @retval None
  */
uint32_t Strip_color(uint8_t u8Red, uint8_t u8Green, uint8_t u8Blue)
{
    return u8Green << 16 | u8Red << 8 | u8Blue;
}

/**
  * @brief  Input a value 0 to 255 to get a color value.
                        The colours are a transition r - g - b - back to r.
  * @param  None
  * @retval None
  */
uint32_t PSIO_StripWheel(uint8_t u8WheelPos)
{
    u8WheelPos = 255 - u8WheelPos;

    if (u8WheelPos < 85)
    {
        return Strip_color(255 - u8WheelPos * 3, 0, u8WheelPos * 3);
    }

    if (u8WheelPos < 170)
    {
        u8WheelPos -= 85;
        return Strip_color(0, u8WheelPos * 3, 255 - u8WheelPos * 3);
    }

    u8WheelPos -= 170;

    return Strip_color(u8WheelPos * 3, 255 - u8WheelPos * 3, 0);
}

/**
  * @brief  RGB setting to all LED
    * @param  n:                    Specify a LED
                        GRBColor:       Set BIT1 or BIT0
  * @retval None
  */
void PSIO_StripSetPixelColor(uint16_t u16Num, uint32_t u32RGBColor)
{
    uint8_t i = 0;

    if (u16Num < PIXEL_NUM)
    {
        for (i = 0; i < GRB; i++)
        {
            gsPSIO_ARGB2_Cfg.au8PixelBuffer[u16Num][i] = ((u32RGBColor << i) & 0x800000) ? BIT1_HIGH : BIT0_LOW;
        }
    }
}

/**
* @brief Set GLOBAL LED brightness
* @param[in] br Brightness [0..255]
* [url=home.php?mod=space&uid=266161]@return[/url] #ARGB_STATE enum
*/
void PSIO_StripSetBrightness(uint8_t u8Brightness)
{
    gsPSIO_ARGB2_Cfg.u8Brightness = u8Brightness;
}

/**
  * @brief  Send one data to a LED
    * @param  24 bits data (Range: 0x000000 to 0xffffff)
  * @retval None
  */
void PSIO_StripSetRGBColor(uint8_t u8Red, uint8_t u8Green, uint8_t u8Blue)
{
    int32_t i32Data = 0;

    u8Red   /= (256 / ((uint16_t) gsPSIO_ARGB2_Cfg.u8Brightness + 1));
    u8Green /= (256 / ((uint16_t) gsPSIO_ARGB2_Cfg.u8Brightness + 1));
    u8Blue  /= (256 / ((uint16_t) gsPSIO_ARGB2_Cfg.u8Brightness + 1));

    i32Data |= (u8Green << 16);
    i32Data |= (u8Red << 8);
    i32Data |= u8Blue;

    PSIO_SendDataWithSize(24, i32Data);
}

使用特权

评论回复
地板
小灵通2018|  楼主 | 2024-5-20 21:35 | 只看该作者
/**************************************************************************//**
* @file     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V1.00
* @brief    Show how to use PSIO input/output to control ARGB2 strip.
*
* SPDX-License-Identifier: Apache-2.0
* [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2022 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#include "stdio.h"
#include "NuMicro.h"
#include "PSIO_ARGB2_Driver.h"

//------------------------------------------------------------------------------
uint32_t sysGetNum(void)
{
    uint8_t cInputTemp = 0x00, InputString[16] = {0};
    uint32_t nLoop = 0;

    while (cInputTemp != 0x0D)
    {
        cInputTemp = getchar();

        if (cInputTemp == 27)   /* 27: ESC key */
        {
            return cInputTemp;
        }

        if (cInputTemp == 'x' || cInputTemp == 'X' || cInputTemp == 'f' ||
                cInputTemp == 'F' || cInputTemp == 'r' || cInputTemp == 'R')
        {
            return cInputTemp;
        }

        if (cInputTemp == '-')
        {
            InputString[nLoop] = cInputTemp;
            printf("%c", cInputTemp);
            nLoop++;
        }
        else if (cInputTemp >= '0' && cInputTemp <= '9')
        {
            InputString[nLoop] = cInputTemp;
            printf("%c", cInputTemp);
            nLoop++;
        }
    }

    printf("\n");

    //return atoi(InputString);
    return atoi((const char *)InputString);
}

//------------------------------------------------------------------------------
/**
  * @brief  Specify a Strip ID in Y cable mode
    * @param  tmpID: Specify a ID
  * @retval None
  */
int Strip_SpecifyIDTest(void)
{
    PSIO_SpecifyStripID(0x05);

    return 0;
}

/**
  * @brief  Check a strip ID in Y cable function
  * @param  count: Check ID count
  * @retval None
  */
int Strip_CheckIDTest(void)
{
    uint8_t u8i = 0;

    for (u8i = 1; u8i < 16; u8i++)
    {
        PSIO_CheckStripkID(u8i);
    }

    return 0;
}

/**
  * @brief  Clear a Strip ID in Y cable function
  * @param  count: Clear ID count
  * @retval None
  */
int Strip_ClearIDTest(void)
{
    uint8_t u8i = 0;

    for (u8i = 1; u8i < 16; u8i++)
    {
        PSIO_ClearStripID(u8i);
    }

    return 0;
}

/**
  * @brief  Set a strip ID in Y cable function
    * @param  count: Set ID count
  * @retval None
  */
int Strip_SetIDTest(void)
{
    uint32_t u32ID = 0;

    printf("Please set ID, then press the ENTER.: (Range: 1 ~ 15): ");
    u32ID = sysGetNum();

    if (u32ID > 15)
    {
        printf("Setting ID is over range. (1 ~ 15)\r\n");
        printf("Leave Y Cable mode.\r\n\r\n");
        return -1;
    }

    PSIO_SetStripID(u32ID);

    return 0;
}

/**
  * @brief  Set a strip ID in Y cable menu function
    * @param  count: Set ID count
  * @retval None
  */
int Strip_YCableSetupMenu(void)
{
    uint8_t u8Index = 0;
    struct
    {
        char *chName;
        int (*funcptr)(void);
    } sSetStripIDMenu[] =
    {
        {"", NULL},
        {"Set strip ID", &Strip_SetIDTest},
        {"Clean strip ID", &Strip_ClearIDTest},
        {"Check strip ID", &Strip_CheckIDTest},
        {"Specify strip ID", &Strip_SpecifyIDTest},
    };

    while (1)
    {
        printf("\r\n\r\n");
        printf("=============================================\r\n");
        printf("\tEnter the select setup strip ID test: \r\n");
        printf("=============================================\r\n");

        for (u8Index = 1; u8Index < sizeof(sSetStripIDMenu) / sizeof(sSetStripIDMenu[0]); u8Index++)
        {
            printf("[%02d] %s\r\n",
                   u8Index,
                   sSetStripIDMenu[u8Index].chName);
        }

        printf("\r\n");

        u8Index = sysGetNum();

        if ((u8Index == 0) || (u8Index >= sizeof(sSetStripIDMenu) / sizeof(sSetStripIDMenu[0])))
        {
            return 0;
        }

        if (sSetStripIDMenu[u8Index].funcptr != NULL)
        {
            sSetStripIDMenu[u8Index].funcptr();
        }
    }

    return 0;
}

/**
  * @brief  Set a strip sleep or wakeup menu function
    * @param  count: Set ID count
  * @retval None
  */
int Strip_SleepWakeupTest(void)
{
    uint8_t u8Index = 0;
    struct
    {
        char *chName;
        void (*funcptr)(void);
    } sSleepWakeupTest[] =
    {
        {"", NULL},
        {"Strip Sleep", &PSIO_StripSleepMode},
        {"strip Wakeup", &PSIO_StripWakeupMode},
    };

    while (1)
    {
        printf("\r\n\r\n");
        printf("=============================================\r\n");
        printf("\tEnter the select sleep or wakeup test: \r\n");
        printf("=============================================\r\n");

        for (u8Index = 1; u8Index < sizeof(sSleepWakeupTest) / sizeof(sSleepWakeupTest[0]); u8Index++)
        {
            printf("[%02d] %s\r\n",
                   u8Index,
                   sSleepWakeupTest[u8Index].chName);
        }

        printf("\r\n");

        u8Index = sysGetNum();

        if ((u8Index == 0) || (u8Index >= sizeof(sSleepWakeupTest) / sizeof(sSleepWakeupTest[0])))
        {
            return 0;
        }

        if (sSleepWakeupTest[u8Index].funcptr != NULL)
        {
            sSleepWakeupTest[u8Index].funcptr();
        }
    }

    return 0;
}

/**
  * @brief  Enable TH20 SET mode
  * @param  None
  * @retval None
  */
int Strip_Th20SetMode(void)
{
    PSIO_StripHighLevelSetup();

    return 0;
}

/**
  * @brief  Theatre-style crawling lights with rainbow effect
  * @param  None
  * @retval None
  */
int Strip_FeedbackMode(void)
{
    printf("There are %d pcs LED in the strip\n", PSIO_StripFeedBackMode());

    return 0;
}

/**
  * @brief  Theatre-style crawling lights with rainbow effect
  * @param  None
  * @retval None
  */
int Strip_TheaterChaseRainbow(void)
{
    uint16_t u16i = 0, u16j = 0;
    uint8_t u8q = 0;

    for (u16j = 0; u16j < 256; u16j++)   // cycle all 256 colors in the wheel
    {
        for (u8q = 0; u8q < 3; u8q++)
        {
            for (u16i = 0; u16i < PIXEL_NUM; u16i = u16i + 3)
            {
                PSIO_StripSetPixelColor(u16i + u8q, PSIO_StripWheel((u16i + u16j) % 255));
            }

            PSIO_StripShow();

            PSIO_StripReset();

            for (u16i = 0; u16i < PIXEL_NUM; u16i = u16i + 3)
            {
                PSIO_StripSetPixelColor(u16i + u8q, 0);      //turn every third pixel off
            }
        }
    }

    PSIO_StripClear();

    return 0;
}

/**
  * @brief  This makes the rainbow equally distributed throughout
  * @param  None
  * @retval None
  */
int Strip_RainbowCycle(void)
{
    uint16_t u16i = 0, u16j = 0;

    for (u16j = 0; u16j < (256 * 5); u16j++)   // 5 cycles of all colors on wheel
    {
        for (u16i = 0; u16i < PIXEL_NUM; u16i++)
        {
            PSIO_StripSetPixelColor(u16i, PSIO_StripWheel(((u16i * 256 / PIXEL_NUM) + u16j) & 255));
        }

        PSIO_StripShow();

        PSIO_StripReset();
    }

    PSIO_StripClear();

    return 0;
}

/**
  * @brief  Set strip brightness.
  * @param  None
  * @retval None
  */
int Strip_SetBrightness(void)
{
    uint16_t u16Biighness = 0;

    printf("\nEnter a brightness level of 0 - 255: ");
    u16Biighness = sysGetNum();

    if (u16Biighness > 255)
    {
        u16Biighness = 255;
    }

    printf("%d\r\n", u16Biighness);

    PSIO_StripSetBrightness((uint8_t)u16Biighness & 0xFF);

    return 0;
}

/**
  * @brief  GRB Loop (Red -> Green -> Blue)
  * @param  None
  * @retval None
  */
int Strip_RGBLoop(void)
{
    uint8_t u8i = 0;

    while (kbhit())
    {
        for (u8i = 0; u8i < PIXEL_NUM; u8i++)
        {
            PSIO_StripSetRGBColor(0xFF, 0x00, 0x00);
        }

        TIMER_Delay(TIMER0, 100000);

        for (u8i = 0; u8i < PIXEL_NUM; u8i++)
        {
            PSIO_StripSetRGBColor(0x00, 0xFF, 0x00);
        }

        TIMER_Delay(TIMER0, 100000);

        for (u8i = 0; u8i < PIXEL_NUM; u8i++)
        {
            PSIO_StripSetRGBColor(0x00, 0x00, 0xFF);
        }

        TIMER_Delay(TIMER0, 100000);
    }

    PSIO_StripClear();

    return 0;
}

/**
  * @brief  ARGB2 Strip test menu for selecting test functions
  * @param  None
  * @retval None
  */
void ARGB2StripTestMenu(void)
{
    uint8_t u8Index = 0;
    struct
    {
        char *chName;
        int (*funcptr)(void);
    } sMainMenu[] =
    {
        {"", NULL},
        {"RGB Loop", &Strip_RGBLoop},
        {"Rainbow cycle", &Strip_RainbowCycle},
        {"Theater chase rainbow", &Strip_TheaterChaseRainbow},
        {"Feedback mode", &Strip_FeedbackMode},
        {"Th20 set mode", &Strip_Th20SetMode},
        //{"Strip Sleep Wakeup Test", &Strip_SleepWakeupTest},
        {"Y cable mode", &Strip_YCableSetupMenu},
        {"Set RGB Brightness", &Strip_SetBrightness},
    };

    while (1)
    {
        printf("\r\n\r\n");
        printf("=============================================\r\n");
        printf("\tEnter the select test function: \r\n");
        printf("=============================================\r\n");

        for (u8Index = 1; u8Index < sizeof(sMainMenu) / sizeof(sMainMenu[0]); u8Index++)
        {
            printf("[%02d] %s\r\n",
                   u8Index,
                   sMainMenu[u8Index].chName);
        }

        printf("\r\n");

        u8Index = sysGetNum();

        if ((u8Index == 0) || (u8Index >= sizeof(sMainMenu) / sizeof(sMainMenu[0])))
        {
            continue;
        }

        if (sMainMenu[u8Index].funcptr != NULL)
        {
            sMainMenu[u8Index].funcptr();
        }
    }
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Enable HIRC clock (Internal RC 48 MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

    /* Wait for HIRC clock ready */
    CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

    /* Select HCLK clock source as HIRC and and HCLK clock divider as 1 */
    CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));

    /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
    PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

    /* Disable digital input path of analog pin XT1_OUT to prevent leakage */
    GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 2));

    /* Disable digital input path of analog pin XT1_IN to prevent leakage */
    GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 3));

    /* Set PCLK1 clock divider as 4 */
    CLK->PCLKDIV = (CLK->PCLKDIV & ~CLK_PCLKDIV_APB1DIV_Msk) | CLK_PCLKDIV_APB1DIV_DIV4;

    /* Set both PCLK0 and PCLK1 as HCLK */
    //CLK->PCLKDIV = CLK_PCLKDIV_APB0DIV_DIV1 | CLK_PCLKDIV_APB1DIV_DIV1;

    /* Select IP clock source */
    /* Select UART0 clock source is HIRC */
    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));

    /* Enable IP clock */
    CLK_EnableModuleClock(GPB_MODULE);
    CLK_EnableModuleClock(UART0_MODULE);
    CLK_EnableModuleClock(TMR0_MODULE);
    CLK_EnableModuleClock(PSIO_MODULE);

    /* Select IP clock source */
    CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_PCLK0, 0);

    /* Select PSIO module clock source as PCLK1(48Mhz/4) and PSIO module clock divider as 0x4 = 0.3125us */
    CLK_SetModuleClock(PSIO_MODULE, CLK_CLKSEL2_PSIOSEL_PCLK1, CLK_CLKDIV1_PSIO(0x04));

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
    SystemCoreClockUpdate();

    /* PSIO multi-function pin CH0(PB.15) */
    SYS->GPB_MFPH = (SYS->GPB_MFPH & ~SYS_GPB_MFPH_PB15MFP_Msk) | SYS_GPB_MFPH_PB15MFP_PSIO0_CH0;

    /*----------------------------------------------------------------------*/
    /* Init I/O Multi-function                                              */
    /*----------------------------------------------------------------------*/
    /* Set PB multi-function pins for UART0 RXD and TXD */
    Uart0DefaultMPF();
}

/*---------------------------------------------------------------------------------------------------------*/
/* Init UART0                                                                                             */
/*---------------------------------------------------------------------------------------------------------*/
void UART0_Init(void)
{
    /* Configure UART0 and set UART0 baud rate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/* Init TIMER0                                                                                             */
/*---------------------------------------------------------------------------------------------------------*/
void TIMER0_Init(void)
{
    /* Configure and set TIMER0 */
    // Give a dummy target frequency here. Will over write prescale and compare value with macro
    TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 48000000);

    // Update prescale and compare value to what we need in event counter mode.
    TIMER_SET_PRESCALE_VALUE(TIMER0, 0);
    TIMER_SET_CMP_VALUE(TIMER0, 160);

    // Counter increase on rising edge
    TIMER_EnableEventCounter(TIMER0, TIMER_COUNTER_EVENT_RISING);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Main Function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, peripheral clock and multi-function I/O */
    SYS_Init();

    /* Init UART0 for printf and test */
    UART0_Init();

    /* Lock protected registers */
    SYS_LockReg();

    Delay_Init();

    /* Use slot control 0 and PIN 0 */
    PSIO_StripInit(PSIO_SC0, PSIO_PIN0);

    PSIO_StripSetBrightness(255);

    ARGB2StripTestMenu();
}

/*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/

使用特权

评论回复
5
wahahaheihei| | 2024-5-20 23:09 | 只看该作者
这是一种新的单片机外设?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

1476

帖子

4

粉丝