WS2822S

WS2822S.cpp

Committer:
zgtk_r
Date:
2018-03-13
Revision:
0:2fc093733833

File content as of revision 0:2fc093733833:

#include "WS2822S.h"

// 送信データの先頭
void WS2822S_Ctrl::PutDataHeader(int MTBP, int BREAK, int MAB, DigitalOut* pin, bool AddressHigh/* = false*/)
{
    *pin = 1;
    wait_us(MTBP);
    *pin = 0;
    wait_us(BREAK);
    *pin = 1;
    wait_us(MAB);
    
    if(AddressHigh){
        AddressPin = 1;
    }
    // SC
    DataPut8(0, pin);
}

// 色情報かアドレス情報の先頭を出力する
void WS2822S_Ctrl::PutDataHeader(bool AddressHeader/*=false*/)
{
    if(!AddressHeader)
    {
        PutDataHeader(C_MTBP, C_BREAK, C_MAB, &ColorPin,true);
    }
    else
    {
        PutDataHeader(A_MTBP, A_BREAK, A_MAB, &AddressPin);
    }
}

// 8bitのデータを出力する
void WS2822S_Ctrl::DataPut8(uint8_t data, DigitalOut* pin)
{
    // MTBF
    *pin = 0;
    wait_us(2);
    for(int i = 0; i < 8; i++)
    {
        if(((data & (1 << i)) != 0x00)){
            *pin = 1;
        }else{
            *pin = 0;
        }
        
        wait_us(1);
    }
    *pin = 1;
    wait_us(STOP_BIT);
}

// コンストラクタ
WS2822S_Ctrl::WS2822S_Ctrl(PinName ColorPinName, PinName AddressPinName, int PixcelNum)
: ColorPin(ColorPinName)
, AddressPin(AddressPinName)
, PixcelNum(PixcelNum)
{
    Display = new uint8_t*[PixcelNum];
    for(int i = 0; i < PixcelNum; i++)
    {
        Display[i] = new uint8_t[3];
    }
}
// デストラクタ
WS2822S_Ctrl::~WS2822S_Ctrl()
{
    for(int i = 0; i < PixcelNum; i++)
    {
        delete[] Display[i];
    }
    delete[] Display;
}

// 色を設定する
void WS2822S_Ctrl::SetColor(int pos, uint8_t R, uint8_t G, uint8_t B)
{
    if(pos >= PixcelNum || pos < 0)
    {
        return;
    }
    
    Display[pos][0] = B;
    Display[pos][1] = G;
    Display[pos][2] = R;
}
// 設定された色を削除する
void WS2822S_Ctrl::ClearColor(uint8_t R, uint8_t G, uint8_t B)
{
    for(int i = 0; i < PixcelNum; i++)
    {
        SetColor(i,R,G,B);
    }
}

// 設定したデータを出力する
void WS2822S_Ctrl::OutputData()
{
    // B > G > R
    PutDataHeader();
    AddressPin = 1;
    for(int i = 0; i < PixcelNum; i++){
        DataPut8(Display[i][0], &ColorPin);
        DataPut8(Display[i][1], &ColorPin);
        DataPut8(Display[i][2], &ColorPin);
    }
}

void WS2822S_Ctrl::OutputAddress()
{
    ColorPin = 1;
    PutDataHeader(true);
    for(int tmp1 = 1; tmp1 < PixcelNum * 3; tmp1+=3){

        //セットするアドレスを用意 32uS
        uint8_t tmp_data = tmp1;
        DataPut8(tmp_data, &AddressPin);

        //セットするアドレスによってブロック番号を変える
        int temp = 0;
        int channel = tmp1;
        if (channel >= 0 && channel < 256)
            temp = 0xF0;//0x0F;                  //0xF0 -> 0b11110000 -reverse order-> 0b00001111 -> 0x0F
        else if (channel >= 256 && channel < 512)
            temp = 0xE1;//0x87;                  //0xE1 -> 0b11100001 -reverse order-> 0b10000111 -> 0x87
        else if (channel >= 512 && channel < 768)
            temp = 0xD2;//0x4B;                  //0xD2 -> 0b11010010 -reverse order-> 0b01001011 -> 0x4B
        else if (channel >= 768 && channel < 1024)
            temp = 0xC3;//0xC3;                  //0xC3 -> 0b11000011 -reverse order-> 0b11000011 -> 0xC3
        else if (channel >= 1024 && channel < 1280)
            temp = 0xB4;//0x2D;                  //0xB4 -> 0b10110100 -reverse order-> 0b00101101 -> 0x2D
        else if (channel >= 1280 && channel < 1536)
            temp = 0xA5;//0xA5;                  //0xA5 -> 0b10100101 -reverse order-> 0b10100101 -> 0xA5
        else if (channel >= 1536 && channel < 1792)
            temp = 0x96;//0x69;                  //0x96 -> 0b10010110 -reverse order-> 0b01101001 -> 0x69
        else if (channel >= 1792 && channel < 2048)
            temp = 0x87;//0xE1;                  //0x87 -> 0b10000111 -reverse order-> 0b11100001 -> 0xE1
        else if (channel >= 2048 && channel < 2304)
            temp = 0x78;//0x1E;                  //0x78 -> 0b01111000 -reverse order-> 0b00011110 -> 0x1E
        else if (channel >= 2304 && channel < 2560)     
            temp = 0x69;//0x96;                  //0x69 -> 0b01101001 -reverse order-> 0b10010110 -> 0x96
        else if (channel >= 2560 && channel < 2816)
            temp = 0x5A;//0x5A;                  //0x5A -> 0b01011010 -reverse order-> 0b01011010 -> 0x5A
        else if (channel >= 2816 && channel < 3072)     
            temp = 0x4B;//0xD2;                  //0x4B -> 0b01001011 -reverse order-> 0b11010010 -> 0xD2
        DataPut8(temp, &AddressPin);

        //アドレス書込み時の定数
        tmp_data = 0xD2;
        DataPut8(tmp_data, &AddressPin);
    }

}