From 74df15caecf05c9c2007e71b5a185d3c289a6152 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 25 Apr 2018 10:40:40 +0200 Subject: bsp/lpc24xx: Move source files to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libbsp/arm/lpc24xx/Makefile.am | 18 +- c/src/lib/libbsp/arm/lpc24xx/misc/bspidle.c | 39 -- c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c | 194 ------- c/src/lib/libbsp/arm/lpc24xx/misc/dma.c | 102 ---- c/src/lib/libbsp/arm/lpc24xx/misc/io.c | 570 ------------------- c/src/lib/libbsp/arm/lpc24xx/misc/lcd.c | 122 ---- c/src/lib/libbsp/arm/lpc24xx/misc/restart.c | 52 -- c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c | 167 ------ c/src/lib/libbsp/arm/lpc24xx/misc/timer.c | 56 -- c/src/lib/libbsp/arm/lpc24xx/ssp/ssp.c | 652 ---------------------- 10 files changed, 9 insertions(+), 1963 deletions(-) delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/bspidle.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/dma.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/io.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/lcd.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/restart.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/misc/timer.c delete mode 100644 c/src/lib/libbsp/arm/lpc24xx/ssp/ssp.c (limited to 'c/src/lib') diff --git a/c/src/lib/libbsp/arm/lpc24xx/Makefile.am b/c/src/lib/libbsp/arm/lpc24xx/Makefile.am index a87f7b75c2..14d836f5a8 100644 --- a/c/src/lib/libbsp/arm/lpc24xx/Makefile.am +++ b/c/src/lib/libbsp/arm/lpc24xx/Makefile.am @@ -87,17 +87,17 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/rtc/rtc-config.c # Misc -librtemsbsp_a_SOURCES += misc/system-clocks.c -librtemsbsp_a_SOURCES += misc/dma.c -librtemsbsp_a_SOURCES += misc/dma-copy.c -librtemsbsp_a_SOURCES += misc/bspidle.c -librtemsbsp_a_SOURCES += misc/io.c -librtemsbsp_a_SOURCES += misc/lcd.c -librtemsbsp_a_SOURCES += misc/restart.c -librtemsbsp_a_SOURCES += misc/timer.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/system-clocks.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/dma.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/dma-copy.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/bspidle.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/io.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/fb/lcd.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/restart.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/timer.c # SSP -librtemsbsp_a_SOURCES += ssp/ssp.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/spi/ssp.c # I2C librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/i2c/i2c.c diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/bspidle.c b/c/src/lib/libbsp/arm/lpc24xx/misc/bspidle.c deleted file mode 100644 index 42a3e106f3..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/bspidle.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief Idle task. - */ - -/* - * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -void *bsp_idle_thread(uintptr_t ignored) -{ - while (true) { - #ifdef ARM_MULTILIB_ARCH_V4 - /* - * Set power mode to idle. Causes the processor clock to be stopped, - * while on-chip peripherals remain active. Any enabled interrupt from a - * peripheral or an external interrupt source will cause the processor to - * resume execution. - */ - PCON = 0x1; - #endif - } -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c b/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c deleted file mode 100644 index 73a8cdc3ab..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/dma-copy.c +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_dma - * - * @brief Direct memory access (DMA) support. - */ - -/* - * Copyright (c) 2008, 2009 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -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(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 ((tc & GPDMA_STATUS_CH_0) != 0) { - rtems_semaphore_release(lpc24xx_dma_sema_table [0]); - } - lpc24xx_dma_status_table [0] = (err & GPDMA_STATUS_CH_0) == 0; - - /* Check channel 1 */ - if ((tc & GPDMA_STATUS_CH_1) != 0) { - rtems_semaphore_release(lpc24xx_dma_sema_table [1]); - } - lpc24xx_dma_status_table [1] = (err & GPDMA_STATUS_CH_1) == 0; -} - -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/dma.c b/c/src/lib/libbsp/arm/lpc24xx/misc/dma.c deleted file mode 100644 index a67760ad3e..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/dma.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_dma - * - * @brief Direct memory access (DMA) support. - */ - -/* - * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -/** - * @brief Table that indicates if a channel is currently occupied. - */ -static bool lpc24xx_dma_channel_occupation [GPDMA_CH_NUMBER]; - -void lpc24xx_dma_initialize(void) -{ - /* Enable module power */ - lpc24xx_module_enable(LPC24XX_MODULE_GPDMA, LPC24XX_MODULE_PCLK_DEFAULT); - - /* Disable module */ - GPDMA_CONFIG = 0; - - /* Reset registers */ - GPDMA_SOFT_SREQ = 0; - GPDMA_SOFT_BREQ = 0; - GPDMA_SOFT_LSREQ = 0; - GPDMA_SOFT_LBREQ = 0; - GPDMA_SYNC = 0; - GPDMA_CH0_CFG = 0; - GPDMA_CH1_CFG = 0; - - /* Enable module */ - #if BYTE_ORDER == LITTLE_ENDIAN - GPDMA_CONFIG = GPDMA_CONFIG_EN; - #else - GPDMA_CONFIG = GPDMA_CONFIG_EN | GPDMA_CONFIG_MODE; - #endif -} - -rtems_status_code lpc24xx_dma_channel_obtain(unsigned channel) -{ - if (channel < GPDMA_CH_NUMBER) { - rtems_interrupt_level level; - bool occupation = true; - - rtems_interrupt_disable(level); - occupation = lpc24xx_dma_channel_occupation [channel]; - lpc24xx_dma_channel_occupation [channel] = true; - rtems_interrupt_enable(level); - - return occupation ? RTEMS_RESOURCE_IN_USE : RTEMS_SUCCESSFUL; - } else { - return RTEMS_INVALID_ID; - } -} - -void lpc24xx_dma_channel_release(unsigned channel) -{ - if (channel < GPDMA_CH_NUMBER) { - lpc24xx_dma_channel_occupation [channel] = false; - } -} - -void lpc24xx_dma_channel_disable(unsigned channel, bool force) -{ - if (channel < GPDMA_CH_NUMBER) { - volatile lpc24xx_dma_channel *ch = GPDMA_CH_BASE_ADDR(channel); - uint32_t cfg = ch->cfg; - - if (!force) { - /* Halt */ - ch->cfg |= GPDMA_CH_CFG_HALT; - - /* Wait for inactive */ - do { - cfg = ch->cfg; - } while ((cfg & GPDMA_CH_CFG_ACTIVE) != 0); - } - - /* Disable */ - ch->cfg &= ~GPDMA_CH_CFG_EN; - } -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/io.c b/c/src/lib/libbsp/arm/lpc24xx/misc/io.c deleted file mode 100644 index c28b5182f0..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/io.c +++ /dev/null @@ -1,570 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_io - * - * @brief Input and output module. - */ - -/* - * Copyright (c) 2009-2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#define LPC24XX_PIN_SELECT(index) ((index) >> 4U) - -#define LPC24XX_PIN_SELECT_SHIFT(index) (((index) & 0xfU) << 1U) - -#define LPC24XX_PIN_SELECT_MASK 0x3U - -rtems_status_code lpc24xx_gpio_config( - unsigned index, - lpc24xx_gpio_settings settings -) -{ - if (index <= LPC24XX_IO_INDEX_MAX) { - rtems_interrupt_level level; - uint32_t port = LPC24XX_IO_PORT(index); - uint32_t port_bit = LPC24XX_IO_PORT_BIT(index); - uint32_t output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U; - uint32_t resistor = settings & 0x3U; - #ifdef ARM_MULTILIB_ARCH_V4 - uint32_t select = LPC24XX_PIN_SELECT(index); - uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index); - - /* Get resistor flags */ - switch (resistor) { - case LPC24XX_GPIO_RESISTOR_PULL_UP: - resistor = 0x0U; - break; - case LPC24XX_GPIO_RESISTOR_NONE: - resistor = 0x2U; - break; - case LPC24XX_GPIO_RESISTOR_PULL_DOWN: - resistor = 0x3U; - break; - default: - return RTEMS_INVALID_NUMBER; - } - #else - uint32_t iocon_mask = IOCON_HYS | IOCON_INV - | IOCON_SLEW | IOCON_OD | IOCON_FILTER; - uint32_t iocon = (settings & iocon_mask) | IOCON_ADMODE; - uint32_t iocon_invalid = settings & ~(iocon_mask | LPC24XX_GPIO_OUTPUT); - - /* Get resistor flags */ - switch (resistor) { - case LPC24XX_GPIO_RESISTOR_NONE: - resistor = IOCON_MODE(0); - break; - case LPC24XX_GPIO_RESISTOR_PULL_DOWN: - resistor = IOCON_MODE(1); - break; - case LPC24XX_GPIO_RESISTOR_PULL_UP: - resistor = IOCON_MODE(2); - break; - case LPC17XX_GPIO_HYSTERESIS: - resistor = IOCON_MODE(3); - break; - } - iocon |= resistor; - - if (iocon_invalid != 0) { - return RTEMS_INVALID_NUMBER; - } - - if (output && (settings & LPC17XX_GPIO_INPUT_INVERT) != 0) { - return RTEMS_INVALID_NUMBER; - } - - if ((settings & LPC17XX_GPIO_INPUT_FILTER) == 0) { - iocon |= IOCON_FILTER; - } else { - iocon &= ~IOCON_FILTER; - } - #endif - - rtems_interrupt_disable(level); - - #ifdef ARM_MULTILIB_ARCH_V4 - /* Resistor */ - LPC24XX_PINMODE [select] = - (LPC24XX_PINMODE [select] & ~(LPC24XX_PIN_SELECT_MASK << shift)) - | ((resistor & LPC24XX_PIN_SELECT_MASK) << shift); - #else - LPC17XX_IOCON [index] = iocon; - #endif - - rtems_interrupt_flash(level); - - /* Input or output */ - LPC24XX_FIO [port].dir = - (LPC24XX_FIO [port].dir & ~(1U << port_bit)) | (output << port_bit); - - rtems_interrupt_enable(level); - } else { - return RTEMS_INVALID_ID; - } - - return RTEMS_SUCCESSFUL; -} - -#define LPC24XX_MODULE_ENTRY(mod, pwr, clk, idx) \ - [mod] = { \ - .power = pwr, \ - .clock = clk, \ - .index = idx \ - } - -typedef struct { - unsigned char power : 1; - unsigned char clock : 1; - unsigned char index : 6; -} lpc24xx_module_entry; - -static const lpc24xx_module_entry lpc24xx_module_table [] = { - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ACF, 0, 1, 15), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ADC, 1, 1, 12), - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_BAT_RAM, 0, 1, 16), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_CAN_0, 1, 1, 13), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_CAN_1, 1, 1, 14), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_DAC, 0, 1, 11), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_EMC, 1, 0, 11), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_ETHERNET, 1, 0, 30), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPDMA, 1, 1, 29), - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPIO, 0, 1, 17), - #else - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_GPIO, 0, 1, 15), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_0, 1, 1, 7), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_1, 1, 1, 19), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2C_2, 1, 1, 26), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_I2S, 1, 1, 27), - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_LCD, 1, 0, 20), - #else - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_LCD, 1, 0, 0), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_MCI, 1, 1, 28), - #ifdef ARM_MULTILIB_ARCH_V7M - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_MCPWM, 1, 1, 17), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PCB, 0, 1, 18), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PWM_0, 1, 1, 5), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_PWM_1, 1, 1, 6), - #ifdef ARM_MULTILIB_ARCH_V7M - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_QEI, 1, 1, 18), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_RTC, 1, 1, 9), - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SPI, 1, 1, 8), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_0, 1, 1, 21), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_1, 1, 1, 10), - #ifdef ARM_MULTILIB_ARCH_V7M - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SSP_2, 1, 1, 20), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_SYSCON, 0, 1, 30), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_0, 1, 1, 1), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_1, 1, 1, 2), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_2, 1, 1, 22), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_TIMER_3, 1, 1, 23), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_0, 1, 1, 3), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_1, 1, 1, 4), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_2, 1, 1, 24), - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_3, 1, 1, 25), - #ifdef ARM_MULTILIB_ARCH_V7M - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_UART_4, 1, 1, 8), - #endif - #ifdef ARM_MULTILIB_ARCH_V4 - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_WDT, 0, 1, 0), - #endif - LPC24XX_MODULE_ENTRY(LPC24XX_MODULE_USB, 1, 0, 31) -}; - -static rtems_status_code lpc24xx_module_do_enable( - lpc24xx_module module, - lpc24xx_module_clock clock, - bool enable -) -{ - rtems_interrupt_level level; - bool has_power = false; - bool has_clock = false; - unsigned index = 0; - #ifdef ARM_MULTILIB_ARCH_V7M - volatile lpc17xx_scb *scb = &LPC17XX_SCB; - #endif - - if ((unsigned) module >= LPC24XX_MODULE_COUNT) { - return RTEMS_INVALID_ID; - } - - #ifdef ARM_MULTILIB_ARCH_V4 - if (clock == LPC24XX_MODULE_PCLK_DEFAULT) { - #if LPC24XX_PCLKDIV == 1U - clock = LPC24XX_MODULE_CCLK; - #elif LPC24XX_PCLKDIV == 2U - clock = LPC24XX_MODULE_CCLK_2; - #elif LPC24XX_PCLKDIV == 4U - clock = LPC24XX_MODULE_CCLK_4; - #elif LPC24XX_PCLKDIV == 8U - clock = LPC24XX_MODULE_CCLK_8; - #endif - } - - if ((clock & ~LPC24XX_MODULE_CLOCK_MASK) != 0U) { - return RTEMS_INVALID_CLOCK; - } - #else - if (clock != LPC24XX_MODULE_PCLK_DEFAULT) { - return RTEMS_INVALID_CLOCK; - } - #endif - - has_power = lpc24xx_module_table [module].power; - has_clock = lpc24xx_module_table [module].clock; - index = lpc24xx_module_table [module].index; - - /* Enable or disable module */ - if (enable) { - if (has_power) { - rtems_interrupt_disable(level); - #ifdef ARM_MULTILIB_ARCH_V4 - PCONP |= 1U << index; - #else - scb->pconp |= 1U << index; - #endif - rtems_interrupt_enable(level); - } - - if (module != LPC24XX_MODULE_USB) { - if (has_clock) { - #ifdef ARM_MULTILIB_ARCH_V4 - unsigned clock_shift = 2U * index; - - rtems_interrupt_disable(level); - if (clock_shift < 32U) { - PCLKSEL0 = (PCLKSEL0 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift)) - | (clock << clock_shift); - } else { - clock_shift -= 32U; - PCLKSEL1 = (PCLKSEL1 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift)) - | (clock << clock_shift); - } - rtems_interrupt_enable(level); - #endif - } - } else { - #ifdef ARM_MULTILIB_ARCH_V4 - unsigned pllclk = lpc24xx_pllclk(); - unsigned usbsel = pllclk / 48000000U - 1U; - - if ( - usbsel > 15U - || (usbsel % 2U != 1U) - || (pllclk % 48000000U) != 0U - ) { - return RTEMS_INCORRECT_STATE; - } - - USBCLKCFG = usbsel; - #else - uint32_t pllclk = lpc24xx_pllclk(); - uint32_t usbclk = 48000000U; - - if (pllclk % usbclk == 0U) { - uint32_t usbdiv = pllclk / usbclk; - - scb->usbclksel = LPC17XX_SCB_USBCLKSEL_USBDIV(usbdiv) - | LPC17XX_SCB_USBCLKSEL_USBSEL(1); - } else { - return RTEMS_INCORRECT_STATE; - } - #endif - } - } else { - if (has_power) { - rtems_interrupt_disable(level); - #ifdef ARM_MULTILIB_ARCH_V4 - PCONP &= ~(1U << index); - #else - scb->pconp &= ~(1U << index); - #endif - rtems_interrupt_enable(level); - } - } - - return RTEMS_SUCCESSFUL; -} - -rtems_status_code lpc24xx_module_enable( - lpc24xx_module module, - lpc24xx_module_clock clock -) -{ - return lpc24xx_module_do_enable(module, clock, true); -} - -rtems_status_code lpc24xx_module_disable( - lpc24xx_module module -) -{ - return lpc24xx_module_do_enable( - module, - LPC24XX_MODULE_PCLK_DEFAULT, - false - ); -} - -bool lpc24xx_module_is_enabled(lpc24xx_module module) -{ - bool enabled = false; - - if ((unsigned) module < LPC24XX_MODULE_COUNT) { - bool has_power = lpc24xx_module_table [module].power; - - if (has_power) { - unsigned index = lpc24xx_module_table [module].index; - #ifdef ARM_MULTILIB_ARCH_V4 - uint32_t pconp = PCONP; - #else - uint32_t pconp = LPC17XX_SCB.pconp; - #endif - - enabled = (pconp & (1U << index)) != 0; - } else { - enabled = true; - } - } - - return enabled; -} - -typedef rtems_status_code (*lpc24xx_pin_visitor)( - #ifdef ARM_MULTILIB_ARCH_V4 - volatile uint32_t *pinsel, - uint32_t pinsel_mask, - uint32_t pinsel_value, - #else - volatile uint32_t *iocon, - lpc24xx_pin_range pin_range, - #endif - volatile uint32_t *fio_dir, - uint32_t fio_bit -); - -static BSP_START_TEXT_SECTION __attribute__((flatten)) rtems_status_code -lpc24xx_pin_set_function( - #ifdef ARM_MULTILIB_ARCH_V4 - volatile uint32_t *pinsel, - uint32_t pinsel_mask, - uint32_t pinsel_value, - #else - volatile uint32_t *iocon, - lpc24xx_pin_range pin_range, - #endif - volatile uint32_t *fio_dir, - uint32_t fio_bit -) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - *pinsel = (*pinsel & ~pinsel_mask) | pinsel_value; - rtems_interrupt_enable(level); - #else - uint32_t iocon_extra = 0; - uint32_t iocon_not_analog = IOCON_ADMODE; - - /* TODO */ - switch (pin_range.fields.type) { - case LPC17XX_PIN_TYPE_ADC: - case LPC17XX_PIN_TYPE_DAC: - iocon_not_analog = 0; - break; - case LPC17XX_PIN_TYPE_I2C_FAST_PLUS: - iocon_extra |= IOCON_HS; - break; - case LPC17XX_PIN_TYPE_OPEN_DRAIN: - iocon_extra |= IOCON_OD; - break; - default: - break; - } - - *iocon = IOCON_FUNC(pin_range.fields.function) | iocon_extra | iocon_not_analog; - #endif - - return RTEMS_SUCCESSFUL; -} - -static BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_check_function( - #ifdef ARM_MULTILIB_ARCH_V4 - volatile uint32_t *pinsel, - uint32_t pinsel_mask, - uint32_t pinsel_value, - #else - volatile uint32_t *iocon, - lpc24xx_pin_range pin_range, - #endif - volatile uint32_t *fio_dir, - uint32_t fio_bit -) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - if ((*pinsel & pinsel_mask) == pinsel_value) { - return RTEMS_SUCCESSFUL; - } else { - return RTEMS_IO_ERROR; - } - #else - /* TODO */ - return RTEMS_IO_ERROR; - #endif -} - -static BSP_START_TEXT_SECTION __attribute__((flatten)) rtems_status_code -lpc24xx_pin_set_input( - #ifdef ARM_MULTILIB_ARCH_V4 - volatile uint32_t *pinsel, - uint32_t pinsel_mask, - uint32_t pinsel_value, - #else - volatile uint32_t *iocon, - lpc24xx_pin_range pin_range, - #endif - volatile uint32_t *fio_dir, - uint32_t fio_bit -) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - *fio_dir &= ~fio_bit; - #ifdef ARM_MULTILIB_ARCH_V4 - *pinsel &= ~pinsel_mask; - #else - *iocon = IOCON_MODE(2) | IOCON_ADMODE | IOCON_FILTER; - #endif - rtems_interrupt_enable(level); - - return RTEMS_SUCCESSFUL; -} - -static BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_check_input( - #ifdef ARM_MULTILIB_ARCH_V4 - volatile uint32_t *pinsel, - uint32_t pinsel_mask, - uint32_t pinsel_value, - #else - volatile uint32_t *iocon, - lpc24xx_pin_range pin_range, - #endif - volatile uint32_t *fio_dir, - uint32_t fio_bit -) -{ - rtems_status_code sc = RTEMS_IO_ERROR; - bool is_input = (*fio_dir & fio_bit) == 0; - - if (is_input) { - #ifdef ARM_MULTILIB_ARCH_V4 - bool is_gpio = (*pinsel & pinsel_mask) == 0; - #else - bool is_gpio = IOCON_FUNC_GET(*iocon) == 0; - #endif - - if (is_gpio) { - sc = RTEMS_SUCCESSFUL; - } - } - - return sc; -} - -static BSP_START_DATA_SECTION const lpc24xx_pin_visitor - lpc24xx_pin_visitors [] = { - [LPC24XX_PIN_SET_FUNCTION] = lpc24xx_pin_set_function, - [LPC24XX_PIN_CHECK_FUNCTION] = lpc24xx_pin_check_function, - [LPC24XX_PIN_SET_INPUT] = lpc24xx_pin_set_input, - [LPC24XX_PIN_CHECK_INPUT] = lpc24xx_pin_check_input -}; - -BSP_START_TEXT_SECTION rtems_status_code lpc24xx_pin_config( - const lpc24xx_pin_range *pins, - lpc24xx_pin_action action -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - - if ((unsigned) action <= LPC24XX_PIN_CHECK_INPUT) { - lpc24xx_pin_visitor visitor = lpc24xx_pin_visitors [action]; - lpc24xx_pin_range terminal = LPC24XX_PIN_TERMINAL; - lpc24xx_pin_range pin_range = *pins; - uint32_t previous_port_bit = pin_range.fields.port_bit; - - while (sc == RTEMS_SUCCESSFUL && pin_range.value != terminal.value) { - uint32_t port = pin_range.fields.port; - uint32_t port_bit = pin_range.fields.port_bit; - uint32_t port_bit_last = port_bit; - uint32_t range = pin_range.fields.range; - #ifdef ARM_MULTILIB_ARCH_V4 - uint32_t function = pin_range.fields.function; - #endif - volatile uint32_t *fio_dir = &LPC24XX_FIO [port].dir; - - if (range) { - port_bit = previous_port_bit; - } - - while (sc == RTEMS_SUCCESSFUL && port_bit <= port_bit_last) { - uint32_t index = LPC24XX_IO_INDEX_BY_PORT(port, port_bit); - uint32_t fio_bit = 1U << port_bit; - #ifdef ARM_MULTILIB_ARCH_V4 - uint32_t select = LPC24XX_PIN_SELECT(index); - uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index); - volatile uint32_t *pinsel = &LPC24XX_PINSEL [select]; - uint32_t pinsel_mask = LPC24XX_PIN_SELECT_MASK << shift; - uint32_t pinsel_value = (function & LPC24XX_PIN_SELECT_MASK) << shift; - - sc = (*visitor)(pinsel, pinsel_mask, pinsel_value, fio_dir, fio_bit); - #else - volatile uint32_t *iocon = &LPC17XX_IOCON [index]; - - sc = (*visitor)(iocon, pin_range, fio_dir, fio_bit); - #endif - - ++port_bit; - } - - ++pins; - previous_port_bit = port_bit; - pin_range = *pins; - } - } else { - sc = RTEMS_NOT_DEFINED; - } - - return sc; -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/lcd.c b/c/src/lib/libbsp/arm/lpc24xx/misc/lcd.c deleted file mode 100644 index 9474eec18a..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/lcd.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_lcd - * - * @brief LCD support. - */ - -/* - * Copyright (c) 2010-2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include -#include - -#ifdef ARM_MULTILIB_ARCH_V4 - #define LCD_ENABLE BSP_BIT32(0) -#endif - -rtems_status_code lpc24xx_lcd_set_mode( - lpc24xx_lcd_mode mode, - const lpc24xx_pin_range *pins -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - bool enable = false; - - switch (mode) { - case LCD_MODE_STN_4_BIT: - case LCD_MODE_STN_8_BIT: - case LCD_MODE_STN_DUAL_PANEL_4_BIT: - case LCD_MODE_STN_DUAL_PANEL_8_BIT: - case LCD_MODE_TFT_12_BIT_4_4_4: - case LCD_MODE_TFT_16_BIT_5_6_5: - case LCD_MODE_TFT_16_BIT_1_5_5_5: - case LCD_MODE_TFT_24_BIT: - enable = true; - break; - case LCD_MODE_DISABLED: - enable = false; - break; - default: - sc = RTEMS_IO_ERROR; - break; - } - - if (sc == RTEMS_SUCCESSFUL) { - if (enable) { - sc = lpc24xx_module_enable(LPC24XX_MODULE_LCD, LPC24XX_MODULE_PCLK_DEFAULT); - assert(sc == RTEMS_SUCCESSFUL); - - #ifdef ARM_MULTILIB_ARCH_V4 - PINSEL11 = BSP_FLD32(mode, 1, 3) | LCD_ENABLE; - #endif - - sc = lpc24xx_pin_config(pins, LPC24XX_PIN_SET_FUNCTION); - assert(sc == RTEMS_SUCCESSFUL); - } else { - if (lpc24xx_lcd_current_mode() != LCD_MODE_DISABLED) { - uint32_t lcd_ctrl = LCD_CTRL; - - /* Disable power */ - lcd_ctrl &= ~BSP_BIT32(11); - LCD_CTRL = lcd_ctrl; - - lpc24xx_micro_seconds_delay(100000); - - /* Disable all signals */ - lcd_ctrl &= ~BSP_BIT32(0); - LCD_CTRL = lcd_ctrl; - } - - sc = lpc24xx_pin_config(pins, LPC24XX_PIN_SET_INPUT); - assert(sc == RTEMS_SUCCESSFUL); - - #ifdef ARM_MULTILIB_ARCH_V4 - PINSEL11 = 0; - #endif - - sc = lpc24xx_module_disable(LPC24XX_MODULE_LCD); - assert(sc == RTEMS_SUCCESSFUL); - } - } - - return sc; -} - -lpc24xx_lcd_mode lpc24xx_lcd_current_mode(void) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - uint32_t pinsel11 = PINSEL11; - - if ((PCONP & BSP_BIT32(20)) != 0 && (pinsel11 & LCD_ENABLE) != 0) { - return BSP_FLD32GET(pinsel11, 1, 3); - } else { - return LCD_MODE_DISABLED; - } - #else - volatile lpc17xx_scb *scb = &LPC17XX_SCB; - - if ((scb->pconp & LPC17XX_SCB_PCONP_LCD) != 0) { - return LCD_CTRL & 0xae; - } else { - return LCD_MODE_DISABLED; - } - #endif -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/restart.c b/c/src/lib/libbsp/arm/lpc24xx/misc/restart.c deleted file mode 100644 index 627f79d19d..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/restart.c +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief Restart implementation. - */ - -/* - * Copyright (c) 2011-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -void bsp_restart(void *addr) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - ARM_SWITCH_REGISTERS; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - (void) level; - - asm volatile ( - ARM_SWITCH_TO_ARM - "mov pc, %[addr]\n" - ARM_SWITCH_BACK - : ARM_SWITCH_OUTPUT - : [addr] "r" (addr) - ); - #else - rtems_interrupt_level level; - void (*start)(void) = addr; - - rtems_interrupt_disable(level); - (void) level; - - (*start)(); - #endif -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c b/c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c deleted file mode 100644 index f64fca1bed..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_clocks - * - * @brief System clocks. - */ - -/* - * Copyright (c) 2008-2014 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include - -/** - * @brief Internal RC oscillator frequency in [Hz]. - */ -#define LPC24XX_OSCILLATOR_INTERNAL 4000000U - -#ifndef LPC24XX_OSCILLATOR_MAIN - #error "unknown main oscillator frequency" -#endif - -#ifndef LPC24XX_OSCILLATOR_RTC - #error "unknown RTC oscillator frequency" -#endif - -void lpc24xx_timer_initialize(void) -{ - /* Reset timer */ - T1TCR = TCR_RST; - - /* Set timer mode */ - T1CTCR = 0; - - /* Set prescaler to zero */ - T1PR = 0; - - /* Reset all interrupt flags */ - T1IR = 0xff; - - /* Do not stop on a match */ - T1MCR = 0; - - /* No captures */ - T1CCR = 0; - - /* Start timer */ - T1TCR = TCR_EN; - - rtems_counter_initialize_converter(LPC24XX_PCLK); -} - -CPU_Counter_ticks _CPU_Counter_read(void) -{ - return lpc24xx_timer(); -} - -void lpc24xx_micro_seconds_delay(unsigned us) -{ - unsigned start = lpc24xx_timer(); - unsigned delay = us * (LPC24XX_PCLK / 1000000); - unsigned elapsed = 0; - - do { - elapsed = lpc24xx_timer() - start; - } while (elapsed < delay); -} - -#ifdef ARM_MULTILIB_ARCH_V7M - static unsigned lpc17xx_sysclk(unsigned clksrcsel) - { - return (clksrcsel & LPC17XX_SCB_CLKSRCSEL_CLKSRC) != 0 ? - LPC24XX_OSCILLATOR_MAIN - : LPC24XX_OSCILLATOR_INTERNAL; - } -#endif - -unsigned lpc24xx_pllclk(void) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - unsigned clksrc = GET_CLKSRCSEL_CLKSRC(CLKSRCSEL); - unsigned pllinclk = 0; - unsigned pllclk = 0; - - /* Get PLL input frequency */ - switch (clksrc) { - case 0: - pllinclk = LPC24XX_OSCILLATOR_INTERNAL; - break; - case 1: - pllinclk = LPC24XX_OSCILLATOR_MAIN; - break; - case 2: - pllinclk = LPC24XX_OSCILLATOR_RTC; - break; - default: - return 0; - } - - /* Get PLL output frequency */ - if ((PLLSTAT & PLLSTAT_PLLC) != 0) { - uint32_t pllcfg = PLLCFG; - unsigned n = GET_PLLCFG_NSEL(pllcfg) + 1; - unsigned m = GET_PLLCFG_MSEL(pllcfg) + 1; - - pllclk = (pllinclk / n) * 2 * m; - } else { - pllclk = pllinclk; - } - #else - volatile lpc17xx_scb *scb = &LPC17XX_SCB; - unsigned sysclk = lpc17xx_sysclk(scb->clksrcsel); - unsigned pllstat = scb->pll_0.stat; - unsigned pllclk = 0; - unsigned enabled_and_locked = LPC17XX_PLL_STAT_PLLE - | LPC17XX_PLL_STAT_PLOCK; - - if ((pllstat & enabled_and_locked) == enabled_and_locked) { - unsigned m = LPC17XX_PLL_SEL_MSEL_GET(pllstat) + 1; - - pllclk = sysclk * m; - } - #endif - - return pllclk; -} - -unsigned lpc24xx_cclk(void) -{ - #ifdef ARM_MULTILIB_ARCH_V4 - /* Get PLL output frequency */ - unsigned pllclk = lpc24xx_pllclk(); - - /* Get CPU frequency */ - unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL(CCLKCFG) + 1); - #else - volatile lpc17xx_scb *scb = &LPC17XX_SCB; - unsigned cclksel = scb->cclksel; - unsigned cclk_in = 0; - unsigned cclk = 0; - - if ((cclksel & LPC17XX_SCB_CCLKSEL_CCLKSEL) != 0) { - cclk_in = lpc24xx_pllclk(); - } else { - cclk_in = lpc17xx_sysclk(scb->clksrcsel); - } - - cclk = cclk_in / LPC17XX_SCB_CCLKSEL_CCLKDIV_GET(cclksel); - #endif - - return cclk; -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c b/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c deleted file mode 100644 index c700d04566..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/misc/timer.c +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx - * - * @brief Benchmark timer support. - */ - -/* - * Copyright (c) 2008, 2009 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include - -bool benchmark_timer_find_average_overhead = false; - -static uint32_t benchmark_timer_base; - -void benchmark_timer_initialize(void) -{ - benchmark_timer_base = lpc24xx_timer(); -} - -benchmark_timer_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; -} diff --git a/c/src/lib/libbsp/arm/lpc24xx/ssp/ssp.c b/c/src/lib/libbsp/arm/lpc24xx/ssp/ssp.c deleted file mode 100644 index 6563d047b2..0000000000 --- a/c/src/lib/libbsp/arm/lpc24xx/ssp/ssp.c +++ /dev/null @@ -1,652 +0,0 @@ -/** - * @file - * - * @ingroup lpc24xx_libi2c - * - * @brief LibI2C bus driver for the Synchronous Serial Port (SSP). - */ - -/* - * Copyright (c) 2008 - * 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.org/license/LICENSE. - */ - -#include - -#include -#include -#include -#include -#include -#include - -#define RTEMS_STATUS_CHECKS_USE_PRINTK - -#include - -#define LPC24XX_SSP_NUMBER 2 - -#define LPC24XX_SSP_FIFO_SIZE 8 - -#define LPC24XX_SSP_BAUD_RATE 2000000 - -typedef enum { - LPC24XX_SSP_DMA_INVALID = 0, - LPC24XX_SSP_DMA_AVAILABLE = 1, - LPC24XX_SSP_DMA_NOT_INITIALIZED = 2, - LPC24XX_SSP_DMA_INITIALIZATION = 3, - LPC24XX_SSP_DMA_TRANSFER_FLAG = 0x80000000U, - LPC24XX_SSP_DMA_WAIT = 1 | LPC24XX_SSP_DMA_TRANSFER_FLAG, - LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_0 = 2 | LPC24XX_SSP_DMA_TRANSFER_FLAG, - LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_1 = 3 | LPC24XX_SSP_DMA_TRANSFER_FLAG, - LPC24XX_SSP_DMA_ERROR = 4 | LPC24XX_SSP_DMA_TRANSFER_FLAG, - LPC24XX_SSP_DMA_DONE = 5 | LPC24XX_SSP_DMA_TRANSFER_FLAG -} lpc24xx_ssp_dma_status; - -typedef struct { - rtems_libi2c_bus_t bus; - volatile lpc24xx_ssp *regs; - unsigned clock; - uint32_t idle_char; -} lpc24xx_ssp_bus_entry; - -typedef struct { - lpc24xx_ssp_dma_status status; - lpc24xx_ssp_bus_entry *bus; - rtems_libi2c_read_write_done_t done; - int n; - void *arg; -} lpc24xx_ssp_dma_entry; - -static lpc24xx_ssp_dma_entry lpc24xx_ssp_dma_data = { - .status = LPC24XX_SSP_DMA_NOT_INITIALIZED, - .bus = NULL, - .done = NULL, - .n = 0, - .arg = NULL -}; - -static uint32_t lpc24xx_ssp_trash = 0; - -static inline bool lpc24xx_ssp_is_busy(const lpc24xx_ssp_bus_entry *bus) -{ - return lpc24xx_ssp_dma_data.bus == bus - && lpc24xx_ssp_dma_data.status != LPC24XX_SSP_DMA_AVAILABLE; -} - -static void lpc24xx_ssp_handler(void *arg) -{ - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) arg; - volatile lpc24xx_ssp *regs = e->regs; - uint32_t mis = regs->mis; - uint32_t icr = 0; - - if ((mis & SSP_MIS_RORRIS) != 0) { - /* TODO */ - icr |= SSP_ICR_RORRIS; - } - - regs->icr = icr; -} - -static void lpc24xx_ssp_dma_handler(void *arg) -{ - lpc24xx_ssp_dma_entry *e = (lpc24xx_ssp_dma_entry *) arg; - lpc24xx_ssp_dma_status status = e->status; - uint32_t tc = 0; - uint32_t err = 0; - int rv = 0; - - /* Return if we are not in a transfer status */ - if ((status & LPC24XX_SSP_DMA_TRANSFER_FLAG) == 0) { - return; - } - - /* Get interrupt status */ - tc = GPDMA_INT_TCSTAT; - err = GPDMA_INT_ERR_STAT; - - /* Clear interrupt status */ - GPDMA_INT_TCCLR = tc; - GPDMA_INT_ERR_CLR = err; - - /* Change status */ - if (err == 0) { - switch (status) { - case LPC24XX_SSP_DMA_WAIT: - if ((tc & (GPDMA_STATUS_CH_0 | GPDMA_STATUS_CH_1)) != 0) { - status = LPC24XX_SSP_DMA_DONE; - } else if ((tc & GPDMA_STATUS_CH_0) != 0) { - status = LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_1; - } else if ((tc & GPDMA_STATUS_CH_1) != 0) { - status = LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_0; - } - break; - case LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_0: - if ((tc & GPDMA_STATUS_CH_1) != 0) { - status = LPC24XX_SSP_DMA_ERROR; - } else if ((tc & GPDMA_STATUS_CH_0) != 0) { - status = LPC24XX_SSP_DMA_DONE; - } - break; - case LPC24XX_SSP_DMA_WAIT_FOR_CHANNEL_1: - if ((tc & GPDMA_STATUS_CH_0) != 0) { - status = LPC24XX_SSP_DMA_ERROR; - } else if ((tc & GPDMA_STATUS_CH_1) != 0) { - status = LPC24XX_SSP_DMA_DONE; - } - break; - default: - status = LPC24XX_SSP_DMA_ERROR; - break; - } - } else { - status = LPC24XX_SSP_DMA_ERROR; - } - - /* Error cleanup */ - if (status == LPC24XX_SSP_DMA_ERROR) { - lpc24xx_dma_channel_disable(0, true); - lpc24xx_dma_channel_disable(1, true); - status = LPC24XX_SSP_DMA_DONE; - rv = -RTEMS_IO_ERROR; - } - - /* Done */ - if (status == LPC24XX_SSP_DMA_DONE) { - status = LPC24XX_SSP_DMA_AVAILABLE; - if (e->done != NULL) { - e->done(rv, e->n, e->arg); - e->done = NULL; - } - } - - /* Set status */ - e->status = status; -} - -static rtems_status_code lpc24xx_ssp_init(rtems_libi2c_bus_t *bus) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_interrupt_level level; - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - volatile lpc24xx_ssp *regs = e->regs; - unsigned pclk = lpc24xx_cclk(); - unsigned pre = - ((pclk + LPC24XX_SSP_BAUD_RATE - 1) / LPC24XX_SSP_BAUD_RATE + 1) & ~1U; - lpc24xx_module module = LPC24XX_MODULE_SSP_0; - rtems_vector_number vector = UINT32_MAX; - - if (lpc24xx_ssp_dma_data.status == LPC24XX_SSP_DMA_NOT_INITIALIZED) { - lpc24xx_ssp_dma_status status = LPC24XX_SSP_DMA_INVALID; - - /* Test and set DMA support status */ - rtems_interrupt_disable(level); - status = lpc24xx_ssp_dma_data.status; - if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) { - lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_INITIALIZATION; - } - rtems_interrupt_enable(level); - - if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) { - /* Install DMA interrupt handler */ - sc = rtems_interrupt_handler_install( - LPC24XX_IRQ_DMA, - "SSP DMA", - RTEMS_INTERRUPT_SHARED, - lpc24xx_ssp_dma_handler, - &lpc24xx_ssp_dma_data - ); - RTEMS_CHECK_SC(sc, "install DMA interrupt handler"); - - /* Set DMA support status */ - lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_AVAILABLE; - } - } - - /* Disable module */ - regs->cr1 = 0; - - switch ((uintptr_t) regs) { - case SSP0_BASE_ADDR: - module = LPC24XX_MODULE_SSP_0; - vector = LPC24XX_IRQ_SPI_SSP_0; - break; - case SSP1_BASE_ADDR: - module = LPC24XX_MODULE_SSP_1; - vector = LPC24XX_IRQ_SSP_1; - break; - default: - return RTEMS_IO_ERROR; - } - - /* Set clock select */ - sc = lpc24xx_module_enable(module, LPC24XX_MODULE_PCLK_DEFAULT); - RTEMS_CHECK_SC(sc, "enable module clock"); - - /* Set serial clock rate to save value */ - regs->cr0 = SET_SSP_CR0_SCR(0, 255); - - /* Set clock prescaler */ - if (pre > 254) { - pre = 254; - } else if (pre < 2) { - pre = 2; - } - regs->cpsr = pre; - - /* Save clock value */ - e->clock = pclk / pre; - - /* Enable module and loop back mode */ - regs->cr1 = SSP_CR1_LBM | SSP_CR1_SSE; - - /* Install interrupt handler */ - sc = rtems_interrupt_handler_install( - vector, - "SSP", - RTEMS_INTERRUPT_UNIQUE, - lpc24xx_ssp_handler, - e - ); - RTEMS_CHECK_SC(sc, "install interrupt handler"); - - /* Enable receiver overrun interrupts */ - e->regs->imsc = SSP_IMSC_RORIM; - - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code lpc24xx_ssp_send_start(rtems_libi2c_bus_t *bus) -{ - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code lpc24xx_ssp_send_stop(rtems_libi2c_bus_t *bus) -{ - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - - /* Release DMA support */ - if (lpc24xx_ssp_dma_data.bus == e) { - if (lpc24xx_ssp_dma_data.status == LPC24XX_SSP_DMA_AVAILABLE) { - lpc24xx_dma_channel_release(0); - lpc24xx_dma_channel_release(1); - lpc24xx_ssp_dma_data.bus = NULL; - } else { - return RTEMS_RESOURCE_IN_USE; - } - } - - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code lpc24xx_ssp_send_addr( - rtems_libi2c_bus_t *bus, - uint32_t addr, - int rw -) -{ - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - - if (lpc24xx_ssp_is_busy(e)) { - return RTEMS_RESOURCE_IN_USE; - } - - return RTEMS_SUCCESSFUL; -} - -static int lpc24xx_ssp_set_transfer_mode( - rtems_libi2c_bus_t *bus, - const rtems_libi2c_tfr_mode_t *mode -) -{ - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - volatile lpc24xx_ssp *regs = e->regs; - unsigned clk = e->clock; - unsigned br = mode->baudrate; - unsigned scr = (clk + br - 1) / br; - - if (lpc24xx_ssp_is_busy(e)) { - return -RTEMS_RESOURCE_IN_USE; - } - - if (mode->bits_per_char != 8) { - return -RTEMS_INVALID_NUMBER; - } - - if (mode->lsb_first) { - return -RTEMS_INVALID_NUMBER; - } - - if (br == 0) { - return -RTEMS_INVALID_NUMBER; - } - - /* Compute new prescaler if necessary */ - if (scr > 256 || scr < 1) { - unsigned pre = regs->cpsr; - unsigned pclk = clk * pre; - - while (scr > 256) { - if (pre > 252) { - return -RTEMS_INVALID_NUMBER; - } - pre += 2; - clk = pclk / pre; - scr = (clk + br - 1) / br; - } - - while (scr < 1) { - if (pre < 4) { - return -RTEMS_INVALID_NUMBER; - } - pre -= 2; - clk = pclk / pre; - scr = (clk + br - 1) / br; - } - - regs->cpsr = pre; - e->clock = clk; - } - - /* Adjust SCR */ - --scr; - - e->idle_char = mode->idle_char; - - while ((regs->sr & SSP_SR_TFE) == 0) { - /* Wait */ - } - - regs->cr0 = SET_SSP_CR0_DSS(0, 0x7) - | SET_SSP_CR0_SCR(0, scr) - | (mode->clock_inv ? SSP_CR0_CPOL : 0) - | (mode->clock_phs ? SSP_CR0_CPHA : 0); - - return 0; -} - -static int lpc24xx_ssp_read_write( - rtems_libi2c_bus_t *bus, - unsigned char *in, - const unsigned char *out, - int n -) -{ - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - volatile lpc24xx_ssp *regs = e->regs; - int r = 0; - int w = 0; - int dr = 1; - int dw = 1; - int m = 0; - uint32_t sr = regs->sr; - unsigned char trash = 0; - unsigned char idle_char = (unsigned char) e->idle_char; - - if (lpc24xx_ssp_is_busy(e)) { - return -RTEMS_RESOURCE_IN_USE; - } - - if (n < 0) { - return -RTEMS_INVALID_SIZE; - } - - /* Disable DMA on SSP */ - regs->dmacr = 0; - - if (in == NULL) { - dr = 0; - in = &trash; - } - - if (out == NULL) { - dw = 0; - out = &idle_char; - } - - /* - * Assumption: The transmit and receive FIFOs are empty. If this assumption - * is not true an input buffer overflow may occur or we may never exit the - * loop due to data loss. This is only possible if entities external to this - * driver operate on the SSP. - */ - - while (w < n) { - /* FIFO capacity */ - m = w - r; - - /* Write */ - if ((sr & SSP_SR_TNF) != 0 && m < LPC24XX_SSP_FIFO_SIZE) { - regs->dr = *out; - ++w; - out += dw; - } - - /* Read */ - if ((sr & SSP_SR_RNE) != 0) { - *in = (unsigned char) regs->dr; - ++r; - in += dr; - } - - /* New status */ - sr = regs->sr; - } - - /* Read outstanding input */ - while (r < n) { - /* Wait */ - do { - sr = regs->sr; - } while ((sr & SSP_SR_RNE) == 0); - - /* Read */ - *in = (unsigned char) regs->dr; - ++r; - in += dr; - } - - return n; -} - -static int lpc24xx_ssp_read_write_async( - rtems_libi2c_bus_t *bus, - unsigned char *in, - const unsigned char *out, - int n, - rtems_libi2c_read_write_done_t done, - void *arg -) -{ - rtems_interrupt_level level; - lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus; - volatile lpc24xx_ssp *ssp = e->regs; - volatile lpc24xx_dma_channel *receive_channel = GPDMA_CH_BASE_ADDR(0); - volatile lpc24xx_dma_channel *transmit_channel = GPDMA_CH_BASE_ADDR(1); - uint32_t di = GPDMA_CH_CTRL_DI; - uint32_t si = GPDMA_CH_CTRL_SI; - - if (n < 0 || n > (int) GPDMA_CH_CTRL_TSZ_MAX) { - return -RTEMS_INVALID_SIZE; - } - - /* Try to reserve DMA support for this bus */ - if (lpc24xx_ssp_dma_data.bus == NULL) { - rtems_interrupt_disable(level); - if (lpc24xx_ssp_dma_data.bus == NULL) { - lpc24xx_ssp_dma_data.bus = e; - } - rtems_interrupt_enable(level); - - /* Try to obtain DMA channels */ - if (lpc24xx_ssp_dma_data.bus == e) { - rtems_status_code cs0 = lpc24xx_dma_channel_obtain(0); - rtems_status_code cs1 = lpc24xx_dma_channel_obtain(1); - - if (cs0 != RTEMS_SUCCESSFUL || cs1 != RTEMS_SUCCESSFUL) { - if (cs0 == RTEMS_SUCCESSFUL) { - lpc24xx_dma_channel_release(0); - } - if (cs1 == RTEMS_SUCCESSFUL) { - lpc24xx_dma_channel_release(1); - } - lpc24xx_ssp_dma_data.bus = NULL; - } - } - } - - /* Check if DMA support is available */ - if (lpc24xx_ssp_dma_data.bus != e - || lpc24xx_ssp_dma_data.status != LPC24XX_SSP_DMA_AVAILABLE) { - return -RTEMS_RESOURCE_IN_USE; - } - - /* Set DMA support status and parameter */ - lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_WAIT; - lpc24xx_ssp_dma_data.done = done; - lpc24xx_ssp_dma_data.n = n; - lpc24xx_ssp_dma_data.arg = arg; - - /* Enable DMA on SSP */ - ssp->dmacr = SSP_DMACR_RXDMAE | SSP_DMACR_TXDMAE; - - /* Receive */ - if (in != NULL) { - receive_channel->desc.dest = (uint32_t) in; - } else { - receive_channel->desc.dest = (uint32_t) &lpc24xx_ssp_trash; - di = 0; - } - receive_channel->desc.src = (uint32_t) &ssp->dr; - receive_channel->desc.lli = 0; - receive_channel->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n) - | SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_4) - | SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_4) - | SET_GPDMA_CH_CTRL_SW(0, GPDMA_CH_CTRL_W_8) - | SET_GPDMA_CH_CTRL_DW(0, GPDMA_CH_CTRL_W_8) - | GPDMA_CH_CTRL_ITC - | di; - receive_channel->cfg = SET_GPDMA_CH_CFG_SRCPER(0, GPDMA_CH_CFG_PER_SSP1_RX) - | SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_PER_TO_MEM_DMA) - | GPDMA_CH_CFG_IE - | GPDMA_CH_CFG_ITC - | GPDMA_CH_CFG_EN; - - /* Transmit */ - if (out != NULL) { - transmit_channel->desc.src = (uint32_t) out; - } else { - transmit_channel->desc.src = (uint32_t) &e->idle_char; - si = 0; - } - transmit_channel->desc.dest = (uint32_t) &ssp->dr; - transmit_channel->desc.lli = 0; - transmit_channel->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ(0, n) - | SET_GPDMA_CH_CTRL_SBSZ(0, GPDMA_CH_CTRL_BSZ_4) - | SET_GPDMA_CH_CTRL_DBSZ(0, GPDMA_CH_CTRL_BSZ_4) - | SET_GPDMA_CH_CTRL_SW(0, GPDMA_CH_CTRL_W_8) - | SET_GPDMA_CH_CTRL_DW(0, GPDMA_CH_CTRL_W_8) - | GPDMA_CH_CTRL_ITC - | si; - transmit_channel->cfg = SET_GPDMA_CH_CFG_DESTPER(0, GPDMA_CH_CFG_PER_SSP1_TX) - | SET_GPDMA_CH_CFG_FLOW(0, GPDMA_CH_CFG_FLOW_MEM_TO_PER_DMA) - | GPDMA_CH_CFG_IE - | GPDMA_CH_CFG_ITC - | GPDMA_CH_CFG_EN; - - return 0; -} - -static int lpc24xx_ssp_read(rtems_libi2c_bus_t *bus, unsigned char *in, int n) -{ - return lpc24xx_ssp_read_write(bus, in, NULL, n); -} - -static int lpc24xx_ssp_write( - rtems_libi2c_bus_t *bus, - unsigned char *out, - int n -) -{ - return lpc24xx_ssp_read_write(bus, NULL, out, n); -} - -static int lpc24xx_ssp_ioctl(rtems_libi2c_bus_t *bus, int cmd, void *arg) -{ - int rv = -1; - const rtems_libi2c_tfr_mode_t *tm = (const rtems_libi2c_tfr_mode_t *) arg; - rtems_libi2c_read_write_t *rw = (rtems_libi2c_read_write_t *) arg; - rtems_libi2c_read_write_async_t *rwa = - (rtems_libi2c_read_write_async_t *) arg; - - switch (cmd) { - case RTEMS_LIBI2C_IOCTL_READ_WRITE: - rv = lpc24xx_ssp_read_write(bus, rw->rd_buf, rw->wr_buf, rw->byte_cnt); - break; - case RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC: - rv = lpc24xx_ssp_read_write_async( - bus, - rwa->rd_buf, - rwa->wr_buf, - rwa->byte_cnt, - rwa->done, - rwa->arg - ); - break; - case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: - rv = lpc24xx_ssp_set_transfer_mode(bus, tm); - break; - default: - rv = -RTEMS_NOT_DEFINED; - break; - } - - return rv; -} - -static const rtems_libi2c_bus_ops_t lpc24xx_ssp_ops = { - .init = lpc24xx_ssp_init, - .send_start = lpc24xx_ssp_send_start, - .send_stop = lpc24xx_ssp_send_stop, - .send_addr = lpc24xx_ssp_send_addr, - .read_bytes = lpc24xx_ssp_read, - .write_bytes = lpc24xx_ssp_write, - .ioctl = lpc24xx_ssp_ioctl -}; - -static lpc24xx_ssp_bus_entry lpc24xx_ssp_bus_table [LPC24XX_SSP_NUMBER] = { - { - /* SSP 0 */ - .bus = { - .ops = &lpc24xx_ssp_ops, - .size = sizeof(lpc24xx_ssp_bus_entry) - }, - .regs = (volatile lpc24xx_ssp *) SSP0_BASE_ADDR, - .clock = 0, - .idle_char = 0xffffffff - }, { - /* SSP 1 */ - .bus = { - .ops = &lpc24xx_ssp_ops, - .size = sizeof(lpc24xx_ssp_bus_entry) - }, - .regs = (volatile lpc24xx_ssp *) SSP1_BASE_ADDR, - .clock = 0, - .idle_char = 0xffffffff - } -}; - -rtems_libi2c_bus_t * const lpc24xx_ssp_0 = - (rtems_libi2c_bus_t *) &lpc24xx_ssp_bus_table [0]; - -rtems_libi2c_bus_t * const lpc24xx_ssp_1 = - (rtems_libi2c_bus_t *) &lpc24xx_ssp_bus_table [1]; -- cgit v1.2.3