Saya Matsuura
/
drum
明石高専ロボ研 drum
neopixel.cpp
- Committer:
- TanakaRobo
- Date:
- 2020-11-12
- Revision:
- 7:678c6b604ac7
- Parent:
- 6:a7894e6982ea
File content as of revision 7:678c6b604ac7:
#include "mbed.h" #include "neopixel.h" const int wait_time[4][2] = { {6, 9}, {2, 5}, {2, 4}, {5, 9} }; NeoPixelOut::NeoPixelOut(PinName pin, int num) : DigitalOut(pin) { normalize = false; global_scale = 1.0f; #if defined(TARGET_NUCLEO_L432KC) board_ = 0; #elif defined(TARGET_NUCLEO_F446RE) board_ = 1; #else #error "This board is not supported" #endif num_pixels_ = num; strip_.resize(num); } // The timing should be approximately 800ns/300ns, 300ns/800ns void NeoPixelOut::byte(register uint32_t byte) { for (int i = 0; i < 8; i++) { gpio_write(&gpio, 1); // duty cycle determines bit value if (byte & 0x80) { // one for(int j = 0; j < wait_time[0][board_]; j++) asm("NOP");//6 9 gpio_write(&gpio, 0); for(int j = 0; j < wait_time[1][board_]; j++) asm("NOP");//2 5 } else { // zero for(int j = 0; j < wait_time[2][board_]; j++) asm("NOP");//2 4 gpio_write(&gpio, 0); for(int j = 0; j < wait_time[3][board_]; j++) asm("NOP");//5 9 } byte = byte << 1; // shift to next bit } } void NeoPixelOut::setPixelColor(uint32_t i,uint32_t color){ if(i >= num_pixels_){ return; } strip_[i].hex = color; } void NeoPixelOut::show(){ // Disable interrupts in the critical section __disable_irq(); float fr,fg,fb; int count = strip_.size(); for (int i = 0; i < count; i++) { fr = strip_[i].r; fg = strip_[i].g; fb = strip_[i].b; if (normalize) { float scale = 255.0f/(fr+fg+fb); fr *= scale; fg *= scale; fb *= scale; } fr *= global_scale; fg *= global_scale; fb *= global_scale; if (fr > 255) fr = 255; if (fg > 255) fg = 255; if (fb > 255) fb = 255; if (fr < 0) fr = 0; if (fg < 0) fg = 0; if (fb < 0) fb = 0; // Black magic to fix distorted timing #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); #endif byte((int)fg); byte((int)fr); byte((int)fb); #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); #endif } __enable_irq(); flip(); } void NeoPixelOut::send(Pixel *colors, uint32_t count, bool flipwait) { // Disable interrupts in the critical section __disable_irq(); Pixel* rgb; float fr,fg,fb; for (int i = 0; i < count; i++) { rgb = colors++; fr = (int)rgb->r; fg = (int)rgb->g; fb = (int)rgb->b; if (normalize) { float scale = 255.0f/(fr+fg+fb); fr *= scale; fg *= scale; fb *= scale; } fr *= global_scale; fg *= global_scale; fb *= global_scale; if (fr > 255) fr = 255; if (fg > 255) fg = 255; if (fb > 255) fb = 255; if (fr < 0) fr = 0; if (fg < 0) fg = 0; if (fb < 0) fb = 0; // Black magic to fix distorted timing #ifdef __HAL_FLASH_INSTRUCTION_CACHE_DISABLE __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); #endif byte((int)fg); byte((int)fr); byte((int)fb); #ifdef __HAL_FLASH_INSTRUCTION_CACHE_ENABLE __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); #endif } __enable_irq(); if (flipwait) flip(); } uint32_t NeoPixelOut::color(uint32_t b,uint32_t g,uint32_t r){ return b + (g << 8) + (r << 16); } int NeoPixelOut::numPixels(){ return num_pixels_; } void NeoPixelOut::off(bool flag){ for(int i = 0;i < strip_.size();i++){ strip_[i].hex = 0; } if(flag){ show(); } } void NeoPixelOut::changeNum(uint32_t num){ strip_.resize(num); num_pixels_ = num; } void NeoPixelOut::setBrightness(float brightness){ global_scale = brightness; } void NeoPixelOut::flip(void) { wait_us(50); }