Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
WS281XU.cpp
00001 /* WS281XU.cpp (for LPC82X/STM32F0x/STM32F746xx) 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2016 muetch, t.kuroki 00004 * Allrights reserved. 00005 * 00006 * Rev 0.97 2016-09-07 00007 * Rev 0.98 2016-09-08 00008 */ 00009 00010 #include "WS281XU.h" 00011 #if defined(TARGET_STM) 00012 #include "pinmap.h" 00013 #endif 00014 00015 // TARGET_STM32F7 00016 // TARGET_DISCO_F746NG 00017 // TARGET_NUCLEO_F746ZG 00018 // TARGET_NUCLEO_F446RE 00019 // TARGET_STM32F0 00020 // TARGET_NUCLEO_F030R8 00021 // TARGET_NUCLEO_F070RB 00022 // TARGET_NUCLEO_F072RB 00023 // TARGET_NUCLEO_F091RC 00024 // TARGET_LPC82X 00025 // TARGET_LPC824 00026 00027 //---------------------------------------------------------------------------- 00028 /* USART は下位ビットから送信 00029 * 800k*3 = 2.4Mbps, N, 7, 1 00030 * start_bit + 7bit_data + stop_bit = 9bit 00031 * 出力BITは反転させる 00032 * WS2811(RGB)/WS2812'GRB)は最上位ビットから送信 00033 */ 00034 00035 #define _0 0b110 00036 #define _1 0b100 00037 00038 #define _B(b2,b1,b0) ((((b2)|((b1)<<3)|((b0)<<6)) >> 1) & 0x7f) 00039 00040 static const uint8_t wstab[8] = 00041 { 00042 _B(_0, _0, _0), 00043 _B(_0, _0, _1), 00044 _B(_0, _1, _0), 00045 _B(_0, _1, _1), 00046 _B(_1, _0, _0), 00047 _B(_1, _0, _1), 00048 _B(_1, _1, _0), 00049 _B(_1, _1, _1) 00050 }; 00051 00052 //---------------------------------------------------------------------------- 00053 WS281XU::WS281XU(PinName txPin, PinMode pinMode, int maxPixels, RGBOrder order) 00054 : RGBPixels(maxPixels), _serial(), _irq_enabled(false) 00055 { 00056 pin_init(txPin, pinMode); 00057 rgbOrder(order); 00058 show(CL_BLACK); 00059 } 00060 00061 WS281XU::WS281XU(PinName txPin, PinMode pinMode, 00062 RGBColor *buffer, int maxPixels, RGBOrder order) 00063 : RGBPixels(buffer, maxPixels), _serial(), _irq_enabled(false) 00064 { 00065 pin_init(txPin, pinMode); 00066 rgbOrder(order); 00067 show(CL_BLACK); 00068 } 00069 00070 WS281XU::~WS281XU() 00071 { 00072 serial_free(&_serial); 00073 } 00074 00075 void WS281XU::pin_init(PinName txPin, PinMode pinMode) 00076 { 00077 _txPin = txPin; 00078 serial_init(&_serial, _txPin, NC); 00079 serial_baud(&_serial, 800000*3); 00080 serial_format(&_serial, 7, ParityNone, 1); 00081 #if defined(TARGET_STM) 00082 pin_mode_ex(txPin, pinMode); 00083 #endif 00084 } 00085 00086 #if defined(TARGET_STM) 00087 /** 00088 * Configure pin pull-up/pull-down/OpenDrain 00089 * typedef enum { 00090 * PullNone = 0, 00091 * PullUp = 1, 00092 * PullDown = 2, 00093 * OpenDrain = 3, 00094 * PullDefault = PullNone 00095 * } PinMode; 00096 */ 00097 void WS281XU::pin_mode_ex(PinName pin, PinMode mode) 00098 { 00099 int port_index = STM_PORT(pin); 00100 int pin_index = STM_PIN(pin); 00101 int offset = pin_index << 1; 00102 GPIO_TypeDef * port_reg = ((GPIO_TypeDef *) (GPIOA_BASE + (port_index << 10))); 00103 00104 // Configure pull-up/pull-down resistors 00105 uint32_t pupd = (uint32_t)mode & 3; 00106 if (pupd > 2) 00107 pupd = 0; // Open-drain = No pull-up/No pull-down 00108 00109 if (mode == OpenDrain) 00110 { 00111 port_reg->PUPDR &= ~(0x3 << offset); // Open-drain = No pull-up/No pull-down 00112 port_reg->OTYPER |= 1 << pin_index; 00113 } 00114 else 00115 { 00116 port_reg->OTYPER &= ~(1 << pin_index); 00117 // pin_mode(pin, mode); 00118 port_reg->PUPDR &= ~(0x3 << offset); 00119 port_reg->PUPDR |= (mode & 0x03) << offset; 00120 } 00121 } 00122 #endif 00123 00124 WS281XU::RGBOrder WS281XU::rgbOrder(RGBOrder order) 00125 { 00126 switch(_rgb_order = order) 00127 { 00128 case RGB: _1st = 0; _2nd = 1; _3rd = 2; break; // WS2811 00129 case RBG: _1st = 0; _2nd = 2; _3rd = 1; break; 00130 case GRB: _1st = 1; _2nd = 0; _3rd = 2; break; // WS2812 00131 case GBR: _1st = 2; _2nd = 0; _3rd = 1; break; 00132 case BRG: _1st = 1; _2nd = 2; _3rd = 0; break; 00133 case BGR: _1st = 2; _2nd = 1; _3rd = 0; break; 00134 default: 00135 _1st = 0; _2nd = 1; _3rd = 2; 00136 _rgb_order = GRB; // WS2812 00137 break; 00138 } 00139 return _rgb_order; 00140 } 00141 00142 void WS281XU::show() 00143 { 00144 if (!_pixels) 00145 return; 00146 00147 uint8_t *pix = (uint8_t *)_pixels; 00148 uint8_t *end = pix + (_num_pixels * sizeof(_pixels[0])); 00149 00150 if (!_irq_enabled) 00151 __disable_irq(); // Disable interrupts temporarily because we don't want our pulse timing to be messed up. 00152 00153 uint32_t value; 00154 do 00155 { 00156 value = pix[_1st]; 00157 putByte(wstab[(value >> 5) & 7]); 00158 putByte(wstab[(value >> 2) & 7]); 00159 00160 value = (value << 8) | pix[_2nd]; 00161 putByte(wstab[(value >> 7) & 7]); 00162 putByte(wstab[(value >> 4) & 7]); 00163 putByte(wstab[(value >> 1) & 7]); 00164 00165 value = (value << 8) | pix[_3rd]; 00166 putByte(wstab[(value >> 6) & 7]); 00167 putByte(wstab[(value >> 3) & 7]); 00168 putByte(wstab[value & 7]); 00169 00170 pix += sizeof(_pixels[0]); 00171 } while (pix < end); 00172 00173 if (!_irq_enabled) 00174 __enable_irq(); // Re-enable interrupts now that we are done. 00175 00176 //@- wait_us(50); 00177 } 00178 00179 // 指定色でバッファを埋めた後表示 00180 void WS281XU::show(const RGBColor color) 00181 { 00182 fill(color); 00183 show(); 00184 } 00185 00186 //----------------------------------------------------------------------------
Generated on Thu Jul 14 2022 04:31:44 by
