diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-09-21 07:44:28 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-09-21 07:44:28 +0000 |
commit | 687e34b6194bd4722d5955a8cdb89389d52f89f9 (patch) | |
tree | ef465839aab0b641efa100268a851474e21d4f3b /c/src/lib/libbsp/arm/lpc24xx/misc | |
parent | 2009-09-20 Joel Sherrill <joel.sherrill@oarcorp.com> (diff) | |
download | rtems-687e34b6194bd4722d5955a8cdb89389d52f89f9.tar.bz2 |
Add missing files.
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc24xx/misc')
-rw-r--r-- | c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c | 194 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/lpc24xx/misc/timer.c | 55 |
2 files changed, 249 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c b/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c new file mode 100644 index 0000000000..55c33e451f --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c @@ -0,0 +1,194 @@ +/** + * @file + * + * @ingroup lpc24xx_dma + * + * @brief Direct memory access (DMA) support. + */ + +/* + * Copyright (c) 2008, 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <bsp/lpc24xx.h> +#include <bsp/dma.h> +#include <bsp/irq.h> + +static rtems_id lpc24xx_dma_sema_table [GPDMA_CH_NUMBER]; + +static bool lpc24xx_dma_status_table [GPDMA_CH_NUMBER]; + +static void lpc24xx_dma_copy_handler(rtems_vector_number vector, void *arg) +{ + /* Get interrupt status */ + uint32_t tc = GPDMA_INT_TCSTAT; + uint32_t err = GPDMA_INT_ERR_STAT; + + /* Clear interrupt status */ + GPDMA_INT_TCCLR = tc; + GPDMA_INT_ERR_CLR = err; + + /* Check channel 0 */ + if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_0)) { + rtems_semaphore_release(lpc24xx_dma_sema_table [0]); + } + lpc24xx_dma_status_table [0] = IS_FLAG_CLEARED(err, GPDMA_STATUS_CH_0); + + /* Check channel 1 */ + if (IS_FLAG_SET(tc, GPDMA_STATUS_CH_1)) { + rtems_semaphore_release(lpc24xx_dma_sema_table [1]); + } + lpc24xx_dma_status_table [1] = IS_FLAG_CLEARED(err, GPDMA_STATUS_CH_1); +} + +rtems_status_code lpc24xx_dma_copy_initialize(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_id id0 = RTEMS_ID_NONE; + rtems_id id1 = RTEMS_ID_NONE; + + /* Create semaphore for channel 0 */ + sc = rtems_semaphore_create( + rtems_build_name('D', 'M', 'A', '0'), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &id0 + ); + if (sc != RTEMS_SUCCESSFUL) { + return sc; + } + + /* Create semaphore for channel 1 */ + sc = rtems_semaphore_create( + rtems_build_name('D', 'M', 'A', '1'), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &id1 + ); + if (sc != RTEMS_SUCCESSFUL) { + rtems_semaphore_delete(id0); + + return sc; + } + + /* Install DMA interrupt handler */ + sc = rtems_interrupt_handler_install( + LPC24XX_IRQ_DMA, + "DMA copy", + RTEMS_INTERRUPT_UNIQUE, + lpc24xx_dma_copy_handler, + NULL + ); + if (sc != RTEMS_SUCCESSFUL) { + rtems_semaphore_delete(id0); + rtems_semaphore_delete(id1); + + return sc; + } + + /* Initialize global data */ + lpc24xx_dma_sema_table [0] = id0; + lpc24xx_dma_sema_table [1] = id1; + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code lpc24xx_dma_copy_release(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_status_code rsc = RTEMS_SUCCESSFUL; + + sc = rtems_interrupt_handler_remove( + LPC24XX_IRQ_DMA, + lpc24xx_dma_copy_handler, + NULL + ); + if (sc != RTEMS_SUCCESSFUL) { + rsc = sc; + } + + sc = rtems_semaphore_delete(lpc24xx_dma_sema_table [0]); + if (sc != RTEMS_SUCCESSFUL) { + rsc = sc; + } + + sc = rtems_semaphore_delete(lpc24xx_dma_sema_table [1]); + if (sc != RTEMS_SUCCESSFUL) { + rsc = sc; + } + + return rsc; +} + +rtems_status_code lpc24xx_dma_copy( + unsigned channel, + void *dest, + const void *src, + size_t n, + size_t width +) +{ + volatile lpc24xx_dma_channel *e = GPDMA_CH_BASE_ADDR(channel); + uint32_t w = GPDMA_CH_CTRL_W_8; + + switch (width) { + case 4: + w = GPDMA_CH_CTRL_W_32; + break; + case 2: + w = GPDMA_CH_CTRL_W_16; + break; + } + + n = n >> w; + + if (n > 0U && n < 4096U) { + e->desc.src = (uint32_t) src; + e->desc.dest = (uint32_t) dest; + e->desc.lli = 0; + e->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n) + | SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_1) + | SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_1) + | SET_GPDMA_CH_CTRL_SW(0, w) + | SET_GPDMA_CH_CTRL_DW(0, w) + | GPDMA_CH_CTRL_ITC + | GPDMA_CH_CTRL_SI + | GPDMA_CH_CTRL_DI; + e->cfg = SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA) + | GPDMA_CH_CFG_IE + | GPDMA_CH_CFG_ITC + | GPDMA_CH_CFG_EN; + } else { + return RTEMS_INVALID_SIZE; + } + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code lpc24xx_dma_copy_wait(unsigned channel) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + sc = rtems_semaphore_obtain( + lpc24xx_dma_sema_table [channel], + RTEMS_WAIT, + RTEMS_NO_TIMEOUT + ); + if (sc != RTEMS_SUCCESSFUL) { + return sc; + } + + return lpc24xx_dma_status_table [channel] + ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR; +} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c b/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c new file mode 100644 index 0000000000..e9d44312ab --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c @@ -0,0 +1,55 @@ +/** + * @file + * + * @ingroup lpc24xx + * + * @brief Benchmark timer support. + */ + +/* + * Copyright (c) 2008, 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <rtems.h> +#include <rtems/timerdrv.h> + +#include <bsp/system-clocks.h> + +static bool benchmark_timer_find_average_overhead = false; + +static uint32_t benchmark_timer_base; + +void benchmark_timer_initialize(void) +{ + benchmark_timer_base = lpc24xx_timer(); +} + +uint32_t benchmark_timer_read(void) +{ + uint32_t delta = lpc24xx_timer() - benchmark_timer_base; + + if (benchmark_timer_find_average_overhead) { + return delta; + } else { + /* Value determined by tmck for NCS board */ + if (delta > 74) { + return delta - 74; + } else { + return 0; + } + } +} + +void benchmark_timer_disable_subtracting_average_overhead( bool find_average_overhead ) +{ + benchmark_timer_find_average_overhead = find_average_overhead; +} |