Skip to content

Instantly share code, notes, and snippets.

@benpeoples
Created May 27, 2022 20:39
Show Gist options
  • Save benpeoples/30f4d1cb92268898ae3f468cc140218d to your computer and use it in GitHub Desktop.
Save benpeoples/30f4d1cb92268898ae3f468cc140218d to your computer and use it in GitHub Desktop.
ch32v307 DMX output!
#include "board.h"
#include "ch32v30x.h"
#include "dmx.h"
#include "debug.h"
uint8_t output_buffer[513];
/*
dmx_init();
dmx_send_break();
dmx_dma_go();
for(;;) {
if(DMA_GetFlagStatus(DMA1_FLAG_TC7) != RESET) // Wait until USART2 TX DMA1 Transfer Complete
{
dmx_send_break();
dmx_dma_go();
}
}
*/
void dmx_init() {
for(int x = 0; x < 513; x++) {
output_buffer[x] = 0;
}
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* USART2 TX-->A.2 RX-->A.3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Board specific, but this is the DE pin, which needs to be HIGH to output DMX
// In this case, it's PB1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_WriteBit(GPIOB, GPIO_Pin_1, Bit_SET);
USART_InitStructure.USART_BaudRate = 250000;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_2;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
DMA_InitTypeDef DMA_InitStructure = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
void dmx_dma_go() {
DMA_DeInit(DMA1_Channel7);
DMA_InitTypeDef DMA_InitStructure = {0};
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DATAR); /* USART2->DATAR:0x40004404 */
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)output_buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 513;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel7, ENABLE); /* USART2 Tx */
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
}
void dmx_send_break() {
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == 0) {
// printf("Waiting on TC\r\n");
}
USART_Cmd(USART2, DISABLE);
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);
Delay_Us(173); // We get an extra 5us out of the transactions, so we can BREAK for 173 and end up OK.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_Cmd(USART2, ENABLE);
Delay_Us(8); // Delay through MAB to be sure we're up before we start DMAing data
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment