Skip to content
Snippets Groups Projects
Commit 4c06d8c5 authored by cnlohr's avatar cnlohr
Browse files

Update comments and add documentation.

parent d466dbaa
No related branches found
No related tags found
No related merge requests found
...@@ -8,10 +8,10 @@ Additionally, this demo only uses 6% CPU while it's outputting LEDs and free whi ...@@ -8,10 +8,10 @@ Additionally, this demo only uses 6% CPU while it's outputting LEDs and free whi
The timing on the SPI bus is not terribly variable, the best I was able to find was: The timing on the SPI bus is not terribly variable, the best I was able to find was:
* Ton0 = 324ns * Ton0 = 333ns
* Ton1 = 990ns * Ton1 = 1us
* Toff0 = 990ns * Toff0 = 1us
* Toff1 = 324ns * Toff1 = 333ns
* Treset = 68us * Treset = 68us
## Usage ## Usage
......
/* Single-File-Header for using asynchronous LEDs with the CH32V003 using DMA to the SPI port. /* Single-File-Header for using asynchronous LEDs with the CH32V003 using DMA to the SPI port.
I may write another version of this to use DMA to timer ports, but, the SPI port can be used I may write another version of this to use DMA to timer ports, but, the SPI port can be used
to generate outputs very efficiently. So, for now, SPI Port. to generate outputs very efficiently. So, for now, SPI Port. Additionally, it uses FAR less
internal bus resources than to do the same thing with timers.
Copyright 2023 <>< Charles Lohr, under the MIT-x11 or NewBSD License, you choose! Copyright 2023 <>< Charles Lohr, under the MIT-x11 or NewBSD License, you choose!
...@@ -93,6 +94,7 @@ static void WS2812FillBuffSec( uint16_t * ptr, int numhalfwords, int tce ) ...@@ -93,6 +94,7 @@ static void WS2812FillBuffSec( uint16_t * ptr, int numhalfwords, int tce )
break; break;
} }
// Use a LUT to figure out how we should set the SPI line.
uint32_t ledval24bit = WS2812BLEDCallback( place++ ); uint32_t ledval24bit = WS2812BLEDCallback( place++ );
ptr[0] = bitquartets[(ledval24bit>>20)&0xf]; ptr[0] = bitquartets[(ledval24bit>>20)&0xf];
ptr[1] = bitquartets[(ledval24bit>>16)&0xf]; ptr[1] = bitquartets[(ledval24bit>>16)&0xf];
...@@ -136,6 +138,7 @@ void DMA1_Channel3_IRQHandler( void ) ...@@ -136,6 +138,7 @@ void DMA1_Channel3_IRQHandler( void )
void WS2812BDMAStart( int leds ) void WS2812BDMAStart( int leds )
{ {
// Enter critical section.
__disable_irq(); __disable_irq();
WS2812BLEDInUse = 1; WS2812BLEDInUse = 1;
DMA1_Channel3->CFGR &= ~DMA_Mode_Circular; DMA1_Channel3->CFGR &= ~DMA_Mode_Circular;
...@@ -143,10 +146,12 @@ void WS2812BDMAStart( int leds ) ...@@ -143,10 +146,12 @@ void WS2812BDMAStart( int leds )
DMA1_Channel3->MADDR = (uint32_t)WS2812dmabuff; DMA1_Channel3->MADDR = (uint32_t)WS2812dmabuff;
WS2812LEDs = leds; WS2812LEDs = leds;
WS2812LEDPlace = -WS2812B_RESET_PERIOD; WS2812LEDPlace = -WS2812B_RESET_PERIOD;
__enable_irq();
WS2812FillBuffSec( WS2812dmabuff, DMA_BUFFER_LEN, 0 ); WS2812FillBuffSec( WS2812dmabuff, DMA_BUFFER_LEN, 0 );
DMA1_Channel3->CNTR = DMA_BUFFER_LEN; // Number of unique uint16_t entries. DMA1_Channel3->CNTR = DMA_BUFFER_LEN; // Number of unique uint16_t entries.
DMA1_Channel3->CFGR |= DMA_Mode_Circular; DMA1_Channel3->CFGR |= DMA_Mode_Circular;
__enable_irq();
} }
void WS2812BDMAInit( ) void WS2812BDMAInit( )
...@@ -163,16 +168,14 @@ void WS2812BDMAInit( ) ...@@ -163,16 +168,14 @@ void WS2812BDMAInit( )
SPI1->CTLR1 = SPI1->CTLR1 =
SPI_NSS_Soft | SPI_CPHA_1Edge | SPI_CPOL_Low | SPI_DataSize_16b | SPI_NSS_Soft | SPI_CPHA_1Edge | SPI_CPOL_Low | SPI_DataSize_16b |
SPI_Mode_Master | SPI_Direction_1Line_Tx | SPI_Mode_Master | SPI_Direction_1Line_Tx |
3<<3; // Dvisior 3<<3; // Divisior = 16 (48/16 = 3MHz)
SPI1->CTLR2 = SPI_CTLR2_TXDMAEN; SPI1->CTLR2 = SPI_CTLR2_TXDMAEN;
SPI1->HSCR = 1; SPI1->HSCR = 1;
SPI1->CTLR1 |= CTLR1_SPE_Set; SPI1->CTLR1 |= CTLR1_SPE_Set;
SPI1->DATAR = 0; // Set LEDs Low. SPI1->DATAR = 0; // Set SPI line Low.
//memset( bufferset, 0xaa, sizeof( bufferset ) );
//DMA1_Channel3 is for SPI1TX //DMA1_Channel3 is for SPI1TX
DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR; DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR;
...@@ -188,7 +191,7 @@ void WS2812BDMAInit( ) ...@@ -188,7 +191,7 @@ void WS2812BDMAInit( )
DMA_DIR_PeripheralDST | DMA_DIR_PeripheralDST |
DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts.
// NVIC_SetPriority( DMA1_Channel3_IRQn, 0<<4 ); // Regular priority. // NVIC_SetPriority( DMA1_Channel3_IRQn, 0<<4 ); //We don't need to tweak priority.
NVIC_EnableIRQ( DMA1_Channel3_IRQn ); NVIC_EnableIRQ( DMA1_Channel3_IRQn );
DMA1_Channel3->CFGR |= DMA_CFGR1_EN; DMA1_Channel3->CFGR |= DMA_CFGR1_EN;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment