📄 lh79524_dma_driver.c
字号:
temp = 2;
else
temp = 4;
arg /= temp;
if ((arg & _BITMASK(16) ) != arg)
{
status = _ERROR;
break;
}
DMAC->stream3.max = arg;
break;
/* Set DMA memory to memory transfer source width
arg = 1,2,4 */
case DMA_SET_M2M_SRC_WIDTH:
switch(arg)
{
case 1:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_1BYTE;
break;
case 2:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_2BYTE;
break;
case 4:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_4BYTE;
break;
default:
status = _ERROR;
}
break;
/* Set DMA memory to memory transfer destination width
arg = 1, 2, 4 */
case DMA_SET_M2M_DEST_WIDTH:
switch(arg)
{
case 1:
DMAC->stream3.ctrl |= DMAC_CTRL_DESIZE_1BYTE;
break;
case 2:
DMAC->stream3.ctrl |= DMAC_CTRL_DESIZE_2BYTE;
break;
case 4:
DMAC->stream3.ctrl |= DMAC_CTRL_DESIZE_4BYTE;
break;
default:
status = _ERROR;
}
break;
/* Set DMA memory to memory transfer burst length - Number of
items of src_width the DMAC can read from the source memory
in a single burst, must be 1, 4, 8, 16 */
case DMA_SET_M2M_BURST_LEN:
switch(arg)
{
case 1:
DMAC->stream3.ctrl |= DMAC_CTRL_SOBURST_SINGLE;
break;
case 4:
DMAC->stream3.ctrl |= DMAC_CTRL_SOBURST_4INC;
break;
case 8:
DMAC->stream3.ctrl |= DMAC_CTRL_SOBURST_8INC;
break;
case 16:
DMAC->stream3.ctrl |= DMAC_CTRL_SOBURST_16INC;
break;
default:
status = _ERROR;
}
break;
/* Start DMA memory to memory transfer */
case DMA_START_M2M:
/* chang the IOMUX to GPIO as this is mem2mem DMA mode */
IOCON->mux_ctl_6 = IOCON_MUX6_PB1 | IOCON_MUX6_PB0;
/* clear any previous mem2mem DMA flags */
DMAC->clear = (DMAC_ERROR3 | DMAC_EOT3);
DMAC->stream3.ctrl |= DMAC_CTRL_SOINC | DMAC_CTRL_DEINC |
DMAC_CTRL_ADDR_MODE_WRAP | DMAC_CTRL_MEM2MEM;
DMAC->stream3.ctrl |= DMAC_CTRL_ENABLE;
break;
/* Stop DMA memory to memory transfer */
case DMA_STOP_M2M:
if ( (DMAC->stream3.ctrl & DMAC_CTRL_MEM2MEM) == 0)
status = _ERROR;
else
DMAC->stream3.ctrl &= ~DMAC_CTRL_ENABLE;
break;
/* DMA set external request channel, it can be DREQ0 or DREQ1,
arg = 0 set the DMA channel to be DREQ0, arg = 1 set the DMA
channel to be DREQ1, this is the first function to be called
before other external DMA setting function */
case DMA_SET_EXT_CHANNEL:
if (arg == 0)
{
dma_ext_channel = 0;
/* chang the IOMUX to DMA pins for DREQ0, DACK0, DEOT0 */
IOCON->mux_ctl_6 = IOCON_MUX6_DREQ | IOCON_MUX6_DACK;
}
else if (arg == 1)
{
dma_ext_channel = 1;
/* chang the IOMUX to DMA pins for DREQ0, DACK0, DEOT0 */
IOCON->mux_ctl_6 = IOCON_MUX6_DREQ | IOCON_MUX6_DACK;
}
else
{
if ((dma_ext_channel != 0) && (dma_ext_channel != 1))
dma_ext_channel = 0;
status = _ERROR;
}
break;
/* DMA set external request direction, arg = 0 for peripheral
to memory, arg = 1 for memory to peripheral */
case DMA_SET_EXT_DIRECTION:
if (arg == 0)
{
/* peripheral to memory */
if (dma_ext_channel == 0)
{
/* wait for the DMA stream 2 to be idle */
while (DMAC->status & DMAC_ACTIVE2);
DMAC->stream2.ctrl &= ~DMAC_CTRL_PERIPH_DEST;
}
else
{
/* wait for the DMA stream 3 to be idle */
while (DMAC->status & DMAC_ACTIVE3);
DMAC->stream3.ctrl &= ~DMAC_CTRL_PERIPH_DEST;
}
}
else if (arg == 1)
{
/* memory to peripheral */
if (dma_ext_channel == 0)
{
/* wait for the DMA stream 2 to be idle */
while (DMAC->status & DMAC_ACTIVE2);
DMAC->stream2.ctrl |= DMAC_CTRL_PERIPH_DEST;
}
else
{
/* wait for the DMA stream 3 to be idle */
while (DMAC->status & DMAC_ACTIVE3);
DMAC->stream3.ctrl |= DMAC_CTRL_PERIPH_DEST;
}
}
else
{
status = _ERROR;
}
break;
/* DMA external set source address, arg = address */
case DMA_SET_EXT_SRC:
if (dma_ext_channel == 0)
{
DMAC->stream2.sourcelo = arg & _BITMASK(16);
DMAC->stream2.sourcehi = (arg >> 16) & _BITMASK(16);
}
else if (dma_ext_channel == 1)
{
DMAC->stream3.sourcelo = arg & _BITMASK(16);
DMAC->stream3.sourcehi = (arg >> 16) & _BITMASK(16);
}
else
{
status = _ERROR;
}
break;
/* DMA external set destination address, arg = address */
case DMA_SET_EXT_DEST:
if (dma_ext_channel == 0)
{
DMAC->stream2.destlo = arg & _BITMASK(16);
DMAC->stream2.desthi = (arg >> 16) & _BITMASK(16);
}
else if (dma_ext_channel == 1)
{
DMAC->stream3.destlo = arg & _BITMASK(16);
DMAC->stream3.desthi = (arg >> 16) & _BITMASK(16);
}
else
{
status = _ERROR;
}
break;
/* DMA external set number of bytes to be transfered, arg
= nbytes */
/* The number of bytes to transfer; nbytes / src_width
must be less than 65536 and greater than 0 or this
function will return failure. DMA_SET_EXT_SRC_WIDTH must
be executed before this function call */
case DMA_SET_EXT_BYTES:
if (dma_ext_channel == 0)
{
temp = DMAC->stream2.ctrl;
if (temp == DMAC_CTRL_SOSIZE_1BYTE)
temp = 1;
else if (temp == DMAC_CTRL_SOSIZE_2BYTE)
temp = 2;
else
temp = 4;
arg /= temp;
if ((arg & _BITMASK(16) ) != arg)
{
status = _ERROR;
break;
}
DMAC->stream2.max = arg;
}
else if (dma_ext_channel == 1)
{
temp = DMAC->stream3.ctrl;
if (temp == DMAC_CTRL_SOSIZE_1BYTE)
temp = 1;
else if (temp == DMAC_CTRL_SOSIZE_2BYTE)
temp = 2;
else
temp = 4;
arg /= temp;
if ((arg & _BITMASK(16) ) != arg)
{
status = _ERROR;
break;
}
DMAC->stream3.max = arg;
}
else
{
status = _ERROR;
}
break;
/* DMA external transfer srouce width, arg = width */
case DMA_SET_EXT_SRC_WIDTH:
if (dma_ext_channel == 0)
{
switch(arg)
{
case 1:
DMAC->stream2.ctrl |= DMAC_CTRL_SOSIZE_1BYTE;
break;
case 2:
DMAC->stream2.ctrl |= DMAC_CTRL_SOSIZE_2BYTE;
break;
case 4:
DMAC->stream2.ctrl |= DMAC_CTRL_SOSIZE_4BYTE;
break;
default:
status = _ERROR;
}
}
else if (dma_ext_channel == 1)
{
switch(arg)
{
case 1:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_1BYTE;
break;
case 2:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_2BYTE;
break;
case 4:
DMAC->stream3.ctrl |= DMAC_CTRL_SOSIZE_4BYTE;
break;
default:
status = _ERROR;
}
}
else
{
status = _ERROR;
}
break;
/* DMA external transfer set destination width, arg = width */
case DMA_SET_EXT_DEST_WIDTH:
if (dma_ext_channel == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -