#include <zephyr/kernel.h>
#include <zephyr/irq.h>
#include <zephyr/device.h>
#include "../lpuart/fsl_lpuart_edma.h"
#include "../dmamux/fsl_dmamux.h"
#include "fsl_iomuxc.h"
#include "dmx.h"
#define LPDMX3LPUART3
#define LPUART_DMA_BASEADDR DMA0
#define LPUART_DMAMUX_BASEADDR DMAMUX
#define LPUART_TX_DMA_CHANNEL 0U
#define DMX_FRAME_SIZE512
static uint8_t dmx_tx_buffer[DMX_FRAME_SIZE] __attribute__((section(".nocache")));
lpuart_edma_handle_t g_lpuartEdmaHandle;
edma_handle_t g_lpuartTxEdmaHandle;
volatile bool txOnGoing = false;
void LPUART_UserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData) {
if (status == kStatus_LPUART_TxIdle) {
txOnGoing = false;
}
}
void lpuart3_tx_dma_irq_handler(const void *arg) {
EDMA_HandleIRQ((edma_handle_t *)arg);
}
void send_break(void){
LPDMX3->CTRL = 1<<13;
LPDMX3->CTRL = 1<<13;
LPDMX3->CTRL = 1<<13;
LPDMX3->CTRL = 1<<13;
}
void dmx_hal_init(void) {
lpuart_config_t config;
edma_config_t edmaConfig;
CLOCK_EnableClock(kCLOCK_Lpuart3);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_LPUART3_TX, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_LPUART3_RX, 0U);
LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 250000; // Standard DMX
config.stopBitCount = kLPUART_TwoStopBit;
LPUART_Init(LPDMX3, &config, CLOCK_GetFreq(kCLOCK_Lpuart3));
DMAMUX_Init(LPUART_DMAMUX_BASEADDR);
DMAMUX_SetSource(LPUART_DMAMUX_BASEADDR, LPUART_TX_DMA_CHANNEL, kDmaRequestMuxLPUART3Tx);
DMAMUX_EnableChannel(LPUART_DMAMUX_BASEADDR, LPUART_TX_DMA_CHANNEL);
EDMA_GetDefaultConfig(&edmaConfig);
EDMA_Init(LPUART_DMA_BASEADDR, &edmaConfig);
EDMA_CreateHandle(&g_lpuartTxEdmaHandle, LPUART_DMA_BASEADDR, LPUART_TX_DMA_CHANNEL);
LPUART_TransferCreateHandleEDMA(LPDMX3, &g_lpuartEdmaHandle, LPUART_UserCallback, NULL, &g_lpuartTxEdmaHandle, NULL);
IRQ_CONNECT(DMA0_DMA16_IRQn, 5, lpuart3_tx_dma_irq_handler, &g_lpuartTxEdmaHandle, 0);
irq_enable(DMA0_DMA16_IRQn);
}
void dmx_send_frame(const uint8_t *src_data) {
// if (txOnGoing) return;
memcpy(dmx_tx_buffer, src_data, DMX_FRAME_SIZE);
lpuart_transfer_t xfer = {
.data = dmx_tx_buffer,
.dataSize = DMX_FRAME_SIZE
};
txOnGoing = true;
if (kStatus_Success != LPUART_SendEDMA(LPDMX3, &g_lpuartEdmaHandle, &xfer)) {
txOnGoing = false;
printk("DMA Transfer Failed!\n");
}
}