Skip to content
Snippets Groups Projects
Commit 13b29878 authored by cnlohr's avatar cnlohr
Browse files

Working on driving WS2812B's with DMA.

parent 0f3e4779
No related branches found
No related tags found
No related merge requests found
......@@ -3,9 +3,23 @@
#include "ch32v00x.h"
#include <stdio.h>
#include <string.h>
#define APB_CLOCK SYSTEM_CORE_CLOCK
// Working on WS2812 driving.
// For debug writing to the UART.
int _write(int fd, char *buf, int size)
{
for(int i = 0; i < size; i++){
while( !(USART1->STATR & USART_FLAG_TC));
USART1->DATAR = *buf++;
}
return size;
}
void SystemInit(void)
{
// Values lifted from the EVT. There is little to no documentation on what this does.
......@@ -25,12 +39,70 @@ void SystemInit(void)
RCC->CFGR0 = ( RCC->CFGR0 & ((uint32_t)~(RCC_SW))) | (uint32_t)RCC_SW_PLL; // Select PLL as system clock source
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08); // Wait till PLL is used as system clock source
// Once clock is up and running, we can enable the UART for other debugging.
// Enable GPIOD and UART.
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1;
// Push-Pull, 10MHz Output, GPIO D5, with AutoFunction
GPIOD->CFGLR &= ~(0xf<<(4*5));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5);
// 115200, 8n1. Note if you don't specify a mode, UART remains off even when UE_Set.
USART1->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Tx;
USART1->CTLR2 = USART_StopBits_1;
USART1->CTLR3 = USART_HardwareFlowControl_None;
#define UART_BAUD_RATE 115200
#define OVER8DIV 4
#define INTEGER_DIVIDER (((25 * (APB_CLOCK)) / (OVER8DIV * (UART_BAUD_RATE))))
#define FRACTIONAL_DIVIDER ((INTEGER_DIVIDER)%100)
USART1->BRR = ((INTEGER_DIVIDER / 100) << 4) | ((((FRACTIONAL_DIVIDER * (OVER8DIV*2)) + 50)/100)&7);
USART1->CTLR1 |= CTLR1_UE_Set;
}
int main()
uint16_t bufferset[128];
void ConfigSpeedyLED()
{
RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;
RCC->APB2PCENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1;
// MOSI
GPIOC->CFGLR &= ~(0xf<<(4*6));
GPIOC->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP_AF)<<(4*6);
SPI1->CTLR1 =
SPI_NSS_Hard | SPI_CPHA_1Edge | SPI_CPOL_Low | SPI_DataSize_16b |
SPI_Mode_Master | SPI_NSS_Soft | SPI_Direction_1Line_Tx |
3<<3; // Dvisior
SPI1->CTLR2 = SPI_CTLR2_TXDMAEN;
SPI1->HSCR = 1;
SPI1->CTLR1 |= CTLR1_SPE_Set;
memset( bufferset, 0xaa, sizeof( bufferset ) );
//DMA1_Channel3 is for SPI1TX
DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR;
DMA1_Channel3->MADDR = (uint32_t)bufferset;
DMA1_Channel3->CNTR = sizeof( bufferset )/2; // Number of unique copies.
DMA1_Channel3->CFGR =
DMA_M2M_Disable |
DMA_Priority_VeryHigh |
DMA_MemoryDataSize_HalfWord |
DMA_PeripheralDataSize_HalfWord |
DMA_MemoryInc_Enable |
DMA_Mode_Normal | // OR DMA_Mode_Circular
DMA_DIR_PeripheralDST;
DMA1_Channel3->CFGR |= DMA_CFGR1_EN;
}
int main()
{
// PLL + Prescale down ADC
// RCC->CFGR0 = RCC_SW_PLL | RCC_SWS_PLL | RCC_ADCPRE_DIV8;
// RCC->CTLR = RCC_PLLON | RCC_HSION | 0xff00;
......@@ -54,8 +126,13 @@ int main()
GPIOD->CFGLR &= ~(0xf<<(4*6));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6);
ConfigSpeedyLED();
printf( "CFG: %08x\n", SPI1->CTLR1 );
while(1)
{
GPIOD->BSHR = 128+64+1;
GPIOD->BSHR = 1<<16;
GPIOD->BSHR = 1;
......
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