WS2812 PWM: prefix for DMA defines (#23111)
* WS2812 PWM: prefix for DMA defines * Add backward compatibility defines
This commit is contained in:
		
							parent
							
								
									3bf1ce5cf8
								
							
						
					
					
						commit
						569b0c70be
					
				
					 98 changed files with 246 additions and 234 deletions
				
			
		| 
						 | 
				
			
			@ -77,11 +77,11 @@
 | 
			
		|||
#    ifndef WS2812_PWM_PAL_MODE
 | 
			
		||||
#        define WS2812_PWM_PAL_MODE 1
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef WS2812_DMA_STREAM
 | 
			
		||||
#        define WS2812_DMA_STREAM STM32_DMA2_STREAM5
 | 
			
		||||
#    ifndef WS2812_PWM_DMA_STREAM
 | 
			
		||||
#        define WS2812_PWM_DMA_STREAM STM32_DMA2_STREAM5
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef WS2812_DMA_CHANNEL
 | 
			
		||||
#        define WS2812_DMA_CHANNEL 6
 | 
			
		||||
#    ifndef WS2812_PWM_DMA_CHANNEL
 | 
			
		||||
#        define WS2812_PWM_DMA_CHANNEL 6
 | 
			
		||||
#    endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ static const pio_program_t ws2812_program = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static uint32_t                WS2812_BUFFER[WS2812_LED_COUNT];
 | 
			
		||||
static const rp_dma_channel_t* WS2812_DMA_CHANNEL;
 | 
			
		||||
static const rp_dma_channel_t* dma_channel;
 | 
			
		||||
static uint32_t                RP_DMA_MODE_WS2812;
 | 
			
		||||
static int                     STATE_MACHINE = -1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -236,9 +236,9 @@ bool ws2812_init(void) {
 | 
			
		|||
    pio_sm_init(pio, STATE_MACHINE, offset, &config);
 | 
			
		||||
    pio_sm_set_enabled(pio, STATE_MACHINE, true);
 | 
			
		||||
 | 
			
		||||
    WS2812_DMA_CHANNEL = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, RP_DMA_PRIORITY_WS2812, (rp_dmaisr_t)ws2812_dma_callback, NULL);
 | 
			
		||||
    dmaChannelEnableInterruptX(WS2812_DMA_CHANNEL);
 | 
			
		||||
    dmaChannelSetDestinationX(WS2812_DMA_CHANNEL, (uint32_t)&pio->txf[STATE_MACHINE]);
 | 
			
		||||
    dma_channel = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, RP_DMA_PRIORITY_WS2812, (rp_dmaisr_t)ws2812_dma_callback, NULL);
 | 
			
		||||
    dmaChannelEnableInterruptX(dma_channel);
 | 
			
		||||
    dmaChannelSetDestinationX(dma_channel, (uint32_t)&pio->txf[STATE_MACHINE]);
 | 
			
		||||
 | 
			
		||||
    // clang-format off
 | 
			
		||||
    RP_DMA_MODE_WS2812 = DMA_CTRL_TRIG_INCR_READ |
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +256,7 @@ static inline void sync_ws2812_transfer(void) {
 | 
			
		|||
        // count of LEDs in milliseconds. This is safely much longer than it
 | 
			
		||||
        // would take to push all the data out.
 | 
			
		||||
        dprintln("ERROR: WS2812 DMA transfer has stalled, aborting!");
 | 
			
		||||
        dmaChannelDisableX(WS2812_DMA_CHANNEL);
 | 
			
		||||
        dmaChannelDisableX(dma_channel);
 | 
			
		||||
        pio_sm_clear_fifos(pio, STATE_MACHINE);
 | 
			
		||||
        pio_sm_restart(pio, STATE_MACHINE);
 | 
			
		||||
        chSemReset(&TRANSFER_COUNTER, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -284,8 +284,8 @@ void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) {
 | 
			
		|||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dmaChannelSetSourceX(WS2812_DMA_CHANNEL, (uint32_t)WS2812_BUFFER);
 | 
			
		||||
    dmaChannelSetCounterX(WS2812_DMA_CHANNEL, leds);
 | 
			
		||||
    dmaChannelSetModeX(WS2812_DMA_CHANNEL, RP_DMA_MODE_WS2812);
 | 
			
		||||
    dmaChannelEnableX(WS2812_DMA_CHANNEL);
 | 
			
		||||
    dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER);
 | 
			
		||||
    dmaChannelSetCounterX(dma_channel, leds);
 | 
			
		||||
    dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812);
 | 
			
		||||
    dmaChannelEnableX(dma_channel);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,18 @@
 | 
			
		|||
#include "gpio.h"
 | 
			
		||||
#include "chibios_config.h"
 | 
			
		||||
 | 
			
		||||
// ======== DEPRECATED DEFINES - DO NOT USE ========
 | 
			
		||||
#ifdef WS2812_DMA_STREAM
 | 
			
		||||
#    define WS2812_PWM_DMA_STREAM WS2812_DMA_STREAM
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef WS2812_DMA_CHANNEL
 | 
			
		||||
#    define WS2812_PWM_DMA_CHANNEL WS2812_DMA_CHANNEL
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef WS2812_DMAMUX_ID
 | 
			
		||||
#    define WS2812_PWM_DMAMUX_ID WS2812_DMAMUX_ID
 | 
			
		||||
#endif
 | 
			
		||||
// ========
 | 
			
		||||
 | 
			
		||||
/* Adapted from https://github.com/joewa/WS2812-LED-Driver_ChibiOS/ */
 | 
			
		||||
 | 
			
		||||
#ifdef RGBW
 | 
			
		||||
| 
						 | 
				
			
			@ -19,14 +31,14 @@
 | 
			
		|||
#ifndef WS2812_PWM_PAL_MODE
 | 
			
		||||
#    define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef WS2812_DMA_STREAM
 | 
			
		||||
#    define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP
 | 
			
		||||
#ifndef WS2812_PWM_DMA_STREAM
 | 
			
		||||
#    define WS2812_PWM_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef WS2812_DMA_CHANNEL
 | 
			
		||||
#    define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP
 | 
			
		||||
#ifndef WS2812_PWM_DMA_CHANNEL
 | 
			
		||||
#    define WS2812_PWM_DMA_CHANNEL 2 // DMA Channel for TIMx_UP
 | 
			
		||||
#endif
 | 
			
		||||
#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && !defined(WS2812_DMAMUX_ID)
 | 
			
		||||
#    error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP"
 | 
			
		||||
#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && !defined(WS2812_PWM_DMAMUX_ID)
 | 
			
		||||
#    error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_PWM_DMAMUX_ID STM32_DMAMUX1_TIM?_UP"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Summarize https://www.st.com/resource/en/application_note/an4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf to
 | 
			
		||||
| 
						 | 
				
			
			@ -270,20 +282,20 @@
 | 
			
		|||
// For all other STM32 DMA transfer will automatically zero pad. We only need to set the right peripheral width.
 | 
			
		||||
#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX)
 | 
			
		||||
#    if defined(WS2812_PWM_TIMER_32BIT)
 | 
			
		||||
#        define WS2812_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_WORD
 | 
			
		||||
#        define WS2812_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_WORD
 | 
			
		||||
#        define WS2812_PWM_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_WORD
 | 
			
		||||
#        define WS2812_PWM_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_WORD
 | 
			
		||||
typedef uint32_t ws2812_buffer_t;
 | 
			
		||||
#    else
 | 
			
		||||
#        define WS2812_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_HWORD
 | 
			
		||||
#        define WS2812_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_HWORD
 | 
			
		||||
#        define WS2812_PWM_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_HWORD
 | 
			
		||||
#        define WS2812_PWM_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_HWORD
 | 
			
		||||
typedef uint16_t ws2812_buffer_t;
 | 
			
		||||
#    endif
 | 
			
		||||
#else
 | 
			
		||||
#    define WS2812_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_BYTE
 | 
			
		||||
#    define WS2812_PWM_DMA_MEMORY_WIDTH STM32_DMA_CR_MSIZE_BYTE
 | 
			
		||||
#    if defined(WS2812_PWM_TIMER_32BIT)
 | 
			
		||||
#        define WS2812_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_WORD
 | 
			
		||||
#        define WS2812_PWM_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_WORD
 | 
			
		||||
#    else
 | 
			
		||||
#        define WS2812_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_HWORD
 | 
			
		||||
#        define WS2812_PWM_DMA_PERIPHERAL_WIDTH STM32_DMA_CR_PSIZE_HWORD
 | 
			
		||||
#    endif
 | 
			
		||||
typedef uint8_t ws2812_buffer_t;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -326,26 +338,26 @@ void ws2812_init(void) {
 | 
			
		|||
    // Configure DMA
 | 
			
		||||
    // dmaInit(); // Joe added this
 | 
			
		||||
#if defined(WB32F3G71xx) || defined(WB32FQ95xx)
 | 
			
		||||
    dmaStreamAlloc(WS2812_DMA_STREAM - WB32_DMA_STREAM(0), 10, NULL, NULL);
 | 
			
		||||
    dmaStreamSetSource(WS2812_DMA_STREAM, ws2812_frame_buffer);
 | 
			
		||||
    dmaStreamSetDestination(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register
 | 
			
		||||
    dmaStreamSetMode(WS2812_DMA_STREAM, WB32_DMA_CHCFG_HWHIF(WS2812_DMA_CHANNEL) | WB32_DMA_CHCFG_DIR_M2P | WB32_DMA_CHCFG_PSIZE_WORD | WB32_DMA_CHCFG_MSIZE_WORD | WB32_DMA_CHCFG_MINC | WB32_DMA_CHCFG_CIRC | WB32_DMA_CHCFG_TCIE | WB32_DMA_CHCFG_PL(3));
 | 
			
		||||
    dmaStreamAlloc(WS2812_PWM_DMA_STREAM - WB32_DMA_STREAM(0), 10, NULL, NULL);
 | 
			
		||||
    dmaStreamSetSource(WS2812_PWM_DMA_STREAM, ws2812_frame_buffer);
 | 
			
		||||
    dmaStreamSetDestination(WS2812_PWM_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register
 | 
			
		||||
    dmaStreamSetMode(WS2812_PWM_DMA_STREAM, WB32_DMA_CHCFG_HWHIF(WS2812_PWM_DMA_CHANNEL) | WB32_DMA_CHCFG_DIR_M2P | WB32_DMA_CHCFG_PSIZE_WORD | WB32_DMA_CHCFG_MSIZE_WORD | WB32_DMA_CHCFG_MINC | WB32_DMA_CHCFG_CIRC | WB32_DMA_CHCFG_TCIE | WB32_DMA_CHCFG_PL(3));
 | 
			
		||||
#else
 | 
			
		||||
    dmaStreamAlloc(WS2812_DMA_STREAM - STM32_DMA_STREAM(0), 10, NULL, NULL);
 | 
			
		||||
    dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register
 | 
			
		||||
    dmaStreamSetMemory0(WS2812_DMA_STREAM, ws2812_frame_buffer);
 | 
			
		||||
    dmaStreamSetMode(WS2812_DMA_STREAM, STM32_DMA_CR_CHSEL(WS2812_DMA_CHANNEL) | STM32_DMA_CR_DIR_M2P | WS2812_DMA_PERIPHERAL_WIDTH | WS2812_DMA_MEMORY_WIDTH | STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
 | 
			
		||||
    dmaStreamAlloc(WS2812_PWM_DMA_STREAM - STM32_DMA_STREAM(0), 10, NULL, NULL);
 | 
			
		||||
    dmaStreamSetPeripheral(WS2812_PWM_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register
 | 
			
		||||
    dmaStreamSetMemory0(WS2812_PWM_DMA_STREAM, ws2812_frame_buffer);
 | 
			
		||||
    dmaStreamSetMode(WS2812_PWM_DMA_STREAM, STM32_DMA_CR_CHSEL(WS2812_PWM_DMA_CHANNEL) | STM32_DMA_CR_DIR_M2P | WS2812_PWM_DMA_PERIPHERAL_WIDTH | WS2812_PWM_DMA_MEMORY_WIDTH | STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
 | 
			
		||||
#endif
 | 
			
		||||
    dmaStreamSetTransactionSize(WS2812_DMA_STREAM, WS2812_BIT_N);
 | 
			
		||||
    dmaStreamSetTransactionSize(WS2812_PWM_DMA_STREAM, WS2812_BIT_N);
 | 
			
		||||
    // M2P: Memory 2 Periph; PL: Priority Level
 | 
			
		||||
 | 
			
		||||
#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE)
 | 
			
		||||
    // If the MCU has a DMAMUX we need to assign the correct resource
 | 
			
		||||
    dmaSetRequestSource(WS2812_DMA_STREAM, WS2812_DMAMUX_ID);
 | 
			
		||||
    dmaSetRequestSource(WS2812_PWM_DMA_STREAM, WS2812_PWM_DMAMUX_ID);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Start DMA
 | 
			
		||||
    dmaStreamEnable(WS2812_DMA_STREAM);
 | 
			
		||||
    dmaStreamEnable(WS2812_PWM_DMA_STREAM);
 | 
			
		||||
 | 
			
		||||
    // Configure PWM
 | 
			
		||||
    // NOTE: It's required that preload be enabled on the timer channel CCR register. This is currently enabled in the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue