@@ -224,7 +224,162 @@ void Adafruit_NeoPixel::rp2040Show(uint8_t pin, uint8_t *pixels, uint32_t numBy
224224 // Bits for transmission must be shifted to top 8 bits
225225 pio_sm_put_blocking (pio, sm, ((uint32_t )*pixels++)<< 24 );
226226}
227+ #elif defined(ARDUINO_ARCH_CH32)
227228
229+ // F_CPU is defined to SystemCoreClock (not constant number)
230+ #if SYSCLK_FREQ_144MHz_HSE == 144000000 || SYSCLK_FREQ_HSE == 144000000 || \
231+ SYSCLK_FREQ_144MHz_HSI == 144000000 || SYSCLK_FREQ_HSI == 144000000
232+ #define CH32_F_CPU 144000000
233+
234+ #elif SYSCLK_FREQ_120MHz_HSE == 120000000 || SYSCLK_FREQ_HSE == 120000000 || \
235+ SYSCLK_FREQ_120MHz_HSI == 120000000 || SYSCLK_FREQ_HSI == 120000000
236+ #define CH32_F_CPU 120000000
237+
238+ #elif SYSCLK_FREQ_96MHz_HSE == 96000000 || SYSCLK_FREQ_HSE == 96000000 || \
239+ SYSCLK_FREQ_96MHz_HSI == 96000000 || SYSCLK_FREQ_HSI == 96000000
240+ #define CH32_F_CPU 96000000
241+
242+ #elif SYSCLK_FREQ_72MHz_HSE == 72000000 || SYSCLK_FREQ_HSE == 72000000 || \
243+ SYSCLK_FREQ_72MHz_HSI == 72000000 || SYSCLK_FREQ_HSI == 72000000
244+ #define CH32_F_CPU 72000000
245+
246+ #elif SYSCLK_FREQ_56MHz_HSE == 56000000 || SYSCLK_FREQ_HSE == 56000000 || \
247+ SYSCLK_FREQ_56MHz_HSI == 56000000 || SYSCLK_FREQ_HSI == 56000000
248+ #define CH32_F_CPU 56000000
249+
250+ #elif SYSCLK_FREQ_48MHz_HSE == 48000000 || SYSCLK_FREQ_HSE == 48000000 || \
251+ SYSCLK_FREQ_48MHz_HSI == 48000000 || SYSCLK_FREQ_HSI == 48000000
252+ #define CH32_F_CPU 48000000
253+
254+ #endif
255+
256+ static void ch32Show (GPIO_TypeDef* ch_port, uint32_t ch_pin, uint8_t * pixels, uint32_t numBytes, bool is800KHz) {
257+ // not support 400khz
258+ if (!is800KHz) return ;
259+
260+ volatile uint32_t * set = &ch_port->BSHR ;
261+ volatile uint32_t * clr = &ch_port->BCR ;
262+
263+ uint8_t * ptr = pixels;
264+ uint8_t * end = ptr + numBytes;
265+ uint8_t p = *ptr++;
266+ uint8_t bitMask = 0x80 ;
267+
268+ // NVIC_DisableIRQ(SysTicK_IRQn);
269+
270+ while (1 ) {
271+ if (p & bitMask) { // ONE
272+ // High 800ns
273+ *set = ch_pin;
274+ __asm volatile (" nop; nop; nop; nop; nop; nop; nop; nop;"
275+ " nop; nop; nop; nop; nop; nop; nop; nop;"
276+ " nop; nop; nop; nop; nop; nop; nop; nop;"
277+ " nop; nop; nop; nop; nop; nop; nop; nop;"
278+ " nop; nop; nop; nop; nop; nop; nop; nop;"
279+ " nop;"
280+ #if CH32_F_CPU >= 72000000
281+ " nop; nop; nop; nop; nop; nop; nop;"
282+ " nop; nop; nop; nop; nop; nop;"
283+ #endif
284+ #if CH32_F_CPU >= 96000000
285+ " nop; nop;"
286+ " nop; nop; nop; nop; nop; nop; nop; nop;"
287+ " nop; nop; nop; nop; nop; nop; nop; nop;"
288+ #endif
289+ #if CH32_F_CPU >= 120000000
290+ " nop; nop; nop; nop; nop; nop; nop; nop;"
291+ " nop; nop; nop; nop; nop; nop; nop; nop;"
292+ " nop; nop; nop; nop; nop; nop; nop; nop;"
293+ #endif
294+ #if CH32_F_CPU >= 144000000
295+ " nop; nop; nop; nop; nop; nop; nop; nop;"
296+ " nop; nop; nop; nop; nop; nop; nop; nop;"
297+ #endif
298+ );
299+
300+ // Low 450ns
301+ *clr = ch_pin;
302+ __asm volatile (" nop; nop; nop; nop; nop; nop; nop; nop;"
303+ " nop; nop; nop; nop; nop; nop; nop; nop;"
304+ " nop;"
305+ #if CH32_F_CPU >= 72000000
306+ " nop; nop; nop; nop; nop; nop; nop; nop; nop;"
307+ #endif
308+ #if CH32_F_CPU >= 96000000
309+ " nop; nop; nop; nop; nop; nop;"
310+ #endif
311+ #if CH32_F_CPU >= 120000000
312+ " nop; nop; nop; nop; nop;"
313+ " nop; nop; nop; nop; nop; nop; nop; nop;"
314+ #endif
315+ #if CH32_F_CPU >= 144000000
316+ " nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
317+ #endif
318+ );
319+ } else { // ZERO
320+ // High 400ns
321+ *set = ch_pin;
322+ __asm volatile (" nop; nop; nop; nop; nop; nop; nop; nop;"
323+ " nop; nop; nop; nop; nop; nop; nop; nop;"
324+ " nop;"
325+ #if CH32_F_CPU >= 72000000
326+ " nop; nop; nop; nop; nop; nop; nop;"
327+ #endif
328+ #if CH32_F_CPU >= 96000000
329+ " nop; nop; nop; nop; nop; nop; nop; nop;"
330+ #endif
331+ #if CH32_F_CPU >= 120000000
332+ " nop; nop; nop; "
333+ " nop; nop; nop; nop; nop; nop; nop; nop;"
334+ #endif
335+ #if CH32_F_CPU >= 144000000
336+ " nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
337+ #endif
338+ );
339+
340+ // Low 850ns
341+ *clr = ch_pin;
342+ __asm volatile (" nop; nop; nop; nop; nop; nop; nop; nop;"
343+ " nop; nop; nop; nop; nop; nop; nop; nop;"
344+ " nop; nop; nop; nop; nop; nop; nop; nop;"
345+ " nop; nop; nop; nop; nop; nop; nop; nop;"
346+ " nop; nop; nop; nop; nop;"
347+ #if CH32_F_CPU >= 72000000
348+ " nop; nop; nop;"
349+ " nop; nop; nop; nop; nop; nop; nop; nop;"
350+ #endif
351+ #if CH32_F_CPU >= 96000000
352+ " nop; nop; nop; nop; nop; nop; nop; nop;"
353+ " nop; nop; nop; nop; nop; nop; nop; nop;"
354+ " nop; nop; nop; nop; nop; nop;"
355+ #endif
356+ #if CH32_F_CPU >= 120000000
357+ " nop; nop; nop; nop; nop; nop; nop; nop;"
358+ " nop; nop; nop; nop; nop; nop; nop; nop;"
359+ " nop; nop; nop; nop; nop; nop;"
360+ #endif
361+ #if CH32_F_CPU >= 144000000
362+ " nop; nop; nop; nop;"
363+ " nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
364+ #endif
365+ );
366+ }
367+
368+ if (bitMask >>= 1 ) {
369+ // Move on to the next pixel
370+ asm (" nop;" );
371+ }
372+ else {
373+ if (ptr >= end) {
374+ break ;
375+ }
376+ p = *ptr++;
377+ bitMask = 0x80 ;
378+ }
379+ }
380+
381+ // NVIC_EnableIRQ(SysTicK_IRQn);
382+ }
228383#endif
229384
230385#if defined(ESP8266)
@@ -282,8 +437,8 @@ void Adafruit_NeoPixel::show(void) {
282437 // state, computes 'pin high' and 'pin low' values, and writes these back
283438 // to the PORT register as needed.
284439
285- // NRF52 may use PWM + DMA (if available), may not need to disable interrupt
286- // ESP32 may not disable interrupts because espShow() uses RMT which tries to acquire locks
440+ // NRF52 may use PWM + DMA (if available), may not need to disable interrupt
441+ // ESP32 may not disable interrupts because espShow() uses RMT which tries to acquire locks
287442#if !(defined(NRF52) || defined(NRF52_SERIES) || defined(ESP32))
288443 noInterrupts (); // Need 100% focus on instruction timing
289444#endif
@@ -3108,6 +3263,8 @@ if(is800KHz) {
31083263 }
31093264 }
31103265
3266+ #elif defined(ARDUINO_ARCH_CH32)
3267+ ch32Show (gpioPort, gpioPin, pixels, numBytes, is800KHz);
31113268#else
31123269#error Architecture not supported
31133270#endif
@@ -3141,6 +3298,15 @@ void Adafruit_NeoPixel::setPin(int16_t p) {
31413298#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32)
31423299 gpioPort = digitalPinToPort (p);
31433300 gpioPin = STM_LL_GPIO_PIN (digitalPinToPinName (p));
3301+ #elif defined(ARDUINO_ARCH_CH32)
3302+ PinName const pin_name = digitalPinToPinName (pin);
3303+ gpioPort = get_GPIO_Port (CH_PORT (pin_name));
3304+ gpioPin = CH_GPIO_PIN (pin_name);
3305+ #if defined (CH32V20x_D6)
3306+ if (gpioPort == GPIOC && ((*(volatile uint32_t *)0x40022030 ) & 0x0F000000 ) == 0 ) {
3307+ gpioPin = gpioPin >> 13 ;
3308+ }
3309+ #endif
31443310#endif
31453311}
31463312
@@ -3553,4 +3719,4 @@ neoPixelType Adafruit_NeoPixel::str2order(const char *v) {
35533719 }
35543720 if (w < 0 ) w = r; // If 'w' not specified, duplicate r bits
35553721 return (w << 6 ) | (r << 4 ) | ((g & 3 ) << 2 ) | (b & 3 );
3556- }
3722+ }
0 commit comments