talon/User/ws2812.c
2024-01-13 12:57:51 -05:00

134 lines
3.9 KiB
C

#include "ws2812.h"
#include "ch32v20x.h"
u8 colors[12*3] = {
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0,
255, 0, 255,
0, 255,255,
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0,
255, 0, 255,
0, 255,255
};
u8 pbuf[12*3*8]; // = {15, 30, 30, 15, 22, 22, 0, 0, 45, 45, 22, 22};
void fuckballs() {
u32 idx = 0;
for (int i = 0; i < 12 * 3; i++)
{
for(int j = 0; j < 4; j++) {
if (colors[i] & (1 << j)) {
pbuf[idx++] = 29;
} else {
pbuf[idx++] = 14;
}
}
}
}
void ws2812_init() {
fuckballs();
// Enable TIM1 and GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);
// TIM1_CH1 - PA8
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
gpio_init.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOA, &gpio_init);
// GPIO_SetBits(GPIOA, GPIO_Pin_8);
TIM_TimeBaseInitTypeDef timebase_init;
TIM_TimeBaseStructInit(&timebase_init);
timebase_init.TIM_Prescaler = 0;
timebase_init.TIM_Period = 43; // 0 - 45 where 45 is 36MHz / 45 = 800kHz
timebase_init.TIM_ClockDivision = TIM_CKD_DIV1;
timebase_init.TIM_CounterMode = TIM_CounterMode_Up;
timebase_init.TIM_RepetitionCounter = 0x0000;
TIM_TimeBaseInit(TIM1, &timebase_init);
// Reload the CNT register with period?
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_OCInitTypeDef oc_init;
TIM_OCStructInit(&oc_init);
oc_init.TIM_OCMode = TIM_OCMode_PWM2;
oc_init.TIM_OutputState = TIM_OutputState_Enable;
oc_init.TIM_OutputNState = TIM_OutputNState_Disable;
oc_init.TIM_Pulse = 0;
oc_init.TIM_OCPolarity = TIM_OCPolarity_High;
oc_init.TIM_OCNPolarity = TIM_OCPolarity_Low;
oc_init.TIM_OCIdleState = TIM_OCIdleState_Reset;
oc_init.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(TIM1, &oc_init);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
// TIM_OC1FastConfig(TIM1, ENABLE);
// TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
// TIM_CtrlPWMOutputs(TIM1, ENABLE);
// TIM_Cmd(TIM1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_InitTypeDef dma_init;
DMA_StructInit(&dma_init);
dma_init.DMA_PeripheralBaseAddr = (u32)(&(TIM1->CH1CVR));
dma_init.DMA_MemoryBaseAddr = (u32)&pbuf[0];
dma_init.DMA_DIR = DMA_DIR_PeripheralDST;
dma_init.DMA_BufferSize = 12;
dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma_init.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
dma_init.DMA_Mode = DMA_Mode_Normal;
dma_init.DMA_Priority = DMA_Priority_VeryHigh;
dma_init.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &dma_init);
DMA_Cmd(DMA1_Channel5, ENABLE);
TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
// TIM_SetCompare1(TIM1, 14);
// TIM_Cmd(TIM1, ENABLE);
// DMA_Cmd(DMA1_Channel5, DISABLE);
while(1) {
// DMA_ClearFlag(DMA1_FLAG_HT5);
// DMA_ClearFlag(DMA1_FLAG_TC5);
// DMA_Cmd(DMA1_Channel5, ENABLE);
// TIM_Cmd(TIM1, ENABLE);
DMA_Cmd(DMA1_Channel5, DISABLE);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_Cmd(TIM1, DISABLE);
// TIM_DMACmd(TIM1, TIM_DMA_Update, DISABLE);
Delay_Ms(100);
// DMA_Cmd(DMA1_Channel5, ENABLE);
// TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
// TIM_Cmd(TIM1, ENABLE);
// TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
DMA_ClearFlag(DMA1_FLAG_TC5);
// DMA_ClearFlag(DMA1_FLAG_HT5);
DMA_SetCurrDataCounter(DMA1_Channel5, 12*3*8);
DMA_Cmd(DMA1_Channel5, ENABLE);
TIM_SetCounter(TIM1, 0);
TIM_Cmd(TIM1, ENABLE);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
// Delay_Ms(100);
while(!DMA_GetITStatus(DMA1_IT_TC5));
// Delay_Ms(10);
}
}