LEDCubeを作る(2) WS2812B点灯

f:id:tohkaf:20160131233657j:plain

LEDCubeを作る(1) 基板作成 - 今日やったこと で発注した基板も届き、LEDも届いたので光るか試した。

制御

http://akizukidenshi.com/download/ds/adafruit/WS2812B.pdf

データシートを読むにPWMのデューティーで0,1判定をしているそうなので(Duty=0%でリセット)適当にPWMを起こした。

f:id:tohkaf:20160131234004p:plain

#include <project.h>

#define LED_N               (4)
#define LED_RESOLUTION      (8)
#define LED_COLOR           (3)
#define LED_RESET_DURATION  (50)

volatile uint16_t current_led = 0x0;
volatile uint8_t current_color = 0x0;
volatile uint8_t current_bit = 0x0;

volatile uint8_t is_led_reset = 0x0;
volatile uint8_t led_reset_counter = 0x0;

volatile uint8_t color_data[LED_N][LED_COLOR] = { };
CY_ISR(pwm_ovf){
    if(is_led_reset){
        PWM_1_WriteCompare(0);
        
        if(led_reset_counter++ >= LED_RESET_DURATION){
            is_led_reset = 0x0;
        }
    } else {
        PWM_1_WriteCompare((color_data[current_led][current_color] & (0x80 >> current_bit++)) ? 2 : 1);
        if(current_bit >= LED_RESOLUTION) {
            current_bit = 0x0;
            current_color++;
        }    
        if(current_color >= LED_COLOR) {
            current_color = 0x0;
            current_led++;
        }
        if(current_led >= LED_N){
            current_led = 0x0;
            is_led_reset = 0x1;
            led_reset_counter = 0x0;
        }
    }
}
int main()
{
    uint32 i,j,k;
    
    PWM_1_Start();
    PWM_1_WriteCompare(0);
    CyDelay(10);

    isr_PWM_OVF_StartEx(pwm_ovf);
    CyGlobalIntEnable;
    
    for(;;)
    {
        for(j = 0 ; j < LED_COLOR ; ++j){
            for(i = 0 ; i < LED_N ; ++i){
                for(k = 0 ; k < 0xffff ; ++k){
                    color_data[i][j] = (k >> 8);
                }
            }
        }
        for(j = 0 ; j < LED_COLOR ; ++j){
            for(i = 0 ; i < LED_N ; ++i){
                for(k = 0 ; k < 0xffff ; ++k){
                    color_data[i][j] = ~(k >> 8);
                }
            }
        }
    }
}

DMAでLEDの書き換えをし続けるコンポーネントを作るかFPGAで制御したくなったが、FPGAなんざ使ったら本末転倒感がある。