LPC17: Fix a critical error in GPDMA reported by Lizhuoyi
This commit is contained in:
parent
39cf9e248b
commit
dc32678da1
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/src/lpc17xx/lpc17_gpdma.c
|
* arch/arm/src/lpc17xx/lpc17_gpdma.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2010, 2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -73,6 +73,7 @@ struct lpc17_dmach_s
|
|||||||
uint8_t chn; /* The DMA channel number */
|
uint8_t chn; /* The DMA channel number */
|
||||||
bool inuse; /* True: The channel is in use */
|
bool inuse; /* True: The channel is in use */
|
||||||
bool inprogress; /* True: DMA is in progress on this channel */
|
bool inprogress; /* True: DMA is in progress on this channel */
|
||||||
|
uint16_t nxfrs; /* Number of transfers */
|
||||||
dma_callback_t callback; /* DMA completion callback function */
|
dma_callback_t callback; /* DMA completion callback function */
|
||||||
void *arg; /* Argument to pass to the callback function */
|
void *arg; /* Argument to pass to the callback function */
|
||||||
};
|
};
|
||||||
@ -464,7 +465,7 @@ int lpc17_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
|
|||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
|
|
||||||
DEBUGASSERT(dmach && dmach->inuse);
|
DEBUGASSERT(dmach && dmach->inuse && nxfrs < 4096);
|
||||||
|
|
||||||
chbit = DMACH((uint32_t)dmach->chn);
|
chbit = DMACH((uint32_t)dmach->chn);
|
||||||
base = LPC17_DMACH_BASE((uint32_t)dmach->chn);
|
base = LPC17_DMACH_BASE((uint32_t)dmach->chn);
|
||||||
@ -522,6 +523,10 @@ int lpc17_dmasetup(DMA_HANDLE handle, uint32_t control, uint32_t config,
|
|||||||
regval |= ((uint32_t)nxfrs << DMACH_CONTROL_XFRSIZE_SHIFT);
|
regval |= ((uint32_t)nxfrs << DMACH_CONTROL_XFRSIZE_SHIFT);
|
||||||
putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET);
|
putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET);
|
||||||
|
|
||||||
|
/* Save the number of transfer to perform for lpc17_dmastart */
|
||||||
|
|
||||||
|
dmach->nxfrs = (uint16_t)nxfrs;
|
||||||
|
|
||||||
/* 7. "Write the channel configuration information into the DMACCxConfig
|
/* 7. "Write the channel configuration information into the DMACCxConfig
|
||||||
* register. If the enable bit is set then the DMA channel is
|
* register. If the enable bit is set then the DMA channel is
|
||||||
* automatically enabled."
|
* automatically enabled."
|
||||||
@ -573,11 +578,15 @@ int lpc17_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg)
|
|||||||
putreg32(chbit, LPC17_DMA_INTTCCLR);
|
putreg32(chbit, LPC17_DMA_INTTCCLR);
|
||||||
putreg32(chbit, LPC17_DMA_INTERRCLR);
|
putreg32(chbit, LPC17_DMA_INTERRCLR);
|
||||||
|
|
||||||
/* Enable terminal count interrupt */
|
/* Enable terminal count interrupt. Note that we need to restore the
|
||||||
|
* number transfers. That is because the value has a different meaning
|
||||||
|
* when it is read.
|
||||||
|
*/
|
||||||
|
|
||||||
base = LPC17_DMACH_BASE((uint32_t)dmach->chn);
|
base = LPC17_DMACH_BASE((uint32_t)dmach->chn);
|
||||||
regval = getreg32(base + LPC17_DMACH_CONTROL_OFFSET);
|
regval = getreg32(base + LPC17_DMACH_CONTROL_OFFSET);
|
||||||
regval |= DMACH_CONTROL_I;
|
regval &= ~DMACH_CONTROL_XFRSIZE_MASK;
|
||||||
|
regval |= (DMACH_CONTROL_I | ((uint32_t)dmach->nxfrs << DMACH_CONTROL_XFRSIZE_SHIFT));
|
||||||
putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET);
|
putreg32(regval, base + LPC17_DMACH_CONTROL_OFFSET);
|
||||||
|
|
||||||
/* Enable the channel and unmask terminal count and error interrupts.
|
/* Enable the channel and unmask terminal count and error interrupts.
|
||||||
|
Loading…
Reference in New Issue
Block a user