diff options
Diffstat (limited to 'tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP')
275 files changed, 40092 insertions, 0 deletions
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PeripheralNames.h new file mode 100644 index 0000000000..21a8a637ff --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PeripheralNames.h @@ -0,0 +1,73 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART0_BASE, + UART_1 = (int)LPC_USART1_BASE, + UART_2 = (int)LPC_USART2_BASE, + UART_3 = (int)LPC_USART3_BASE, + UART_4 = (int)LPC_USART4_BASE, +} UARTName; + +typedef enum { + ADC_0 = 0, + ADC_1, + ADC_2, + ADC_3, + ADC_4, + ADC_5, + ADC_6, + ADC_7, + ADC_8, + ADC_9, + ADC_10, + ADC_11, +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE +} I2CName; + +typedef enum { + SCT0_0 = 0, + SCT0_1, + SCT0_2, + SCT0_3, + SCT1_0, + SCT1_1, + SCT1_2, + SCT1_3, +} PWMName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PinNames.h new file mode 100644 index 0000000000..143c5775ea --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PinNames.h @@ -0,0 +1,181 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 16 +#define PIN_SHIFT 9 + +typedef enum { + // LPC11U68 Pin Names (PORT[19:16] + PIN[15:9] + IOCON offset[8:0]) + + P0_0 = (0 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x000, + P0_1 = (0 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x004, + P0_2 = (0 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x008, + P0_3 = (0 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x00C, + P0_4 = (0 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x010, + P0_5 = (0 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x014, + P0_6 = (0 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x018, + P0_7 = (0 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x01C, + P0_8 = (0 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x020, + P0_9 = (0 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x024, + P0_10= (0 << PORT_SHIFT) | (10<< PIN_SHIFT) | 0x028, + P0_11= (0 << PORT_SHIFT) | (11<< PIN_SHIFT) | 0x02C, + P0_12= (0 << PORT_SHIFT) | (12<< PIN_SHIFT) | 0x030, + P0_13= (0 << PORT_SHIFT) | (13<< PIN_SHIFT) | 0x034, + P0_14= (0 << PORT_SHIFT) | (14<< PIN_SHIFT) | 0x038, + P0_15= (0 << PORT_SHIFT) | (15<< PIN_SHIFT) | 0x03C, + P0_16= (0 << PORT_SHIFT) | (16<< PIN_SHIFT) | 0x040, + P0_17= (0 << PORT_SHIFT) | (17<< PIN_SHIFT) | 0x044, + P0_18= (0 << PORT_SHIFT) | (18<< PIN_SHIFT) | 0x048, + P0_19= (0 << PORT_SHIFT) | (19<< PIN_SHIFT) | 0x04C, + P0_20= (0 << PORT_SHIFT) | (20<< PIN_SHIFT) | 0x050, + P0_21= (0 << PORT_SHIFT) | (21<< PIN_SHIFT) | 0x054, + P0_22= (0 << PORT_SHIFT) | (22<< PIN_SHIFT) | 0x058, + P0_23= (0 << PORT_SHIFT) | (23<< PIN_SHIFT) | 0x05C, + + P1_0 = (1 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x060, + P1_1 = (1 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x064, + P1_2 = (1 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x068, + P1_3 = (1 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x06C, + P1_4 = (1 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x070, + P1_5 = (1 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x074, + P1_6 = (1 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x078, + P1_7 = (1 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x07C, + P1_8 = (1 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x080, + P1_9 = (1 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x084, + P1_10= (1 << PORT_SHIFT) | (10<< PIN_SHIFT) | 0x088, + P1_11= (1 << PORT_SHIFT) | (11<< PIN_SHIFT) | 0x08C, + P1_12= (1 << PORT_SHIFT) | (12<< PIN_SHIFT) | 0x090, + P1_13= (1 << PORT_SHIFT) | (13<< PIN_SHIFT) | 0x094, + P1_14= (1 << PORT_SHIFT) | (14<< PIN_SHIFT) | 0x098, + P1_15= (1 << PORT_SHIFT) | (15<< PIN_SHIFT) | 0x09C, + P1_16= (1 << PORT_SHIFT) | (16<< PIN_SHIFT) | 0x0A0, + P1_17= (1 << PORT_SHIFT) | (17<< PIN_SHIFT) | 0x0A4, + P1_18= (1 << PORT_SHIFT) | (18<< PIN_SHIFT) | 0x0A8, + P1_19= (1 << PORT_SHIFT) | (19<< PIN_SHIFT) | 0x0AC, + P1_20= (1 << PORT_SHIFT) | (20<< PIN_SHIFT) | 0x0B0, + P1_21= (1 << PORT_SHIFT) | (21<< PIN_SHIFT) | 0x0B4, + P1_22= (1 << PORT_SHIFT) | (22<< PIN_SHIFT) | 0x0B8, + P1_23= (1 << PORT_SHIFT) | (23<< PIN_SHIFT) | 0x0BC, + P1_24= (1 << PORT_SHIFT) | (24<< PIN_SHIFT) | 0x0C0, + P1_25= (1 << PORT_SHIFT) | (25<< PIN_SHIFT) | 0x0C4, + P1_26= (1 << PORT_SHIFT) | (26<< PIN_SHIFT) | 0x0C8, + P1_27= (1 << PORT_SHIFT) | (27<< PIN_SHIFT) | 0x0CC, + P1_28= (1 << PORT_SHIFT) | (28<< PIN_SHIFT) | 0x0D0, + P1_29= (1 << PORT_SHIFT) | (29<< PIN_SHIFT) | 0x0D4, + P1_30= (1 << PORT_SHIFT) | (30<< PIN_SHIFT) | 0x0D8, + P1_31= (1 << PORT_SHIFT) | (31<< PIN_SHIFT) | 0x0DC, + + P2_0 = (2 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x0F0, + P2_1 = (2 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x0F4, + P2_2 = (2 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x0FC, + P2_3 = (2 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x100, + P2_4 = (2 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x104, + P2_5 = (2 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x108, + P2_6 = (2 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x10C, + P2_7 = (2 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x110, + P2_8 = (2 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x114, + P2_9 = (2 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x118, + P2_10= (2 << PORT_SHIFT) | (10<< PIN_SHIFT) | 0x11C, + P2_11= (2 << PORT_SHIFT) | (11<< PIN_SHIFT) | 0x120, + P2_12= (2 << PORT_SHIFT) | (12<< PIN_SHIFT) | 0x124, + P2_13= (2 << PORT_SHIFT) | (13<< PIN_SHIFT) | 0x128, + P2_14= (2 << PORT_SHIFT) | (14<< PIN_SHIFT) | 0x12C, + P2_15= (2 << PORT_SHIFT) | (15<< PIN_SHIFT) | 0x130, + P2_16= (2 << PORT_SHIFT) | (16<< PIN_SHIFT) | 0x134, + P2_17= (2 << PORT_SHIFT) | (17<< PIN_SHIFT) | 0x138, + P2_18= (2 << PORT_SHIFT) | (18<< PIN_SHIFT) | 0x13C, + P2_19= (2 << PORT_SHIFT) | (19<< PIN_SHIFT) | 0x140, + P2_20= (2 << PORT_SHIFT) | (20<< PIN_SHIFT) | 0x144, + P2_21= (2 << PORT_SHIFT) | (21<< PIN_SHIFT) | 0x148, + P2_22= (2 << PORT_SHIFT) | (22<< PIN_SHIFT) | 0x14C, + P2_23= (2 << PORT_SHIFT) | (23<< PIN_SHIFT) | 0x150, + + LED_RED = P2_17, + LED_GREEN = P2_16, + LED_BLUE = P2_18, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_BLUE, + + // Serial to USB pins + USBTX = P0_19, + USBRX = P0_18, + + // Arduino Shield Receptacles Names + D0 = P0_18, + D1 = P0_19, + D2 = P1_18, + D3 = P1_24, + D4 = P1_19, + D5 = P1_26, + D6 = P1_27, + D7 = P1_25, + D8 = P1_28, + D9 = P2_3, + D10= P0_2, + D11= P0_9, + D12= P0_8, + D13= P1_29, + D14= P0_5, + D15= P0_4, + + A0 = P1_9, + A1 = P0_14, + A2 = P0_13, + A3 = P0_12, + A4 = P0_5, // same port as SDA + A5 = P0_4, // same port as SCL + SDA= P0_5, // same port as A4 + SCL= P0_4, // same port as A5 + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PortNames.h new file mode 100644 index 0000000000..f332b05544 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/PortNames.h @@ -0,0 +1,32 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.c new file mode 100644 index 0000000000..ce81d4cfbf --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.c @@ -0,0 +1,136 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_ANALOGIN + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF +#define PDRUN_VALID_BITS 0x000025FFL +#define PDRUN_RESERVED_ONE 0x0000C800L + +#define ADC_RANGE ADC_12BIT_RANGE + +static const PinMap PinMap_ADC[] = { + {P1_9 , ADC_0, 3}, + {P0_23, ADC_1, 1}, + {P0_16, ADC_2, 1}, + {P0_15, ADC_3, 3}, + {P1_22, ADC_4, 3}, + {P1_3 , ADC_5, 4}, + {P0_14, ADC_6, 2}, + {P0_13, ADC_7, 2}, + {P0_12, ADC_8, 2}, + {P0_11, ADC_9, 2}, + {P1_29, ADC_10,4}, + {P0_22, ADC_11,1}, + {NC , NC ,0} +}; + + +void analogin_init(analogin_t *obj, PinName pin) { + volatile uint32_t tmp; + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + pinmap_pinout(pin, PinMap_ADC); + + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + (pin & 0x1FF)); + // set pin to ADC mode + *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) + + // ADC Powered + tmp = (LPC_SYSCON->PDRUNCFG & PDRUN_VALID_BITS); + tmp &= ~((1 << 4) & PDRUN_VALID_BITS); + LPC_SYSCON->PDRUNCFG = (tmp | PDRUN_RESERVED_ONE); + + // Enable clock for ADC + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); + + // Determine the clock divider for a 500kHz ADC clock during calibration + uint32_t clkdiv = (SystemCoreClock / 500000) - 1; + + // Perform a self-calibration + LPC_ADC->CTRL = (1UL << 30) | (clkdiv & 0xFF); + while ((LPC_ADC->CTRL & (1UL << 30)) != 0); + + // Sampling clock: SystemClock divided by 1 + LPC_ADC->CTRL = 0; +} + +static inline uint32_t adc_read(analogin_t *obj) { + + // select channel + LPC_ADC->SEQA_CTRL &= ~(0xFFF); + LPC_ADC->SEQA_CTRL |= (1UL << obj->adc); + + // start conversion, sequence enable with async mode + LPC_ADC->SEQA_CTRL |= ((1UL << 26) | (1UL << 31) | (1UL << 19)); + + // Repeatedly get the sample data until DONE bit + volatile uint32_t data; + do { + data = LPC_ADC->SEQA_GDAT; + } while ((data & (1UL << 31)) == 0); + data = LPC_ADC->DAT[obj->adc]; + + // Stop conversion + LPC_ADC->SEQA_CTRL &= ~(1UL << 31); + + return ((data >> 4) & ADC_RANGE); +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/device.h new file mode 100644 index 0000000000..4894a9640d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/device.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 0 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_api.c new file mode 100644 index 0000000000..99ee19b2af --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_api.c @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +static int gpio_enabled = 0; + +static void gpio_enable(void) { + gpio_enabled = 1; + + /* Enable AHB clock to the GPIO and IOCON domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= ((1 << 16) | (1 << 6)); +} + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + if (!gpio_enabled) + gpio_enable(); + + int func = ((pin == P0_0) || // reset + (pin == P0_10) || // SWCLK + (pin == P0_12) || // TMS + (pin == P0_13) || // TDO + (pin == P0_14) || // TRST + (pin == P0_15)) ? (1) : (0); // SWDIO + + pin_function(pin, func); + + return (1UL << ((int)pin >> PIN_SHIFT & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + unsigned int port = (unsigned int)(pin >> PORT_SHIFT); + + obj->reg_set = &LPC_GPIO_PORT->SET[port]; + obj->reg_clr = &LPC_GPIO_PORT->CLR[port]; + obj->reg_in = &LPC_GPIO_PORT->PIN[port]; + obj->reg_dir = &LPC_GPIO_PORT->DIR[port]; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_irq_api.c new file mode 100644 index 0000000000..545defb56f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_irq_api.c @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> + +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#if DEVICE_INTERRUPTIN + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_PINT +#define PININT_IRQ PIN_INT0_IRQn + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + LPC_GPIO_X->FALL = ch_bit; + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + // PINT only supprt PIO0_*, PIO1_* and from PIO2_0 to PIO0_7 interrupt + if (pin >= P2_8) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the PIN, GPIO and IOCON domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= ((1 << 19) | (1 << 16) | (1 << 7)); + + LPC_SYSCON->PINTSEL[obj->ch] = ((((pin >> PORT_SHIFT) & 0x3) * 24) + ((pin >> PIN_SHIFT) & 0x1F)); + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= (1 << obj->ch); + + LPC_GPIO_PORT->DIR[(pin >> PORT_SHIFT) & 0x3] &= ~(1 << ((pin >> PIN_SHIFT) & 0x1F)); + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c new file mode 100644 index 0000000000..718ef5ea0f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c @@ -0,0 +1,394 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#if DEVICE_I2C + +static const PinMap PinMap_I2C_SDA[] = { + {P0_5 , I2C_0, 1}, + {P1_3 , I2C_1, 3}, + {P1_14, I2C_1, 1}, + {P1_24, I2C_1, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_4 , I2C_0, 1}, + {P0_7 , I2C_1, 3}, + {P1_11, I2C_1, 1}, + {P1_30, I2C_1, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, // slave address offset + {0x30, 0x34, 0x38, 0x3C} // slave address mask offset +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + volatile int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= ((1 << 5) | (1 << 25)); + LPC_SYSCON->PRESETCTRL |= ((1 << 1) | (1 << 3)); +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C0_Type *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + } +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/objects.h new file mode 100644 index 0000000000..796b97abc4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/objects.h @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if DEVICE_INTERRUPTIN +struct gpio_irq_s { + uint32_t ch; +}; +#endif + +#if DEVICE_PWMOUT +struct pwmout_s { + LPC_SCT0_Type* pwm; + uint32_t pwm_ch; +}; +#endif + +#if DEVICE_SERIAL +struct serial_s { + LPC_USART0_Type *uart; + LPC_USART4_Type *mini_uart; + unsigned char index; +}; +#endif + +#if DEVICE_ANALOGIN +struct analogin_s { + ADCName adc; +}; +#endif + +#if DEVICE_ANALOGOUT +struct dac_s { + DACName dac; +}; +#endif + +#if DEVICE_I2C +struct i2c_s { + LPC_I2C0_Type *i2c; +}; +#endif + +#if DEVICE_SPI +struct spi_s { + LPC_SSP0_Type *spi; + unsigned char spi_n; +}; +#endif + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pinmap.c new file mode 100644 index 0000000000..548d1d58ab --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pinmap.c @@ -0,0 +1,45 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + (pin & 0x1FF)); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + if ((pin == P0_4) || (pin == P0_5)) { + // The true open-drain pins PIO0_4 and PIO0_5 can be configured for different I2C-bus speeds. + return; + } + + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + (pin & 0x1FF)); + + if (mode == OpenDrain) { + *reg |= (1 << 10); + } else { + uint32_t tmp = *reg; + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + *reg = tmp; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c new file mode 100644 index 0000000000..71f9aaa41b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/pwmout_api.c @@ -0,0 +1,188 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_PWMOUT + +#define SCT_CHANNELS 2 + +static const PinMap PinMap_PWM[] = { + {P1_19, SCT0_0, 2}, + {P2_2 , SCT0_1, 3}, + {P2_7 , SCT0_2, 2}, + {P1_13, SCT0_3, 2}, + {P2_16, SCT1_0, 1}, + {P2_17, SCT1_1, 1}, + {P2_18, SCT1_2, 1}, + {P2_19, SCT1_3, 1}, + {NC , NC ,0} +}; + + +static LPC_SCT0_Type *SCTs[SCT_CHANNELS] = { + (LPC_SCT0_Type*)LPC_SCT0, + (LPC_SCT0_Type*)LPC_SCT1, + +}; + +// bit flags for used SCTs +static unsigned char sct_used = 0; + +static int get_available_sct(void) { + int i; + for (i=0; i<SCT_CHANNELS; i++) { + if ((sct_used & (1 << i)) == 0) + return i; + } + return -1; +} + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the SPI to use + PWMName pwm_mapped = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + if (pwm_mapped == (PWMName)NC) { + error("PwmOut pin mapping failed"); + } + int sct_n = get_available_sct(); + if (sct_n == -1) { + error("No available SCT"); + } + + sct_used |= (1 << sct_n); + obj->pwm = SCTs[sct_n]; + obj->pwm_ch = sct_n; + + // Enable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 31); + + // Clear peripheral reset the SCT: + LPC_SYSCON->PRESETCTRL |= (1 << (obj->pwm_ch + 9)); + pinmap_pinout(pin, PinMap_PWM); + LPC_SCT0_Type* pwm = obj->pwm; + + // Unified 32-bit counter, autolimit + pwm->CONFIG |= ((0x3 << 17) | 0x01); + + // halt and clear the counter + pwm->CTRL |= (1 << 2) | (1 << 3); + + // System Clock -> us_ticker (1)MHz + pwm->CTRL &= ~(0x7F << 5); + pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5); + + switch(pwm_mapped) { + case SCT0_0: + case SCT1_0: + pwm->OUT0_SET = (1 << 0); // event 0 + pwm->OUT0_CLR = (1 << 1); // event 1 + break; + case SCT0_1: + case SCT1_1: + pwm->OUT1_SET = (1 << 0); // event 0 + pwm->OUT1_CLR = (1 << 1); // event 1 + break; + case SCT0_2: + case SCT1_2: + pwm->OUT2_SET = (1 << 0); // event 0 + pwm->OUT2_CLR = (1 << 1); // event 1 + break; + case SCT0_3: + case SCT1_3: + pwm->OUT3_SET = (1 << 0); // event 0 + pwm->OUT3_CLR = (1 << 1); // event 1 + break; + default: + break; + } + // Event 0 : MATCH and MATCHSEL=0 + pwm->EV0_CTRL = (1 << 12); + pwm->EV0_STATE = 0xFFFFFFFF; + // Event 1 : MATCH and MATCHSEL=1 + pwm->EV1_CTRL = (1 << 12) | (1 << 0); + pwm->EV1_STATE = 0xFFFFFFFF; + + // Match reload register + pwm->MATCHREL0 = 20000; // 20ms + pwm->MATCHREL1 = (pwm->MATCHREL0 / 4); // 50% duty + + // unhalt the counter: + // - clearing bit 2 of the CTRL register + pwm->CTRL &= ~(1 << 2); + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); +} + +void pwmout_free(pwmout_t* obj) { + sct_used &= ~(1 << obj->pwm_ch); + if (sct_used == 0) { + // Disable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1UL << 31); + } +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL0) * value); + obj->pwm->MATCHREL1 = t_on; +} + +float pwmout_read(pwmout_t* obj) { + uint32_t t_off = obj->pwm->MATCHREL0; + uint32_t t_on = obj->pwm->MATCHREL1; + float v = (float)t_on/(float)t_off; + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + uint32_t t_off = obj->pwm->MATCHREL0; + uint32_t t_on = obj->pwm->MATCHREL1; + float v = (float)t_on/(float)t_off; + obj->pwm->MATCHREL0 = (uint32_t)us; + obj->pwm->MATCHREL1 = (uint32_t)((float)us * (float)v); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + obj->pwm->MATCHREL1 = (uint32_t)us; +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/rtc_api.c new file mode 100644 index 0000000000..f535dc191a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/rtc_api.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rtc_api.h" + +#if DEVICE_RTC + +void rtc_init(void) +{ + // Enables clock for RTC + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 30); + + // Software reset + LPC_RTC->CTRL |= 1; + + LPC_RTC->COUNT = 0; + + // Enabled RTC + LPC_RTC->CTRL |= (1 << 7); + // clear reset + LPC_RTC->CTRL &= ~1; +} + +void rtc_free(void) +{ + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 30); + LPC_RTC->CTRL &= ~(1 << 7); +} + +int rtc_isenabled(void) +{ + return (((LPC_RTC->CTRL) & 0x80) != 0); +} + +time_t rtc_read(void) +{ + return (time_t)LPC_RTC->COUNT; +} + +void rtc_write(time_t t) +{ + // Disabled RTC + LPC_RTC->CTRL &= ~(1 << 7); + + // Set count + LPC_RTC->COUNT = t; + + //Enabled RTC + LPC_RTC->CTRL |= (1 << 7); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/serial_api.c new file mode 100644 index 0000000000..161f0fd3a1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/serial_api.c @@ -0,0 +1,462 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#if DEVICE_SERIAL + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ + +#define UART_NUM 5 + +// CFG +#define UART_EN (0x01<<0) + +// CTL +#define TXBRKEN (0x01<<1) + +// STAT +#define RXRDY (0x01<<0) +#define TXRDY (0x01<<2) +#define DELTACTS (0x01<<5) +#define RXBRK (0x01<<10) +#define DELTARXBRK (0x01<<11) + +static const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_18, UART_0, 2}, + {P1_27, UART_0, 2}, + {P1_8 , UART_1, 2}, + {P1_0 , UART_2, 3}, + {P1_23, UART_2, 3}, + {P2_4 , UART_3, 1}, + {P2_12, UART_4, 1}, + { NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_17, UART_0, 2}, + {P1_26, UART_0, 2}, + {P1_2 , UART_1, 3}, + {P0_20, UART_2, 2}, + {P1_6 , UART_2, 2}, + {P2_3 , UART_3, 1}, + {P2_11, UART_4, 1}, + {NC , NC , 0} +}; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + switch (uart) { + case UART_0: + obj->index = 0; + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12); + break; + case UART_1: + obj->index = 1; + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 20); + LPC_SYSCON->PRESETCTRL |= (1 << 5); + break; + case UART_2: + obj->index = 2; + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 21); + LPC_SYSCON->PRESETCTRL |= (1 << 6); + break; + case UART_3: + obj->index = 3; + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 22); + LPC_SYSCON->PRESETCTRL |= (1 << 7); + break; + case UART_4: + obj->index = 4; + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 22); + LPC_SYSCON->PRESETCTRL |= (1 << 8); + break; + } + + if (obj->index == 0) + obj->uart = (LPC_USART0_Type *)uart; + else + obj->mini_uart = (LPC_USART4_Type *)uart; + + if (obj->index == 0) { + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Clear + | 0 << 2 // Tx Fifo Clear + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + } + else { + // Clear all status bits + obj->mini_uart->STAT = (DELTACTS | DELTARXBRK); + // Enable UART + obj->mini_uart->CFG |= UART_EN; + } + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart && (obj->index == 0)) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + LPC_SYSCON->USART0CLKDIV = 1; + LPC_SYSCON->FRGCLKDIV = 1; + + if (obj->index == 0) { + uint32_t PCLK = SystemCoreClock; + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); + } + else { + uint32_t UARTSysClk = SystemCoreClock / LPC_SYSCON->FRGCLKDIV; + obj->mini_uart->BRG = UARTSysClk / 16 / baudrate - 1; + + LPC_SYSCON->UARTFRGDIV = 0xFF; + LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) / + (baudrate * (obj->mini_uart->BRG + 1)) + ) - (LPC_SYSCON->UARTFRGDIV + 1); + } +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + + stop_bits -= 1; + + if (obj->index == 0) { + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + return; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; + } + else { + // 0: 7 data bits ... 2: 9 data bits + MBED_ASSERT((data_bits > 6) && (data_bits < 10)); + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven)); + data_bits -= 7; + + int paritysel; + switch (parity) { + case ParityNone: paritysel = 0; break; + case ParityEven: paritysel = 2; break; + case ParityOdd : paritysel = 3; break; + default: + return; + } + obj->mini_uart->CFG = (data_bits << 2) + | (paritysel << 4) + | (stop_bits << 6) + | UART_EN; + } +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() +{ + uart_irq((LPC_USART0->IIR >> 1) & 0x7, 0); +} + +void uart1_irq() +{ + uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 1); +} + +void uart2_irq() +{ + uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 2); +} + +void uart3_irq() +{ + uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 3); +} + +void uart4_irq() +{ + uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 4); +} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n = USART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n = USART1_4_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n = USART2_3_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n = USART2_3_IRQn; vector = (uint32_t)&uart3_irq; break; + case UART_4: irq_n = USART1_4_IRQn; vector = (uint32_t)&uart4_irq; break; + } + + if (enable) { + if (obj->index == 0) { + obj->uart->IER |= (1 << irq); + } + else { + obj->mini_uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2)); + } + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + + if (obj->index == 0) { + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + } + else { + obj->mini_uart->INTENSET &= ~(1 << ((irq == RxIrq) ? 0 : 2)); + all_disabled = (obj->mini_uart->INTENSET & (1 << ((other_irq == RxIrq) ? 0 : 2))) == 0; + } + + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + if (obj->index == 0) { + return obj->uart->RBR; + } + else { + return obj->mini_uart->RXDAT; + } +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + if (obj->index == 0) { + obj->uart->THR = c; + } + else { + obj->mini_uart->TXDAT = c; + } +} + +int serial_readable(serial_t *obj) { + if (obj->index == 0) { + return obj->uart->LSR & 0x01; + } + else { + return obj->mini_uart->STAT & RXRDY; + } +} + +int serial_writable(serial_t *obj) { + if (obj->index == 0) { + return obj->uart->LSR & 0x20; + } + else { + return obj->mini_uart->STAT & TXRDY; + } +} + +void serial_clear(serial_t *obj) { + if (obj->index == 0) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth + } + else { + obj->mini_uart->STAT = 0; + } +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + if (obj->index == 0) { + obj->uart->LCR |= (1 << 6); + } + else { + obj->mini_uart->CTL |= TXBRKEN; + } +} + +void serial_break_clear(serial_t *obj) { + if (obj->index == 0) { + obj->uart->LCR &= ~(1 << 6); + } + else { + obj->mini_uart->CTL &= ~TXBRKEN; + } +} + + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/sleep.c new file mode 100644 index 0000000000..ede20f99dc --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/sleep.c @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +#if DEVICE_SLEEP + +void sleep(void) { + +#if (DEVICE_SEMIHOST == 1) + // ensure debug is disconnected + mbed_interface_disconnect(); +#endif + + // PCON[PM] (bits 2:0) set to 0 + LPC_PMU->PCON &= ~0x03; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + + +void deepsleep(void) { + +#if (DEVICE_SEMIHOST == 1) + // ensure debug is disconnected + mbed_interface_disconnect(); +#endif + + // PCON[PM] (bits 2:0) set to 1 + LPC_PMU->PCON &= ~0x03; + LPC_PMU->PCON |= 0x01; + + //According to user manual it is kinda picky about reserved bits, so we follow that nicely + //Keep WDOSC and BOD in same state as they are now during deepsleep + LPC_SYSCON->PDSLEEPCFG = 0x00000037 | (LPC_SYSCON->PDRUNCFG & (0x00000048)); + + // Power up same as before powerdown + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + + // All interrupts can wake + LPC_SYSCON->STARTERP0 = 0xFF; + LPC_SYSCON->STARTERP1 = 0xFFFFFFFF; + + // SRC[SLEEPDEEP] set to 1 = deep sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/spi_api.c new file mode 100644 index 0000000000..d152794f8d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/spi_api.c @@ -0,0 +1,221 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_SPI + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P2_7 , SPI_0, 0x01}, + {P1_20, SPI_1, 0x02}, + {P1_27, SPI_1, 0x04}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P1_12, SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x01}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P1_16, SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_15, SPI_0, 0x01}, + {P0_23, SPI_1, 0x04}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSP0_Type*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11; + LPC_SYSCON->SSP0CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 0; + break; + case SPI_1: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18; + LPC_SYSCON->SSP1CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 2; + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + ssp_disable(obj); + MBED_ASSERT(((bits >= 4) && (bits <= 16)) || ((mode >= 0) && (mode <= 3))); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c new file mode 100644 index 0000000000..a38df4d5ce --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/us_ticker.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_CT32B0_Type *)LPC_CT32B1_BASE) +#define US_TICKER_TIMER_IRQn CT32B1_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock CT32B1 + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PeripheralPins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PeripheralPins.h new file mode 100644 index 0000000000..28d12e031c --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PeripheralPins.h @@ -0,0 +1,43 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_PERIPHERALPINS_H +#define MBED_PERIPHERALPINS_H + +#include "pinmap.h" +#include "PeripheralNames.h" + +/************ADC***************/ +extern const PinMap PinMap_ADC[]; + +/************I2C***************/ +extern const PinMap PinMap_I2C_SDA[]; +extern const PinMap PinMap_I2C_SCL[]; + +/************UART***************/ +extern const PinMap PinMap_UART_TX[]; +extern const PinMap PinMap_UART_RX[]; + +/************SPI***************/ +extern const PinMap PinMap_SPI_SCLK[]; +extern const PinMap PinMap_SPI_MOSI[]; +extern const PinMap PinMap_SPI_MISO[]; +extern const PinMap PinMap_SPI_SSEL[]; + +/************PWM***************/ +extern const PinMap PinMap_PWM[]; + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PortNames.h new file mode 100644 index 0000000000..3f272730a1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/PortNames.h @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralNames.h new file mode 100644 index 0000000000..ffb2e121f8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralPins.c new file mode 100644 index 0000000000..aba0732521 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PinNames.h new file mode 100644 index 0000000000..de9cf536d1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/PinNames.h @@ -0,0 +1,178 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // MicroNFCBoard pin names + M_RST = P0_0, + M_BOOT = P0_1, + M_RXD = P0_18, + M_TXD = P0_19, + M_SCL = P0_4, + M_SDA = P0_5, + M_D0 = P0_20, + + M_A0 = P0_16, + M_A1 = P0_15, + M_A2 = P0_14, + M_A3 = P0_13, + M_SCK = P0_10, + M_MOSI = P0_9, + M_MISO = P0_8, + M_NCS = P0_2, + M_IRQ = P0_7, + + // MicroNFCBoard pin numbers + p4 = M_RST, + p5 = M_BOOT, + p6 = M_RXD, + p7 = M_TXD, + p8 = M_SCL, + p9 = M_SDA, + p10 = M_D0, + + p11 = M_IRQ, + p12 = M_NCS, + p13 = M_MISO, + p14 = M_MOSI, + p15 = M_SCK, + p16 = M_A3, + p17 = M_A2, + p18 = M_A1, + p19 = M_A0, + + // Other Pin Names + LED1 = P0_11, + LED2 = P0_12, + + // Alias to have correct blue lights of death pattern + LED3 = LED2, + LED4 = LED1, + + UART_TX = M_TXD, + UART_RX = M_RXD, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/device.h new file mode 100644 index 0000000000..62f823dcb3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_APPNEARME_MICRONFCBOARD/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralNames.h new file mode 100644 index 0000000000..705034a2fb --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralNames.h @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7, p8 +#define MBED_SPI1 p11, p12, p13, p14 + +#define MBED_UART0 p9, p10 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p28, p27 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PinNames.h new file mode 100644 index 0000000000..60e1052085 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/PinNames.h @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P1_29, + p8 = P0_2, + p9 = P1_27, + p10 = P1_26, + p11 = P1_22, + p12 = P1_21, + p13 = P1_20, + p14 = P1_23, + p15 = P0_11, + p16 = P0_12, + p17 = P0_13, + p18 = P0_14, + p19 = P0_16, + p20 = P0_22, + p21 = P0_7, + p22 = P0_17, + p23 = P1_17, + p24 = P1_18, + p25 = P1_24, + p26 = P1_25, + p27 = P0_4, + p28 = P0_5, + p29 = P1_5, + p30 = P1_2, + + p33 = P0_3, + p34 = P1_15, + p35 = P0_20, + p36 = P0_21, + + // Other mbed Pin Names + LED1 = P1_8, + LED2 = P1_9, + LED3 = P1_10, + LED4 = P1_11, + + USBTX = P0_19, + USBRX = P0_18, + + // for Arch V1.1 + D0 = P0_18, + D1 = P0_19, + D2 = P0_17, + D3 = P1_17, + D4 = P1_18, + D5 = P1_24, + D6 = P1_25, + D7 = P1_5, + D8 = P1_4, + D9 = P1_28, + D10 = P0_2, + D11 = P0_9, + D12 = P0_8, + D13 = P1_29, + + D14 = P0_5, + D15 = P0_4, + + A0 = P0_11, + A1 = P0_12, + A2 = P0_13, + A3 = P0_14, + A4 = P0_16, + A5 = P0_22, + + I2C_SCL = D15, + I2C_SDA = D14, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/device.h new file mode 100755 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_ARCH_GPRS/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralNames.h new file mode 100644 index 0000000000..705034a2fb --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralNames.h @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7, p8 +#define MBED_SPI1 p11, p12, p13, p14 + +#define MBED_UART0 p9, p10 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p28, p27 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PinNames.h new file mode 100644 index 0000000000..6688e3caff --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/PinNames.h @@ -0,0 +1,166 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P1_29, + p8 = P0_2, + p9 = P1_27, + p10 = P1_26, + p11 = P1_22, + p12 = P1_21, + p13 = P1_20, + p14 = P1_23, + p15 = P0_11, + p16 = P0_12, + p17 = P0_13, + p18 = P0_14, + p19 = P0_16, + p20 = P0_22, + p21 = P0_7, + p22 = P0_17, + p23 = P1_17, + p24 = P1_18, + p25 = P1_24, + p26 = P1_25, + p27 = P0_4, + p28 = P0_5, + p29 = P1_5, + p30 = P1_2, + + p33 = P0_3, + p34 = P1_15, + p35 = P0_20, + p36 = P0_21, + + // Other mbed Pin Names + LED1 = P1_8, + LED2 = P1_9, + LED3 = P1_10, + LED4 = P1_11, + + USBTX = P0_19, + USBRX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/device.h new file mode 100644 index 0000000000..ab3d323804 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_301/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 1 +#define DEVICE_LOCALFILESYSTEM 1 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralNames.h new file mode 100644 index 0000000000..705034a2fb --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralNames.h @@ -0,0 +1,87 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7, p8 +#define MBED_SPI1 p11, p12, p13, p14 + +#define MBED_UART0 p9, p10 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p28, p27 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PinNames.h new file mode 100644 index 0000000000..3a74aab472 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/PinNames.h @@ -0,0 +1,195 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P1_29, + p8 = P0_2, + p9 = P1_27, + p10 = P1_26, + p11 = P1_22, + p12 = P1_21, + p13 = P1_20, + p14 = P1_23, + p15 = P0_11, + p16 = P0_12, + p17 = P0_13, + p18 = P0_14, + p19 = P0_16, + p20 = P0_22, + p21 = P0_7, + p22 = P0_17, + p23 = P1_17, + p24 = P1_18, + p25 = P1_24, + p26 = P1_25, + p27 = P0_4, + p28 = P0_5, + p29 = P1_5, + p30 = P1_2, + + p33 = P0_3, + p34 = P1_15, + p35 = P0_20, + p36 = P0_21, + + // Other mbed Pin Names + LED1 = P1_8, + LED2 = P1_9, + LED3 = P1_10, + LED4 = P1_11, + + USBTX = P0_19, + USBRX = P0_18, + + // for Arch V1.1 + D0 = P0_18, + D1 = P0_19, + D2 = P0_17, + D3 = P1_17, + D4 = P1_18, + D5 = P1_24, + D6 = P1_25, + D7 = P1_5, + D8 = P1_26, + D9 = P1_27, + D10 = P0_2, + D11 = P0_9, // P1_29 for Arch V1.0 + D12 = P0_8, + D13 = P1_29, // P0_9 for Arch V1.0 + + D14 = P0_5, + D15 = P0_4, + + A0 = P0_11, + A1 = P0_12, + A2 = P0_13, + A3 = P0_14, + A4 = P0_16, + A5 = P0_22, + + I2C_SCL = D15, + I2C_SDA = D14, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/device.h new file mode 100644 index 0000000000..ab3d323804 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U24_401/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 1 +#define DEVICE_LOCALFILESYSTEM 1 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralNames.h new file mode 100644 index 0000000000..ffb2e121f8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralPins.c new file mode 100644 index 0000000000..aba0732521 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PinNames.h new file mode 100644 index 0000000000..d9b8eb4b00 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/PinNames.h @@ -0,0 +1,138 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // Other mbed Pin Names + LED1 = P0_7, + LED2 = P0_7, + LED3 = P0_7, + LED4 = P0_7, + + UART_TX = P0_19, + UART_RX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/device.h new file mode 100644 index 0000000000..62f823dcb3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U34_421/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralNames.h new file mode 100644 index 0000000000..969f15f2f6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PinNames.h new file mode 100644 index 0000000000..0d46ea96ca --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/PinNames.h @@ -0,0 +1,166 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + p3 = P0_7, + p4 = P0_8, + p5 = P0_9, + p6 = P0_10, + p7 = P0_22, + p8 = P0_11, + p9 = P0_12, + p10 = P0_13, + p11 = P0_14, + p12 = P0_15, + p13 = P0_16, + p14 = P0_23, + p15 = P1_15, + p16 = P0_17, + p17 = P0_18, + p18 = P0_19, + p19 = P0_1, + p20 = P1_19, + p21 = P0_0, + p22 = P0_20, + p23 = P0_2, + p24 = P0_3, + p25 = P0_4, + p26 = P0_5, + p27 = P0_21, + p28 = P0_6, + + // Other mbed Pin Names + LED1 = P0_7, + LED2 = P0_7, + LED3 = P0_7, + LED4 = P0_7, + + UART_TX = P0_19, + UART_RX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralNames.h new file mode 100644 index 0000000000..969f15f2f6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PinNames.h new file mode 100644 index 0000000000..9a0e81a15b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/PinNames.h @@ -0,0 +1,176 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // LED Names + LED1 = P1_24, + LED2 = P1_25, + LED3 = P1_26, + LED4 = P0_0, + LED5 = P1_3, + LED6 = P1_2, + LED7 = P1_1, + LED8 = P1_0, + + // BTN Names + BTN1 = P0_16, + BTN2 = P0_1, + + // UART + UART_TX = P0_19, + UART_RX = P0_18, + + // Arduino Shield Receptacles Names + D0 = P0_18, + D1 = P0_19, + D2 = P1_17, + D3 = P1_24, + D4 = P1_5, + D5 = P0_1, + D6 = P1_27, + D7 = P0_7, + D8 = P0_2, + D9 = P1_25, + D10= P1_23, + D11= P0_21, + D12= P0_22, + D13= P1_15, + D14= P0_5, + D15= P0_4, + + A0 = P0_11, + A1 = P0_12, + A2 = P0_13, + A3 = P0_16, + A4 = P0_5, // same port as SDA + A5 = P0_4, // same port as SCL + + SDA= P0_5, // same port as A4 + SCL= P0_4, // same port as A5 + + //SD Card pins + SDMOSI = P0_9, + SDMISO = P0_8, + SDSCLK = P1_29, + SDSSEL = P1_12, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U37H_401/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralNames.h new file mode 100644 index 0000000000..969f15f2f6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PinNames.h new file mode 100644 index 0000000000..0099540367 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/PinNames.h @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + + // Other mbed Pin Names + LED1 = P1_19, + LED2 = P1_19, // Negative On + LED3 = P1_19, + LED4 = P1_19, + + UART_TX = P0_19, + UART_RX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPCCAPPUCCINO/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralNames.h new file mode 100644 index 0000000000..969f15f2f6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralPins.c new file mode 100644 index 0000000000..b583d12c1b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/PeripheralPins.c @@ -0,0 +1,117 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, {P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, {P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, {P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/PinNames.h new file mode 100644 index 0000000000..89056391a4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/PinNames.h @@ -0,0 +1,181 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + // CN1-1 (GND) + // CN1-2 (EXTPOWER) + // CN1-3 (NC) + p4 = P0_0, // CN1-4 + p5 = P0_9, // CN1-5 + p6 = P0_8, // CN1-6 + p7 = P0_10, // CN1-7 + p8 = P0_7, // CN1-8 + p9 = P0_19, // CN1-9 + p10 = P0_18, // CN1-10 + p11 = P0_21, // CN1-11 + p12 = P0_22, // CN1-12 + p13 = P1_15, // CN1-13 + p14 = P0_6, // CN1-14 + p15 = P0_11, // CN1-15 + p16 = P0_12, // CN1-16 + p17 = P0_13, // CN1-17 + p18 = P0_14, // CN1-18 + p19 = P0_15, // CN1-19 + p20 = P0_16, // CN1-20 + + p21 = P0_14, // CN2-20 + p22 = P0_2, // CN2-19 + p23 = P0_23, // CN2-18 + p24 = P0_17, // CN2-17 + p25 = P0_20, // CN2-16 + p26 = P1_15, // CN2-15 + p27 = P0_4, // CN2-14 + p28 = P0_5, // CN2-13 + p29 = P1_19, // CN2-12 + p30 = P0_1, // CN2-11 + // CN2-10 (D+USB) + // CN2-9 (D-USB) + p33 = P0_3, // CN2-8 (USB-VBUS) + // CN2-7 (NC) + // CN2-6 (NC) + // CN2-5 (NC) + // CN2-4 (NC) + // CN2-3 (NC) + // CN2-2 (VDD) + // CN2-1 (VDD) + + // Other mbed Pin Names + LED1 = P0_20, + LED2 = P0_21, + LED3 = P0_20, + LED4 = P0_21, + + UART_TX = P0_19, + UART_RX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_501/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/PinNames.h new file mode 100644 index 0000000000..5ba0145589 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/PinNames.h @@ -0,0 +1,140 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Other mbed Pin Names + LED1 = P0_20, //Approved + LED2 = P0_9, //Approved + LED3 = P0_11, //Approved + LED4 = NC, + + UART_TX = P0_19, + UART_RX = P0_18, + + + + // Standard but not supported pins + USBTX = NC, + USBRX = NC + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_LPC11U35_Y5_MBUG/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/PinNames.h new file mode 100644 index 0000000000..b343556241 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/PinNames.h @@ -0,0 +1,184 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + P0_24 = 24, + P0_25 = 25, + P0_26 = 26, + P0_27 = 27, + + P1_0 = 32, + P1_1 = 33, + P1_2 = 34, + P1_3 = 35, + P1_4 = 36, + P1_5 = 37, + P1_6 = 38, + P1_7 = 39, + P1_8 = 40, + P1_9 = 41, + P1_10 = 42, + P1_11 = 43, + P1_12 = 44, + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + P1_17 = 49, + P1_18 = 50, + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // mbed DIP Pin Names + // CN1-1 (GND) + // CN1-2 (EXTPOWER) + // CN1-3 (NC) + p4 = P0_0, // CN1-4 + p5 = P0_9, // CN1-5 + p6 = P0_8, // CN1-6 + p7 = P0_10, // CN1-7 + p8 = P0_7, // CN1-8 + p9 = P0_19, // CN1-9 + p10 = P0_18, // CN1-10 + p11 = P0_21, // CN1-11 + p12 = P0_22, // CN1-12 + p13 = P1_15, // CN1-13 + p14 = P0_6, // CN1-14 + p15 = P0_11, // CN1-15 + p16 = P0_12, // CN1-16 + p17 = P0_13, // CN1-17 + p18 = P0_14, // CN1-18 + p19 = P0_15, // CN1-19 + p20 = P0_16, // CN1-20 + + p21 = P0_14, // CN2-20 + p22 = P0_2, // CN2-19 + p23 = P0_23, // CN2-18 + p24 = P0_17, // CN2-17 + p25 = P0_20, // CN2-16 + p26 = P1_15, // CN2-15 + p27 = P0_4, // CN2-14 + p28 = P0_5, // CN2-13 + p29 = P1_19, // CN2-12 + p30 = P0_1, // CN2-11 + // CN2-10 (D+USB) + // CN2-9 (D-USB) + p33 = P0_3, // CN2-8 (USB-VBUS) + // CN2-7 (NC) + // CN2-6 (NC) + // CN2-5 (NC) + // CN2-4 (NC) + // CN2-3 (NC) + // CN2-2 (VDD) + // CN2-1 (VDD) + + // Other mbed Pin Names + LED1 = P0_20, + LED2 = P0_23, + LED3 = P0_20, + LED4 = P0_23, + + UART_TX = P0_19, + UART_RX = P0_18, + + I2C_SCL = P0_4, + I2C_SDA = P0_5, + + // Not connected + NC = (int)0xFFFFFFFF, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/device.h new file mode 100644 index 0000000000..120ca9edb6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_MCU_LPC11U35_501/TARGET_XADOW_M0/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralNames.h new file mode 100644 index 0000000000..a6130fd4ee --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralNames.h @@ -0,0 +1,91 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11, + PWM_12, + PWM_13 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 P0_9, P0_8, P0_6, P0_2 // MOSI, MISO, CLK, SEL +#define MBED_SPI1 P0_21, P0_22, P1_15, P01_19 // MOSI, MISO, CLK, SEL + +#define MBED_UART0 USBTX, USBRX +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 P0_5, P0_4 + +#define MBED_ANALOGIN0 P0_11 +#define MBED_ANALOGIN1 P0_12 +#define MBED_ANALOGIN2 P0_13 +#define MBED_ANALOGIN3 P0_14 +#define MBED_ANALOGIN4 P0_15 +#define MBED_ANALOGIN5 P0_16 +#define MBED_ANALOGIN6 P0_22 +#define MBED_ANALOGIN7 P0_23 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralPins.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralPins.c new file mode 100644 index 0000000000..8819609c3e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PeripheralPins.c @@ -0,0 +1,106 @@ + +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PeripheralPins.h" + +/************ADC***************/ +const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +/************I2C***************/ +const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +/************UART***************/ +const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + { NC , NC , 0} +}; + +const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {NC , NC , 0} +}; + +/************SPI***************/ +const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_15, SPI_1, 0x03}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {NC , NC , 0} +}; + +const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {NC , NC , 0} +}; + +/************PWM***************/ +const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, /* MR2 */ + {P1_15, PWM_3, 2}, /* MR2 */ // Same channel as P0_10 + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, /* MR0 */ + {P0_19, PWM_7, 2}, /* MR1 */ + {P0_1 , PWM_8, 2}, /* MR2 */ + {P0_11, PWM_9, 3}, /* MR3 */ + + /* CT32B1 */ + {P0_13, PWM_10, 3}, /* MR0 */ + {P0_14, PWM_11, 3}, /* MR1 */ + {P0_15, PWM_12, 3}, /* MR2 */ + {P0_16, PWM_13, 2}, /* MR3 */ + + {NC, NC, 0} +}; diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PinNames.h new file mode 100644 index 0000000000..272ebe1196 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/PinNames.h @@ -0,0 +1,105 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC11U24 HVQFN33 Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + + P1_15 = 47, + P1_19 = 51, + + // Other mbed Pin Names + LED1 = P0_7, + LED2 = P0_8, + LED3 = P0_2, + LED4 = P0_20, + LED5 = P1_19, + LED6 = P0_17, + LED7 = P0_23, + + USBTX = P0_19, + USBRX = P0_18, + + I2C_SCL = P0_4, + I2C_SDA = P0_5, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = FLEX_INT0_IRQn, + CHANNEL1 = FLEX_INT1_IRQn, + CHANNEL2 = FLEX_INT2_IRQn, + CHANNEL3 = FLEX_INT3_IRQn, + CHANNEL4 = FLEX_INT4_IRQn, + CHANNEL5 = FLEX_INT5_IRQn, + CHANNEL6 = FLEX_INT6_IRQn, + CHANNEL7 = FLEX_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/device.h new file mode 100644 index 0000000000..a45349a9e3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_OC_MBUINO/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/analogin_api.c new file mode 100644 index 0000000000..c2f3cff350 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/analogin_api.c @@ -0,0 +1,114 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +#define LPC_IOCON0_BASE (LPC_IOCON_BASE) +#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60) + +#define ADC_RANGE ADC_10BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // Power up ADC + LPC_SYSCON->PDRUNCFG &= ~ (1 << 4); + LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13); + + uint32_t pin_number = (uint32_t)pin; + __IO uint32_t *reg = (pin_number < 32) ? (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + + // set pin to ADC mode + *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) + + uint32_t PCLK = SystemCoreClock; + uint32_t MAX_ADC_CLK = 4500000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + LPC_ADC->CR = (0 << 0) // no channels selected + | (clkdiv << 8) // max of 4.5MHz + | (0 << 16) // BURST = 0, software controlled + | ( 0 << 17 ); // CLKS = 0, not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 6) & ADC_RANGE; // 10 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_api.c new file mode 100644 index 0000000000..8a5a55a5e0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_api.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + int f = ((pin == P0_0) || + (pin == P0_10) || + (pin == P0_11) || + (pin == P0_12) || + (pin == P0_13) || + (pin == P0_14) || + (pin == P0_15)) ? (1) : (0); + + pin_function(pin, f); + + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + unsigned int port = (unsigned int)pin >> PORT_SHIFT; + + obj->reg_set = &LPC_GPIO->SET[port]; + obj->reg_clr = &LPC_GPIO->CLR[port]; + obj->reg_in = &LPC_GPIO->PIN[port]; + obj->reg_dir = &LPC_GPIO->DIR[port]; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_irq_api.c new file mode 100644 index 0000000000..ef4e16c710 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_irq_api.c @@ -0,0 +1,141 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_GPIO_PIN_INT +#define PININT_IRQ 0 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + /* Enable AHB clock to the FlexInt, GroupedInt domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<19) | (1<<23) | (1<<24)); + + /* To select a pin for any of the eight pin interrupts, write the pin number + * as 0 to 23 for pins PIO0_0 to PIO0_23 and 24 to 55. + * @see: mbed_capi/PinNames.h + */ + LPC_SYSCON->PINTSEL[obj->ch] = (pin >> 5) ? (pin - 8) : (pin); + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= 1 << obj->ch; + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c new file mode 100644 index 0000000000..b100dc439a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c @@ -0,0 +1,375 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); + LPC_SYSCON->PRESETCTRL |= 1 << 1; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_Type *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/objects.h new file mode 100644 index 0000000000..755e77311a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/objects.h @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_mpin; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + PWMName pwm; +}; + +struct serial_s { + LPC_USART_Type *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct i2c_s { + LPC_I2C_Type *i2c; +}; + +struct spi_s { + LPC_SSPx_Type *spi; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pinmap.c new file mode 100644 index 0000000000..9ca018c86a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pinmap.c @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +#define LPC_IOCON0_BASE (LPC_IOCON_BASE) +#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60) + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + if (pin == (PinName)NC) return; + + uint32_t pin_number = (uint32_t)pin; + + __IO uint32_t *reg = (pin_number < 32) ? + (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : + (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + uint32_t pin_number = (uint32_t)pin; + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + __IO uint32_t *reg = (pin_number < 32) ? + (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : + (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + // drain + tmp &= ~(0x1 << 10); + tmp |= drain << 10; + + *reg = tmp; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/port_api.c new file mode 100644 index 0000000000..334c347391 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/port_api.c @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) { + return (PinName)((port << PORT_SHIFT) | pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO->MASK[port] = ~mask; + + obj->reg_mpin = &LPC_GPIO->MPIN[port]; + obj->reg_dir = &LPC_GPIO->DIR[port]; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_mpin = value; +} + +int port_read(port_t *obj) { + return (*obj->reg_mpin); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.c new file mode 100644 index 0000000000..c008c75989 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.c @@ -0,0 +1,157 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +typedef struct { + uint8_t timer; + uint8_t mr; +} timer_mr; + +static timer_mr pwm_timer_map[11] = { + {0, 0}, {0, 1}, {0, 2}, + {1, 0}, {1, 1}, + {2, 0}, {2, 1}, {2, 2}, + {3, 0}, {3, 1}, {3, 2}, +}; + +static LPC_CTxxBx_Type *Timers[4] = { + LPC_CT16B0, LPC_CT16B1, + LPC_CT32B0, LPC_CT32B1 +}; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->pwm = pwm; + + // Timer registers + timer_mr tid = pwm_timer_map[pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + + // Disable timer + timer->TCR = 0; + + // Power the correspondent timer + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7); + + /* Enable PWM function */ + timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0); + + /* Reset Functionality on MR3 controlling the PWM period */ + timer->MCR = 1 << 10; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + uint32_t t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value); + + timer->MR[tid.mr] = t_off; +} + +float pwmout_read(pwmout_t* obj) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + + float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + int i = 0; + uint32_t period_ticks = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000); + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + uint32_t old_period_ticks = timer->MR3; + + // for 16bit timer, set prescaler to avoid overflow + if (timer == LPC_CT16B0 || timer == LPC_CT16B1) { + uint16_t high_period_ticks = period_ticks >> 16; + timer->PR = high_period_ticks; + period_ticks /= (high_period_ticks + 1); + } + + timer->TCR = TCR_RESET; + timer->MR3 = period_ticks; + + // Scale the pulse width to preserve the duty ratio + if (old_period_ticks > 0) { + for (i=0; i<3; i++) { + uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks); + timer->MR[i] = t_off; + } + } + timer->TCR = TCR_CNT_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + uint32_t t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000 / (timer->PR + 1)); + + timer->TCR = TCR_RESET; + if (t_on > timer->MR3) { + pwmout_period_us(obj, us); + t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000 / (timer->PR + 1)); + } + uint32_t t_off = timer->MR3 - t_on; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/serial_api.c new file mode 100644 index 0000000000..18a3894d31 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/serial_api.c @@ -0,0 +1,288 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 1 + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_USART_Type *)uart; + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + + // [TODO] Consider more elegant approach + // disconnect USBTX/RX mapping mux, for case when switching ports +#ifdef USBTX + pin_function(USBTX, 0); + pin_function(USBRX, 0); +#endif + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + LPC_SYSCON->UARTCLKDIV = 0x1; + uint32_t PCLK = SystemCoreClock; + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable = 0, parity_select = 0; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART->IIR >> 1) & 0x7, 0);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=UART_IRQn ; vector = (uint32_t)&uart0_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/sleep.c new file mode 100644 index 0000000000..b7b979326b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/sleep.c @@ -0,0 +1,79 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + // ensure debug is disconnected + #if DEVICE_SEMIHOST + mbed_interface_disconnect(); + #endif + + // PCON[PD] set to sleep + LPC_PMU->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +/* +* The mbed lpc1768 does not support the deepsleep mode +* as a debugger is connected to it (the mbed interface). +* +* As mentionned in an application note from NXP: +* +* http://www.po-star.com/public/uploads/20120319123122_141.pdf +* +* {{{ +* The user should be aware of certain limitations during debugging. +* The most important is that, due to limitations of the Cortex-M3 +* integration, the LPC17xx cannot wake up in the usual manner from +* Deep Sleep and Power-down modes. It is recommended not to use these +* modes during debug. Once an application is downloaded via JTAG/SWD +* interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example) +* should be removed from the target board, and thereafter, power cycle +* the LPC17xx to allow wake-up from deep sleep and power-down modes +* }}} +* +* As the interface firmware does not reset the target when a +* mbed_interface_disconnect() semihosting call is made, the +* core cannot wake-up from deepsleep. +* +* We treat a deepsleep() as a normal sleep(). +*/ + +void deepsleep(void) { + // ensure debug is disconnected + #if DEVICE_SEMIHOST + mbed_interface_disconnect(); + #endif + + // PCON[PD] set to deepsleep + LPC_PMU->PCON = 0x1; + + // SRC[SLEEPDEEP] set to 1 = deep sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // Power up everything after powerdown + LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800; + + // wait for interrupt + __WFI(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/spi_api.c new file mode 100644 index 0000000000..594f1f086b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/spi_api.c @@ -0,0 +1,185 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "PeripheralPins.h" // For the Peripheral to Pin Definitions found in the individual Target's Platform + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSPx_Type*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11; + LPC_SYSCON->SSP0CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 0; + break; + case SPI_1: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18; + LPC_SYSCON->SSP1CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 2; + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT((bits >= 4 && bits <= 16) || (mode >= 0 && mode <= 3)); + + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c new file mode 100644 index 0000000000..059b272233 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/us_ticker.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_CTxxBx_Type *)LPC_CT32B1_BASE) +#define US_TICKER_TIMER_IRQn TIMER_32_1_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1 + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PeripheralNames.h new file mode 100644 index 0000000000..3ec662f11c --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PeripheralNames.h @@ -0,0 +1,65 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PortNames.h new file mode 100644 index 0000000000..4887fecb33 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/PortNames.h @@ -0,0 +1,33 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/README.md b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/README.md new file mode 100644 index 0000000000..ba7c05892a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/README.md @@ -0,0 +1,4 @@ +LPC1114/LPC11C24 Port +-------------- +A port of the MBED SDK to the NXP LPC1114 by Yoshihiro Tsuboi, Toyomasa Watarai and Matthew Else. +Extra, LPC11C24-specific things added by Joris Aerts.
\ No newline at end of file diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/PinNames.h new file mode 100644 index 0000000000..d99c0de8db --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/PinNames.h @@ -0,0 +1,219 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 12 +#define PIN_SHIFT 8 + +typedef enum { + // LPC1114 Pin Names (PORT[15:12] + PIN[11:8] + IOCON offset[7:0]) + + P0_0 = (0 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x0c, + P0_1 = (0 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x10, + P0_2 = (0 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x1c, + P0_3 = (0 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x2c, + P0_4 = (0 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x30, + P0_5 = (0 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x34, + P0_6 = (0 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x4c, + P0_7 = (0 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x50, + P0_8 = (0 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x60, + P0_9 = (0 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x64, + P0_10 = (0 << PORT_SHIFT) | (10 << PIN_SHIFT) | 0x68, + P0_11 = (0 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x74, + + P1_0 = (1 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x78, + P1_1 = (1 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x7c, + P1_2 = (1 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x80, + P1_3 = (1 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x90, + P1_4 = (1 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x94, + P1_5 = (1 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0xa0, + P1_6 = (1 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0xa4, + P1_7 = (1 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0xa8, + P1_8 = (1 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x14, + P1_9 = (1 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x38, + P1_10 = (1 << PORT_SHIFT) | (10 << PIN_SHIFT) | 0x6c, + P1_11 = (1 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x98, + + P2_0 = (2 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x08, + P2_1 = (2 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x28, + P2_2 = (2 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x5c, + P2_3 = (2 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x8c, + P2_4 = (2 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x40, + P2_5 = (2 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x44, + P2_6 = (2 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x00, + P2_7 = (2 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x20, + P2_8 = (2 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x24, + P2_9 = (2 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x54, + P2_10 = (2 << PORT_SHIFT) | (10 << PIN_SHIFT) | 0x58, + P2_11 = (2 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x70, + + P3_0 = (3 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x84, + P3_1 = (3 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x88, + P3_2 = (3 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x9c, + P3_3 = (3 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0xac, + P3_4 = (3 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x3c, + P3_5 = (3 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x48, + + // mbed DIP Pin Names (CQ board) + p4 = P0_0, + p5 = P0_9, + p6 = P0_8, + p7 = P0_6, + p8 = P1_5, + p9 = P1_7, + p10 = P1_6, + p11 = P0_7, + p12 = P1_0, + p13 = P1_1, + p14 = P1_2, + p15 = P0_11, + p16 = P1_0, + p17 = P1_1, + p18 = P1_2, + p19 = P1_3, + p20 = P1_4, + p21 = P0_10, + p22 = P0_2, + p23 = P0_11, + p24 = P0_2, + p25 = P1_8, + p26 = P1_9, + p27 = P0_4, + p28 = P0_5, + p29 = P0_3, + p30 = P0_1, + + // Other mbed Pin Names + LED1 = P1_5, + LED2 = P0_7, + LED3 = P1_5, + LED4 = P0_7, + + USBTX = P1_7, + USBRX = P1_6, + + // mbed DIP Pin Names (LPCXpresso LPC1114) + xp4 = P0_0, + xp5 = P0_9, + xp6 = P0_8, + xp7 = P2_11, + xp8 = P0_2, + xp9 = P1_7, + xp10 = P1_6, + xp11 = P0_7, + xp12 = P2_0, + xp13 = P2_1, + xp14 = P2_2, + xp15 = P0_11, + xp16 = P1_0, + xp17 = P1_1, + xp18 = P1_2, + xp19 = P1_3, + xp20 = P1_4, + xp21 = P1_5, + xp22 = P1_8, + xp23 = P0_6, + xp24 = P0_10, + xp25 = P3_0, + xp26 = P3_1, + xp27 = P3_2, + + xp29 = P3_3, + xp30 = P2_10, + xp31 = P2_9, + xp32 = P2_8, + xp33 = P2_7, + xp34 = P2_6, + xp35 = P2_5, + xp36 = P2_4, + xp37 = P2_3, + xp38 = P1_11, + xp39 = P1_10, + xp40 = P1_9, + xp41 = P0_4, + xp42 = P0_5, + xp43 = P0_3, + xp44 = P0_1, + + // Other mbed Pin Names + xLED1 = P0_7, + + // DIP Package Names + + dp1 = P0_8, + dp2 = P0_9, + dp3 = P0_10, + dp4 = P0_11, + dp5 = P0_5, + dp6 = P0_6, + dp9 = P1_0, + dp10 = P1_1, + dp11 = P1_2, + dp12 = P1_3, + dp13 = P1_4, + dp14 = P1_5, + dp15 = P1_6, + dp16 = P1_7, + dp17 = P1_8, + dp18 = P1_9, + dp23 = P0_0, + dp24 = P0_1, + dp25 = P0_2, + dp26 = P0_3, + dp27 = P0_4, + dp28 = P0_7, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = WAKEUP0_IRQn, + CHANNEL1 = WAKEUP1_IRQn, + CHANNEL2 = WAKEUP2_IRQn, + CHANNEL3 = WAKEUP3_IRQn, + CHANNEL4 = WAKEUP4_IRQn, + CHANNEL5 = WAKEUP5_IRQn, + CHANNEL6 = WAKEUP6_IRQn, + CHANNEL7 = WAKEUP7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/can_api.c new file mode 100644 index 0000000000..b017d1ab25 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/can_api.c @@ -0,0 +1,424 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "can_api.h" + +#include "cmsis.h" +#include "mbed_error.h" + +#include <math.h> +#include <string.h> + +/* Handy defines */ +#define MSG_OBJ_MAX 32 +#define DLC_MAX 8 + +#define ID_STD_MASK 0x07FF +#define ID_EXT_MASK 0x1FFFFFFF +#define DLC_MASK 0x0F + +static uint32_t can_irq_id = 0; +static can_irq_handler irq_handler; + +static uint32_t can_disable(can_t *obj) { + uint32_t sm = LPC_CAN->CNTL; + LPC_CAN->CNTL |= CANCNTL_INIT; + return sm; +} + +static inline void can_enable(can_t *obj) { + if (LPC_CAN->CNTL & CANCNTL_INIT) { + LPC_CAN->CNTL &= ~CANCNTL_INIT; + } +} + +int can_mode(can_t *obj, CanMode mode) { + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + uint16_t i; + + // Find first free message object + if(handle == 0) { + uint32_t msgval = LPC_CAN->MSGV1 | (LPC_CAN->MSGV2 << 16); + // Find first free messagebox + for(i = 0; i < 32; i++) { + if((msgval & (1 << i)) == 0) { + handle = i+1; + break; + } + } + } + + if(handle > 0 && handle < 32) { + if(format == CANExtended) { + // Mark message valid, Direction = TX, Extended Frame, Set Identifier and mask everything + LPC_CAN->IF1_ARB1 = BFN_PREP(id, CANIFn_ARB1_ID); + LPC_CAN->IF1_ARB2 = CANIFn_ARB2_MSGVAL | CANIFn_ARB2_XTD | BFN_PREP(id >> 16, CANIFn_ARB2_ID); + LPC_CAN->IF1_MSK1 = BFN_PREP(mask, CANIFn_MSK1_MSK); + LPC_CAN->IF1_MSK2 = CANIFn_MSK2_MXTD /* | CANIFn_MSK2_MDIR */ | BFN_PREP(mask >> 16, CANIFn_MSK2_MSK); + } + else { + // Mark message valid, Direction = TX, Set Identifier and mask everything + LPC_CAN->IF1_ARB2 = CANIFn_ARB2_MSGVAL | BFN_PREP(id << 2, CANIFn_ARB2_ID); + LPC_CAN->IF1_MSK2 = /* CANIFn_MSK2_MDIR | */ BFN_PREP(mask << 2, CANIFn_MSK2_MSK); + } + + // Use mask, single message object and set DLC + LPC_CAN->IF1_MCTRL = CANIFn_MCTRL_UMASK | CANIFn_MCTRL_EOB | CANIFn_MCTRL_RXIE | BFN_PREP(DLC_MAX, CANIFn_MCTRL_DLC); + + // Transfer all fields to message object + LPC_CAN->IF1_CMDMSK = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL; + + // Start Transfer to given message number + LPC_CAN->IF1_CMDREQ = BFN_PREP(handle, CANIFn_CMDREQ_MN); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while( LPC_CAN->IF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + } + + return handle; +} + +static inline void can_irq() { + irq_handler(can_irq_id, IRQ_RX); +} + +// Register CAN object's irq handler +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { + irq_handler = handler; + can_irq_id = id; +} + +// Unregister CAN object's irq handler +void can_irq_free(can_t *obj) { + LPC_CAN->CNTL &= ~CANCNTL_IE; // Disable Interrupts :) + + can_irq_id = 0; + NVIC_DisableIRQ(CAN_IRQn); +} + +// Clear or set a irq +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { + // Put CAN in Reset Mode and enable interrupt + can_disable(obj); + if(enable == 0) { + LPC_CAN->CNTL &= ~(CANCNTL_IE | CANCNTL_SIE); + } + else { + LPC_CAN->CNTL |= CANCNTL_IE | CANCNTL_SIE; + } + // Take it out of reset... + can_enable(obj); + + // Enable NVIC if at least 1 interrupt is active + NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq); + NVIC_EnableIRQ(CAN_IRQn); +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int sclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint32_t clkdiv = 1; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits = 0; + + bitwidth = sclk / cclk; + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + /* This might be funky + while(btr > 63 && clkdiv < 16) { + btr = btr / 2; + clkdiv = clkdiv * 2; + } + */ + clkdiv = clkdiv - 1; + + if (hit) { + btr = BFN_PREP(timing_pts[bits][1], CANBT_TSEG2) + | BFN_PREP(timing_pts[bits][0], CANBT_TSEG1) + | BFN_PREP(psjw, CANBT_SJW) + | BFN_PREP(brp, CANBT_BRP); + btr = btr | (clkdiv << 16); + + } else { + btr = 0; + } + + return btr; +} + + +int can_config_rxmsgobj(can_t *obj) { + uint16_t i = 0; + + // Make sure the interface is available + //while( LPC_CAN->IF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Mark message valid, Direction = RX, Don't care about anything else + LPC_CAN->IF1_ARB1 = 0; + LPC_CAN->IF1_ARB2 = 0; + LPC_CAN->IF1_MCTRL = 0; + + for ( i = 0; i < MSG_OBJ_MAX; i++ ) + { + // Transfer arb and control fields to message object + LPC_CAN->IF1_CMDMSK = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_TXRQST; + + // Start Transfer to given message number + LPC_CAN->IF1_CMDREQ = BFN_PREP(i, CANIFn_CMDREQ_MN); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while( LPC_CAN->IF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + } + + // Accept all messages + can_filter(obj, 0, 0, CANStandard, 1); + + return 1; +} + + +void can_init(can_t *obj, PinName rd, PinName td) { + // Enable power and clock + LPC_SYSCON->PRESETCTRL |= PRESETCTRL_CAN_RST_N; + LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_CAN; + + // Enable Initialization mode + if (!(LPC_CAN->CNTL & CANCNTL_INIT)) { + LPC_CAN->CNTL |= CANCNTL_INIT; + } + + can_frequency(obj, 125000); + + // Resume operation + LPC_CAN->CNTL &= ~CANCNTL_INIT; + while ( LPC_CAN->CNTL & CANCNTL_INIT ); + + // Initialize RX message object + can_config_rxmsgobj(obj); +} + +void can_free(can_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL &= ~(SYSAHBCLKCTRL_CAN); + LPC_SYSCON->PRESETCTRL &= ~(PRESETCTRL_CAN_RST_N); +} + +int can_frequency(can_t *obj, int f) { + int btr = can_speed(SystemCoreClock, (unsigned int)f, 1); + int clkdiv = (btr >> 16) & 0x0F; + btr = btr & 0xFFFF; + + if (btr > 0) { + uint32_t cntl_init = LPC_CAN->CNTL | CANCNTL_INIT; + // Set the bit clock + LPC_CAN->CNTL |= CANCNTL_CCE | CANCNTL_INIT; + LPC_CAN->CLKDIV = clkdiv; + LPC_CAN->BT = btr; + LPC_CAN->BRPE = 0x0000; + LPC_CAN->CNTL &= ~(CANCNTL_CCE | CANCNTL_INIT); + LPC_CAN->CNTL |= cntl_init; + return 1; + } + return 0; +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + uint16_t msgnum = 0; + + // Make sure controller is enabled + can_enable(obj); + + // Make sure the interface is available + while( LPC_CAN->IF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Set the direction bit based on the message type + uint32_t direction = 0; + if (msg.type == CANData) { + direction = CANIFn_ARB2_DIR; + } + + if(msg.format == CANExtended) { + // Mark message valid, Extended Frame, Set Identifier and mask everything + LPC_CAN->IF1_ARB1 = BFN_PREP(msg.id, CANIFn_ARB1_ID); + LPC_CAN->IF1_ARB2 = CANIFn_ARB2_MSGVAL | CANIFn_ARB2_XTD | direction | BFN_PREP(msg.id >> 16, CANIFn_ARB2_ID); + LPC_CAN->IF1_MSK1 = BFN_PREP(ID_EXT_MASK, CANIFn_MSK1_MSK); + LPC_CAN->IF1_MSK2 = CANIFn_MSK2_MXTD | CANIFn_MSK2_MDIR | BFN_PREP(ID_EXT_MASK >> 16, CANIFn_MSK2_MSK); + } + else { + // Mark message valid, Set Identifier and mask everything + LPC_CAN->IF1_ARB2 = CANIFn_ARB2_MSGVAL | direction | BFN_PREP(msg.id << 2, CANIFn_ARB2_ID); + LPC_CAN->IF1_MSK2 = CANIFn_MSK2_MDIR | BFN_PREP(ID_STD_MASK << 2, CANIFn_MSK2_MSK); + } + + // Use mask, request transmission, single message object and set DLC + LPC_CAN->IF1_MCTRL = CANIFn_MCTRL_UMASK | CANIFn_MCTRL_TXRQST | CANIFn_MCTRL_EOB | BFN_PREP(msg.len, CANIFn_MCTRL_DLC); + + LPC_CAN->IF1_DA1 = BFN_PREP(msg.data[1], CANIFn_DA1_DATA1) | BFN_PREP(msg.data[0], CANIFn_DA1_DATA0); + LPC_CAN->IF1_DA2 = BFN_PREP(msg.data[3], CANIFn_DA2_DATA3) | BFN_PREP(msg.data[2], CANIFn_DA2_DATA2); + LPC_CAN->IF1_DB1 = BFN_PREP(msg.data[5], CANIFn_DB1_DATA5) | BFN_PREP(msg.data[4], CANIFn_DB1_DATA4); + LPC_CAN->IF1_DB2 = BFN_PREP(msg.data[7], CANIFn_DB2_DATA7) | BFN_PREP(msg.data[6], CANIFn_DB2_DATA6); + + // Transfer all fields to message object + LPC_CAN->IF1_CMDMSK = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_TXRQST | CANIFn_CMDMSK_DATA_A | CANIFn_CMDMSK_DATA_B; + + // Start Transfer to given message number + LPC_CAN->IF1_CMDREQ = BFN_PREP(msgnum, CANIFn_CMDREQ_MN); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while( LPC_CAN->IF1_CMDREQ & CANIFn_CMDREQ_BUSY); + + // Wait until TXOK is set, then clear it - TODO: maybe not block + //while( !(LPC_CAN->STAT & CANSTAT_TXOK) ); + LPC_CAN->STAT &= ~(CANSTAT_TXOK); + + return 1; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + uint16_t i; + + // Make sure controller is enabled + can_enable(obj); + + // Find first message object with new data + if(handle == 0) { + uint32_t newdata = LPC_CAN->ND1 | (LPC_CAN->ND2 << 16); + // Find first free messagebox + for(i = 0; i < 32; i++) { + if(newdata & (1 << i)) { + handle = i+1; + break; + } + } + } + + if(handle > 0 && handle < 32) { + // Wait until message interface is free + while( LPC_CAN->IF2_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Transfer all fields to message object + LPC_CAN->IF2_CMDMSK = CANIFn_CMDMSK_RD | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_CLRINTPND | CANIFn_CMDMSK_TXRQST | CANIFn_CMDMSK_DATA_A | CANIFn_CMDMSK_DATA_B; + + // Start Transfer from given message number + LPC_CAN->IF2_CMDREQ = BFN_PREP(handle, CANIFn_CMDREQ_MN); + + // Wait until transfer to message ram complete + while( LPC_CAN->IF2_CMDREQ & CANIFn_CMDREQ_BUSY ); + + if (LPC_CAN->IF2_ARB2 & CANIFn_ARB2_XTD) { + msg->format = CANExtended; + msg->id = (LPC_CAN->IF2_ARB1 & CANIFn_ARB2_ID_MASK) << 16; + msg->id |= (LPC_CAN->IF2_ARB2 & CANIFn_ARB2_ID_MASK); + } + else { + msg->format = CANStandard; + msg->id = (LPC_CAN->IF2_ARB2 & CANIFn_ARB2_ID_MASK) >> 2; + } + + if (LPC_CAN->IF2_ARB2 & CANIFn_ARB2_DIR) { + msg->type = CANRemote; + } + else { + msg->type = CANData; + } + + msg->len = BFN_GET(LPC_CAN->IF2_MCTRL, CANIFn_MCTRL_DLC); // TODO: If > 8, len = 8 + msg->data[0] = BFN_GET(LPC_CAN->IF2_DA1, CANIFn_DA1_DATA0); + msg->data[1] = BFN_GET(LPC_CAN->IF2_DA1, CANIFn_DA1_DATA1); + msg->data[2] = BFN_GET(LPC_CAN->IF2_DA2, CANIFn_DA2_DATA2); + msg->data[3] = BFN_GET(LPC_CAN->IF2_DA2, CANIFn_DA2_DATA3); + msg->data[4] = BFN_GET(LPC_CAN->IF2_DB1, CANIFn_DB1_DATA4); + msg->data[5] = BFN_GET(LPC_CAN->IF2_DB1, CANIFn_DB1_DATA5); + msg->data[6] = BFN_GET(LPC_CAN->IF2_DB2, CANIFn_DB2_DATA6); + msg->data[7] = BFN_GET(LPC_CAN->IF2_DB2, CANIFn_DB2_DATA7); + + LPC_CAN->STAT &= ~(CANSTAT_RXOK); + return 1; + } + + return 0; +} + +void can_reset(can_t *obj) { + LPC_SYSCON->PRESETCTRL &= ~PRESETCTRL_CAN_RST_N; + LPC_CAN->STAT = 0; + + can_config_rxmsgobj(obj); +} + +unsigned char can_rderror(can_t *obj) { + return BFN_GET(LPC_CAN->EC, CANEC_REC); +} + +unsigned char can_tderror(can_t *obj) { + return BFN_GET(LPC_CAN->EC, CANEC_TEC); +} + +void can_monitor(can_t *obj, int silent) { + if (silent) { + LPC_CAN->CNTL |= CANCNTL_TEST; + LPC_CAN->TEST |= CANTEST_SILENT; + } else { + LPC_CAN->CNTL &= ~(CANCNTL_TEST); + LPC_CAN->TEST &= ~CANTEST_SILENT; + } + + if (!(LPC_CAN->CNTL & CANCNTL_INIT)) { + LPC_CAN->CNTL |= CANCNTL_INIT; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/device.h new file mode 100644 index 0000000000..f7d2f2a614 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/reserved_pins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/reserved_pins.h new file mode 100644 index 0000000000..7c8a7ba3c4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11CXX/reserved_pins.h @@ -0,0 +1,8 @@ +// List of reserved pins for LPC11C24 + +#ifndef RESERVED_PINS_H +#define RESERVED_PINS_H + +#define TARGET_RESERVED_PINS {P0_0, P0_10, P0_11, P1_0, P1_1, P1_2, P1_3} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/PinNames.h new file mode 100644 index 0000000000..263fb3bb78 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/PinNames.h @@ -0,0 +1,234 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 12 +#define PIN_SHIFT 8 + +typedef enum { + // LPC1114 Pin Names (PORT[15:12] + PIN[11:8] + IOCON offset[7:0]) + + P0_0 = (0 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x0c, + P0_1 = (0 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x10, + P0_2 = (0 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x1c, + P0_3 = (0 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x2c, + P0_4 = (0 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x30, + P0_5 = (0 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x34, + P0_6 = (0 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x4c, + P0_7 = (0 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x50, + P0_8 = (0 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x60, + P0_9 = (0 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x64, + P0_11 = (0 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x74, + + P1_0 = (1 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x78, + P1_1 = (1 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x7c, + P1_2 = (1 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x80, + P1_4 = (1 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x94, + P1_5 = (1 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0xa0, + P1_6 = (1 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0xa4, + P1_7 = (1 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0xa8, + P1_8 = (1 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x14, + P1_9 = (1 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x38, + P1_10 = (1 << PORT_SHIFT) | (10 << PIN_SHIFT) | 0x6c, + P1_11 = (1 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x98, + + P2_0 = (2 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x08, + P2_1 = (2 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x28, + P2_2 = (2 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x5c, + P2_3 = (2 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0x8c, + P2_4 = (2 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x40, + P2_5 = (2 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x44, + P2_6 = (2 << PORT_SHIFT) | (6 << PIN_SHIFT) | 0x00, + P2_7 = (2 << PORT_SHIFT) | (7 << PIN_SHIFT) | 0x20, + P2_8 = (2 << PORT_SHIFT) | (8 << PIN_SHIFT) | 0x24, + P2_9 = (2 << PORT_SHIFT) | (9 << PIN_SHIFT) | 0x54, + P2_10 = (2 << PORT_SHIFT) | (10 << PIN_SHIFT) | 0x58, + P2_11 = (2 << PORT_SHIFT) | (11 << PIN_SHIFT) | 0x70, + + P3_0 = (3 << PORT_SHIFT) | (0 << PIN_SHIFT) | 0x84, + P3_1 = (3 << PORT_SHIFT) | (1 << PIN_SHIFT) | 0x88, + P3_2 = (3 << PORT_SHIFT) | (2 << PIN_SHIFT) | 0x9c, + P3_3 = (3 << PORT_SHIFT) | (3 << PIN_SHIFT) | 0xac, + P3_4 = (3 << PORT_SHIFT) | (4 << PIN_SHIFT) | 0x3c, + P3_5 = (3 << PORT_SHIFT) | (5 << PIN_SHIFT) | 0x48, + + // mbed DIP Pin Names (CQ board) +// p4 = P0_0, + p5 = P0_9, + p6 = P0_8, + p7 = P0_6, + p8 = P1_5, + p9 = P1_7, + p10 = P1_6, + p11 = P0_7, + p12 = P1_0, + p13 = P1_1, + p14 = P1_2, + p15 = P0_11, + p16 = P1_0, + p17 = P1_1, + p18 = P1_2, + p20 = P1_4, + p22 = P0_2, + p23 = P0_11, + p24 = P0_2, + p25 = P1_8, + p26 = P1_9, + p27 = P0_4, + p28 = P0_5, + p29 = P0_3, + p30 = P0_1, + + // Other mbed Pin Names + LED1 = P1_5, + LED2 = P0_7, + LED3 = P1_5, + LED4 = P0_7, + + USBTX = P1_7, + USBRX = P1_6, + + // mbed DIP Pin Names (LPCXpresso LPC1114) +// xp4 = P0_0, + xp5 = P0_9, + xp6 = P0_8, + xp7 = P2_11, + xp8 = P0_2, + xp9 = P1_7, + xp10 = P1_6, + xp11 = P0_7, + xp12 = P2_0, + xp13 = P2_1, + xp14 = P2_2, + xp15 = P0_11, + xp16 = P1_0, + xp17 = P1_1, + xp18 = P1_2, + xp20 = P1_4, + xp21 = P1_5, + xp22 = P1_8, + xp23 = P0_6, + xp25 = P3_0, + xp26 = P3_1, + xp27 = P3_2, + + xp29 = P3_3, + xp30 = P2_10, + xp31 = P2_9, + xp32 = P2_8, + xp33 = P2_7, + xp34 = P2_6, + xp35 = P2_5, + xp36 = P2_4, + xp37 = P2_3, + xp38 = P1_11, + xp39 = P1_10, + xp40 = P1_9, + xp41 = P0_4, + xp42 = P0_5, + xp43 = P0_3, + xp44 = P0_1, + + // Other mbed Pin Names + xLED1 = P0_7, + + // DIP Package Names + + dp1 = P0_8, + dp2 = P0_9, + dp4 = P0_11, + dp5 = P0_5, + dp6 = P0_6, + dp9 = P1_0, + dp10 = P1_1, + dp11 = P1_2, + dp13 = P1_4, + dp14 = P1_5, + dp15 = P1_6, + dp16 = P1_7, + dp17 = P1_8, + dp18 = P1_9, +// dp23 = P0_0, + dp24 = P0_1, + dp25 = P0_2, + dp26 = P0_3, + dp27 = P0_4, + dp28 = P0_7, + + dip1 = P0_8, + dip2 = P0_9, + dip4 = P0_11, + dip5 = P0_5, + dip6 = P0_6, + dip9 = P1_0, + dip10 = P1_1, + dip11 = P1_2, + dip13 = P1_4, + dip14 = P1_5, + dip15 = P1_6, + dip16 = P1_7, + dip17 = P1_8, + dip18 = P1_9, +// dip23 = P0_0, + dip24 = P0_1, + dip25 = P0_2, + dip26 = P0_3, + dip27 = P0_4, + dip28 = P0_7, + + + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = WAKEUP0_IRQn, + CHANNEL1 = WAKEUP1_IRQn, + CHANNEL2 = WAKEUP2_IRQn, + CHANNEL3 = WAKEUP3_IRQn, + CHANNEL4 = WAKEUP4_IRQn, + CHANNEL5 = WAKEUP5_IRQn, + CHANNEL6 = WAKEUP6_IRQn, + CHANNEL7 = WAKEUP7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/device.h new file mode 100644 index 0000000000..a45349a9e3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/reserved_pins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/reserved_pins.h new file mode 100644 index 0000000000..f33637f557 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/TARGET_LPC11XX/reserved_pins.h @@ -0,0 +1,8 @@ +// List of reserved pins for LPC1114 + +#ifndef RESERVED_PINS_H +#define RESERVED_PINS_H + +#define TARGET_RESERVED_PINS {P0_0, P0_11, P1_0, P1_1, P1_2} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/analogin_api.c new file mode 100644 index 0000000000..073d973693 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/analogin_api.c @@ -0,0 +1,122 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 2}, + {P1_0 , ADC0_1, 2}, + {P1_1 , ADC0_2, 2}, + {P1_2 , ADC0_3, 2}, + // {P1_3 , ADC0_4, 2}, -- should be mapped to SWDIO only + {P1_4 , ADC0_5, 1}, + {P1_10, ADC0_6, 1}, + {P1_11, ADC0_7, 1}, + {NC , NC , 0} +}; + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +#define ADC_RANGE ADC_10BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (uint32_t)NC); + + // Power up ADC + LPC_SYSCON->PDRUNCFG &= ~ (1 << 4); + LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13); + + uint32_t offset = (uint32_t)pin & 0xff; + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + + // set pin to ADC mode + *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) + + uint32_t PCLK = SystemCoreClock; + uint32_t MAX_ADC_CLK = 4500000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + LPC_ADC->CR = (0 << 0) // no channels selected + | (clkdiv << 8) // max of 4.5MHz + | (0 << 16) // BURST = 0, software controlled + | ( 0 << 17 ); // CLKS = 0, not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 6) & ADC_RANGE; // 10 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_api.c new file mode 100644 index 0000000000..5875ca9e85 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_api.c @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" +#include "reserved_pins.h" + +static const PinName reserved_pins[] = TARGET_RESERVED_PINS; + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + // PIO default value of following ports are not same as others + unsigned i; + int f = 0; + + for (i = 0; i < sizeof(reserved_pins) / sizeof(PinName); i ++) { + if (pin == reserved_pins[i]) { + f = 1; + break; + } + } + pin_function(pin, f); + return ((pin & 0x0F00) >> 8); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (((pin & 0xF000) >> PORT_SHIFT) * 0x10000))); + + obj->reg_mask_read = &port_reg->MASKED_ACCESS[1 << gpio_set(pin)]; + obj->reg_dir = &port_reg->DIR; + obj->reg_write = &port_reg->DATA; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + int pin_number = ((obj->pin & 0x0F00) >> 8); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~(1 << pin_number); + break; + case PIN_OUTPUT: + *obj->reg_dir |= (1 << pin_number); + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_irq_api.c new file mode 100644 index 0000000000..db111511d3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_irq_api.c @@ -0,0 +1,216 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include "gpio_api.h" + +// The chip is capable of 42 GPIO interrupts. +// PIO0_0..PIO0_11, PIO1_0..PIO1_11, PIO2_0..PIO2_11, PIO3_0..PIO3_5 +#define CHANNEL_NUM 42 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline int numofbits(uint32_t bits) +{ + // Count number of bits + bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555); + bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333); + bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f); + bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff); + return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff); +} + +static inline void handle_interrupt_in(uint32_t port) { + // Find out whether the interrupt has been triggered by a high or low value... + // As the LPC1114 doesn't have a specific register for this, we'll just have to read + // the level of the pin as if it were just a normal input... + + uint32_t channel; + + // Get the number of the pin being used and the port typedef + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (port * 0x10000))); + + // Get index of function table from Mask Interrupt Status register + channel = numofbits(port_reg->MIS - 1) + (port * 12); + + if (port_reg->MIS & port_reg->IBE) { + // both edge, read the level of pin + if ((port_reg->DATA & port_reg->MIS) != 0) + irq_handler(channel_ids[channel], IRQ_RISE); + else + irq_handler(channel_ids[channel], IRQ_FALL); + } + else if (port_reg->MIS & port_reg->IEV) { + irq_handler(channel_ids[channel], IRQ_RISE); + } + else { + irq_handler(channel_ids[channel], IRQ_FALL); + } + + // Clear the interrupt... + port_reg->IC = port_reg->MIS; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + int channel; + uint32_t port_num; + + if (pin == NC) return -1; + + // Firstly, we'll put some data in *obj so we can keep track of stuff. + obj->pin = pin; + + // Set the handler to be the pointer at the top... + irq_handler = handler; + + // Which port are we using? + port_num = ((pin & 0xF000) >> PORT_SHIFT); + + switch (port_num) { + case 0: + NVIC_SetVector(EINT0_IRQn, (uint32_t)gpio_irq0); + NVIC_EnableIRQ(EINT0_IRQn); + break; + case 1: + NVIC_SetVector(EINT1_IRQn, (uint32_t)gpio_irq1); + NVIC_EnableIRQ(EINT1_IRQn); + break; + case 2: + NVIC_SetVector(EINT2_IRQn, (uint32_t)gpio_irq2); + NVIC_EnableIRQ(EINT2_IRQn); + break; + case 3: + NVIC_SetVector(EINT3_IRQn, (uint32_t)gpio_irq3); + NVIC_EnableIRQ(EINT3_IRQn); + break; + default: + return -1; + } + + // Generate index of function pointer table + // PIO0_0 - PIO0_11 : 0..11 + // PIO1_0 - PIO1_11 : 12..23 + // PIO2_0 - PIO2_11 : 24..35 + // PIO3_0 - PIO3_5 : 36..41 + channel = (port_num * 12) + ((pin & 0x0F00) >> PIN_SHIFT); + + channel_ids[channel] = id; + obj->ch = channel; + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + // Firstly, check if there is an existing event stored... + + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (((obj->pin & 0xF000) >> PORT_SHIFT) * 0x10000))); + + // Need to get the pin number of the pin, not the value of the enum + uint32_t pin_num = (1 << ((obj->pin & 0x0f00) >> PIN_SHIFT)); + + // Clear + port_reg->IC |= pin_num; + + // Make it edge sensitive. + port_reg->IS &= ~pin_num; + + if ( (port_reg->IE & pin_num) != 0) { + // We have an event. + // Enable both edge interrupts. + + if (enable) { + port_reg->IBE |= pin_num; + port_reg->IE |= pin_num; + } + else { + // These all need to be opposite, to reenable the other one. + port_reg->IBE &= ~pin_num; + + if (event == IRQ_RISE) + port_reg->IEV &= ~pin_num; + else + port_reg->IEV |= pin_num; + + port_reg->IE |= pin_num; + } + } + else { + // One edge + port_reg->IBE &= ~pin_num; + // Rising/falling? + if (event == IRQ_RISE) + port_reg->IEV |= pin_num; + else + port_reg->IEV &= ~pin_num; + + if (enable) { + port_reg->IE |= pin_num; + } + } + +} + +void gpio_irq_enable(gpio_irq_t *obj) { + uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT); + switch (port_num) { + case 0: + NVIC_EnableIRQ(EINT0_IRQn); + break; + case 1: + NVIC_EnableIRQ(EINT1_IRQn); + break; + case 2: + NVIC_EnableIRQ(EINT2_IRQn); + break; + case 3: + NVIC_EnableIRQ(EINT3_IRQn); + break; + default: + break; + } +} + +void gpio_irq_disable(gpio_irq_t *obj) { + uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT); + switch (port_num) { + case 0: + NVIC_DisableIRQ(EINT0_IRQn); + break; + case 1: + NVIC_DisableIRQ(EINT1_IRQn); + break; + case 2: + NVIC_DisableIRQ(EINT2_IRQn); + break; + case 3: + NVIC_DisableIRQ(EINT3_IRQn); + break; + default: + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_object.h new file mode 100644 index 0000000000..f295911aaa --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/gpio_object.h @@ -0,0 +1,54 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + __I uint32_t *reg_mask_read; + __IO uint32_t *reg_dir; + __IO uint32_t *reg_write; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + uint32_t pin_number = ((obj->pin & 0x0F00) >> 8); + if (value) + *obj->reg_write |= (1 << pin_number); + else + *obj->reg_write &= ~(1 << pin_number); +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_mask_read) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c new file mode 100644 index 0000000000..f4a271e1d0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c @@ -0,0 +1,387 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); + LPC_SYSCON->PRESETCTRL |= 1 << 1; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; + *((uint32_t *) addr) = mask & 0xFE; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/objects.h new file mode 100644 index 0000000000..f98fd59233 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/objects.h @@ -0,0 +1,74 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; + PinName pin; + __I uint32_t *reg_mask_read; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_data; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + PWMName pwm; +}; + +struct serial_s { + LPC_UART_TypeDef *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SSP_TypeDef *spi; +}; + +#if DEVICE_CAN +struct can_s { + int index; +}; +#endif + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pinmap.c new file mode 100644 index 0000000000..7dbb40c386 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pinmap.c @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + uint32_t offset = (uint32_t)pin & 0xff; + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + uint32_t offset = (uint32_t)pin & 0xff; + uint32_t drain = ((uint32_t)mode & (uint32_t)OpenDrain) >> 2; + + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + // drain + tmp &= ~(0x1 << 10); + tmp |= drain << 10; + + *reg = tmp; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/port_api.c new file mode 100644 index 0000000000..3dd911eed5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/port_api.c @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +// LPC114 IOCON offset table [port][pin] + +static uint8_t iocon_offset[4][12] = { + {0x0c,0x10,0x1c,0x2c,0x30,0x34,0x4c,0x50,0x60,0x64,0x68,0x74}, // PORT 0 + {0x78,0x7c,0x80,0x90,0x94,0xa0,0xa4,0xa8,0x14,0x38,0x6c,0x98}, // PORT 1 + {0x08,0x28,0x5c,0x8c,0x40,0x44,0x00,0x20,0x24,0x54,0x58,0x70}, // PORT 2 + {0x84,0x88,0x9c,0xac,0x3c,0x48} // PORT 3 +}; + +PinName port_pin(PortName port, int pin) { + return (PinName)((port << PORT_SHIFT) | (pin << PIN_SHIFT) | (uint32_t)iocon_offset[port][pin]); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) (LPC_GPIO0_BASE + (port * 0x10000))); + + obj->reg_data = &port_reg->DATA; + obj->reg_dir = &port_reg->DIR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<12; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<12; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_data = (value & obj->mask); +} + +int port_read(port_t *obj) { + return (*obj->reg_data & obj->mask); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c new file mode 100644 index 0000000000..6d0fbefbb3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/pwmout_api.c @@ -0,0 +1,188 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +static const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 0x02}, /* MR0 */ + {P0_9 , PWM_2, 0x02}, /* MR1 */ + + /* CT16B1 */ + {P1_9 , PWM_3, 0x01}, /* MR0 */ + {P1_10, PWM_4, 0x02}, /* MR1 */ + + /* CT32B0 */ + {P0_1 , PWM_5, 0x02}, /* MR2 */ + + {NC , NC ,0x00} +}; + +typedef struct { + uint8_t timer; + uint8_t mr; +} timer_mr; + +static timer_mr pwm_timer_map[5] = { + {0, 0}, /* CT16B0, MR0 */ + {0, 1}, /* CT16B0, MR1 */ + + {1, 0}, /* CT16B1, MR0 */ + {1, 1}, /* CT16B1, MR1 */ + + {2, 2}, /* CT32B0, MR2 */ +}; + +static LPC_TMR_TypeDef *Timers[3] = { + LPC_TMR16B0, LPC_TMR16B1, + LPC_TMR32B0 +}; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (uint32_t)NC); + + obj->pwm = pwm; + + // Timer registers + timer_mr tid = pwm_timer_map[pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + + // Disable timer + timer->TCR = 0; + + // Power the correspondent timer + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7); + + /* Enable PWM function */ + timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0); + + /* Reset Functionality on MR3 controlling the PWM period */ + timer->MCR = 1 << 10; + + if (timer == LPC_TMR16B0 || timer == LPC_TMR16B1) { + /* Set 16-bit timer prescaler to avoid timer expire for default 20ms */ + /* This can be also modified by user application, but the prescaler value */ + /* might be trade-off to timer accuracy */ + timer->PR = 30; + } + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + uint32_t t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value); + // to avoid spike pulse when duty is 0% + if (value == 0) { + t_off++; + } + + timer->TCR = TCR_RESET; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} + +float pwmout_read(pwmout_t* obj) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + + float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3); + if (timer->MR[tid.mr] > timer->MR3) { + v = 0.0f; + } + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + int i = 0; + uint32_t period_ticks; + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + uint32_t old_period_ticks = timer->MR3; + period_ticks = (SystemCoreClock / 1000000 * us) / (timer->PR + 1); + + timer->TCR = TCR_RESET; + timer->MR3 = period_ticks; + + // Scale the pulse width to preserve the duty ratio + if (old_period_ticks > 0) { + for (i=0; i<3; i++) { + uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks); + timer->MR[i] = t_off; + } + } + timer->TCR = TCR_CNT_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + uint32_t t_on = (uint32_t)((((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000) / (timer->PR + 1)); + + timer->TCR = TCR_RESET; + if (t_on > timer->MR3) { + pwmout_period_us(obj, us); + } + uint32_t t_off = timer->MR3 - t_on; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/serial_api.c new file mode 100644 index 0000000000..7fc8168884 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/serial_api.c @@ -0,0 +1,301 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 1 + +static const PinMap PinMap_UART_TX[] = { + {P2_8 , UART_0, 0x02}, + {P3_5 , UART_0, 0x02}, + {P3_0 , UART_0, 0x03}, + {P1_7 , UART_0, 0x01}, + {NC , NC , 0x00} +}; + +static const PinMap PinMap_UART_RX[] = { + {P2_7 , UART_0, 0x02}, + {P3_4 , UART_0, 0x02}, + {P3_1 , UART_0, 0x03}, + {P1_6 , UART_0, 0x01}, + {NC , NC , 0x00} +}; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_UART_TypeDef *)uart; + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + LPC_SYSCON->UARTCLKDIV = 0x1; + uint32_t PCLK = SystemCoreClock; + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART->IIR >> 1) & 0x7, 0);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: + irq_n=UART_IRQn; + vector = (uint32_t)&uart0_irq; + break; + default: + return; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= 1 << 6; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c new file mode 100644 index 0000000000..8507cc5a75 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/sleep.c @@ -0,0 +1,49 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + + // PCON[DPDEN] set to sleep + LPC_PMU->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +void deepsleep(void) { + + // PCON[DPDEN] set to deepsleep + LPC_PMU->PCON = 0; + + // SRC[SLEEPDEEP] set to 1 = deep sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + //According to user manual it is kinda picky about reserved bits, so we follow that nicely + //Keep WDOSC and BOD in same state as they are now during deepsleep + LPC_SYSCON->PDSLEEPCFG = 0x000018B7 | (LPC_SYSCON->PDRUNCFG & (PDRUNCFG_WDTOSC_PD | PDRUNCFG_BOD_PD)); + + // Power up same as before powerdown + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + + // wait for interrupt + __WFI(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/spi_api.c new file mode 100644 index 0000000000..314ed1b922 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/spi_api.c @@ -0,0 +1,221 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + // {P0_10, SPI_0, 0x02}, -- should be mapped to SWCLK only + {P2_11, SPI_0, 0x01}, + {P2_1 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P2_3 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P2_2 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P2_0 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11; + LPC_SYSCON->SSP0CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 0; + if (sclk == P0_6) { + LPC_IOCON->SCK_LOC = 0x02; + } + else { + LPC_IOCON->SCK_LOC = 0x01; + } + break; + case SPI_1: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18; + LPC_SYSCON->SSP1CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 2; + LPC_IOCON->SCK1_LOC = 0x00; + LPC_IOCON->MISO1_LOC = 0x00; + LPC_IOCON->MOSI1_LOC = 0x00; + if (ssel != NC) { + LPC_IOCON->SSEL1_LOC = 0x00; + } + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT((bits >= 4 && bits <= 16) || (mode >= 0 && mode <= 3)); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return ssp_readable(obj) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR & 0xFFFF; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c new file mode 100644 index 0000000000..909263782b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/us_ticker.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TMR_TypeDef *)LPC_CT32B1_BASE) +#define US_TICKER_TIMER_IRQn TIMER_32_1_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1 + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PeripheralNames.h new file mode 100644 index 0000000000..969f15f2f6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX UART_TX +#define STDIO_UART_RX UART_RX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PinNames.h new file mode 100644 index 0000000000..bed2940fa3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PinNames.h @@ -0,0 +1,156 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC1347 Pin Names + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + P0_18 = 18, + P0_19 = 19, + P0_20 = 20, + P0_21 = 21, + P0_22 = 22, + P0_23 = 23, + + P1_13 = 45, + P1_14 = 46, + P1_15 = 47, + P1_16 = 48, + + P1_19 = 51, + P1_20 = 52, + P1_21 = 53, + P1_22 = 54, + P1_23 = 55, + P1_24 = 56, + P1_25 = 57, + P1_26 = 58, + P1_27 = 59, + P1_28 = 60, + P1_29 = 61, + + P1_31 = 63, + + // DIP Pin Names + p1 = P0_0, + p2 = P0_11, + p3 = P0_12, + p4 = P0_13, + p5 = P0_14, + p6 = P1_31, + p8 = P0_16, + p9 = P0_22, + p10 = P0_23, + p13 = P1_29, + p14 = P1_21, + p15 = P0_8, + p16 = P0_9, + p17 = P1_24, + p18 = P0_4, + p19 = P1_13, + p20 = P1_14, + p21 = P1_22, + p22 = P0_17, + p23 = P0_5, + p24 = P0_21, + p25 = P0_19, + p26 = P0_18, + p27 = P1_15, + p28 = P1_16, + p29 = P1_25, + p30 = P1_19, + p33 = P0_20, + p34 = P0_2, + p35 = P1_26, + p36 = P1_27, + p37 = P1_20, + p38 = P1_23, + p39 = P0_7, + p40 = P1_28, + + UART_TX = P0_19, + UART_RX = P0_18, + + // Not connected + NC = (int)0xFFFFFFFF, + + LED1 = p21, + LED2 = p21, + LED3 = p21, + LED4 = p21, + + // Standard but not supported pins + USBTX = NC, + USBRX = NC, + +} PinName; + +typedef enum { + CHANNEL0 = PIN_INT0_IRQn, + CHANNEL1 = PIN_INT1_IRQn, + CHANNEL2 = PIN_INT2_IRQn, + CHANNEL3 = PIN_INT3_IRQn, + CHANNEL4 = PIN_INT4_IRQn, + CHANNEL5 = PIN_INT5_IRQn, + CHANNEL6 = PIN_INT6_IRQn, + CHANNEL7 = PIN_INT7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PortNames.h new file mode 100644 index 0000000000..3f272730a1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/PortNames.h @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/analogin_api.c new file mode 100644 index 0000000000..5084bad02b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/analogin_api.c @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 0x02}, + {P0_12, ADC0_1, 0x02}, + {P0_13, ADC0_2, 0x02}, + {P0_14, ADC0_3, 0x02}, + {P0_15, ADC0_4, 0x02}, + {P0_16, ADC0_5, 0x01}, + {P0_22, ADC0_6, 0x01}, + {P0_23, ADC0_7, 0x01}, + {NC , NC , 0 } +}; + +#define LPC_IOCON0_BASE (LPC_IOCON_BASE) +#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60) + +#define ADC_RANGE ADC_10BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // Power up ADC + LPC_SYSCON->PDRUNCFG &= ~ (1 << 4); + LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13); + + uint32_t pin_number = (uint32_t)pin; + __IO uint32_t *reg = (pin_number < 32) ? (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + + // set pin to ADC mode + *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) + + uint32_t PCLK = SystemCoreClock; + uint32_t MAX_ADC_CLK = 4500000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + LPC_ADC->CR = (0 << 0) // no channels selected + | (clkdiv << 8) // max of 4.5MHz + | (0 << 16) // BURST = 0, software controlled + | ( 0 << 17 ); // CLKS = 0, not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 6) & ADC_RANGE; // 10 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/device.h new file mode 100644 index 0000000000..00991eafd8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/device.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_api.c new file mode 100644 index 0000000000..9300b42d04 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_api.c @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + int f = ((pin == P0_11) || (pin == P0_12) || + (pin == P0_13) || (pin == P0_14)) ? (1) : (0); + pin_function(pin, f); + + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + unsigned int port = (unsigned int)pin >> PORT_SHIFT; + + obj->reg_set = &LPC_GPIO->SET[port]; + obj->reg_clr = &LPC_GPIO->CLR[port]; + obj->reg_in = &LPC_GPIO->PIN[port]; + obj->reg_dir = &LPC_GPIO->DIR[port]; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_irq_api.c new file mode 100644 index 0000000000..4bb2e5b42d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_irq_api.c @@ -0,0 +1,142 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_GPIO_PIN_INT +#define PININT_IRQ 0 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + /* Enable AHB clock to the FlexInt, GroupedInt domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<19) | (1<<23) | (1<<24)); + + /* To select a pin for any of the eight pin interrupts, write the pin number + * as 0 to 23 for pins PIO0_0 to PIO0_23 and 24 to 55. + * @see: mbed_capi/PinNames.h + */ + LPC_SYSCON->PINSEL[obj->ch] = (pin >> 5) ? (pin - 8) : (pin); + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= 1 << obj->ch; + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c new file mode 100644 index 0000000000..a19a87deb5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c @@ -0,0 +1,385 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); + LPC_SYSCON->PRESETCTRL |= 1 << 1; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_Type *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/objects.h new file mode 100644 index 0000000000..02edfa2191 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/objects.h @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_mpin; + PortName port; + uint32_t mask; +}; + + +struct pwmout_s { + PWMName pwm; +}; + + +struct serial_s { + LPC_USART_Type *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + + +struct i2c_s { + LPC_I2C_Type *i2c; +}; + + +struct spi_s { + LPC_SSPx_Type *spi; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pinmap.c new file mode 100644 index 0000000000..b656b4fae4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pinmap.c @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +#define LPC_IOCON0_BASE (LPC_IOCON_BASE) +#define LPC_IOCON1_BASE (LPC_IOCON_BASE + 0x60) + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t pin_number = (uint32_t)pin; + + __IO uint32_t *reg = (pin_number < 32) ? + (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : + (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t pin_number = (uint32_t)pin; + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + __IO uint32_t *reg = (pin_number < 32) ? + (__IO uint32_t*)(LPC_IOCON0_BASE + 4 * pin_number) : + (__IO uint32_t*)(LPC_IOCON1_BASE + 4 * (pin_number - 32)); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + // drain + tmp &= ~(0x1 << 10); + tmp |= drain << 10; + + *reg = tmp; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/port_api.c new file mode 100644 index 0000000000..334c347391 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/port_api.c @@ -0,0 +1,67 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) { + return (PinName)((port << PORT_SHIFT) | pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO->MASK[port] = ~mask; + + obj->reg_mpin = &LPC_GPIO->MPIN[port]; + obj->reg_dir = &LPC_GPIO->DIR[port]; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_mpin = value; +} + +int port_read(port_t *obj) { + return (*obj->reg_mpin); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pwmout_api.c new file mode 100644 index 0000000000..0d4fa92729 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/pwmout_api.c @@ -0,0 +1,180 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +static const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 2}, {P1_13, PWM_1, 2}, /* MR0 */ + {P0_9 , PWM_2, 2}, {P1_14, PWM_2, 2}, /* MR1 */ + {P0_10, PWM_3, 3}, {P1_15, PWM_3, 2}, /* MR2 */ + + /* CT16B1 */ + {P0_21, PWM_4, 1}, /* MR0 */ + {P0_22, PWM_5, 2}, {P1_23, PWM_5, 1}, /* MR1 */ + + /* CT32B0 */ + {P0_18, PWM_6, 2}, {P1_24, PWM_6, 1}, /* MR0 */ + {P0_19, PWM_7, 2}, {P1_25, PWM_7, 1}, /* MR1 */ + {P0_1 , PWM_8, 2}, {P1_26, PWM_8, 1}, /* MR2 */ + + /* CT32B1 */ + {P0_13, PWM_9 , 3}, //{P1_0, PWM_9 , 1}, /* MR0 */ + {P0_14, PWM_10, 3}, //{P1_1, PWM_10, 1}, /* MR1 */ + {P0_15, PWM_11, 3}, //{P1_2, PWM_11, 1}, /* MR2 */ + + {NC, NC, 0} +}; + +typedef struct { + uint8_t timer; + uint8_t mr; +} timer_mr; + +static timer_mr pwm_timer_map[11] = { + {0, 0}, {0, 1}, {0, 2}, + {1, 0}, {1, 1}, + {2, 0}, {2, 1}, {2, 2}, + {3, 0}, {3, 1}, {3, 2}, +}; + +static LPC_CTxxBx_Type *Timers[4] = { + LPC_CT16B0, LPC_CT16B1, + LPC_CT32B0, LPC_CT32B1 +}; + +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (uint32_t)NC); + + obj->pwm = pwm; + + // Timer registers + timer_mr tid = pwm_timer_map[pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + + // Disable timer + timer->TCR = 0; + + // Power the correspondent timer + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7); + + /* Enable PWM function */ + timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0); + + /* Reset Functionality on MR3 controlling the PWM period */ + timer->MCR = 1 << 10; + + pwm_clock_mhz = SystemCoreClock / 1000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + uint32_t t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value); + + timer->MR[tid.mr] = t_off; +} + +float pwmout_read(pwmout_t* obj) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + + float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + int i = 0; + uint32_t period_ticks = pwm_clock_mhz * us; + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + uint32_t old_period_ticks = timer->MR3; + + timer->TCR = TCR_RESET; + timer->MR3 = period_ticks; + + // Scale the pulse width to preserve the duty ratio + if (old_period_ticks > 0) { + for (i=0; i<3; i++) { + uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks); + timer->MR[i] = t_off; + } + } + timer->TCR = TCR_CNT_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + uint32_t t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000); + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_CTxxBx_Type *timer = Timers[tid.timer]; + + timer->TCR = TCR_RESET; + if (t_on > timer->MR3) { + pwmout_period_us(obj, us); + } + uint32_t t_off = timer->MR3 - t_on; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/serial_api.c new file mode 100644 index 0000000000..5020afc54b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/serial_api.c @@ -0,0 +1,300 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 1 + +static const PinMap PinMap_UART_TX[] = { + {P0_19, UART_0, 1}, + {P1_13, UART_0, 3}, + {P1_27, UART_0, 2}, + { NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_18, UART_0, 1}, + {P1_14, UART_0, 3}, + {P1_26, UART_0, 2}, + {NC , NC , 0} +}; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_USART_Type *)uart; + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + + // [TODO] Consider more elegant approach + // disconnect USBTX/RX mapping mux, for case when switching ports + //pin_function(USBTX, 0); + //pin_function(USBRX, 0); + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + LPC_SYSCON->UARTCLKDIV = 0x1; + uint32_t PCLK = SystemCoreClock; + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART->IIR >> 1) & 0x7, 0);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=USART_IRQn ; vector = (uint32_t)&uart0_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/sleep.c new file mode 100644 index 0000000000..1515891d1e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/sleep.c @@ -0,0 +1,43 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + // PCON[PD] set to sleep + LPC_PMU->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +void deepsleep(void) { + // PCON[PD] set to deepsleep + LPC_PMU->PCON = 0x1; + + // SRC[SLEEPDEEP] set to 1 = deep sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // Power up everything after powerdown + LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800; + + // wait for interrupt + __WFI(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/spi_api.c new file mode 100644 index 0000000000..4581b07706 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/spi_api.c @@ -0,0 +1,213 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P1_29, SPI_0, 0x01}, + {P1_15, SPI_1, 0x03}, + {P1_20, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P0_21, SPI_1, 0x02}, + {P1_22, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P0_22, SPI_1, 0x03}, + {P1_21, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P1_19, SPI_1, 0x02}, + {P1_23, SPI_1, 0x02}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSPx_Type*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11; + LPC_SYSCON->SSP0CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 0; + break; + case SPI_1: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18; + LPC_SYSCON->SSP1CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 2; + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + ssp_disable(obj); + MBED_ASSERT((bits >= 4 && bits <= 16) || (mode >= 0 && mode <= 3)); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/us_ticker.c new file mode 100644 index 0000000000..d77495d03c --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC13XX/us_ticker.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_CT32B1_Type *)LPC_CT32B1_BASE) +#define US_TICKER_TIMER_IRQn CT32B1_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1 + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h new file mode 100644 index 0000000000..742d7a7818 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h @@ -0,0 +1,60 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7, + ADC0_8, + ADC0_9, + ADC0_10, + ADC0_11, + ADC1_0, + ADC1_1, + ADC1_2, + ADC1_3, + ADC1_4, + ADC1_5, + ADC1_6, + ADC1_7, + ADC1_8, + ADC1_9, + ADC1_10, + ADC1_11, +} ADCName; + +typedef enum { + DAC0_0 = 0, +} DACName; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PinNames.h new file mode 100644 index 0000000000..664d9b7161 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PinNames.h @@ -0,0 +1,103 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + // LPC Pin Names + P0_0 = 0, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, + + LED_RED = P0_25, + LED_GREEN = P0_3, + LED_BLUE = P1_1, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_BLUE, + + // Serial to USB pins + USBTX = P0_18, + USBRX = P0_13, + + // Arduino Shield Receptacles Names + D0 = P0_13, + D1 = P0_18, + D2 = P0_29, + D3 = P0_9, + D4 = P0_10, + D5 = P0_16, // same port as D13 + D6 = P1_3, + D7 = P0_0, + D8 = P0_24, + D9 = P1_0, + D10= P0_27, + D11= P0_28, + D12= P0_12, + D13= P0_16, // same port as D5 + D14= P0_23, + D15= P0_22, + + A0 = P0_8, + A1 = P0_7, + A2 = P0_6, + A3 = P0_5, + A4 = P0_23, // same port as SDA + A5 = P0_22, // same port as SCL + SDA= P0_23, // same port as A4 + SCL= P0_22, // same port as A5 + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX + +typedef struct { + unsigned char n; + unsigned char offset; +} SWM_Map; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PortNames.h new file mode 100644 index 0000000000..f332b05544 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PortNames.h @@ -0,0 +1,32 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogin_api.c new file mode 100644 index 0000000000..da3bcef999 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogin_api.c @@ -0,0 +1,158 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +#define ADC_RANGE ADC_12BIT_RANGE + +static const PinMap PinMap_ADC[] = { + {P0_8 , ADC0_0, 0}, + {P0_7 , ADC0_1, 0}, + {P0_6 , ADC0_2, 0}, + {P0_5 , ADC0_3, 0}, + {P0_4 , ADC0_4, 0}, + {P0_3 , ADC0_5, 0}, + {P0_2 , ADC0_6, 0}, + {P0_1 , ADC0_7, 0}, + {P1_0 , ADC0_8, 0}, + {P0_31, ADC0_9, 0}, + {P0_0 , ADC0_10,0}, + {P0_30, ADC0_11,0}, + {P1_1 , ADC1_0, 0}, + {P0_9 , ADC1_1, 0}, + {P0_10, ADC1_2, 0}, + {P0_11, ADC1_3, 0}, + {P1_2 , ADC1_4, 0}, + {P1_3 , ADC1_5, 0}, + {P0_13, ADC1_6, 0}, + {P0_14, ADC1_7, 0}, + {P0_15, ADC1_8, 0}, + {P0_16, ADC1_9, 0}, + {P1_4 , ADC1_10,0}, + {P1_5 , ADC1_11,0}, +}; + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + uint32_t port = (pin >> 5); + // enable clock for GPIOx + LPC_SYSCON->SYSAHBCLKCTRL0 |= (1UL << (14 + port)); + // pin enable + LPC_SWM->PINENABLE0 &= ~(1UL << obj->adc); + // configure GPIO as input + LPC_GPIO_PORT->DIR[port] &= ~(1UL << (pin & 0x1F)); + + // power up ADC + if (obj->adc < ADC1_0) + { + // ADC0 + LPC_SYSCON->PDRUNCFG &= ~(1 << 10); + LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 27); + } + else { + // ADC1 + LPC_SYSCON->PDRUNCFG &= ~(1 << 11); + LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 28); + } + + // select IRC as asynchronous clock, divided by 1 + LPC_SYSCON->ADCASYNCCLKSEL = 0; + LPC_SYSCON->ADCASYNCCLKDIV = 1; + + __IO LPC_ADC0_Type *adc_reg = (obj->adc < ADC1_0) ? (__IO LPC_ADC0_Type*)(LPC_ADC0) : (__IO LPC_ADC0_Type*)(LPC_ADC1); + + // determine the system clock divider for a 500kHz ADC clock during calibration + uint32_t clkdiv = (SystemCoreClock / 500000) - 1; + + // perform a self-calibration + adc_reg->CTRL = (1UL << 30) | (clkdiv & 0xFF); + while ((adc_reg->CTRL & (1UL << 30)) != 0); + + // switch to asynchronous mode + adc_reg->CTRL = (1UL << 8); +} + +static inline uint32_t adc_read(analogin_t *obj) { + uint32_t channels; + + __IO LPC_ADC0_Type *adc_reg = (obj->adc < ADC1_0) ? (__IO LPC_ADC0_Type*)(LPC_ADC0) : (__IO LPC_ADC0_Type*)(LPC_ADC1); + + if (obj->adc >= ADC1_0) + channels = ((obj->adc - ADC1_0) & 0x1F); + else + channels = (obj->adc & 0x1F); + + // select channel + adc_reg->SEQA_CTRL &= ~(0xFFF); + adc_reg->SEQA_CTRL |= (1UL << channels); + + // start conversion and sequence enable + adc_reg->SEQA_CTRL |= ((1UL << 26) | (1UL << 31)); + + // Repeatedly get the sample data until DONE bit + volatile uint32_t data; + do { + data = adc_reg->SEQA_GDAT; + } while ((data & (1UL << 31)) == 0); + + // Stop conversion + adc_reg->SEQA_CTRL &= ~(1UL << 31); + + return ((data >> 4) & ADC_RANGE); +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c new file mode 100644 index 0000000000..5c9d57a1b8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +void analogout_init(dac_t *obj, PinName pin) { + MBED_ASSERT(pin == P0_12); + + LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 29); + LPC_SYSCON->PDRUNCFG &= ~(1 << 12); + LPC_IOCON->PIO0_12 = 0; + LPC_SWM->PINENABLE0 &= ~(1 << 24); + LPC_DAC->CTRL = 0; + + analogout_write_u16(obj, 0); +} + +void analogout_free(dac_t *obj) +{ + LPC_SYSCON->SYSAHBCLKCTRL0 &= ~(1 << 29); + LPC_SWM->PINENABLE0 |= (1 << 24); +} + +static inline void dac_write(int value) { + value &= 0xFFF; // 12-bit + + // Set the DAC output + LPC_DAC->VAL = (value << 4); +} + +static inline int dac_read() { + return ((LPC_DAC->VAL >> 4) & 0xFFF); +} + +void analogout_write(dac_t *obj, float value) { + if (value < 0.0f) { + dac_write(0); + } else if (value > 1.0f) { + dac_write(0xFFF); + } else { + dac_write((uint32_t)(value * (float)0xFFF)); + } +} + +void analogout_write_u16(dac_t *obj, uint16_t value) { + dac_write(value); +} + +float analogout_read(dac_t *obj) { + uint32_t value = dac_read(); + return (float)value * (1.0f / (float)0xFFF); +} + +uint16_t analogout_read_u16(dac_t *obj) { + return (uint16_t)dac_read(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/can_api.c new file mode 100644 index 0000000000..bb738dbf2b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/can_api.c @@ -0,0 +1,437 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "can_api.h" + +#include "cmsis.h" +#include "mbed_error.h" + +#include <math.h> +#include <string.h> + +/* Handy defines */ +#define MSG_OBJ_MAX 32 +#define DLC_MAX 8 + +#define ID_STD_MASK 0x07FF +#define ID_EXT_MASK 0x1FFFFFFF +#define DLC_MASK 0x0F + +#define CANIFn_ARB2_DIR (1UL << 13) +#define CANIFn_ARB2_XTD (1UL << 14) +#define CANIFn_ARB2_MSGVAL (1UL << 15) +#define CANIFn_MSK2_MXTD (1UL << 15) +#define CANIFn_MSK2_MDIR (1UL << 14) +#define CANIFn_MCTRL_EOB (1UL << 7) +#define CANIFn_MCTRL_TXRQST (1UL << 8) +#define CANIFn_MCTRL_RMTEN (1UL << 9) +#define CANIFn_MCTRL_RXIE (1UL << 10) +#define CANIFn_MCTRL_TXIE (1UL << 11) +#define CANIFn_MCTRL_UMASK (1UL << 12) +#define CANIFn_MCTRL_INTPND (1UL << 13) +#define CANIFn_MCTRL_MSGLST (1UL << 14) +#define CANIFn_MCTRL_NEWDAT (1UL << 15) +#define CANIFn_CMDMSK_DATA_B (1UL << 0) +#define CANIFn_CMDMSK_DATA_A (1UL << 1) +#define CANIFn_CMDMSK_TXRQST (1UL << 2) +#define CANIFn_CMDMSK_NEWDAT (1UL << 2) +#define CANIFn_CMDMSK_CLRINTPND (1UL << 3) +#define CANIFn_CMDMSK_CTRL (1UL << 4) +#define CANIFn_CMDMSK_ARB (1UL << 5) +#define CANIFn_CMDMSK_MASK (1UL << 6) +#define CANIFn_CMDMSK_WR (1UL << 7) +#define CANIFn_CMDMSK_RD (0UL << 7) +#define CANIFn_CMDREQ_BUSY (1UL << 15) + +static uint32_t can_irq_id = 0; +static can_irq_handler irq_handler; + +static inline void can_disable(can_t *obj) { + LPC_C_CAN0->CANCNTL |= 0x1; +} + +static inline void can_enable(can_t *obj) { + if (LPC_C_CAN0->CANCNTL & 0x1) { + LPC_C_CAN0->CANCNTL &= ~(0x1); + } +} + +int can_mode(can_t *obj, CanMode mode) { + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + uint16_t i; + + // Find first free message object + if (handle == 0) { + uint32_t msgval = LPC_C_CAN0->CANMSGV1 | (LPC_C_CAN0->CANMSGV2 << 16); + + // Find first free messagebox + for (i = 0; i < 32; i++) { + if ((msgval & (1 << i)) == 0) { + handle = i+1; + break; + } + } + } + + if (handle > 0 && handle < 32) { + if (format == CANExtended) { + // Mark message valid, Direction = TX, Extended Frame, Set Identifier and mask everything + LPC_C_CAN0->CANIF1_ARB1 = (id & 0xFFFF); + LPC_C_CAN0->CANIF1_ARB2 = CANIFn_ARB2_MSGVAL | CANIFn_ARB2_XTD | ((id >> 16) & 0x1FFF); + LPC_C_CAN0->CANIF1_MSK1 = (mask & 0xFFFF); + LPC_C_CAN0->CANIF1_MSK2 = CANIFn_MSK2_MXTD /*| CANIFn_MSK2_MDIR*/ | ((mask >> 16) & 0x1FFF); + } else { + // Mark message valid, Direction = TX, Set Identifier and mask everything + LPC_C_CAN0->CANIF1_ARB2 = CANIFn_ARB2_MSGVAL | ((id << 2) & 0x1FFF); + LPC_C_CAN0->CANIF1_MSK2 = /*CANIFn_MSK2_MDIR |*/ ((mask << 2) & 0x1FFF); + } + + // Use mask, single message object and set DLC + LPC_C_CAN0->CANIF1_MCTRL = CANIFn_MCTRL_UMASK | CANIFn_MCTRL_EOB | CANIFn_MCTRL_RXIE | (DLC_MAX & 0xF); + + // Transfer all fields to message object + LPC_C_CAN0->CANIF1_CMDMSK_W = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL; + + // Start Transfer to given message number + LPC_C_CAN0->CANIF1_CMDREQ = (handle & 0x3F); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while ( LPC_C_CAN0->CANIF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + } + + return handle; +} + +static inline void can_irq() { + irq_handler(can_irq_id, IRQ_RX); +} + +// Register CAN object's irq handler +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { + irq_handler = handler; + can_irq_id = id; +} + +// Unregister CAN object's irq handler +void can_irq_free(can_t *obj) { + LPC_C_CAN0->CANCNTL &= ~(1UL << 1); // Disable Interrupts :) + can_irq_id = 0; + NVIC_DisableIRQ(C_CAN0_IRQn); +} + +// Clear or set a irq +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { + // Put CAN in Reset Mode and enable interrupt + can_disable(obj); + if (enable == 0) { + LPC_C_CAN0->CANCNTL &= ~(1UL << 1 | 1UL << 2); + } else { + LPC_C_CAN0->CANCNTL |= 1UL << 1 | 1UL << 2; + } + // Take it out of reset... + can_enable(obj); + + // Enable NVIC if at least 1 interrupt is active + NVIC_SetVector(C_CAN0_IRQn, (uint32_t) &can_irq); + NVIC_EnableIRQ(C_CAN0_IRQn); +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int sclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint32_t clkdiv = 1; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits = 0; + + bitwidth = sclk / cclk; + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + clkdiv = clkdiv - 1; + + if (hit) { + btr = (timing_pts[bits][1] & 0x7) << 12 + | (timing_pts[bits][0] & 0xf) << 8 + | (psjw & 0x3) << 6 + | (brp & 0x3F); + btr = btr | (clkdiv << 16); + } else { + btr = 0; + } + + return btr; +} + + +int can_config_rxmsgobj(can_t *obj) { + uint16_t i = 0; + + // Make sure the interface is available + while ( LPC_C_CAN0->CANIF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Mark message valid, Direction = RX, Don't care about anything else + LPC_C_CAN0->CANIF1_ARB1 = 0; + LPC_C_CAN0->CANIF1_ARB2 = 0; + LPC_C_CAN0->CANIF1_MCTRL = 0; + + for ( i = 0; i < MSG_OBJ_MAX; i++ ) { + // Transfer arb and control fields to message object + LPC_C_CAN0->CANIF1_CMDMSK_W = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_TXRQST; + + // Start Transfer to given message number + LPC_C_CAN0->CANIF1_CMDREQ = (i & 0x3F); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while ( LPC_C_CAN0->CANIF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + } + + // Accept all messages + can_filter(obj, 0, 0, CANStandard, 1); + + return 1; +} + + +void can_init(can_t *obj, PinName rd, PinName td) { + // Enable power and clock + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1UL << 7); + LPC_SYSCON->PRESETCTRL1 |= (1UL << 7); + LPC_SYSCON->PRESETCTRL1 &= ~(1UL << 7); + + // Enable Initialization mode + if (!(LPC_C_CAN0->CANCNTL & (1UL << 0))) { + LPC_C_CAN0->CANCNTL |= (1UL << 0); + } + + LPC_SWM->PINASSIGN[6] &= ~(0x00FFFF00L); + LPC_SWM->PINASSIGN[6] |= (rd << 16) | (td << 8); + + can_frequency(obj, 100000); + + // Resume operation + LPC_C_CAN0->CANCNTL &= ~(1UL << 0); + while ( LPC_C_CAN0->CANCNTL & (1UL << 0) ); + + // Initialize RX message object + can_config_rxmsgobj(obj); +} + +void can_free(can_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL1 &= ~(1UL << 7); + LPC_SYSCON->PRESETCTRL1 &= ~(1UL << 7); +} + +int can_frequency(can_t *obj, int f) { + int btr = can_speed(SystemCoreClock, (unsigned int)f, 1); + int clkdiv = (btr >> 16) & 0x0F; + btr = btr & 0xFFFF; + + if (btr > 0) { + // Set the bit clock + LPC_C_CAN0->CANCNTL |= (1UL << 6 | 1UL << 0); // set CCE and INIT + LPC_C_CAN0->CANCLKDIV = clkdiv; + LPC_C_CAN0->CANBT = btr; + LPC_C_CAN0->CANBRPE = 0x0000; + LPC_C_CAN0->CANCNTL &= ~(1UL << 6 | 1UL << 0); // clear CCE and INIT + return 1; + } + return 0; +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + uint16_t msgnum = 0; + + // Make sure controller is enabled + can_enable(obj); + + // Make sure the interface is available + while ( LPC_C_CAN0->CANIF1_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Set the direction bit based on the message type + uint32_t direction = 0; + if (msg.type == CANData) { + direction = CANIFn_ARB2_DIR; + } + + if (msg.format == CANExtended) { + // Mark message valid, Extended Frame, Set Identifier and mask everything + LPC_C_CAN0->CANIF1_ARB1 = (msg.id & 0xFFFF); + LPC_C_CAN0->CANIF1_ARB2 = CANIFn_ARB2_MSGVAL | CANIFn_ARB2_XTD | direction | ((msg.id >> 16) & 0x1FFFF); + LPC_C_CAN0->CANIF1_MSK1 = (ID_EXT_MASK & 0xFFFF); + LPC_C_CAN0->CANIF1_MSK2 = CANIFn_MSK2_MXTD | CANIFn_MSK2_MDIR | ((ID_EXT_MASK >> 16) & 0x1FFF); + } else { + // Mark message valid, Set Identifier and mask everything + LPC_C_CAN0->CANIF1_ARB2 = CANIFn_ARB2_MSGVAL | direction | ((msg.id << 2) & 0x1FFF); + LPC_C_CAN0->CANIF1_MSK2 = CANIFn_MSK2_MDIR | ((ID_STD_MASK << 2) & 0x1FFF); + } + + // Use mask, request transmission, single message object and set DLC + LPC_C_CAN0->CANIF1_MCTRL = CANIFn_MCTRL_UMASK | CANIFn_MCTRL_TXRQST | CANIFn_MCTRL_EOB | (msg.len & 0xF); + + LPC_C_CAN0->CANIF1_DA1 = ((msg.data[1] & 0xFF) << 8) | (msg.data[0] & 0xFF); + LPC_C_CAN0->CANIF1_DA2 = ((msg.data[3] & 0xFF) << 8) | (msg.data[2] & 0xFF); + LPC_C_CAN0->CANIF1_DB1 = ((msg.data[5] & 0xFF) << 8) | (msg.data[4] & 0xFF); + LPC_C_CAN0->CANIF1_DB2 = ((msg.data[7] & 0xFF) << 8) | (msg.data[6] & 0xFF); + + // Transfer all fields to message object + LPC_C_CAN0->CANIF1_CMDMSK_W = CANIFn_CMDMSK_WR | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_TXRQST | CANIFn_CMDMSK_DATA_A | CANIFn_CMDMSK_DATA_B; + + // Start Transfer to given message number + LPC_C_CAN0->CANIF1_CMDREQ = (msgnum & 0x3F); + + // Wait until transfer to message ram complete - TODO: maybe not block?? + while ( LPC_C_CAN0->CANIF1_CMDREQ & CANIFn_CMDREQ_BUSY); + + // Wait until TXOK is set, then clear it - TODO: maybe not block + //while ( !(LPC_C_CAN0->STAT & CANSTAT_TXOK) ); + LPC_C_CAN0->CANSTAT &= ~(1UL << 3); + + return 1; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + uint16_t i; + + // Make sure controller is enabled + can_enable(obj); + + // Find first message object with new data + if (handle == 0) { + uint32_t newdata = LPC_C_CAN0->CANND1 | (LPC_C_CAN0->CANND2 << 16); + // Find first free messagebox + for (i = 0; i < 32; i++) { + if (newdata & (1 << i)) { + handle = i+1; + break; + } + } + } + + if (handle > 0 && handle < 32) { + // Wait until message interface is free + while ( LPC_C_CAN0->CANIF2_CMDREQ & CANIFn_CMDREQ_BUSY ); + + // Transfer all fields to message object + LPC_C_CAN0->CANIF2_CMDMSK_W = CANIFn_CMDMSK_RD | CANIFn_CMDMSK_MASK | CANIFn_CMDMSK_ARB | CANIFn_CMDMSK_CTRL | CANIFn_CMDMSK_CLRINTPND | CANIFn_CMDMSK_TXRQST | CANIFn_CMDMSK_DATA_A | CANIFn_CMDMSK_DATA_B; + + // Start Transfer from given message number + LPC_C_CAN0->CANIF2_CMDREQ = (handle & 0x3F); + + // Wait until transfer to message ram complete + while ( LPC_C_CAN0->CANIF2_CMDREQ & CANIFn_CMDREQ_BUSY ); + + if (LPC_C_CAN0->CANIF2_ARB2 & CANIFn_ARB2_XTD) { + msg->format = CANExtended; + msg->id = (LPC_C_CAN0->CANIF2_ARB1 & 0x1FFF) << 16; + msg->id |= (LPC_C_CAN0->CANIF2_ARB2 & 0x1FFF); + } else { + msg->format = CANStandard; + msg->id = (LPC_C_CAN0->CANIF2_ARB2 & 0x1FFF) >> 2; + } + + if (LPC_C_CAN0->CANIF2_ARB2 & CANIFn_ARB2_DIR) { + msg->type = CANRemote; + } + else { + msg->type = CANData; + } + + msg->len = (LPC_C_CAN0->CANIF2_MCTRL & 0xF); // TODO: If > 8, len = 8 + msg->data[0] = ((LPC_C_CAN0->CANIF2_DA1 >> 0) & 0xFF); + msg->data[1] = ((LPC_C_CAN0->CANIF2_DA1 >> 8) & 0xFF); + msg->data[2] = ((LPC_C_CAN0->CANIF2_DA2 >> 0) & 0xFF); + msg->data[3] = ((LPC_C_CAN0->CANIF2_DA2 >> 8) & 0xFF); + msg->data[4] = ((LPC_C_CAN0->CANIF2_DB1 >> 0) & 0xFF); + msg->data[5] = ((LPC_C_CAN0->CANIF2_DB1 >> 8) & 0xFF); + msg->data[6] = ((LPC_C_CAN0->CANIF2_DB2 >> 0) & 0xFF); + msg->data[7] = ((LPC_C_CAN0->CANIF2_DB2 >> 8) & 0xFF); + + LPC_C_CAN0->CANSTAT &= ~(1UL << 4); + return 1; + } + return 0; +} + +void can_reset(can_t *obj) { + LPC_SYSCON->PRESETCTRL1 &= ~(1UL << 7); + LPC_C_CAN0->CANSTAT = 0; + can_config_rxmsgobj(obj); +} + +unsigned char can_rderror(can_t *obj) { + return ((LPC_C_CAN0->CANEC >> 8) & 0x7F); +} + +unsigned char can_tderror(can_t *obj) { + return (LPC_C_CAN0->CANEC & 0xFF); +} + +void can_monitor(can_t *obj, int silent) { + if (silent) { + LPC_C_CAN0->CANCNTL |= (1UL << 7); + LPC_C_CAN0->CANTEST |= (1UL << 3); + } else { + LPC_C_CAN0->CANCNTL &= ~(1UL << 7); + LPC_C_CAN0->CANTEST &= ~(1UL << 3); + } + + if (!(LPC_C_CAN0->CANCNTL & (1UL << 0))) { + LPC_C_CAN0->CANCNTL |= (1UL << 0); + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h new file mode 100644 index 0000000000..1ef3bcbb3e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 0 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 + +#define DEVICE_SLEEP 0 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_RED 0 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_api.c new file mode 100644 index 0000000000..624a4d76b5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_api.c @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +static int gpio_enabled = 0; + +static void gpio_enable(void) { + gpio_enabled = 1; + + /* Enable AHB clock to the GPIO0/1/2 and IOCON domain. */ + LPC_SYSCON->SYSAHBCLKCTRL0 |= (0xFUL << 13); +} + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + if (!gpio_enabled) + gpio_enable(); + + return (1UL << ((int)pin & 0x1f)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + unsigned int port = (unsigned int)(pin >> 5); + + obj->reg_set = &LPC_GPIO_PORT->SET[port]; + obj->reg_clr = &LPC_GPIO_PORT->CLR[port]; + obj->reg_in = &LPC_GPIO_PORT->PIN[port]; + obj->reg_dir = &LPC_GPIO_PORT->DIR[port]; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_irq_api.c new file mode 100644 index 0000000000..f4b379295a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_irq_api.c @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> + +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_PINT +#define PININT_IRQ PIN_INT0_IRQn + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + LPC_GPIO_X->FALL = ch_bit; + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + // PINT only supprt GPIO port 0 and 1 interrupt + if (pin >= P2_0) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the PIN, GPIO0/1, IOCON and MUX domain. */ + LPC_SYSCON->SYSAHBCLKCTRL0 |= ((1 << 18) | (0x1D << 11)); + + LPC_INMUX->PINTSEL[obj->ch] = pin; + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= (1 << (obj->ch + 5)); + + LPC_GPIO_PORT->DIR[pin >> 5] &= ~(1 << (pin & 0x1F)); + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << (obj->ch + 5)); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_object.h new file mode 100644 index 0000000000..0252448103 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_object.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c new file mode 100644 index 0000000000..0ca7c7dccf --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c @@ -0,0 +1,217 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static uint8_t repeated_start = 0; + +#define I2C_STAT(x) ((LPC_I2C0->STAT >> 1) & (0x07)) + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + volatile int timeout = 0; + while (!(LPC_I2C0->STAT & (1 << 0))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + LPC_I2C0->CFG |= (1 << 0); +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + MBED_ASSERT((sda == P0_23) && (scl == P0_22)); + + // Enables clock for I2C0 + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 13); + + LPC_SYSCON->PRESETCTRL1 |= (1 << 13); + LPC_SYSCON->PRESETCTRL1 &= ~(1 << 13); + + // pin enable + LPC_SWM->PINENABLE1 &= ~(0x3 << 3); + + // set default frequency at 100kHz + i2c_frequency(obj, 100000); + i2c_interface_enable(obj); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + if (repeated_start) { + LPC_I2C0->MSTCTL = (1 << 1) | (1 << 0); + repeated_start = 0; + } else { + LPC_I2C0->MSTCTL = (1 << 1); + } + return status; +} + +inline int i2c_stop(i2c_t *obj) { + volatile int timeout = 0; + + LPC_I2C0->MSTCTL = (1 << 2) | (1 << 0); + while ((LPC_I2C0->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + LPC_I2C0->MSTDAT = value; + + if (!addr) + LPC_I2C0->MSTCTL = (1 << 0); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // wait for it to arrive + i2c_wait_SI(obj); + if (!last) + LPC_I2C0->MSTCTL = (1 << 0); + + // return the data + return (LPC_I2C0->MSTDAT & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + uint32_t clkdiv = PCLK / (hz * 4) - 1; + + LPC_I2C0->DIV = clkdiv; + LPC_I2C0->MSTTIME = 0; +} + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + i2c_start(obj); + + LPC_I2C0->MSTDAT = (address | 0x01); + LPC_I2C0->MSTCTL |= 0x20; + if (i2c_wait_SI(obj) == -1) + return -1; + + status = ((LPC_I2C0->STAT >> 1) & (0x07)); + if (status != 0x01) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + if (i2c_wait_SI(obj) == -1) + return -1; + LPC_I2C0->MSTCTL = (1 << 0); + data[count] = (LPC_I2C0->MSTDAT & 0xFF); + status = ((LPC_I2C0->STAT >> 1) & (0x07)); + if (status != 0x01) { + i2c_stop(obj); + return count; + } + } + + // read in last byte + if (i2c_wait_SI(obj) == -1) + return -1; + + data[count] = (LPC_I2C0->MSTDAT & 0xFF); + status = i2c_status(obj); + if (status != 0x01) { + i2c_stop(obj); + return length - 1; + } + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } else { + repeated_start = 1; + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + i2c_start(obj); + + LPC_I2C0->MSTDAT = (address & 0xFE); + LPC_I2C0->MSTCTL |= 0x20; + if (i2c_wait_SI(obj) == -1) + return -1; + + status = ((LPC_I2C0->STAT >> 1) & (0x07)); + if (status != 0x02) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + LPC_I2C0->MSTDAT = data[i]; + LPC_I2C0->MSTCTL = (1 << 0); + if (i2c_wait_SI(obj) == -1) + return -1; + + status = ((LPC_I2C0->STAT >> 1) & (0x07)); + if (status != 0x02) { + i2c_stop(obj); + return i; + } + } + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } else { + repeated_start = 1; + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + if (i2c_do_write(obj, (data & 0xFF), 0) == 2) { + return 1; + } else { + return 0; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h new file mode 100644 index 0000000000..621419bce7 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h @@ -0,0 +1,69 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct pwmout_s { + LPC_SCT0_Type* pwm; + uint32_t pwm_ch; +}; + +struct serial_s { + LPC_USART0_Type *uart; + unsigned char index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct dac_s { + DACName dac; +}; + +struct i2c_s { + LPC_I2C0_Type *i2c; +}; + +struct spi_s { + LPC_SPI0_Type *spi; + unsigned char spi_n; +}; + +struct can_s { + int index; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pinmap.c new file mode 100644 index 0000000000..c466534cf9 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pinmap.c @@ -0,0 +1,41 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + + if ((pin == P0_22) || (pin == P0_23)) { + // The true open-drain pins PIO0_22 and PIO0_23 can be configured for different I2C-bus speeds. + return; + } + + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + (pin * 4)); + + if (mode == OpenDrain) { + *reg |= (1 << 10); + } else { + uint32_t tmp = *reg; + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + *reg = tmp; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c new file mode 100644 index 0000000000..8a17f4be48 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c @@ -0,0 +1,170 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static LPC_SCT0_Type *SCTs[4] = { + (LPC_SCT0_Type*)LPC_SCT0, + (LPC_SCT0_Type*)LPC_SCT1, + (LPC_SCT0_Type*)LPC_SCT2, + (LPC_SCT0_Type*)LPC_SCT3, +}; + +// bit flags for used SCTs +static unsigned char sct_used = 0; +static int get_available_sct(void) { + int i; + for (i=0; i<4; i++) { + if ((sct_used & (1 << i)) == 0) + return i; + } + return -1; +} + +void pwmout_init(pwmout_t* obj, PinName pin) { + MBED_ASSERT(pin != (uint32_t)NC); + + int sct_n = get_available_sct(); + if (sct_n == -1) { + error("No available SCT"); + } + + sct_used |= (1 << sct_n); + obj->pwm = SCTs[sct_n]; + obj->pwm_ch = sct_n; + + LPC_SCT0_Type* pwm = obj->pwm; + + // Enable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << (obj->pwm_ch + 2)); + + // Clear peripheral reset the SCT: + LPC_SYSCON->PRESETCTRL1 |= (1 << (obj->pwm_ch + 2)); + LPC_SYSCON->PRESETCTRL1 &= ~(1 << (obj->pwm_ch + 2)); + + switch(obj->pwm_ch) { + case 0: + // SCT0_OUT0 + LPC_SWM->PINASSIGN[7] &= ~0x0000FF00; + LPC_SWM->PINASSIGN[7] |= (pin << 8); + break; + case 1: + // SCT1_OUT0 + LPC_SWM->PINASSIGN[8] &= ~0x000000FF; + LPC_SWM->PINASSIGN[8] |= (pin); + break; + case 2: + // SCT2_OUT0 + LPC_SWM->PINASSIGN[8] &= ~0xFF000000; + LPC_SWM->PINASSIGN[8] |= (pin << 24); + break; + case 3: + // SCT3_OUT0 + LPC_SWM->PINASSIGN[9] &= ~0x00FF0000; + LPC_SWM->PINASSIGN[9] |= (pin << 16); + break; + default: + break; + } + + // Unified 32-bit counter, autolimit + pwm->CONFIG |= ((0x3 << 17) | 0x01); + + // halt and clear the counter + pwm->CTRL |= (1 << 2) | (1 << 3); + + // System Clock -> us_ticker (1)MHz + pwm->CTRL &= ~(0x7F << 5); + pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5); + + // Match reload register + pwm->MATCHREL0 = 20000; // 20ms + pwm->MATCHREL1 = (pwm->MATCHREL0 / 4); // 50% duty + + pwm->OUT0_SET = (1 << 0); // event 0 + pwm->OUT0_CLR = (1 << 1); // event 1 + + pwm->EV0_CTRL = (1 << 12); + pwm->EV0_STATE = 0xFFFFFFFF; + pwm->EV1_CTRL = (1 << 12) | (1 << 0); + pwm->EV1_STATE = 0xFFFFFFFF; + + // unhalt the counter: + // - clearing bit 2 of the CTRL register + pwm->CTRL &= ~(1 << 2); + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); +} + +void pwmout_free(pwmout_t* obj) { + // Disable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL1 &= ~(1 << (obj->pwm_ch + 2)); + sct_used &= ~(1 << obj->pwm_ch); +} + +void pwmout_write(pwmout_t* obj, float value) { + LPC_SCT0_Type* pwm = obj->pwm; + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + uint32_t t_on = (uint32_t)((float)(pwm->MATCHREL0) * value); + pwm->MATCHREL1 = t_on; +} + +float pwmout_read(pwmout_t* obj) { + uint32_t t_off = obj->pwm->MATCHREL0; + uint32_t t_on = obj->pwm->MATCHREL1; + float v = (float)t_on/(float)t_off; + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + LPC_SCT0_Type* pwm = obj->pwm; + uint32_t t_off = pwm->MATCHREL0; + uint32_t t_on = pwm->MATCHREL1; + float v = (float)t_on/(float)t_off; + pwm->MATCHREL0 = (uint32_t)us; + pwm->MATCHREL1 = (uint32_t)((float)us * (float)v); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + obj->pwm->MATCHREL1 = (uint32_t)us; +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/rtc_api.c new file mode 100644 index 0000000000..120652672c --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/rtc_api.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rtc_api.h" + +#if DEVICE_RTC + +void rtc_init(void) +{ + // Enables clock for RTC + LPC_SYSCON->SYSAHBCLKCTRL0 |= (1 << 23); + + // Software reset + LPC_RTC->CTRL |= 1; + + LPC_RTC->COUNT = 0; + + // Enabled RTC + LPC_RTC->CTRL |= (1 << 7); + // clear reset + LPC_RTC->CTRL &= ~1; +} + +void rtc_free(void) +{ + LPC_SYSCON->SYSAHBCLKCTRL0 &= ~(1 << 23); + LPC_RTC->CTRL &= ~(1 << 7); +} + +int rtc_isenabled(void) +{ + return (((LPC_RTC->CTRL) & 0x80) != 0); +} + +time_t rtc_read(void) +{ + return (time_t)LPC_RTC->COUNT; +} + +void rtc_write(time_t t) +{ + // Disabled RTC + LPC_RTC->CTRL &= ~(1 << 7); + + // Set count + LPC_RTC->COUNT = t; + + //Enabled RTC + LPC_RTC->CTRL |= (1 << 7); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c new file mode 100644 index 0000000000..ab06380329 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c @@ -0,0 +1,316 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 3 + +static const SWM_Map SWM_UART_TX[] = { + {0, 0}, // Pin assign register0, 7:0bit + {1, 8}, // Pin assign register1, 15:8bit + {2, 16}, // Pin assign register2, 23:16bit +}; + +static const SWM_Map SWM_UART_RX[] = { + {0, 8}, + {1, 16}, + {2, 24}, +}; + +static const SWM_Map SWM_UART_RTS[] = { + {0, 16}, + {1, 24}, + {3, 0}, // not available +}; + +static const SWM_Map SWM_UART_CTS[] = { + {0, 24}, + {2, 0}, + {3, 8} // not available +}; + +// bit flags for used UARTs +static unsigned char uart_used = 0; +static int get_available_uart(void) { + int i; + for (i=0; i<3; i++) { + if ((uart_used & (1 << i)) == 0) + return i; + } + return -1; +} + +#define UART_EN (0x01<<0) + +#define CTS_DELTA (0x01<<5) +#define RXBRK (0x01<<10) +#define DELTA_RXBRK (0x01<<11) + +#define RXRDY (0x01<<0) +#define TXRDY (0x01<<2) + +#define TXBRKEN (0x01<<1) +#define CTSEN (0x01<<9) + +static uint32_t UARTSysClk; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +static void switch_pin(const SWM_Map *swm, PinName pn) +{ + uint32_t regVal; + if (pn != NC) + { + // check if we have any function mapped to this pin already and remove it + for (uint32_t n = 0; n < sizeof(LPC_SWM->PINASSIGN)/sizeof(*LPC_SWM->PINASSIGN); n ++) { + regVal = LPC_SWM->PINASSIGN[n]; + for (uint32_t j = 0; j <= 24; j += 8) { + if (((regVal >> j) & 0xFF) == (uint32_t)pn) + regVal |= (0xFF << j); + } + LPC_SWM->PINASSIGN[n] = regVal; + } + } + // now map it + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (pn << swm->offset); +} + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + int uart_n = get_available_uart(); + if (uart_n == -1) { + error("No available UART"); + } + obj->index = uart_n; + switch (uart_n) { + case 0: obj->uart = (LPC_USART0_Type *)LPC_USART0_BASE; break; + case 1: obj->uart = (LPC_USART0_Type *)LPC_USART1_BASE; break; + case 2: obj->uart = (LPC_USART0_Type *)LPC_USART2_BASE; break; + } + uart_used |= (1 << uart_n); + + switch_pin(&SWM_UART_TX[uart_n], tx); + switch_pin(&SWM_UART_RX[uart_n], rx); + + /* uart clock divided by 6 */ + LPC_SYSCON->UARTCLKDIV =6; + + /* disable uart interrupts */ + NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART clock */ + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << (17 + uart_n)); + + /* Peripheral reset control to UART, a "1" bring it out of reset. */ + LPC_SYSCON->PRESETCTRL1 |= (0x1 << (17 + uart_n)); + LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << (17 + uart_n)); + + UARTSysClk = SystemCoreClock / LPC_SYSCON->UARTCLKDIV; + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + /* Clear all status bits. */ + obj->uart->STAT = CTS_DELTA | DELTA_RXBRK; + + /* enable uart interrupts */ + NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART */ + obj->uart->CFG |= UART_EN; + + is_stdio_uart = ((tx == USBTX) && (rx == USBRX)); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + uart_used &= ~(1 << obj->index); + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + /* Integer divider: + BRG = UARTSysClk/(Baudrate * 16) - 1 + + Frational divider: + FRG = ((UARTSysClk / (Baudrate * 16 * (BRG + 1))) - 1) + + where + FRG = (LPC_SYSCON->UARTFRDADD + 1) / (LPC_SYSCON->UARTFRDSUB + 1) + + (1) The easiest way is set SUB value to 256, -1 encoded, thus SUB + register is 0xFF. + (2) In ADD register value, depending on the value of UartSysClk, + baudrate, BRG register value, and SUB register value, be careful + about the order of multiplier and divider and make sure any + multiplier doesn't exceed 32-bit boundary and any divider doesn't get + down below one(integer 0). + (3) ADD should be always less than SUB. + */ + obj->uart->BRG = UARTSysClk / 16 / baudrate - 1; + + // To use of the fractional baud rate generator, you must write 0xFF to the DIV + // value to yield a denominator value of 256. All other values are not supported. + LPC_SYSCON->FRGCTRL = 0xFF; + + LPC_SYSCON->FRGCTRL |= ( ( ((UARTSysClk / 16) * (0xFF + 1)) / + (baudrate * (obj->uart->BRG + 1)) + ) - (0xFF + 1) ) << 8; + +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 6) && (data_bits < 10)); // 0: 7 data bits ... 2: 9 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityEven) || (parity == ParityOdd)); + + stop_bits -= 1; + data_bits -= 7; + + int paritysel; + switch (parity) { + case ParityNone: paritysel = 0; break; + case ParityEven: paritysel = 2; break; + case ParityOdd : paritysel = 3; break; + default: + break; + } + + // First disable the the usart as described in documentation and then enable while updating CFG + + // 24.6.1 USART Configuration register + // Remark: If software needs to change configuration values, the following sequence should + // be used: 1) Make sure the USART is not currently sending or receiving data. 2) Disable + // the USART by writing a 0 to the Enable bit (0 may be written to the entire register). 3) + // Write the new configuration value, with the ENABLE bit set to 1. + obj->uart->CFG &= ~(1 << 0); + + obj->uart->CFG = (1 << 0) // this will enable the usart + | (data_bits << 2) + | (paritysel << 4) + | (stop_bits << 6); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(SerialIrq irq_type, uint32_t index) { + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART0->INTSTAT & 1) ? RxIrq : TxIrq, 0);} +void uart1_irq() {uart_irq((LPC_USART1->INTSTAT & 1) ? RxIrq : TxIrq, 1);} +void uart2_irq() {uart_irq((LPC_USART2->INTSTAT & 1) ? RxIrq : TxIrq, 2);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + } + + if (enable) { + NVIC_DisableIRQ(irq_n); + obj->uart->INTENSET |= (1 << ((irq == RxIrq) ? 0 : 2)); + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->INTENCLR |= (1 << ((irq == RxIrq) ? 0 : 2)); // disable the interrupt + all_disabled = (obj->uart->INTENSET & (1 << ((other_irq == RxIrq) ? 0 : 2))) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RXDATA; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->TXDATA = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->STAT & RXRDY; +} + +int serial_writable(serial_t *obj) { + return obj->uart->STAT & TXRDY; +} + +void serial_clear(serial_t *obj) { + // [TODO] +} + +void serial_pinout_tx(PinName tx) { + +} + +void serial_break_set(serial_t *obj) { + obj->uart->CTRL |= TXBRKEN; +} + +void serial_break_clear(serial_t *obj) { + obj->uart->CTRL &= ~TXBRKEN; +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { + if ((FlowControlNone == type || FlowControlRTS == type)) txflow = NC; + if ((FlowControlNone == type || FlowControlCTS == type)) rxflow = NC; + switch_pin(&SWM_UART_RTS[obj->index], rxflow); + switch_pin(&SWM_UART_CTS[obj->index], txflow); + if (txflow == NC) obj->uart->CFG &= ~CTSEN; + else obj->uart->CFG |= CTSEN; +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c new file mode 100644 index 0000000000..79d1d2aeef --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c @@ -0,0 +1,276 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const SWM_Map SWM_SPI_SSEL[] = { + {4, 0}, + {5, 24}, +}; + +static const SWM_Map SWM_SPI_SCLK[] = { + {3, 8}, + {5, 0}, +}; + +static const SWM_Map SWM_SPI_MOSI[] = { + {3, 16}, + {5, 8}, +}; + +static const SWM_Map SWM_SPI_MISO[] = { + {3, 24}, + {5, 16}, +}; + +// bit flags for used SPIs +static unsigned char spi_used = 0; +static int get_available_spi(PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + if (spi_used == 0) { + return 0; // The first user + } + + const SWM_Map *swm; + uint32_t regVal; + + // Investigate if same pins as the used SPI0/1 - to be able to reuse it + for (int spi_n = 0; spi_n < 2; spi_n++) { + if (spi_used & (1<<spi_n)) { + if (sclk != NC) { + swm = &SWM_SPI_SCLK[spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + if (regVal != (sclk << swm->offset)) { + // Existing pin is not the same as the one we want + continue; + } + } + + if (mosi != NC) { + swm = &SWM_SPI_MOSI[spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + if (regVal != (mosi << swm->offset)) { + // Existing pin is not the same as the one we want + continue; + } + } + + if (miso != NC) { + swm = &SWM_SPI_MISO[spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + if (regVal != (miso << swm->offset)) { + // Existing pin is not the same as the one we want + continue; + } + } + + if (ssel != NC) { + swm = &SWM_SPI_SSEL[spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + if (regVal != (ssel << swm->offset)) { + // Existing pin is not the same as the one we want + continue; + } + } + + // The pins for the currently used SPIx are the same as the + // ones we want so we will reuse it + return spi_n; + } + } + + // None of the existing SPIx pin setups match the pins we want + // so the last hope is to select one unused SPIx + if ((spi_used & 1) == 0) { + return 0; + } else if ((spi_used & 2) == 0) { + return 1; + } + + // No matching setup and no free SPIx + return -1; +} + +static inline void spi_disable(spi_t *obj); +static inline void spi_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + int spi_n = get_available_spi(mosi, miso, sclk, ssel); + if (spi_n == -1) { + error("No available SPI"); + } + + obj->spi_n = spi_n; + spi_used |= (1 << spi_n); + + obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE); + + const SWM_Map *swm; + uint32_t regVal; + + if (sclk != NC) { + swm = &SWM_SPI_SCLK[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (sclk << swm->offset); + } + + if (mosi != NC) { + swm = &SWM_SPI_MOSI[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (mosi << swm->offset); + } + + if (miso != NC) { + swm = &SWM_SPI_MISO[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (miso << swm->offset); + } + + if (ssel != NC) { + swm = &SWM_SPI_SSEL[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (ssel << swm->offset); + } + + // clear interrupts + obj->spi->INTENCLR = 0x3f; + + // enable power and clocking + LPC_SYSCON->SYSAHBCLKCTRL1 |= (0x1 << (obj->spi_n + 9)); + LPC_SYSCON->PRESETCTRL1 |= (0x1 << (obj->spi_n + 9)); + LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << (obj->spi_n + 9)); + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the spi channel + spi_enable(obj); +} + +void spi_free(spi_t *obj) +{ +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) +{ + spi_disable(obj); + MBED_ASSERT((bits >= 1 && bits <= 16) && (mode >= 0 && mode <= 3)); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int LEN = bits - 1; // LEN - Data Length + int CPOL = (polarity) ? 1 : 0; // CPOL - Clock Polarity select + int CPHA = (phase) ? 1 : 0; // CPHA - Clock Phase select + + uint32_t tmp = obj->spi->CFG; + tmp &= ~((1 << 5) | (1 << 4) | (1 << 2)); + tmp |= (CPOL << 5) | (CPHA << 4) | ((slave ? 0 : 1) << 2); + obj->spi->CFG = tmp; + + // select frame length + tmp = obj->spi->TXCTL; + tmp &= ~(0xf << 24); + tmp |= (LEN << 24); + obj->spi->TXCTL = tmp; + + spi_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) +{ + spi_disable(obj); + + // rise DIV value if it cannot be divided + obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1; + obj->spi->DLY = 0; + + spi_enable(obj); +} + +static inline void spi_disable(spi_t *obj) +{ + obj->spi->CFG &= ~(1 << 0); +} + +static inline void spi_enable(spi_t *obj) +{ + obj->spi->CFG |= (1 << 0); +} + +static inline int spi_readable(spi_t *obj) +{ + return obj->spi->STAT & (1 << 0); +} + +static inline int spi_writeable(spi_t *obj) +{ + return obj->spi->STAT & (1 << 1); +} + +static inline void spi_write(spi_t *obj, int value) +{ + while (!spi_writeable(obj)); + // end of transfer + obj->spi->TXCTL |= (1 << 20); + obj->spi->TXDAT = (value & 0xffff); +} + +static inline int spi_read(spi_t *obj) +{ + while (!spi_readable(obj)); + return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data +} + +int spi_busy(spi_t *obj) +{ + // checking RXOV(Receiver Overrun interrupt flag) + return obj->spi->STAT & (1 << 2); +} + +int spi_master_write(spi_t *obj, int value) +{ + spi_write(obj, value); + return spi_read(obj); +} + +int spi_slave_receive(spi_t *obj) +{ + return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) +{ + return obj->spi->RXDAT & 0xffff; // Only the lower 16 bits contain data +} + +void spi_slave_write(spi_t *obj, int value) +{ + while (spi_writeable(obj) == 0) ; + obj->spi->TXDAT = value; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c new file mode 100644 index 0000000000..a4ad2d0039 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c @@ -0,0 +1,73 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER_IRQn RIT_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + // Enable the RIT clock + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 1); + + // Clear peripheral reset the RIT + LPC_SYSCON->PRESETCTRL1 |= (1 << 1); + LPC_SYSCON->PRESETCTRL1 &= ~(1 << 1); + + LPC_RIT->MASK = 0; + LPC_RIT->MASK_H = 0; + + LPC_RIT->COUNTER = 0; + LPC_RIT->COUNTER_H = 0; + + LPC_RIT->COMPVAL = 0xffffffff; + LPC_RIT->COMPVAL_H = 0x0000ffff; + + // Timer enable, enable for debug + LPC_RIT->CTRL = 0xC; + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + uint64_t temp; + temp = LPC_RIT->COUNTER | ((uint64_t)LPC_RIT->COUNTER_H << 32); + temp /= (SystemCoreClock/1000000); + return (uint32_t)temp; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + uint64_t temp = ((uint64_t)timestamp * (SystemCoreClock/1000000)); + LPC_RIT->COMPVAL = (temp & 0xFFFFFFFFL); + LPC_RIT->COMPVAL_H = ((temp >> 32)& 0x0000FFFFL); +} + +void us_ticker_disable_interrupt(void) { + LPC_RIT->CTRL |= (1 << 3); +} + +void us_ticker_clear_interrupt(void) { + LPC_RIT->CTRL |= (1 << 0); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PeripheralNames.h new file mode 100644 index 0000000000..a8d1ee298f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PeripheralNames.h @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART0_BASE, + UART_1 = (int)LPC_UART1_BASE, + UART_2 = (int)LPC_UART2_BASE, + UART_3 = (int)LPC_UART3_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE, + I2C_2 = (int)LPC_I2C2_BASE +} I2CName; + +typedef enum { + PWM_1 = 1, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6 +} PWMName; + +typedef enum { + CAN_1 = (int)LPC_CAN1_BASE, + CAN_2 = (int)LPC_CAN2_BASE +} CANName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7, p8 +#define MBED_SPI1 p11, p12, p13, p14 + +#define MBED_UART0 p9, p10 +#define MBED_UART1 p13, p14 +#define MBED_UART2 p28, p27 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p28, p27 +#define MBED_I2C1 p9, p10 + +#define MBED_CAN0 p30, p29 + +#define MBED_ANALOGOUT0 p18 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#define MBED_PWMOUT0 p26 +#define MBED_PWMOUT1 p25 +#define MBED_PWMOUT2 p24 +#define MBED_PWMOUT3 p23 +#define MBED_PWMOUT4 p22 +#define MBED_PWMOUT5 p21 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PortNames.h new file mode 100644 index 0000000000..270cdeecb0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/PortNames.h @@ -0,0 +1,34 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3, + Port4 = 4 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/PinNames.h new file mode 100644 index 0000000000..f0b060d8d9 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/PinNames.h @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = LPC_GPIO0_BASE, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P0_7, + p8 = P0_6, + p9 = P0_0, + p10 = P0_1, + p11 = P0_18, + p12 = P0_17, + p13 = P0_15, + p14 = P0_16, + p15 = P0_23, + p16 = P0_24, + p17 = P0_25, + p18 = P0_26, + p19 = P1_30, + p20 = P1_31, + p21 = P2_5, + p22 = P2_4, + p23 = P2_3, + p24 = P2_2, + p25 = P2_1, + p26 = P2_0, + p27 = P0_11, + p28 = P0_10, + p29 = P0_5, + p30 = P0_4, + + // Other mbed Pin Names +#ifdef MCB1700 + LED1 = P1_28, + LED2 = P1_29, + LED3 = P1_31, + LED4 = P2_2, +#else + LED1 = P1_18, + LED2 = P1_20, + LED3 = P1_21, + LED4 = P1_23, +#endif + USBTX = P0_2, + USBRX = P0_3, + + // Arch Pro Pin Names + D0 = P4_29, + D1 = P4_28, + D2 = P0_4, + D3 = P0_5, + D4 = P2_2, + D5 = P2_3, + D6 = P2_4, + D7 = P2_5, + D8 = P0_0, + D9 = P0_1, + D10 = P0_6, + D11 = P0_9, + D12 = P0_8, + D13 = P0_7, + D14 = P0_27, + D15 = P0_28, + + A0 = P0_23, + A1 = P0_24, + A2 = P0_25, + A3 = P0_26, + A4 = P1_30, + A5 = P1_31, + + I2C_SCL = D15, + I2C_SDA = D14, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + Repeater = 1, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +// version of PINCON_TypeDef using register arrays +typedef struct { + __IO uint32_t PINSEL[11]; + uint32_t RESERVED0[5]; + __IO uint32_t PINMODE[10]; + __IO uint32_t PINMODE_OD[5]; +} PINCONARRAY_TypeDef; + +#define PINCONARRAY ((PINCONARRAY_TypeDef *)LPC_PINCON_BASE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/device.h new file mode 100644 index 0000000000..a60f677905 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/device.h @@ -0,0 +1,60 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 0 +#define DEVICE_MAC_OFFSET 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/reserved_pins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/reserved_pins.h new file mode 100644 index 0000000000..b392cd2f21 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/reserved_pins.h @@ -0,0 +1,8 @@ +// List of reserved pins for MBED LPC1768 + +#ifndef RESERVED_PINS_H +#define RESERVED_PINS_H + +#define TARGET_RESERVED_PINS {} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/PinNames.h new file mode 100644 index 0000000000..f0b060d8d9 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/PinNames.h @@ -0,0 +1,139 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = LPC_GPIO0_BASE, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P0_7, + p8 = P0_6, + p9 = P0_0, + p10 = P0_1, + p11 = P0_18, + p12 = P0_17, + p13 = P0_15, + p14 = P0_16, + p15 = P0_23, + p16 = P0_24, + p17 = P0_25, + p18 = P0_26, + p19 = P1_30, + p20 = P1_31, + p21 = P2_5, + p22 = P2_4, + p23 = P2_3, + p24 = P2_2, + p25 = P2_1, + p26 = P2_0, + p27 = P0_11, + p28 = P0_10, + p29 = P0_5, + p30 = P0_4, + + // Other mbed Pin Names +#ifdef MCB1700 + LED1 = P1_28, + LED2 = P1_29, + LED3 = P1_31, + LED4 = P2_2, +#else + LED1 = P1_18, + LED2 = P1_20, + LED3 = P1_21, + LED4 = P1_23, +#endif + USBTX = P0_2, + USBRX = P0_3, + + // Arch Pro Pin Names + D0 = P4_29, + D1 = P4_28, + D2 = P0_4, + D3 = P0_5, + D4 = P2_2, + D5 = P2_3, + D6 = P2_4, + D7 = P2_5, + D8 = P0_0, + D9 = P0_1, + D10 = P0_6, + D11 = P0_9, + D12 = P0_8, + D13 = P0_7, + D14 = P0_27, + D15 = P0_28, + + A0 = P0_23, + A1 = P0_24, + A2 = P0_25, + A3 = P0_26, + A4 = P1_30, + A5 = P1_31, + + I2C_SCL = D15, + I2C_SDA = D14, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + Repeater = 1, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +// version of PINCON_TypeDef using register arrays +typedef struct { + __IO uint32_t PINSEL[11]; + uint32_t RESERVED0[5]; + __IO uint32_t PINMODE[10]; + __IO uint32_t PINMODE_OD[5]; +} PINCONARRAY_TypeDef; + +#define PINCONARRAY ((PINCONARRAY_TypeDef *)LPC_PINCON_BASE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/device.h new file mode 100644 index 0000000000..a4646b7a00 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/device.h @@ -0,0 +1,60 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 1 +#define DEVICE_LOCALFILESYSTEM 1 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/reserved_pins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/reserved_pins.h new file mode 100644 index 0000000000..b392cd2f21 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/reserved_pins.h @@ -0,0 +1,8 @@ +// List of reserved pins for MBED LPC1768 + +#ifndef RESERVED_PINS_H +#define RESERVED_PINS_H + +#define TARGET_RESERVED_PINS {} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.c new file mode 100644 index 0000000000..cb290d45e7 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.c @@ -0,0 +1,81 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "gpio_api.h" +#include "wait_api.h" +#include "C027_api.h" + +static gpio_t mdmEn, mdmLvlOe, mdmILvlOe, mdmUsbDet; +static gpio_t gpsEn; + +void c027_init(void) { + gpio_t led, mdmRts, mdmRst, gpsRst, mdmPwrOn; + // start with modem disabled + gpio_init_out_ex(&mdmEn, MDMEN, 0); + gpio_init_out_ex(&mdmRst, MDMRST, 1); + gpio_init_out_ex(&mdmPwrOn, MDMPWRON, 1); + gpio_init_out_ex(&mdmLvlOe, MDMLVLOE, 1); // LVLEN: 1=disabled + gpio_init_out_ex(&mdmILvlOe, MDMILVLOE, 0); // ILVLEN: 0=disabled + gpio_init_out_ex(&mdmUsbDet, MDMUSBDET, 0); + gpio_init_out_ex(&mdmRts, MDMRTS, 0); + // start with gps disabled + gpio_init_out_ex(&gpsEn, GPSEN, 0); + gpio_init_out_ex(&gpsRst, GPSRST, 1); + // led should be off + gpio_init_out_ex(&led, LED, 0); + + wait_ms(50); // when USB cable is inserted the interface chip issues +} + +void c027_mdm_powerOn(int usb) { + // turn on the mode by enabling power with power on pin low and correct USB detect level + gpio_write(&mdmUsbDet, usb ? 1 : 0); // USBDET: 0=disabled, 1=enabled + if (!gpio_read(&mdmEn)) { // enable modem + gpio_write(&mdmEn, 1); // LDOEN: 1=on + wait_ms(1); // wait until supply switched off + // now we can safely enable the level shifters + gpio_write(&mdmLvlOe, 0); // LVLEN: 0=enabled (uart/gpio) + if (gpio_read(&gpsEn)) + gpio_write(&mdmILvlOe, 1); // ILVLEN: 1=enabled (i2c) + } +} + +void c027_mdm_powerOff(void) { + if (gpio_read(&mdmEn)) { + // diable all level shifters + gpio_write(&mdmILvlOe, 0); // ILVLEN: 0=disabled (i2c) + gpio_write(&mdmLvlOe, 1); // LVLEN: 1=disabled (uart/gpio) + gpio_write(&mdmUsbDet, 0); // USBDET: 0=disabled + // now we can savely switch off the ldo + gpio_write(&mdmEn, 0); // LDOEN: 0=off + } +} + +void c027_gps_powerOn(void) { + if (!gpio_read(&gpsEn)) { + // switch on power supply + gpio_write(&gpsEn, 1); // LDOEN: 1=on + wait_ms(1); // wait until supply switched off + if (gpio_read(&mdmEn)) + gpio_write(&mdmILvlOe, 1); // ILVLEN: 1=enabled (i2c) + } +} + +void c027_gps_powerOff(void) { + if (gpio_read(&gpsEn)) { + gpio_write(&mdmILvlOe, 0); // ILVLEN: 0=disabled (i2c) + gpio_write(&gpsEn, 0); // LDOEN: 0=off + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.h new file mode 100644 index 0000000000..46897945cb --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/C027_api.h @@ -0,0 +1,22 @@ +#ifndef C027_H +#define C027_H + +#ifdef __cplusplus +extern "C" { +#endif + +void c027_init(void); + +void c027_mdm_powerOn(int usb); + +void c027_mdm_powerOff(void); + +void c027_gps_powerOn(void); + +void c027_gps_powerOff(void); + +#ifdef __cplusplus +} +#endif + +#endif // C027_H diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h new file mode 100644 index 0000000000..e1c99e8a08 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h @@ -0,0 +1,193 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = LPC_GPIO0_BASE, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + + // Arduino Pin Names + + // PIN header connector + // for standard-based form factor with expansion board + // ----------------------------------------------------------- + // PMW = Pulswidth Modulator + // EINT = External Interrupt + // AOUT = Analog Output + + // Analog Ports (A0-A5) + A0 = P0_23, // I2S_CLK + A1 = P0_24, // I2S_WS + A2 = P0_25, // I2S_SDA + A3 = P0_26, // AOUT + A4 = P1_30, // + A5 = P1_31, // + // Digital Port (D0-D7) + D0 = P4_29, // TXD + D1 = P4_28, // RXD + D2 = P2_13, // EINT + D3 = P2_0, // PWM + D4 = P2_12, // EINT + D5 = P2_1, // PWM + D6 = P2_2, // PWM + D7 = P2_11, // EINT + // Digital Port (D8-D13) + D8 = P2_4, // PWM + D9 = P2_3, // PWM + D10 = P1_21, // PWM SSEL + D11 = P1_24, // PWM MOSI + D12 = P1_23, // PWM MISO + D13 = P1_20, // PWM SCK + // GND + // AREF + SDA = P0_0, + D14 = SDA, + SCL = P0_1, + D15 = SCL, + + // I2C (shared with LISA/SARA) + GPSSDA = P0_27, + GPSSCL = P0_28, + // UART + GPSTXD = P0_10, + GPSRXD = P0_11, + // Control + GPSRST = P1_18, // Reset (input to GPS, active low) + GPSPPS = P1_19, // 1PPS Timepulse (output from GPS) + GPSINT = P1_22, // Interrupt (input to GPS) + GPSEN = P1_29, // Supply Control (high = enabled) + + // u-blox LISA/SARA cellular modem + // http://www.u-blox.com/wireless-modules.html + // ----------------------------------------------------------- + // UART (LPC1768 = DTE, LISA/SARA = DCE) + MDMTXD = P0_15, // Transmit Data + MDMRXD = P0_16, // Receive Data + MDMCTS = P0_17, // Clear to Send + MDMDCD = P0_18, // Data Carrier Detect + MDMDSR = P0_19, // Data Set Ready + MDMDTR = P0_20, // Data Terminal Ready (set high or use handshake) + MDMRI = P0_21, // Ring Indicator + MDMRTS = P0_22, // Request to Send (set high or use handshake) + + // USB (not available on C27-G35) + MDMUSBDP = P0_29, // USB D+ + MDMUSBDN = P0_30, // USB D- + MDMUSBCON = P2_9, // USB Connect + MDMUSBDET = P0_7, // USB Detect (n/a on REV.A board) + // Control + MDMEN = P2_5, // Supply Control (high = enabled) + MDMPWRON = P2_6, // + MDMGPIO1 = P2_7, // GPIO1, Network status + MDMRST = P2_8, // Reset (active low, set as open drain!) + MDMLVLOE = P0_9, // Serial/GPIO Level Shifter Output Enable (n/a on REV.A board) + MDMILVLOE = P0_8, // I2C Level Shifter Output Enable (n/a on REV.A board) + + // CAN (TJA1040) + // ----------------------------------------------------------- + CANRD = P0_4, + CANTD = P0_5, + CANS = P0_6, // standby (low=normal, high=standby/rxonly) + + // Ethernet (DP83848) + // ----------------------------------------------------------- + ETHTXD0 = P1_0, + ETHTXD1 = P1_1, + ETHTXEN = P1_4, + ETHCRS = P1_8, + ETHRXD0 = P1_9, + ETHRXD1 = P1_10, + ETHRXEN = P1_14, + ETHREFCLK = P1_15, + ETHMDC = P1_16, + ETHMDIO = P1_17, + ETHOSCEN = P1_27, + ETHRST = P1_28, + ETHLINK = P1_25, // LED_LINK + ETHSPEED = P1_26, // LED_SPEED + + // ISP port + // ----------------------------------------------------------- + ISP = P2_10, + + // Other mbed Pin Names + LED = P3_25, + LED1 = LED, + LED2 = LED, + LED3 = LED, + LED4 = LED, + LED_RED = LED, + + // mbed / debug IF (LPC11) + // ----------------------------------------------------------- + // Serial Port + USBTX = P0_2, + USBRX = P0_3, + USBTXD = USBTX, // identical USBTX + USBRXD = USBRX, // identical USBRX + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + Repeater = 1, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +// version of PINCON_TypeDef using register arrays +typedef struct { + __IO uint32_t PINSEL[11]; + uint32_t RESERVED0[5]; + __IO uint32_t PINMODE[10]; + __IO uint32_t PINMODE_OD[5]; +} PINCONARRAY_TypeDef; + +#define PINCONARRAY ((PINCONARRAY_TypeDef *)LPC_PINCON_BASE) + +//Additional C027 stuff +#define GPSADR (66<<1) // GPS I2C Address +#define GPSBAUD 9600 // Default GPS Baud Rate +#define MDMBAUD 115200 // Default Modem Baud Rate + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/device.h new file mode 100644 index 0000000000..3b6e556a40 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/device.h @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 0 +#define DEVICE_MAC_OFFSET 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +// should only enable one or the other, not both +#define DEVICE_ERROR_PATTERN 0 +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_overrides.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_overrides.c new file mode 100644 index 0000000000..9d9eac1c19 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_overrides.c @@ -0,0 +1,21 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "C027_api.h" + +// called before main +void mbed_sdk_init() { + c027_init(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/reserved_pins.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/reserved_pins.h new file mode 100644 index 0000000000..512dd6908b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/reserved_pins.h @@ -0,0 +1,8 @@ +// List of reserved pins for C027 LPC1768 + +#ifndef RESERVED_PINS_H +#define RESERVED_PINS_H + +#define TARGET_RESERVED_PINS {P3_26} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogin_api.c new file mode 100644 index 0000000000..2015c0d43d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogin_api.c @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" + +#include "cmsis.h" +#include "pinmap.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_23, ADC0_0, 1}, + {P0_24, ADC0_1, 1}, + {P0_25, ADC0_2, 1}, + {P0_26, ADC0_3, 1}, + {P1_30, ADC0_4, 3}, + {P1_31, ADC0_5, 3}, + {P0_2, ADC0_7, 2}, + {P0_3, ADC0_6, 2}, + {NC, NC, 0} +}; + +#define ADC_RANGE ADC_12BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // ensure power is turned on + LPC_SC->PCONP |= (1 << 12); + + // set PCLK of ADC to /1 + LPC_SC->PCLKSEL0 &= ~(0x3 << 24); + LPC_SC->PCLKSEL0 |= (0x1 << 24); + uint32_t PCLK = SystemCoreClock; + + // calculate minimum clock divider + // clkdiv = divider - 1 + uint32_t MAX_ADC_CLK = 13000000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + // Set the generic software-controlled ADC settings + LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected + | (clkdiv << 8) // CLKDIV: PCLK max ~= 25MHz, /25 to give safe 1MHz at fastest + | (0 << 16) // BURST: 0 = software control + | (0 << 17) // CLKS: not applicable + | (1 << 21) // PDN: 1 = operational + | (0 << 24) // START: 0 = no start + | (0 << 27); // EDGE: not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= 1 << (int)obj->adc; + LPC_ADC->ADCR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->ADGDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->ADCR &= ~(1 << 24); + + return (data >> 4) & ADC_RANGE; // 12 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogout_api.c new file mode 100644 index 0000000000..ae64e8e179 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/analogout_api.c @@ -0,0 +1,76 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogout_api.h" + +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_DAC[] = { + {P0_26, DAC_0, 2}, + {NC , NC , 0} +}; + +void analogout_init(dac_t *obj, PinName pin) { + obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); + MBED_ASSERT(obj->dac != (DACName)NC); + + // power is on by default, set DAC clk divider is /4 + LPC_SC->PCLKSEL0 &= ~(0x3 << 22); + + // map out (must be done before accessing registers) + pinmap_pinout(pin, PinMap_DAC); + + analogout_write_u16(obj, 0); +} + +void analogout_free(dac_t *obj) {} + +static inline void dac_write(int value) { + value &= 0x3FF; // 10-bit + + // Set the DAC output + LPC_DAC->DACR = (0 << 16) // bias = 0 + | (value << 6); +} + +static inline int dac_read() { + return (LPC_DAC->DACR >> 6) & 0x3FF; +} + +void analogout_write(dac_t *obj, float value) { + if (value < 0.0f) { + dac_write(0); + } else if (value > 1.0f) { + dac_write(0x3FF); + } else { + dac_write(value * (float)0x3FF); + } +} + +void analogout_write_u16(dac_t *obj, uint16_t value) { + dac_write(value >> 6); // 10-bit +} + +float analogout_read(dac_t *obj) { + uint32_t value = dac_read(); + return (float)value * (1.0f / (float)0x3FF); +} + +uint16_t analogout_read_u16(dac_t *obj) { + uint32_t value = dac_read(); // 10-bit + return (value << 6) | ((value >> 4) & 0x003F); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c new file mode 100644 index 0000000000..5aab445133 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/can_api.c @@ -0,0 +1,406 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "can_api.h" + +#include "cmsis.h" +#include "pinmap.h" + +#include <math.h> +#include <string.h> + +#define CAN_NUM 2 + +/* Acceptance filter mode in AFMR register */ +#define ACCF_OFF 0x01 +#define ACCF_BYPASS 0x02 +#define ACCF_ON 0x00 +#define ACCF_FULLCAN 0x04 + +/* There are several bit timing calculators on the internet. +http://www.port.de/engl/canprod/sv_req_form.html +http://www.kvaser.com/can/index.htm +*/ + +static const PinMap PinMap_CAN_RD[] = { + {P0_0 , CAN_1, 1}, + {P0_4 , CAN_2, 2}, + {P0_21, CAN_1, 3}, + {P2_7 , CAN_2, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_CAN_TD[] = { + {P0_1 , CAN_1, 1}, + {P0_5 , CAN_2, 2}, + {P0_22, CAN_1, 3}, + {P2_8 , CAN_2, 1}, + {NC , NC , 0} +}; + +// Type definition to hold a CAN message +struct CANMsg { + unsigned int reserved1 : 16; + unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter + unsigned int reserved0 : 10; + unsigned int rtr : 1; // Bit 30: Set if this is a RTR message + unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message + unsigned int id; // CAN Message ID (11-bit or 29-bit) + unsigned char data[8]; // CAN Message Data Bytes 0-7 +}; +typedef struct CANMsg CANMsg; + +static uint32_t can_irq_ids[CAN_NUM] = {0}; +static can_irq_handler irq_handler; + +static uint32_t can_disable(can_t *obj) { + uint32_t sm = obj->dev->MOD; + obj->dev->MOD |= 1; + return sm; +} + +static inline void can_enable(can_t *obj) { + if (obj->dev->MOD & 1) { + obj->dev->MOD &= ~(1); + } +} + +int can_mode(can_t *obj, CanMode mode) { + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + return 0; // not implemented +} + +static inline void can_irq(uint32_t icr, uint32_t index) { + uint32_t i; + + for(i = 0; i < 8; i++) + { + if((can_irq_ids[index] != 0) && (icr & (1 << i))) + { + switch (i) { + case 0: irq_handler(can_irq_ids[index], IRQ_RX); break; + case 1: irq_handler(can_irq_ids[index], IRQ_TX); break; + case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break; + case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break; + case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break; + case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break; + case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break; + case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break; + case 8: irq_handler(can_irq_ids[index], IRQ_READY); break; + } + } + } +} + +// Have to check that the CAN block is active before reading the Interrupt +// Control Register, or the mbed hangs +void can_irq_n() { + uint32_t icr; + + if(LPC_SC->PCONP & (1 << 13)) { + icr = LPC_CAN1->ICR & 0x1FF; + can_irq(icr, 0); + } + + if(LPC_SC->PCONP & (1 << 14)) { + icr = LPC_CAN2->ICR & 0x1FF; + can_irq(icr, 1); + } +} + +// Register CAN object's irq handler +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +// Unregister CAN object's irq handler +void can_irq_free(can_t *obj) { + obj->dev->IER &= ~(1); + can_irq_ids[obj->index] = 0; + + if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +// Clear or set a irq +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { + uint32_t ier; + + switch (type) { + case IRQ_RX: ier = (1 << 0); break; + case IRQ_TX: ier = (1 << 1); break; + case IRQ_ERROR: ier = (1 << 2); break; + case IRQ_OVERRUN: ier = (1 << 3); break; + case IRQ_WAKEUP: ier = (1 << 4); break; + case IRQ_PASSIVE: ier = (1 << 5); break; + case IRQ_ARB: ier = (1 << 6); break; + case IRQ_BUS: ier = (1 << 7); break; + case IRQ_READY: ier = (1 << 8); break; + default: return; + } + + obj->dev->MOD |= 1; + if(enable == 0) { + obj->dev->IER &= ~ier; + } + else { + obj->dev->IER |= ier; + } + obj->dev->MOD &= ~(1); + + // Enable NVIC if at least 1 interrupt is active + if(((LPC_SC->PCONP & (1 << 13)) && LPC_CAN1->IER) || ((LPC_SC->PCONP & (1 << 14)) && LPC_CAN2->IER)) { + NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n); + NVIC_EnableIRQ(CAN_IRQn); + } + else { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +static int can_pclk(can_t *obj) { + int value = 0; + switch ((int)obj->dev) { + case CAN_1: value = (LPC_SC->PCLKSEL0 & (0x3 << 26)) >> 26; break; + case CAN_2: value = (LPC_SC->PCLKSEL0 & (0x3 << 28)) >> 28; break; + } + + switch (value) { + case 1: return 1; + case 2: return 2; + case 3: return 6; + default: return 4; + } +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits; + + bitwidth = sclk / (pclk * cclk); + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + if (hit) { + btr = ((timing_pts[bits][1] << 20) & 0x00700000) + | ((timing_pts[bits][0] << 16) & 0x000F0000) + | ((psjw << 14) & 0x0000C000) + | ((brp << 0) & 0x000003FF); + } else { + btr = 0xFFFFFFFF; + } + + return btr; + +} + +void can_init(can_t *obj, PinName rd, PinName td) { + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)obj->dev != NC); + + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP |= 1 << 13; break; + case CAN_2: LPC_SC->PCONP |= 1 << 14; break; + } + + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + + switch ((int)obj->dev) { + case CAN_1: obj->index = 0; break; + case CAN_2: obj->index = 1; break; + } + + can_reset(obj); + obj->dev->IER = 0; // Disable Interrupts + can_frequency(obj, 100000); + + LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter +} + +void can_free(can_t *obj) { + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break; + case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break; + } +} + +int can_frequency(can_t *obj, int f) { + int pclk = can_pclk(obj); + + int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1); + + if (btr > 0) { + uint32_t modmask = can_disable(obj); + obj->dev->BTR = btr; + obj->dev->MOD = modmask; + return 1; + } else { + return 0; + } +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + unsigned int CANStatus; + CANMsg m; + + can_enable(obj); + + m.id = msg.id ; + m.dlc = msg.len & 0xF; + m.rtr = msg.type; + m.type = msg.format; + memcpy(m.data, msg.data, msg.len); + const unsigned int *buf = (const unsigned int *)&m; + + CANStatus = obj->dev->SR; + if (CANStatus & 0x00000004) { + obj->dev->TFI1 = buf[0] & 0xC00F0000; + obj->dev->TID1 = buf[1]; + obj->dev->TDA1 = buf[2]; + obj->dev->TDB1 = buf[3]; + if(cc) { + obj->dev->CMR = 0x30; + } else { + obj->dev->CMR = 0x21; + } + return 1; + + } else if (CANStatus & 0x00000400) { + obj->dev->TFI2 = buf[0] & 0xC00F0000; + obj->dev->TID2 = buf[1]; + obj->dev->TDA2 = buf[2]; + obj->dev->TDB2 = buf[3]; + if (cc) { + obj->dev->CMR = 0x50; + } else { + obj->dev->CMR = 0x41; + } + return 1; + + } else if (CANStatus & 0x00040000) { + obj->dev->TFI3 = buf[0] & 0xC00F0000; + obj->dev->TID3 = buf[1]; + obj->dev->TDA3 = buf[2]; + obj->dev->TDB3 = buf[3]; + if (cc) { + obj->dev->CMR = 0x90; + } else { + obj->dev->CMR = 0x81; + } + return 1; + } + + return 0; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + CANMsg x; + unsigned int *i = (unsigned int *)&x; + + can_enable(obj); + + if (obj->dev->GSR & 0x1) { + *i++ = obj->dev->RFS; // Frame + *i++ = obj->dev->RID; // ID + *i++ = obj->dev->RDA; // Data A + *i++ = obj->dev->RDB; // Data B + obj->dev->CMR = 0x04; // release receive buffer + + msg->id = x.id; + msg->len = x.dlc; + msg->format = (x.type)? CANExtended : CANStandard; + msg->type = (x.rtr)? CANRemote: CANData; + memcpy(msg->data,x.data,x.dlc); + return 1; + } + + return 0; +} + +void can_reset(can_t *obj) { + can_disable(obj); + obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset +} + +unsigned char can_rderror(can_t *obj) { + return (obj->dev->GSR >> 16) & 0xFF; +} + +unsigned char can_tderror(can_t *obj) { + return (obj->dev->GSR >> 24) & 0xFF; +} + +void can_monitor(can_t *obj, int silent) { + uint32_t mod_mask = can_disable(obj); + if (silent) { + obj->dev->MOD |= (1 << 1); + } else { + obj->dev->MOD &= ~(1 << 1); + } + if (!(mod_mask & 1)) { + can_enable(obj); + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/ethernet_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/ethernet_api.c new file mode 100644 index 0000000000..6790249a90 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/ethernet_api.c @@ -0,0 +1,948 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ethernet_api.h" + +#include <string.h> +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "mbed_error.h" + +#define NEW_LOGIC 0 +#define NEW_ETH_BUFFER 0 + +#if NEW_ETH_BUFFER + +#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets) +#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets) + +#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size +#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length) + +#else + +// Memfree calculation: +// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) + +// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556 +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ +#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */ +#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */ + +const int ethernet_MTU_SIZE = 0x300; + +#endif + +#define ETHERNET_ADDR_SIZE 6 + +struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +} PACKED; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +struct RX_STAT_TypeDef { /* RX Status struct */ + unsigned int Info; + unsigned int HashCRC; +} PACKED; +typedef struct RX_STAT_TypeDef RX_STAT_TypeDef; + +struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +} PACKED; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +struct TX_STAT_TypeDef { /* TX Status struct */ + unsigned int Info; +} PACKED; +typedef struct TX_STAT_TypeDef TX_STAT_TypeDef; + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ + + +static int phy_read(unsigned int PhyReg); +static int phy_write(unsigned int PhyReg, unsigned short Data); + +static void txdscr_init(void); +static void rxdscr_init(void); + +#if defined (__ICCARM__) +# define AHBSRAM1 +#elif defined(TOOLCHAIN_GCC_CR) +# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32"))) +#else +# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned)) +#endif + +AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG]; +AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG]; +AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG]; +AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG]; + + +#if NEW_LOGIC +static int rx_consume_offset = -1; +static int tx_produce_offset = -1; +#else +static int send_doff = 0; +static int send_idx = -1; +static int send_size = 0; + +static int receive_soff = 0; +static int receive_idx = -1; +#endif + +static uint32_t phy_id = 0; + +static inline int rinc(int idx, int mod) { + ++idx; + idx %= mod; + return idx; +} + +//extern unsigned int SystemFrequency; +static inline unsigned int clockselect() { + if(SystemCoreClock < 10000000) { + return 1; + } else if(SystemCoreClock < 15000000) { + return 2; + } else if(SystemCoreClock < 20000000) { + return 3; + } else if(SystemCoreClock < 25000000) { + return 4; + } else if(SystemCoreClock < 35000000) { + return 5; + } else if(SystemCoreClock < 50000000) { + return 6; + } else if(SystemCoreClock < 70000000) { + return 7; + } else if(SystemCoreClock < 80000000) { + return 8; + } else if(SystemCoreClock < 90000000) { + return 9; + } else if(SystemCoreClock < 100000000) { + return 10; + } else if(SystemCoreClock < 120000000) { + return 11; + } else if(SystemCoreClock < 130000000) { + return 12; + } else if(SystemCoreClock < 140000000) { + return 13; + } else if(SystemCoreClock < 150000000) { + return 15; + } else if(SystemCoreClock < 160000000) { + return 16; + } else { + return 0; + } +} + +#ifndef min +#define min(x, y) (((x)<(y))?(x):(y)) +#endif + +/*---------------------------------------------------------------------------- + Ethernet Device initialize + *----------------------------------------------------------------------------*/ +int ethernet_init() { + int regv, tout; + char mac[ETHERNET_ADDR_SIZE]; + unsigned int clock = clockselect(); + + LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ + + LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */ + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005; + + /* Reset all EMAC internal modules. */ + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | + MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */ + + LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */ + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + LPC_EMAC->MAXF = ETH_MAX_FLEN; + LPC_EMAC->CLRT = CLRT_DEF; + LPC_EMAC->IPGR = IPGR_DEF; + + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ + LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ + + for(tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; + LPC_EMAC->MCMD = 0; + + LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ + + for (tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->SUPP = 0; + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return -1; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) { + error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); + } + + ethernet_set_link(-1, 0); + + /* Set the Ethernet MAC Address registers */ + ethernet_address(mac); + LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4]; + LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2]; + LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0]; + + txdscr_init(); /* initialize DMA TX Descriptor */ + rxdscr_init(); /* initialize DMA RX Descriptor */ + + LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + /* Receive Broadcast, Perfect Match Packets */ + + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ + LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ + + + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->MAC1 |= MAC1_REC_EN; + +#if NEW_LOGIC + rx_consume_offset = -1; + tx_produce_offset = -1; +#else + send_doff = 0; + send_idx = -1; + send_size = 0; + + receive_soff = 0; + receive_idx = -1; +#endif + + return 0; +} + +/*---------------------------------------------------------------------------- + Ethernet Device Uninitialize + *----------------------------------------------------------------------------*/ +void ethernet_free() { + LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); + LPC_EMAC->IntClear = 0xFFFF; + + LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */ + + LPC_PINCON->PINSEL2 &= ~0x50150105; /* Disable P1 ethernet pins. */ + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000000; +} + +// if(TxProduceIndex == TxConsumeIndex) buffer array is empty +// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill +// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment +// TxConsumeIndex - The buffer that will/is beign sent by hardware + +int ethernet_write(const char *data, int slen) { + +#if NEW_LOGIC + + if(tx_produce_offset < 0) { // mark as active if not already + tx_produce_offset = 0; + } + + int index = LPC_EMAC->TxProduceIndex; + + int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum + int requested = slen; + int ncopy = min(remaining, requested); + + void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset); + void *psrc = (void *)(data); + + if(ncopy > 0 ){ + if(data != NULL) { + memcpy(pdst, psrc, ncopy); + } else { + memset(pdst, 0, ncopy); + } + } + + tx_produce_offset += ncopy; + + return ncopy; + +#else + void *pdst, *psrc; + const int dlen = ETH_FRAG_SIZE; + int copy = 0; + int soff = 0; + + if(send_idx == -1) { + send_idx = LPC_EMAC->TxProduceIndex; + } + + if(slen + send_doff > ethernet_MTU_SIZE) { + return -1; + } + + do { + copy = min(slen - soff, dlen - send_doff); + pdst = (void *)(txdesc[send_idx].Packet + send_doff); + psrc = (void *)(data + soff); + if(send_doff + copy > ETH_FRAG_SIZE) { + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT); + send_idx = rinc(send_idx, NUM_TX_FRAG); + send_doff = 0; + } + + if(data != NULL) { + memcpy(pdst, psrc, copy); + } else { + memset(pdst, 0, copy); + } + + soff += copy; + send_doff += copy; + send_size += copy; + } while(soff != slen); + + return soff; +#endif +} + +int ethernet_send() { + +#if NEW_LOGIC + if(tx_produce_offset < 0) { // no buffer active + return -1; + } + + // ensure there is a link + if(!ethernet_link()) { + return -2; + } + + // we have been writing in to a buffer, so finalise it + int size = tx_produce_offset; + int index = LPC_EMAC->TxProduceIndex; + txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST); + + // Increment ProduceIndex to allow it to be sent + // We can only do this if the next slot is free + int next = rinc(index, NUM_TX_FRAG); + while(next == LPC_EMAC->TxConsumeIndex) { + for(int i=0; i<1000; i++) { __NOP(); } + } + + LPC_EMAC->TxProduceIndex = next; + tx_produce_offset = -1; + return size; + +#else + int s = send_size; + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST); + send_idx = rinc(send_idx, NUM_TX_FRAG); + LPC_EMAC->TxProduceIndex = send_idx; + send_doff = 0; + send_idx = -1; + send_size = 0; + return s; +#endif +} + +// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read +// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd +// +// if(RxConsumeIndex == RxProduceIndex) buffer array is empty +// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full + +// Recevies an arrived ethernet packet. +// Receiving an ethernet packet will drop the last received ethernet packet +// and make a new ethernet packet ready to read. +// Returns size of packet, else 0 if nothing to receive + +// We read from RxConsumeIndex from position rx_consume_offset +// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading +// rx_consume_offset = -1 // no frame +// rx_consume_offset = 0 // start of frame +// Assumption: A fragment should alway be a whole frame + +int ethernet_receive() { +#if NEW_LOGIC + + // if we are currently reading a valid RxConsume buffer, increment to the next one + if(rx_consume_offset >= 0) { + LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG); + } + + // if the buffer is empty, mark it as no valid buffer + if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) { + rx_consume_offset = -1; + return 0; + } + + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + rx_consume_offset = 0; + + // check if it is not marked as last or for errors + if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) { + return -1; + } + + int size = (info & RINFO_SIZE) + 1; + return size - 4; // don't include checksum bytes + +#else + if(receive_idx == -1) { + receive_idx = LPC_EMAC->RxConsumeIndex; + } else { + while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + unsigned int info = rxstat[receive_idx].Info; + int slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + + LPC_EMAC->RxConsumeIndex = receive_idx; + } + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) { + receive_idx = -1; + return 0; + } + + return (rxstat[receive_idx].Info & RINFO_SIZE) - 3; +#endif +} + +// Read from an recevied ethernet packet. +// After receive returnd a number bigger than 0 it is +// possible to read bytes from this packet. +// Read will write up to size bytes into data. +// It is possible to use read multible times. +// Each time read will start reading after the last read byte before. + +int ethernet_read(char *data, int dlen) { +#if NEW_LOGIC + // Check we have a valid buffer to read + if(rx_consume_offset < 0) { + return 0; + } + + // Assume 1 fragment block + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum + + int remaining = size - rx_consume_offset; + int requested = dlen; + int ncopy = min(remaining, requested); + + void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset); + void *pdst = (void *)(data); + + if(data != NULL && ncopy > 0) { + memcpy(pdst, psrc, ncopy); + } + + rx_consume_offset += ncopy; + + return ncopy; +#else + int slen; + int copy = 0; + unsigned int more; + unsigned int info; + void *pdst, *psrc; + int doff = 0; + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) { + return 0; + } + + do { + info = rxstat[receive_idx].Info; + more = !(info & RINFO_LAST_FLAG); + slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } else { + + copy = min(slen - receive_soff, dlen - doff); + psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff); + pdst = (void *)(data + doff); + + if(data != NULL) { + /* check if Buffer available */ + memcpy(pdst, psrc, copy); + } + + receive_soff += copy; + doff += copy; + + if((more && (receive_soff == slen))) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + } + } + } while(more && !(doff == dlen) && !receive_soff); + + return doff; +#endif +} + +int ethernet_link(void) { + + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } + else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MWTD = Data; + + for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + return 0; + } + } + + return -1; +} + + +static int phy_read(unsigned int PhyReg) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + LPC_EMAC->MCMD = 0; + return LPC_EMAC->MRDD; /* Return a 16-bit value. */ + } + } + + return -1; +} + + +static void txdscr_init() { + int i; + + for(i = 0; i < NUM_TX_FRAG; i++) { + txdesc[i].Packet = (uint32_t)&txbuf[i]; + txdesc[i].Ctrl = 0; + txstat[i].Info = 0; + } + + LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxStatus = (uint32_t)txstat; + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; + + LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */ +} + + +static void rxdscr_init() { + int i; + + for(i = 0; i < NUM_RX_FRAG; i++) { + rxdesc[i].Packet = (uint32_t)&rxbuf[i]; + rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1); + rxstat[i].Info = 0; + rxstat[i].HashCRC = 0; + } + + LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxStatus = (uint32_t)rxstat; + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; + + LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */ +} + +void ethernet_address(char *mac) { + mbed_mac_address(mac); +} + +void ethernet_set_link(int speed, int duplex) { + unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + + phy_data = PHY_AUTO_NEG; + + } else { + + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for(tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + switch(phy_id) { + case DP83848C_ID: + + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } else { + LPC_EMAC->SUPP |= SUPP_SPEED; + } + + + break; + case LAN8720_ID: + + phy_data = phy_read(PHY_REG_SCSR); + + if (phy_data & PHY_SCSR_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_SCSR_100MBIT) { + LPC_EMAC->SUPP |= SUPP_SPEED; + } else { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } + + + break; + } + + +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_api.c new file mode 100644 index 0000000000..6a133b67aa --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_api.c @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + pin_function(pin, 0); + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)((int)pin & ~0x1F); + obj->reg_set = &port_reg->FIOSET; + obj->reg_clr = &port_reg->FIOCLR; + obj->reg_in = &port_reg->FIOPIN; + obj->reg_dir = &port_reg->FIODIR; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_irq_api.c new file mode 100644 index 0000000000..f6ca2da1a1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_irq_api.c @@ -0,0 +1,161 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> + +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include "cmsis.h" + +#define CHANNEL_NUM 48 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(void) { + // Read in all current interrupt registers. We do this once as the + // GPIO interrupt registers are on the APB bus, and this is slow. + uint32_t rise0 = LPC_GPIOINT->IO0IntStatR; + uint32_t fall0 = LPC_GPIOINT->IO0IntStatF; + uint32_t rise2 = LPC_GPIOINT->IO2IntStatR; + uint32_t fall2 = LPC_GPIOINT->IO2IntStatF; + uint8_t bitloc; + + while(rise0 > 0) { //Continue as long as there are interrupts pending + bitloc = 31 - __CLZ(rise0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt + if (channel_ids[bitloc] != 0) + irq_handler(channel_ids[bitloc], IRQ_RISE); //Run that interrupt + + //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register + LPC_GPIOINT->IO0IntClr = 1 << bitloc; + rise0 -= 1<<bitloc; + } + + while(fall0 > 0) { //Continue as long as there are interrupts pending + bitloc = 31 - __CLZ(fall0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt + if (channel_ids[bitloc] != 0) + irq_handler(channel_ids[bitloc], IRQ_FALL); //Run that interrupt + + //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register + LPC_GPIOINT->IO0IntClr = 1 << bitloc; + fall0 -= 1<<bitloc; + } + + //Same for port 2, only we need to watch the channel_index + while(rise2 > 0) { //Continue as long as there are interrupts pending + bitloc = 31 - __CLZ(rise2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt + + if (bitloc < 16) //Not sure if this is actually needed + if (channel_ids[bitloc+32] != 0) + irq_handler(channel_ids[bitloc+32], IRQ_RISE); //Run that interrupt + + //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register + LPC_GPIOINT->IO2IntClr = 1 << bitloc; + rise2 -= 1<<bitloc; + } + + while(fall2 > 0) { //Continue as long as there are interrupts pending + bitloc = 31 - __CLZ(fall2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt + + if (bitloc < 16) //Not sure if this is actually needed + if (channel_ids[bitloc+32] != 0) + irq_handler(channel_ids[bitloc+32], IRQ_FALL); //Run that interrupt + + //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register + LPC_GPIOINT->IO2IntClr = 1 << bitloc; + fall2 -= 1<<bitloc; + } +} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + obj->port = (int)pin & ~0x1F; + obj->pin = (int)pin & 0x1F; + + // Interrupts available only on GPIO0 and GPIO2 + if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) { + error("pins on this port cannot generate interrupts"); + } + + // put us in the interrupt table + int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32; + channel_ids[index] = id; + obj->ch = index; + + NVIC_SetVector(EINT3_IRQn, (uint32_t)handle_interrupt_in); + NVIC_EnableIRQ(EINT3_IRQn); + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + // ensure nothing is pending + switch (obj->port) { + case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break; + case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break; + } + + // enable the pin interrupt + if (event == IRQ_RISE) { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin); + } + break; + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin); + } + break; + } + } else { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin); + } + break; + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin); + } + break; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ(EINT3_IRQn); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ(EINT3_IRQn); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c new file mode 100644 index 0000000000..c7eea7cee7 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c @@ -0,0 +1,394 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_0 , I2C_1, 3}, + {P0_10, I2C_2, 2}, + {P0_19, I2C_1, 3}, + {P0_27, I2C_0, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_1 , I2C_1, 3}, + {P0_11, I2C_2, 2}, + {P0_20, I2C_1, 3}, + {P0_28, I2C_0, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->I2CONSET) +#define I2C_CONCLR(x) (x->i2c->I2CONCLR) +#define I2C_STAT(x) (x->i2c->I2STAT) +#define I2C_DAT(x) (x->i2c->I2DAT) +#define I2C_SCLL(x, val) (x->i2c->I2SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->I2SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + switch ((int)obj->i2c) { + case I2C_0: LPC_SC->PCONP |= 1 << 7; break; + case I2C_1: LPC_SC->PCONP |= 1 << 19; break; + case I2C_2: LPC_SC->PCONP |= 1 << 26; break; + } +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if(last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // [TODO] set pclk to /4 + uint32_t PCLK = SystemCoreClock / 4; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if ((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; + *((uint32_t *) addr) = mask & 0xFE; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/objects.h new file mode 100644 index 0000000000..ecbd354934 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/objects.h @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "gpio_object.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t port; + uint32_t pin; + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + __IO uint32_t *MR; + PWMName pwm; +}; + +struct serial_s { + LPC_UART_TypeDef *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct dac_s { + DACName dac; +}; + +struct can_s { + LPC_CAN_TypeDef *dev; + int index; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SSP_TypeDef *spi; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pinmap.c new file mode 100644 index 0000000000..d7af42e427 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pinmap.c @@ -0,0 +1,49 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0; + int index = pin_number >> 4; + int offset = (pin_number & 0xF) << 1; + + PINCONARRAY->PINSEL[index] &= ~(0x3 << offset); + PINCONARRAY->PINSEL[index] |= function << offset; +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0; + int index = pin_number >> 5; + int offset = pin_number & 0x1F; + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + PINCONARRAY->PINMODE_OD[index] &= ~(drain << offset); + PINCONARRAY->PINMODE_OD[index] |= drain << offset; + + if (!drain) { + index = pin_number >> 4; + offset = (pin_number & 0xF) << 1; + + PINCONARRAY->PINMODE[index] &= ~(0x3 << offset); + PINCONARRAY->PINMODE[index] |= (uint32_t)mode << offset; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/port_api.c new file mode 100644 index 0000000000..24f6d2c278 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/port_api.c @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) { + return (PinName)(LPC_GPIO0_BASE + ((port << PORT_SHIFT) | pin_n)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20)); + + // Do not use masking, because it prevents the use of the unmasked pins + // port_reg->FIOMASK = ~mask; + + obj->reg_out = &port_reg->FIOPIN; + obj->reg_in = &port_reg->FIOPIN; + obj->reg_dir = &port_reg->FIODIR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) { + return (*obj->reg_in & obj->mask); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pwmout_api.c new file mode 100644 index 0000000000..b8e2050e1d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/pwmout_api.c @@ -0,0 +1,171 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +// PORT ID, PWM ID, Pin function +static const PinMap PinMap_PWM[] = { + {P1_18, PWM_1, 2}, + {P1_20, PWM_2, 2}, + {P1_21, PWM_3, 2}, + {P1_23, PWM_4, 2}, + {P1_24, PWM_5, 2}, + {P1_26, PWM_6, 2}, + {P2_0 , PWM_1, 1}, + {P2_1 , PWM_2, 1}, + {P2_2 , PWM_3, 1}, + {P2_3 , PWM_4, 1}, + {P2_4 , PWM_5, 1}, + {P2_5 , PWM_6, 1}, + {P3_25, PWM_2, 3}, + {P3_26, PWM_3, 3}, + {NC, NC, 0} +}; + +__IO uint32_t *PWM_MATCH[] = { + &(LPC_PWM1->MR0), + &(LPC_PWM1->MR1), + &(LPC_PWM1->MR2), + &(LPC_PWM1->MR3), + &(LPC_PWM1->MR4), + &(LPC_PWM1->MR5), + &(LPC_PWM1->MR6) +}; + +#define TCR_PWM_EN 0x00000008 + +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->pwm = pwm; + obj->MR = PWM_MATCH[pwm]; + + // ensure the power is on + LPC_SC->PCONP |= 1 << 6; + + // ensure clock to /4 + LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4 + LPC_PWM1->PR = 0; // no pre-scale + + // ensure single PWM mode + LPC_PWM1->MCR = 1 << 1; // reset TC on match 0 + + // enable the specific PWM output + LPC_PWM1->PCR |= 1 << (8 + pwm); + + pwm_clock_mhz = SystemCoreClock / 4000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // set channel match to percentage + uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value); + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == LPC_PWM1->MR0) { + v++; + } + + *obj->MR = v; + + // accept on next period start + LPC_PWM1->LER |= 1 << obj->pwm; +} + +float pwmout_read(pwmout_t* obj) { + float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t ticks = pwm_clock_mhz * us; + + // set reset + LPC_PWM1->TCR = TCR_RESET; + + // set the global match register + LPC_PWM1->MR0 = ticks; + + // Scale the pulse width to preserve the duty ratio + if (LPC_PWM1->MR0 > 0) { + *obj->MR = (*obj->MR * ticks) / LPC_PWM1->MR0; + } + + // set the channel latch to update value at next period start + LPC_PWM1->LER |= 1 << 0; + + // enable counter and pwm, clear reset + LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t v = pwm_clock_mhz * us; + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == LPC_PWM1->MR0) { + v++; + } + + // set the match register value + *obj->MR = v; + + // set the channel latch to update value at next period start + LPC_PWM1->LER |= 1 << obj->pwm; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/rtc_api.c new file mode 100644 index 0000000000..ccf76f1211 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/rtc_api.c @@ -0,0 +1,113 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rtc_api.h" + +// ensure rtc is running (unchanged if already running) + +/* Setup the RTC based on a time structure, ensuring RTC is enabled + * + * Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock + * - We want to use the 32khz clock, allowing for sleep mode + * + * Most registers are not changed by a Reset + * - We must initialize these registers between power-on and setting the RTC into operation + + * Clock Control Register + * RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled + * RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset + * RTC_CCR[4] : Clock Source - 0 = Prescaler, 1 = 32k Xtal + * + * The RTC may already be running, so we should set it up + * without impacting if it is the case + */ +void rtc_init(void) { + LPC_SC->PCONP |= 0x200; // Ensure power is on + LPC_RTC->CCR = 0x00; + + LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled +} + +void rtc_free(void) { + // [TODO] +} + +/* + * Little check routine to see if the RTC has been enabled + * + * Clock Control Register + * RTC_CCR[0] : 0 = Disabled, 1 = Enabled + * + */ +int rtc_isenabled(void) { + return(((LPC_RTC->CCR) & 0x01) != 0); +} + +/* + * RTC Registers + * RTC_SEC Seconds 0-59 + * RTC_MIN Minutes 0-59 + * RTC_HOUR Hour 0-23 + * RTC_DOM Day of Month 1-28..31 + * RTC_DOW Day of Week 0-6 + * RTC_DOY Day of Year 1-365 + * RTC_MONTH Month 1-12 + * RTC_YEAR Year 0-4095 + * + * struct tm + * tm_sec seconds after the minute 0-61 + * tm_min minutes after the hour 0-59 + * tm_hour hours since midnight 0-23 + * tm_mday day of the month 1-31 + * tm_mon months since January 0-11 + * tm_year years since 1900 + * tm_wday days since Sunday 0-6 + * tm_yday days since January 1 0-365 + * tm_isdst Daylight Saving Time flag + */ +time_t rtc_read(void) { + // Setup a tm structure based on the RTC + struct tm timeinfo; + timeinfo.tm_sec = LPC_RTC->SEC; + timeinfo.tm_min = LPC_RTC->MIN; + timeinfo.tm_hour = LPC_RTC->HOUR; + timeinfo.tm_mday = LPC_RTC->DOM; + timeinfo.tm_mon = LPC_RTC->MONTH - 1; + timeinfo.tm_year = LPC_RTC->YEAR - 1900; + + // Convert to timestamp + time_t t = mktime(&timeinfo); + + return t; +} + +void rtc_write(time_t t) { + // Convert the time in to a tm + struct tm *timeinfo = localtime(&t); + + // Pause clock, and clear counter register (clears us count) + LPC_RTC->CCR |= 2; + + // Set the RTC + LPC_RTC->SEC = timeinfo->tm_sec; + LPC_RTC->MIN = timeinfo->tm_min; + LPC_RTC->HOUR = timeinfo->tm_hour; + LPC_RTC->DOM = timeinfo->tm_mday; + LPC_RTC->MONTH = timeinfo->tm_mon + 1; + LPC_RTC->YEAR = timeinfo->tm_year + 1900; + + // Restart clock + LPC_RTC->CCR &= ~((uint32_t)2); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c new file mode 100644 index 0000000000..32da943249 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c @@ -0,0 +1,443 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "gpio_api.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 4 + +static const PinMap PinMap_UART_TX[] = { + {P0_0, UART_3, 2}, + {P0_2, UART_0, 1}, + {P0_10, UART_2, 1}, + {P0_15, UART_1, 1}, + {P0_25, UART_3, 3}, + {P2_0 , UART_1, 2}, + {P2_8 , UART_2, 2}, + {P4_28, UART_3, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_1 , UART_3, 2}, + {P0_3 , UART_0, 1}, + {P0_11, UART_2, 1}, + {P0_16, UART_1, 1}, + {P0_26, UART_3, 3}, + {P2_1 , UART_1, 2}, + {P2_9 , UART_2, 2}, + {P4_29, UART_3, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_UART_RTS[] = { + {P0_22, UART_1, 1}, + {P2_7, UART_1, 2}, + {NC, NC, 0} +}; + +static const PinMap PinMap_UART_CTS[] = { + {P0_17, UART_1, 1}, + {P2_2, UART_1, 2}, + {NC, NC, 0} +}; + +#define UART_MCR_RTSEN_MASK (1 << 6) +#define UART_MCR_CTSEN_MASK (1 << 7) +#define UART_MCR_FLOWCTRL_MASK (UART_MCR_RTSEN_MASK | UART_MCR_CTSEN_MASK) + +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +struct serial_global_data_s { + uint32_t serial_irq_id; + gpio_t sw_rts, sw_cts; + uint8_t count, rx_irq_set_flow, rx_irq_set_api; +}; + +static struct serial_global_data_s uart_data[UART_NUM]; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_UART_TypeDef *)uart; + // enable power + switch (uart) { + case UART_0: LPC_SC->PCONP |= 1 << 3; break; + case UART_1: LPC_SC->PCONP |= 1 << 4; break; + case UART_2: LPC_SC->PCONP |= 1 << 24; break; + case UART_3: LPC_SC->PCONP |= 1 << 25; break; + } + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; + } + uart_data[obj->index].sw_rts.pin = NC; + uart_data[obj->index].sw_cts.pin = NC; + serial_set_flow_control(obj, FlowControlNone, NC, NC); + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + uart_data[obj->index].serial_irq_id = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + MBED_ASSERT((int)obj->uart <= UART_3); + // The LPC2300 and LPC1700 have a divider and a fractional divider to control the + // baud rate. The formula is: + // + // Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal) + // where: + // 1 < MulVal <= 15 + // 0 <= DivAddVal < 14 + // DivAddVal < MulVal + // + // set pclk to /1 + switch ((int)obj->uart) { + case UART_0: LPC_SC->PCLKSEL0 &= ~(0x3 << 6); LPC_SC->PCLKSEL0 |= (0x1 << 6); break; + case UART_1: LPC_SC->PCLKSEL0 &= ~(0x3 << 8); LPC_SC->PCLKSEL0 |= (0x1 << 8); break; + case UART_2: LPC_SC->PCLKSEL1 &= ~(0x3 << 16); LPC_SC->PCLKSEL1 |= (0x1 << 16); break; + case UART_3: LPC_SC->PCLKSEL1 &= ~(0x3 << 18); LPC_SC->PCLKSEL1 |= (0x1 << 18); break; + default: break; + } + + uint32_t PCLK = SystemCoreClock; + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + parity_enable = 0, parity_select = 0; + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index, LPC_UART_TypeDef *puart) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) { + gpio_write(&uart_data[index].sw_rts, 1); + // Disable interrupt if it wasn't enabled by other part of the application + if (!uart_data[index].rx_irq_set_api) + puart->IER &= ~(1 << RxIrq); + } + if (uart_data[index].serial_irq_id != 0) + if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api)) + irq_handler(uart_data[index].serial_irq_id, irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0, (LPC_UART_TypeDef*)LPC_UART0);} +void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_UART_TypeDef*)LPC_UART1);} +void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2, (LPC_UART_TypeDef*)LPC_UART2);} +void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LPC_UART3);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + uart_data[obj->index].serial_irq_id = id; +} + +static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + if (RxIrq == irq) + uart_data[obj->index].rx_irq_set_api = enable; + serial_irq_set_internal(obj, irq, enable); +} + +static void serial_flow_irq_set(serial_t *obj, uint32_t enable) { + uart_data[obj->index].rx_irq_set_flow = enable; + serial_irq_set_internal(obj, RxIrq, enable); +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + int data = obj->uart->RBR; + if (NC != uart_data[obj->index].sw_rts.pin) { + gpio_write(&uart_data[obj->index].sw_rts, 0); + obj->uart->IER |= 1 << RxIrq; + } + return data; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; + uart_data[obj->index].count++; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + int isWritable = 1; + if (NC != uart_data[obj->index].sw_cts.pin) + isWritable = (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40); //If flow control: writable if CTS low + UART done + else { + if (obj->uart->LSR & 0x20) + uart_data[obj->index].count = 0; + else if (uart_data[obj->index].count >= 16) + isWritable = 0; + } + return isWritable; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { + // Only UART1 has hardware flow control on LPC176x + LPC_UART1_TypeDef *uart1 = (uint32_t)obj->uart == (uint32_t)LPC_UART1 ? LPC_UART1 : NULL; + int index = obj->index; + + // First, disable flow control completely + if (uart1) + uart1->MCR = uart1->MCR & ~UART_MCR_FLOWCTRL_MASK; + uart_data[index].sw_rts.pin = uart_data[index].sw_cts.pin = NC; + serial_flow_irq_set(obj, 0); + if (FlowControlNone == type) + return; + // Check type(s) of flow control to use + UARTName uart_rts = (UARTName)pinmap_find_peripheral(rxflow, PinMap_UART_RTS); + UARTName uart_cts = (UARTName)pinmap_find_peripheral(txflow, PinMap_UART_CTS); + if (((FlowControlCTS == type) || (FlowControlRTSCTS == type)) && (NC != txflow)) { + // Can this be enabled in hardware? + if ((UART_1 == uart_cts) && (NULL != uart1)) { + // Enable auto-CTS mode + uart1->MCR |= UART_MCR_CTSEN_MASK; + pinmap_pinout(txflow, PinMap_UART_CTS); + } else { + // Can't enable in hardware, use software emulation + gpio_init_in(&uart_data[index].sw_cts, txflow); + } + } + if (((FlowControlRTS == type) || (FlowControlRTSCTS == type)) && (NC != rxflow)) { + // Enable FIFOs, trigger level of 1 char on RX FIFO + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 1 << 1 // Rx Fifo Reset + | 1 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + // Can this be enabled in hardware? + if ((UART_1 == uart_rts) && (NULL != uart1)) { + // Enable auto-RTS mode + uart1->MCR |= UART_MCR_RTSEN_MASK; + pinmap_pinout(rxflow, PinMap_UART_RTS); + } else { // can't enable in hardware, use software emulation + gpio_init_out_ex(&uart_data[index].sw_rts, rxflow, 0); + // Enable RX interrupt + serial_flow_irq_set(obj, 1); + } + } +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/sleep.c new file mode 100644 index 0000000000..e8b734324d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/sleep.c @@ -0,0 +1,72 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + +#if (DEVICE_SEMIHOST == 1) + // ensure debug is disconnected + mbed_interface_disconnect(); +#endif + + // PCON[PD] set to sleep + LPC_SC->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +/* +* The mbed lpc1768 does not support the deepsleep mode +* as a debugger is connected to it (the mbed interface). +* +* As mentionned in an application note from NXP: +* +* http://www.po-star.com/public/uploads/20120319123122_141.pdf +* +* {{{ +* The user should be aware of certain limitations during debugging. +* The most important is that, due to limitations of the Cortex-M3 +* integration, the LPC17xx cannot wake up in the usual manner from +* Deep Sleep and Power-down modes. It is recommended not to use these +* modes during debug. Once an application is downloaded via JTAG/SWD +* interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example) +* should be removed from the target board, and thereafter, power cycle +* the LPC17xx to allow wake-up from deep sleep and power-down modes +* }}} +* +* As the interface firmware does not reset the target when a +* mbed_interface_disconnect() semihosting call is made, the +* core cannot wake-up from deepsleep. +* +* We treat a deepsleep() as a normal sleep(). +*/ + +void deepsleep(void) { + +#if (DEVICE_SEMIHOST == 1) + // ensure debug is disconnected + mbed_interface_disconnect(); +#endif + + // PCON[PD] set to deepsleep + sleep(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/spi_api.c new file mode 100644 index 0000000000..aee389df5e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/spi_api.c @@ -0,0 +1,219 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_7 , SPI_1, 2}, + {P0_15, SPI_0, 2}, + {P1_20, SPI_0, 3}, + {P1_31, SPI_1, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_1, 2}, + {P0_13, SPI_1, 2}, + {P0_18, SPI_0, 2}, + {P1_24, SPI_0, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_1, 2}, + {P0_12, SPI_1, 2}, + {P0_17, SPI_0, 2}, + {P1_23, SPI_0, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_6 , SPI_1, 2}, + {P0_11, SPI_1, 2}, + {P0_16, SPI_0, 2}, + {P1_21, SPI_0, 3}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: LPC_SC->PCONP |= 1 << 21; break; + case SPI_1: LPC_SC->PCONP |= 1 << 10; break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + ssp_disable(obj); + MBED_ASSERT(((bits >= 4) && (bits <= 16)) && (mode >= 0 && mode <= 3)); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + // setup the spi clock diveder to /1 + switch ((int)obj->spi) { + case SPI_0: + LPC_SC->PCLKSEL1 &= ~(3 << 10); + LPC_SC->PCLKSEL1 |= (1 << 10); + break; + case SPI_1: + LPC_SC->PCLKSEL0 &= ~(3 << 20); + LPC_SC->PCLKSEL0 |= (1 << 20); + break; + } + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/us_ticker.c new file mode 100644 index 0000000000..b46d75e6bc --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/us_ticker.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE) +#define US_TICKER_TIMER_IRQn TIMER3_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3 + + US_TICKER_TIMER->CTCR = 0x0; // timer mode + uint32_t PCLK = SystemCoreClock / 4; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PeripheralNames.h new file mode 100644 index 0000000000..285837eedf --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PeripheralNames.h @@ -0,0 +1,110 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART0_BASE, + UART_1 = (int)LPC_UART1_BASE, + UART_2 = (int)LPC_UART2_BASE, + UART_3 = (int)LPC_UART3_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE, + I2C_2 = (int)LPC_I2C2_BASE +} I2CName; + +typedef enum { + PWM_1 = 1, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6 +} PWMName; + +typedef enum { + CAN_1 = (int)LPC_CAN1_BASE, + CAN_2 = (int)LPC_CAN2_BASE +} CANName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7, p8 +#define MBED_SPI1 p11, p12, p13, p14 + +#define MBED_UART0 p9, p10 +#define MBED_UART1 p13, p14 +#define MBED_UART2 p28, p27 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p28, p27 +#define MBED_I2C1 p9, p10 + +#define MBED_CAN0 p30, p29 + +#define MBED_ANALOGOUT0 p18 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#define MBED_PWMOUT0 p26 +#define MBED_PWMOUT1 p25 +#define MBED_PWMOUT2 p24 +#define MBED_PWMOUT3 p23 +#define MBED_PWMOUT4 p22 +#define MBED_PWMOUT5 p21 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PinNames.h new file mode 100644 index 0000000000..2b85b9ca27 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PinNames.h @@ -0,0 +1,104 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = LPC_GPIO0_BASE, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + + // mbed DIP Pin Names + p5 = P0_9, + p6 = P0_8, + p7 = P0_7, + p8 = P0_6, + p9 = P0_0, + p10 = P0_1, + p11 = P0_18, + p12 = P0_17, + p13 = P0_15, + p14 = P0_16, + p15 = P0_23, + p16 = P0_24, + p17 = P0_25, + p18 = P0_26, + p19 = P1_30, + p20 = P1_31, + p21 = P2_5, + p22 = P2_4, + p23 = P2_3, + p24 = P2_2, + p25 = P2_1, + p26 = P2_0, + p27 = P0_11, + p28 = P0_10, + p29 = P0_5, + p30 = P0_4, + + // Other mbed Pin Names + LED1 = P1_18, + LED2 = P1_20, + LED3 = P1_21, + LED4 = P1_23, + + USBTX = P0_2, + USBRX = P0_3, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +// version of PINCON_TypeDef using register arrays +typedef struct { + __IO uint32_t PINSEL[11]; + uint32_t RESERVED0[5]; + __IO uint32_t PINMODE[10]; +} PINCONARRAY_TypeDef; + +#define PINCONARRAY ((PINCONARRAY_TypeDef *)LPC_PINCON_BASE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PortNames.h new file mode 100644 index 0000000000..270cdeecb0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/PortNames.h @@ -0,0 +1,34 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3, + Port4 = 4 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogin_api.c new file mode 100644 index 0000000000..4c3770e836 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogin_api.c @@ -0,0 +1,123 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_23, ADC0_0, 1}, + {P0_24, ADC0_1, 1}, + {P0_25, ADC0_2, 1}, + {P0_26, ADC0_3, 1}, + {P1_30, ADC0_4, 3}, + {P1_31, ADC0_5, 3}, + {NC, NC, 0} +}; + +#define ADC_RANGE ADC_10BIT_RANGE + + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // ensure power is turned on + LPC_SC->PCONP |= (1 << 12); + + // set PCLK of ADC to /1 + LPC_SC->PCLKSEL0 &= ~(0x3 << 24); + LPC_SC->PCLKSEL0 |= (0x1 << 24); + uint32_t PCLK = SystemCoreClock; + + // calculate minimum clock divider + // clkdiv = divider - 1 + uint32_t MAX_ADC_CLK = 13000000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + // Set the generic software-controlled ADC settings + LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected + | (clkdiv << 8) // CLKDIV: PCLK max ~= 25MHz, /25 to give safe 1MHz at fastest + | (0 << 16) // BURST: 0 = software control + | (0 << 17) // CLKS: not applicable + | (1 << 21) // PDN: 1 = operational + | (0 << 24) // START: 0 = no start + | (0 << 27); // EDGE: not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= 1 << (int)obj->adc; + LPC_ADC->ADCR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->ADGDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->ADCR &= ~(1 << 24); + + return (data >> 6) & ADC_RANGE; // 10 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogout_api.c new file mode 100644 index 0000000000..66c77ceace --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/analogout_api.c @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_DAC[] = { + {P0_26, DAC_0, 2}, + {NC , NC , 0} +}; + +void analogout_init(dac_t *obj, PinName pin) { + obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); + MBED_ASSERT(obj->dac != (DACName)NC); + + // power is on by default, set DAC clk divider is /4 + LPC_SC->PCLKSEL0 &= ~(0x3 << 22); + + // map out (must be done before accessing registers) + pinmap_pinout(pin, PinMap_DAC); + + analogout_write_u16(obj, 0); +} + +void analogout_free(dac_t *obj) {} + +static inline void dac_write(int value) { + value &= 0x3FF; // 10-bit + + // Set the DAC output + LPC_DAC->DACR = (0 << 16) // bias = 0 + | (value << 6); +} + +static inline int dac_read() { + return (LPC_DAC->DACR >> 6) & 0x3FF; +} + +void analogout_write(dac_t *obj, float value) { + if (value < 0.0f) { + dac_write(0); + } else if (value > 1.0f) { + dac_write(0x3FF); + } else { + dac_write(value * (float)0x3FF); + } +} + +void analogout_write_u16(dac_t *obj, uint16_t value) { + dac_write(value >> 6); // 10-bit +} + +float analogout_read(dac_t *obj) { + uint32_t value = dac_read(); + return (float)value * (1.0f / (float)0x3FF); +} + +uint16_t analogout_read_u16(dac_t *obj) { + uint32_t value = dac_read(); // 10-bit + return (value << 6) | ((value >> 4) & 0x003F); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/can_api.c new file mode 100644 index 0000000000..a3170acc1d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/can_api.c @@ -0,0 +1,303 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "can_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#include <math.h> +#include <string.h> + +/* Acceptance filter mode in AFMR register */ +#define ACCF_OFF 0x01 +#define ACCF_BYPASS 0x02 +#define ACCF_ON 0x00 +#define ACCF_FULLCAN 0x04 + +/* There are several bit timing calculators on the internet. +http://www.port.de/engl/canprod/sv_req_form.html +http://www.kvaser.com/can/index.htm +*/ + +static const PinMap PinMap_CAN_RD[] = { + {P0_0 , CAN_1, 1}, + {P0_4 , CAN_2, 2}, + {P0_21, CAN_1, 3}, + {P2_7 , CAN_2, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_CAN_TD[] = { + {P0_1 , CAN_1, 1}, + {P0_5 , CAN_2, 2}, + {P0_22, CAN_1, 3}, + {P2_8 , CAN_2, 1}, + {NC , NC , 0} +}; + +// Type definition to hold a CAN message +struct CANMsg { + unsigned int reserved1 : 16; + unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter + unsigned int reserved0 : 10; + unsigned int rtr : 1; // Bit 30: Set if this is a RTR message + unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message + unsigned int id; // CAN Message ID (11-bit or 29-bit) + unsigned char data[8]; // CAN Message Data Bytes 0-7 +}; +typedef struct CANMsg CANMsg; + +static uint32_t can_disable(can_t *obj) { + uint32_t sm = obj->dev->MOD; + obj->dev->MOD |= 1; + return sm; +} + +static inline void can_enable(can_t *obj) { + if (obj->dev->MOD & 1) { + obj->dev->MOD &= ~(1); + } +} + +int can_mode(can_t *obj, CanMode mode) { + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + return 0; // not implemented +} + +static int can_pclk(can_t *obj) { + int value = 0; + switch ((int)obj->dev) { + case CAN_1: value = (LPC_SC->PCLKSEL0 & (0x3 << 26)) >> 26; break; + case CAN_2: value = (LPC_SC->PCLKSEL0 & (0x3 << 28)) >> 28; break; + } + + switch (value) { + case 1: return 1; + case 2: return 2; + case 3: return 6; + default: return 4; + } +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits; + + bitwidth = sclk / (pclk * cclk); + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + if (hit) { + btr = ((timing_pts[bits][1] << 20) & 0x00700000) + | ((timing_pts[bits][0] << 16) & 0x000F0000) + | ((psjw << 14) & 0x0000C000) + | ((brp << 0) & 0x000003FF); + } else { + btr = 0xFFFFFFFF; + } + + return btr; +} + +void can_init(can_t *obj, PinName rd, PinName td) { + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)obj->dev != NC); + + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP |= 1 << 13; break; + case CAN_2: LPC_SC->PCONP |= 1 << 14; break; + } + + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + + can_reset(obj); + obj->dev->IER = 0; // Disable Interrupts + can_frequency(obj, 100000); + + LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter +} + +void can_free(can_t *obj) { + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break; + case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break; + } +} + +int can_frequency(can_t *obj, int f) { + int pclk = can_pclk(obj); + int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1); + + if (btr > 0) { + uint32_t modmask = can_disable(obj); + obj->dev->BTR = btr; + obj->dev->MOD = modmask; + return 1; + } else { + return 0; + } +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + unsigned int CANStatus; + CANMsg m; + + can_enable(obj); + + m.id = msg.id ; + m.dlc = msg.len & 0xF; + m.rtr = msg.type; + m.type = msg.format; + memcpy(m.data, msg.data, msg.len); + const unsigned int *buf = (const unsigned int *)&m; + + CANStatus = obj->dev->SR; + if (CANStatus & 0x00000004) { + obj->dev->TFI1 = buf[0] & 0xC00F0000; + obj->dev->TID1 = buf[1]; + obj->dev->TDA1 = buf[2]; + obj->dev->TDB1 = buf[3]; + if (cc) { + obj->dev->CMR = 0x30; + } else { + obj->dev->CMR = 0x21; + } + return 1; + + } else if (CANStatus & 0x00000400) { + obj->dev->TFI2 = buf[0] & 0xC00F0000; + obj->dev->TID2 = buf[1]; + obj->dev->TDA2 = buf[2]; + obj->dev->TDB2 = buf[3]; + if (cc) { + obj->dev->CMR = 0x50; + } else { + obj->dev->CMR = 0x41; + } + return 1; + + } else if (CANStatus & 0x00040000) { + obj->dev->TFI3 = buf[0] & 0xC00F0000; + obj->dev->TID3 = buf[1]; + obj->dev->TDA3 = buf[2]; + obj->dev->TDB3 = buf[3]; + if (cc) { + obj->dev->CMR = 0x90; + } else { + obj->dev->CMR = 0x81; + } + return 1; + } + + return 0; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + CANMsg x; + unsigned int *i = (unsigned int *)&x; + + can_enable(obj); + + if (obj->dev->GSR & 0x1) { + *i++ = obj->dev->RFS; // Frame + *i++ = obj->dev->RID; // ID + *i++ = obj->dev->RDA; // Data A + *i++ = obj->dev->RDB; // Data B + obj->dev->CMR = 0x04; // release receive buffer + + msg->id = x.id; + msg->len = x.dlc; + msg->format = (x.type)? CANExtended : CANStandard; + msg->type = (x.rtr)? CANRemote: CANData; + memcpy(msg->data,x.data,x.dlc); + return 1; + } + + return 0; +} + +void can_reset(can_t *obj) { + can_disable(obj); + obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset +} + +unsigned char can_rderror(can_t *obj) { + return (obj->dev->GSR >> 16) & 0xFF; +} + +unsigned char can_tderror(can_t *obj) { + return (obj->dev->GSR >> 24) & 0xFF; +} + +void can_monitor(can_t *obj, int silent) { + uint32_t mod_mask = can_disable(obj); + if (silent) { + obj->dev->MOD |= (1 << 1); + } else { + obj->dev->MOD &= ~(1 << 1); + } + if (!(mod_mask & 1)) { + can_enable(obj); + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/device.h new file mode 100644 index 0000000000..9a20ae4a36 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 1 +#define DEVICE_LOCALFILESYSTEM 1 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 0 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/ethernet_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/ethernet_api.c new file mode 100644 index 0000000000..ba76cbc916 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/ethernet_api.c @@ -0,0 +1,935 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> + +#include "ethernet_api.h" +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "mbed_error.h" + +#define NEW_LOGIC 0 +#define NEW_ETH_BUFFER 0 + +#if NEW_ETH_BUFFER + +#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets) +#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets) + +#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size +#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length) + +#else + +// Memfree calculation: +// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) + +// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556 +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ +#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */ +#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */ + +const int ethernet_MTU_SIZE = 0x300; + +#endif + +#define ETHERNET_ADDR_SIZE 6 + +PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +PACKED struct RX_STAT_TypeDef { /* RX Status struct */ + unsigned int Info; + unsigned int HashCRC; +}; +typedef struct RX_STAT_TypeDef RX_STAT_TypeDef; + +PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +PACKED struct TX_STAT_TypeDef { /* TX Status struct */ + unsigned int Info; +}; +typedef struct TX_STAT_TypeDef TX_STAT_TypeDef; + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ + + +static int phy_read(unsigned int PhyReg); +static int phy_write(unsigned int PhyReg, unsigned short Data); + +static void txdscr_init(void); +static void rxdscr_init(void); + +#if defined (__ICCARM__) +# define AHBSRAM1 +#elif defined(TOOLCHAIN_GCC_CR) +# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32"))) +#else +# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned)) +#endif + +AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG]; +AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG]; +AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG]; +AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG]; + + +#if NEW_LOGIC +static int rx_consume_offset = -1; +static int tx_produce_offset = -1; +#else +static int send_doff = 0; +static int send_idx = -1; +static int send_size = 0; + +static int receive_soff = 0; +static int receive_idx = -1; +#endif + +static uint32_t phy_id = 0; + +static inline int rinc(int idx, int mod) { + ++idx; + idx %= mod; + return idx; +} + +//extern unsigned int SystemFrequency; +static inline unsigned int clockselect() { + if(SystemCoreClock < 10000000) { + return 1; + } else if(SystemCoreClock < 15000000) { + return 2; + } else if(SystemCoreClock < 20000000) { + return 3; + } else if(SystemCoreClock < 25000000) { + return 4; + } else if(SystemCoreClock < 35000000) { + return 5; + } else if(SystemCoreClock < 50000000) { + return 6; + } else if(SystemCoreClock < 70000000) { + return 7; + } else if(SystemCoreClock < 80000000) { + return 8; + } else if(SystemCoreClock < 90000000) { + return 9; + } else if(SystemCoreClock < 100000000) { + return 10; + } else if(SystemCoreClock < 120000000) { + return 11; + } else if(SystemCoreClock < 130000000) { + return 12; + } else if(SystemCoreClock < 140000000) { + return 13; + } else if(SystemCoreClock < 150000000) { + return 15; + } else if(SystemCoreClock < 160000000) { + return 16; + } else { + return 0; + } +} + +#ifndef min +#define min(x, y) (((x)<(y))?(x):(y)) +#endif + +/*---------------------------------------------------------------------------- + Ethernet Device initialize + *----------------------------------------------------------------------------*/ +int ethernet_init() { + int regv, tout; + char mac[ETHERNET_ADDR_SIZE]; + unsigned int clock = clockselect(); + + LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ + + LPC_PINCON->PINSEL2 = 0x50150105; /* Enable P1 Ethernet Pins. */ + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000005; + + /* Reset all EMAC internal modules. */ + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | + MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */ + + LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */ + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + LPC_EMAC->MAXF = ETH_MAX_FLEN; + LPC_EMAC->CLRT = CLRT_DEF; + LPC_EMAC->IPGR = IPGR_DEF; + + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ + LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ + + for(tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; + LPC_EMAC->MCMD = 0; + + LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ + + for (tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->SUPP = 0; + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return -1; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) { + error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); + } + + ethernet_set_link(-1, 0); + + /* Set the Ethernet MAC Address registers */ + ethernet_address(mac); + LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4]; + LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2]; + LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0]; + + txdscr_init(); /* initialize DMA TX Descriptor */ + rxdscr_init(); /* initialize DMA RX Descriptor */ + + LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + /* Receive Broadcast, Perfect Match Packets */ + + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ + LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ + + + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->MAC1 |= MAC1_REC_EN; + +#if NEW_LOGIC + rx_consume_offset = -1; + tx_produce_offset = -1; +#else + send_doff = 0; + send_idx = -1; + send_size = 0; + + receive_soff = 0; + receive_idx = -1; +#endif + + return 0; +} + +/*---------------------------------------------------------------------------- + Ethernet Device Uninitialize + *----------------------------------------------------------------------------*/ +void ethernet_free() { + LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); + LPC_EMAC->IntClear = 0xFFFF; + + LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */ + + LPC_PINCON->PINSEL2 &= ~0x50150105; /* Disable P1 ethernet pins. */ + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & ~0x0000000F) | 0x00000000; +} + +// if(TxProduceIndex == TxConsumeIndex) buffer array is empty +// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill +// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment +// TxConsumeIndex - The buffer that will/is beign sent by hardware + +int ethernet_write(const char *data, int slen) { + +#if NEW_LOGIC + + if(tx_produce_offset < 0) { // mark as active if not already + tx_produce_offset = 0; + } + + int index = LPC_EMAC->TxProduceIndex; + + int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum + int requested = slen; + int ncopy = min(remaining, requested); + + void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset); + void *psrc = (void *)(data); + + if(ncopy > 0 ){ + if(data != NULL) { + memcpy(pdst, psrc, ncopy); + } else { + memset(pdst, 0, ncopy); + } + } + + tx_produce_offset += ncopy; + + return ncopy; + +#else + void *pdst, *psrc; + const int dlen = ETH_FRAG_SIZE; + int copy = 0; + int soff = 0; + + if(send_idx == -1) { + send_idx = LPC_EMAC->TxProduceIndex; + } + + if(slen + send_doff > ethernet_MTU_SIZE) { + return -1; + } + + do { + copy = min(slen - soff, dlen - send_doff); + pdst = (void *)(txdesc[send_idx].Packet + send_doff); + psrc = (void *)(data + soff); + if(send_doff + copy > ETH_FRAG_SIZE) { + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT); + send_idx = rinc(send_idx, NUM_TX_FRAG); + send_doff = 0; + } + + if(data != NULL) { + memcpy(pdst, psrc, copy); + } else { + memset(pdst, 0, copy); + } + + soff += copy; + send_doff += copy; + send_size += copy; + } while(soff != slen); + + return soff; +#endif +} + +int ethernet_send() { + +#if NEW_LOGIC + if(tx_produce_offset < 0) { // no buffer active + return -1; + } + + // ensure there is a link + if(!ethernet_link()) { + return -2; + } + + // we have been writing in to a buffer, so finalise it + int size = tx_produce_offset; + int index = LPC_EMAC->TxProduceIndex; + txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST); + + // Increment ProduceIndex to allow it to be sent + // We can only do this if the next slot is free + int next = rinc(index, NUM_TX_FRAG); + while(next == LPC_EMAC->TxConsumeIndex) { + for(int i=0; i<1000; i++) { __NOP(); } + } + + LPC_EMAC->TxProduceIndex = next; + tx_produce_offset = -1; + return size; + +#else + int s = send_size; + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST); + send_idx = rinc(send_idx, NUM_TX_FRAG); + LPC_EMAC->TxProduceIndex = send_idx; + send_doff = 0; + send_idx = -1; + send_size = 0; + return s; +#endif +} + +// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read +// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd +// +// if(RxConsumeIndex == RxProduceIndex) buffer array is empty +// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full + +// Recevies an arrived ethernet packet. +// Receiving an ethernet packet will drop the last received ethernet packet +// and make a new ethernet packet ready to read. +// Returns size of packet, else 0 if nothing to receive + +// We read from RxConsumeIndex from position rx_consume_offset +// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading +// rx_consume_offset = -1 // no frame +// rx_consume_offset = 0 // start of frame +// Assumption: A fragment should alway be a whole frame + +int ethernet_receive() { +#if NEW_LOGIC + + // if we are currently reading a valid RxConsume buffer, increment to the next one + if(rx_consume_offset >= 0) { + LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG); + } + + // if the buffer is empty, mark it as no valid buffer + if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) { + rx_consume_offset = -1; + return 0; + } + + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + rx_consume_offset = 0; + + // check if it is not marked as last or for errors + if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) { + return -1; + } + + int size = (info & RINFO_SIZE) + 1; + return size - 4; // don't include checksum bytes + +#else + if(receive_idx == -1) { + receive_idx = LPC_EMAC->RxConsumeIndex; + } else { + while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + unsigned int info = rxstat[receive_idx].Info; + int slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + + LPC_EMAC->RxConsumeIndex = receive_idx; + } + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) { + receive_idx = -1; + return 0; + } + + return (rxstat[receive_idx].Info & RINFO_SIZE) - 3; +#endif +} + +// Read from an recevied ethernet packet. +// After receive returnd a number bigger than 0 it is +// possible to read bytes from this packet. +// Read will write up to size bytes into data. +// It is possible to use read multible times. +// Each time read will start reading after the last read byte before. + +int ethernet_read(char *data, int dlen) { +#if NEW_LOGIC + // Check we have a valid buffer to read + if(rx_consume_offset < 0) { + return 0; + } + + // Assume 1 fragment block + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum + + int remaining = size - rx_consume_offset; + int requested = dlen; + int ncopy = min(remaining, requested); + + void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset); + void *pdst = (void *)(data); + + if(data != NULL && ncopy > 0) { + memcpy(pdst, psrc, ncopy); + } + + rx_consume_offset += ncopy; + + return ncopy; +#else + int slen; + int copy = 0; + unsigned int more; + unsigned int info; + void *pdst, *psrc; + int doff = 0; + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) { + return 0; + } + + do { + info = rxstat[receive_idx].Info; + more = !(info & RINFO_LAST_FLAG); + slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } else { + + copy = min(slen - receive_soff, dlen - doff); + psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff); + pdst = (void *)(data + doff); + + if(data != NULL) { + /* check if Buffer available */ + memcpy(pdst, psrc, copy); + } + + receive_soff += copy; + doff += copy; + + if((more && (receive_soff == slen))) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + } + } + } while(more && !(doff == dlen) && !receive_soff); + + return doff; +#endif +} + +int ethernet_link(void) { + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } + else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MWTD = Data; + + for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + return 0; + } + } + + return -1; +} + +static int phy_read(unsigned int PhyReg) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + LPC_EMAC->MCMD = 0; + return LPC_EMAC->MRDD; /* Return a 16-bit value. */ + } + } + + return -1; +} + + +static void txdscr_init() { + int i; + + for(i = 0; i < NUM_TX_FRAG; i++) { + txdesc[i].Packet = (uint32_t)&txbuf[i]; + txdesc[i].Ctrl = 0; + txstat[i].Info = 0; + } + + LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxStatus = (uint32_t)txstat; + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; + + LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */ +} + +static void rxdscr_init() { + int i; + + for(i = 0; i < NUM_RX_FRAG; i++) { + rxdesc[i].Packet = (uint32_t)&rxbuf[i]; + rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1); + rxstat[i].Info = 0; + rxstat[i].HashCRC = 0; + } + + LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxStatus = (uint32_t)rxstat; + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; + + LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */ +} + +void ethernet_address(char *mac) { + mbed_mac_address(mac); +} + +void ethernet_set_link(int speed, int duplex) { + unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + phy_data = PHY_AUTO_NEG; + } else { + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for(tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + switch(phy_id) { + case DP83848C_ID: + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } else { + LPC_EMAC->SUPP |= SUPP_SPEED; + } + break; + + case LAN8720_ID: + phy_data = phy_read(PHY_REG_SCSR); + + if (phy_data & PHY_SCSR_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_SCSR_100MBIT) { + LPC_EMAC->SUPP |= SUPP_SPEED; + } else { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_api.c new file mode 100644 index 0000000000..10ac3664fc --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_api.c @@ -0,0 +1,53 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + LPC_SC->SCS |= 1; // High speed GPIO is enabled on ports 0 and 1 + + pin_function(pin, 0); + + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + if (pin == (PinName)NC) + return; + obj->pin = pin; + obj->mask = gpio_set(pin); + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *) ((int)pin & ~0x1F); + + obj->reg_set = &port_reg->FIOSET; + obj->reg_clr = &port_reg->FIOCLR; + obj->reg_in = &port_reg->FIOPIN; + obj->reg_dir = &port_reg->FIODIR; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + if (obj->pin == (PinName)NC) + return; + switch (direction) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_irq_api.c new file mode 100644 index 0000000000..40fcaa6dbe --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_irq_api.c @@ -0,0 +1,154 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include <stddef.h> +#include "cmsis.h" + +#define CHANNEL_NUM 48 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(void) { + // Read in all current interrupt registers. We do this once as the + // GPIO interrupt registers are on the APB bus, and this is slow. + uint32_t rise0 = LPC_GPIOINT->IO0IntStatR; + uint32_t fall0 = LPC_GPIOINT->IO0IntStatF; + uint32_t rise2 = LPC_GPIOINT->IO2IntStatR; + uint32_t fall2 = LPC_GPIOINT->IO2IntStatF; + uint32_t mask0 = 0; + uint32_t mask2 = 0; + int i; + + // P0.0-0.31 + for (i = 0; i < 32; i++) { + uint32_t pmask = (1 << i); + if (rise0 & pmask) { + mask0 |= pmask; + if (channel_ids[i] != 0) + irq_handler(channel_ids[i], IRQ_RISE); + } + if (fall0 & pmask) { + mask0 |= pmask; + if (channel_ids[i] != 0) + irq_handler(channel_ids[i], IRQ_FALL); + } + } + + // P2.0-2.15 + for (i = 0; i < 16; i++) { + uint32_t pmask = (1 << i); + int channel_index = i + 32; + if (rise2 & pmask) { + mask2 |= pmask; + if (channel_ids[channel_index] != 0) + irq_handler(channel_ids[channel_index], IRQ_RISE); + } + if (fall2 & pmask) { + mask2 |= pmask; + if (channel_ids[channel_index] != 0) + irq_handler(channel_ids[channel_index], IRQ_FALL); + } + } + + // Clear the interrupts we just handled + LPC_GPIOINT->IO0IntClr = mask0; + LPC_GPIOINT->IO2IntClr = mask2; +} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + obj->port = (int)pin & ~0x1F; + obj->pin = (int)pin & 0x1F; + + // Interrupts available only on GPIO0 and GPIO2 + if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) { + error("pins on this port cannot generate interrupts"); + } + + // put us in the interrupt table + int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32; + channel_ids[index] = id; + obj->ch = index; + + NVIC_SetVector(EINT3_IRQn, (uint32_t)handle_interrupt_in); + NVIC_EnableIRQ(EINT3_IRQn); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + // ensure nothing is pending + switch (obj->port) { + case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break; + case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break; + } + + // enable the pin interrupt + if (event == IRQ_RISE) { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin); + } + break; + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin); + } + break; + } + } else { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin); + } + break; + + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin); + } + break; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ(EINT3_IRQn); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ(EINT3_IRQn); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c new file mode 100644 index 0000000000..f4bceb4969 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c @@ -0,0 +1,393 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_0 , I2C_1, 3}, + {P0_10, I2C_2, 2}, + {P0_19, I2C_1, 3}, + {P0_27, I2C_0, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_1 , I2C_1, 3}, + {P0_11, I2C_2, 2}, + {P0_20, I2C_1, 3}, + {P0_28, I2C_0, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->I2CONSET) +#define I2C_CONCLR(x) (x->i2c->I2CONCLR) +#define I2C_STAT(x) (x->i2c->I2STAT) +#define I2C_DAT(x) (x->i2c->I2DAT) +#define I2C_SCLL(x, val) (x->i2c->I2SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->I2SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + switch ((int)obj->i2c) { + case I2C_0: LPC_SC->PCONP |= 1 << 7; break; + case I2C_1: LPC_SC->PCONP |= 1 << 19; break; + case I2C_2: LPC_SC->PCONP |= 1 << 26; break; + } +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while (I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // [TODO] set pclk to /4 + uint32_t PCLK = SystemCoreClock / 4; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if (status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + + case 0xB8: // Slave transmit ACK + ack = 1; + break; + + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/objects.h new file mode 100644 index 0000000000..41d717adc6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/objects.h @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t port; + uint32_t pin; + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + __IO uint32_t *MR; + PWMName pwm; +}; + +struct serial_s { + LPC_UART_TypeDef *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct dac_s { + DACName dac; +}; + +struct can_s { + LPC_CAN_TypeDef *dev; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SSP_TypeDef *spi; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pinmap.c new file mode 100644 index 0000000000..12636f5d69 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pinmap.c @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0; + int index = pin_number >> 4; + int offset = (pin_number & 0xF) << 1; + + PINCONARRAY->PINSEL[index] &= ~(0x3 << offset); + PINCONARRAY->PINSEL[index] |= function << offset; +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT((pin != (PinName)NC) && (mode != OpenDrain)); + + uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0; + int index = pin_number >> 5; + int offset = pin_number & 0x1F; + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + if (!drain) { + index = pin_number >> 4; + offset = (pin_number & 0xF) << 1; + + PINCONARRAY->PINMODE[index] &= ~(0x3 << offset); + PINCONARRAY->PINMODE[index] |= (uint32_t)mode << offset; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/port_api.c new file mode 100644 index 0000000000..2a84a3ffc4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/port_api.c @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) { + return (PinName)(LPC_GPIO0_BASE + ((port << PORT_SHIFT) | pin_n)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20)); + + // Do not use masking, because it prevents the use of the unmasked pins + // port_reg->FIOMASK = ~mask; + + obj->reg_out = &port_reg->FIOPIN; + obj->reg_in = &port_reg->FIOPIN; + obj->reg_dir = &port_reg->FIODIR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) { + return (*obj->reg_in & obj->mask); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pwmout_api.c new file mode 100644 index 0000000000..3773d7e6b7 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/pwmout_api.c @@ -0,0 +1,171 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +// PORT ID, PWM ID, Pin function +static const PinMap PinMap_PWM[] = { + {P1_18, PWM_1, 2}, + {P1_20, PWM_2, 2}, + {P1_21, PWM_3, 2}, + {P1_23, PWM_4, 2}, + {P1_24, PWM_5, 2}, + {P1_26, PWM_6, 2}, + {P2_0 , PWM_1, 1}, + {P2_1 , PWM_2, 1}, + {P2_2 , PWM_3, 1}, + {P2_3 , PWM_4, 1}, + {P2_4 , PWM_5, 1}, + {P2_5 , PWM_6, 1}, + {P3_25, PWM_2, 3}, + {P3_26, PWM_3, 3}, + {NC, NC, 0} +}; + +__IO uint32_t *PWM_MATCH[] = { + &(LPC_PWM1->MR0), + &(LPC_PWM1->MR1), + &(LPC_PWM1->MR2), + &(LPC_PWM1->MR3), + &(LPC_PWM1->MR4), + &(LPC_PWM1->MR5), + &(LPC_PWM1->MR6) +}; + +#define TCR_PWM_EN 0x00000008 + +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->pwm = pwm; + obj->MR = PWM_MATCH[pwm]; + + // ensure the power is on + LPC_SC->PCONP |= 1 << 6; + + // ensure clock to /4 + LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4 + LPC_PWM1->PR = 0; // no pre-scale + + // ensure single PWM mode + LPC_PWM1->MCR = 1 << 1; // reset TC on match 0 + + // enable the specific PWM output + LPC_PWM1->PCR |= 1 << (8 + pwm); + + pwm_clock_mhz = SystemCoreClock / 4000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // set channel match to percentage + uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value); + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == LPC_PWM1->MR0) { + v++; + } + + *obj->MR = v; + + // accept on next period start + LPC_PWM1->LER |= 1 << obj->pwm; +} + +float pwmout_read(pwmout_t* obj) { + float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t ticks = pwm_clock_mhz * us; + + // set reset + LPC_PWM1->TCR = TCR_RESET; + + // set the global match register + LPC_PWM1->MR0 = ticks; + + // Scale the pulse width to preserve the duty ratio + if (LPC_PWM1->MR0 > 0) { + *obj->MR = (*obj->MR * ticks) / LPC_PWM1->MR0; + } + + // set the channel latch to update value at next period start + LPC_PWM1->LER |= 1 << 0; + + // enable counter and pwm, clear reset + LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t v = pwm_clock_mhz * us; + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == LPC_PWM1->MR0) { + v++; + } + + // set the match register value + *obj->MR = v; + + // set the channel latch to update value at next period start + LPC_PWM1->LER |= 1 << obj->pwm; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/rtc_api.c new file mode 100644 index 0000000000..a4e7b96a61 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/rtc_api.c @@ -0,0 +1,117 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rtc_api.h" + +// ensure rtc is running (unchanged if already running) + +/* Setup the RTC based on a time structure, ensuring RTC is enabled + * + * Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock + * - We want to use the 32khz clock, allowing for sleep mode + * + * Most registers are not changed by a Reset + * - We must initialize these registers between power-on and setting the RTC into operation + + * Clock Control Register + * RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled + * RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset + * RTC_CCR[4] : Clock Source - 0 = Prescaler, 1 = 32k Xtal + * + * The RTC may already be running, so we should set it up + * without impacting if it is the case + */ +void rtc_init(void) { + LPC_SC->PCONP |= 0x200; // Ensure power is on + LPC_RTC->CCR = 0x00; + + // clock source on 2368 is special test mode on 1768! + LPC_RTC->CCR |= 1 << 4; // Ensure clock source is 32KHz Xtal + + LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled +} + +void rtc_free(void) { + // [TODO] +} + +/* + * Little check routine to see if the RTC has been enabled + * + * Clock Control Register + * RTC_CCR[0] : 0 = Disabled, 1 = Enabled + * + */ + +int rtc_isenabled(void) { + return(((LPC_RTC->CCR) & 0x01) != 0); +} + +/* + * RTC Registers + * RTC_SEC Seconds 0-59 + * RTC_MIN Minutes 0-59 + * RTC_HOUR Hour 0-23 + * RTC_DOM Day of Month 1-28..31 + * RTC_DOW Day of Week 0-6 + * RTC_DOY Day of Year 1-365 + * RTC_MONTH Month 1-12 + * RTC_YEAR Year 0-4095 + * + * struct tm + * tm_sec seconds after the minute 0-61 + * tm_min minutes after the hour 0-59 + * tm_hour hours since midnight 0-23 + * tm_mday day of the month 1-31 + * tm_mon months since January 0-11 + * tm_year years since 1900 + * tm_wday days since Sunday 0-6 + * tm_yday days since January 1 0-365 + * tm_isdst Daylight Saving Time flag + */ +time_t rtc_read(void) { + // Setup a tm structure based on the RTC + struct tm timeinfo; + timeinfo.tm_sec = LPC_RTC->SEC; + timeinfo.tm_min = LPC_RTC->MIN; + timeinfo.tm_hour = LPC_RTC->HOUR; + timeinfo.tm_mday = LPC_RTC->DOM; + timeinfo.tm_mon = LPC_RTC->MONTH - 1; + timeinfo.tm_year = LPC_RTC->YEAR - 1900; + + // Convert to timestamp + time_t t = mktime(&timeinfo); + + return t; +} + +void rtc_write(time_t t) { + // Convert the time in to a tm + struct tm *timeinfo = localtime(&t); + + // Pause clock, and clear counter register (clears us count) + LPC_RTC->CCR |= 2; + + // Set the RTC + LPC_RTC->SEC = timeinfo->tm_sec; + LPC_RTC->MIN = timeinfo->tm_min; + LPC_RTC->HOUR = timeinfo->tm_hour; + LPC_RTC->DOM = timeinfo->tm_mday; + LPC_RTC->MONTH = timeinfo->tm_mon + 1; + LPC_RTC->YEAR = timeinfo->tm_year + 1900; + + // Restart clock + LPC_RTC->CCR &= ~((uint32_t)2); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c new file mode 100644 index 0000000000..12142ab59f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c @@ -0,0 +1,337 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 4 + +static const PinMap PinMap_UART_TX[] = { + {P0_0, UART_3, 2}, + {P0_2, UART_0, 1}, + {P0_10, UART_2, 1}, + {P0_15, UART_1, 1}, + {P0_25, UART_3, 3}, + {P2_0 , UART_1, 2}, + {P2_8 , UART_2, 2}, + {P4_28, UART_3, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_1 , UART_3, 2}, + {P0_3 , UART_0, 1}, + {P0_11, UART_2, 1}, + {P0_16, UART_1, 1}, + {P0_26, UART_3, 3}, + {P2_1 , UART_1, 2}, + {P2_9 , UART_2, 2}, + {P4_29, UART_3, 3}, + {NC , NC , 0} +}; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_UART_TypeDef *)uart; + // enable power + switch (uart) { + case UART_0: LPC_SC->PCONP |= 1 << 3; break; + case UART_1: LPC_SC->PCONP |= 1 << 4; break; + case UART_2: LPC_SC->PCONP |= 1 << 24; break; + case UART_3: LPC_SC->PCONP |= 1 << 25; break; + } + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + MBED_ASSERT((int)obj->uart <= UART_3); + // The LPC2300 and LPC1700 have a divider and a fractional divider to control the + // baud rate. The formula is: + // + // Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal) + // where: + // 1 < MulVal <= 15 + // 0 <= DivAddVal < 14 + // DivAddVal < MulVal + // + // set pclk to /1 + switch ((int)obj->uart) { + case UART_0: LPC_SC->PCLKSEL0 &= ~(0x3 << 6); LPC_SC->PCLKSEL0 |= (0x1 << 6); break; + case UART_1: LPC_SC->PCLKSEL0 &= ~(0x3 << 8); LPC_SC->PCLKSEL0 |= (0x1 << 8); break; + case UART_2: LPC_SC->PCLKSEL1 &= ~(0x3 << 16); LPC_SC->PCLKSEL1 |= (0x1 << 16); break; + case UART_3: LPC_SC->PCLKSEL1 &= ~(0x3 << 18); LPC_SC->PCLKSEL1 |= (0x1 << 18); break; + default: break; + } + + uint32_t PCLK = SystemCoreClock; + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable = 0, parity_select = 0; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);} +void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);} +void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);} +void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/spi_api.c new file mode 100644 index 0000000000..b658769889 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/spi_api.c @@ -0,0 +1,219 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_7 , SPI_1, 2}, + {P0_15, SPI_0, 2}, + {P1_20, SPI_0, 3}, + {P1_31, SPI_1, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_1, 2}, + {P0_13, SPI_1, 2}, + {P0_18, SPI_0, 2}, + {P1_24, SPI_0, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_1, 2}, + {P0_12, SPI_1, 2}, + {P0_17, SPI_0, 2}, + {P1_23, SPI_0, 3}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_6 , SPI_1, 2}, + {P0_11, SPI_1, 2}, + {P0_16, SPI_0, 2}, + {P1_21, SPI_0, 3}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: LPC_SC->PCONP |= 1 << 21; break; + case SPI_1: LPC_SC->PCONP |= 1 << 10; break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3))); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + // setup the spi clock diveder to /1 + switch ((int)obj->spi) { + case SPI_0: + LPC_SC->PCLKSEL1 &= ~(3 << 10); + LPC_SC->PCLKSEL1 |= (1 << 10); + break; + case SPI_1: + LPC_SC->PCLKSEL0 &= ~(3 << 20); + LPC_SC->PCLKSEL0 |= (1 << 20); + break; + } + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/us_ticker.c new file mode 100644 index 0000000000..b46d75e6bc --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC23XX/us_ticker.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE) +#define US_TICKER_TIMER_IRQn TIMER3_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3 + + US_TICKER_TIMER->CTCR = 0x0; // timer mode + uint32_t PCLK = SystemCoreClock / 4; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/PortNames.h new file mode 100644 index 0000000000..613a5b6916 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/PortNames.h @@ -0,0 +1,35 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3, + Port4 = 4, + Port5 = 5 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PeripheralNames.h new file mode 100644 index 0000000000..574cb24218 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PeripheralNames.h @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART0_BASE, + UART_1 = (int)LPC_UART1_BASE, + UART_2 = (int)LPC_UART2_BASE, + UART_3 = (int)LPC_UART3_BASE, + UART_4 = (int)LPC_UART4_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE, + SPI_2 = (int)LPC_SSP2_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE, + I2C_2 = (int)LPC_I2C2_BASE +} I2CName; + +typedef enum { + PWM0_1 = 1, + PWM0_2, + PWM0_3, + PWM0_4, + PWM0_5, + PWM0_6, + PWM1_1, + PWM1_2, + PWM1_3, + PWM1_4, + PWM1_5, + PWM1_6 +} PWMName; + +typedef enum { + CAN_1 = (int)LPC_CAN1_BASE, + CAN_2 = (int)LPC_CAN2_BASE +} CANName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p5, p6, p7 +#define MBED_SPI1 p11, p12, p13, p14 +#define MBED_SPI2 p39, p38, p32, p31 + +#define MBED_UART3 p9, p10 +#define MBED_UART4 p37, p31 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 p32, p31 +#define MBED_I2C1 p9, p10 + +#define MBED_CAN1 p9, p10 +#define MBED_CAN2 p34, p33 + +#define MBED_ANALOGOUT0 p18 + +#define MBED_ANALOGIN0 p15 +#define MBED_ANALOGIN1 p16 +#define MBED_ANALOGIN2 p17 +#define MBED_ANALOGIN3 p18 +#define MBED_ANALOGIN4 p19 +#define MBED_ANALOGIN5 p20 + +#define MBED_PWMOUT0 p30 +#define MBED_PWMOUT1 p29 +#define MBED_PWMOUT2 p28 +#define MBED_PWMOUT3 p27 +#define MBED_PWMOUT4 p26 +#define MBED_PWMOUT5 p25 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PinNames.h new file mode 100644 index 0000000000..57b49d6aa8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/PinNames.h @@ -0,0 +1,130 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = /*LPC_GPIO0_BASE*/0, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + P5_0, P5_1, P5_2, P5_3, P5_4, + + // mbed DIP Pin Names + p5 = P1_24, + p6 = P1_23, + p7 = P1_20, + p8 = P0_21, + p9 = P0_0, + p10 = P0_1, + p11 = P0_9, + p12 = P0_8, + p13 = P0_7, + p14 = P0_6, + p15 = P0_23, + p16 = P0_24, + p17 = P0_25, + p18 = P0_26, + p19 = P1_30, + p20 = P1_31, + + p23 = P2_10, + p24 = P1_12, + p25 = P1_11, + p26 = P1_7, + p27 = P1_6, + p28 = P1_5, + p29 = P1_3, + p30 = P1_2, + p31 = P5_3, + p32 = P5_2, + p33 = P0_5, + p34 = P0_4, + + p37 = P5_4, + p38 = P5_1, + p39 = P5_0, + + // Other mbed Pin Names + LED1 = P1_18, + LED2 = P0_13, + LED3 = P1_13, + LED4 = P2_19, + + USBTX = P0_2, + USBRX = P0_3, + + // QSB baseboard Arduino shield pins + D0 = p10, + D1 = p9, + D2 = p31, + D3 = p32, + D4 = p33, + D5 = p37, + D6 = p38, + D7 = p34, + D8 = p8, + D9 = p39, + D10 = p14, + D11 = p11, + D12 = p12, + D13 = p13, + D14 = p19, + D15 = p20, + + A0 = p15, + A1 = p16, + A2 = p17, + A3 = p18, + A4 = p19, + A5 = p20, + + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/analogin_api.c new file mode 100644 index 0000000000..be53b09c04 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/analogin_api.c @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_23, ADC0_0, 0x01}, + {P0_24, ADC0_1, 0x01}, + {P0_25, ADC0_2, 0x01}, + {P0_26, ADC0_3, 0x01}, + {P1_30, ADC0_4, 0x03}, + {P1_31, ADC0_5, 0x03}, + {P0_12, ADC0_6, 0x03}, + {P0_13, ADC0_7, 0x03}, + {NC , NC , 0 } +}; + +#define ADC_RANGE ADC_12BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // ensure power is turned on + LPC_SC->PCONP |= (1 << 12); + + uint32_t PCLK = PeripheralClock; + + // calculate minimum clock divider + // clkdiv = divider - 1 + uint32_t MAX_ADC_CLK = 12400000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + // Set the generic software-controlled ADC settings + LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected + | (clkdiv << 8) // CLKDIV: + | (0 << 16) // BURST: 0 = software control + | (1 << 21) // PDN: 1 = operational + | (0 << 24) // START: 0 = no start + | (0 << 27); // EDGE: not applicable + + // must enable analog mode (ADMODE = 0) + __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); + *reg &= ~(1 << 7); + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 4) & ADC_RANGE; // 12 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/can_api.c new file mode 100644 index 0000000000..34f1a04d24 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/can_api.c @@ -0,0 +1,391 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "can_api.h" + +#include "cmsis.h" +#include "pinmap.h" + +#include <math.h> +#include <string.h> + +#define CAN_NUM 2 + +/* Acceptance filter mode in AFMR register */ +#define ACCF_OFF 0x01 +#define ACCF_BYPASS 0x02 +#define ACCF_ON 0x00 +#define ACCF_FULLCAN 0x04 + +/* There are several bit timing calculators on the internet. +http://www.port.de/engl/canprod/sv_req_form.html +http://www.kvaser.com/can/index.htm +*/ + +static const PinMap PinMap_CAN_RD[] = { + {P0_0 , CAN_1, 1}, + {P0_4 , CAN_2, 2}, + {P0_21, CAN_1, 4}, + {P2_7 , CAN_2, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_CAN_TD[] = { + {P0_1 , CAN_1, 1}, + {P0_5 , CAN_2, 2}, + {P0_22, CAN_1, 4}, + {P2_8 , CAN_2, 1}, + {NC , NC , 0} +}; + +// Type definition to hold a CAN message +struct CANMsg { + unsigned int reserved1 : 16; + unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter + unsigned int reserved0 : 10; + unsigned int rtr : 1; // Bit 30: Set if this is a RTR message + unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message + unsigned int id; // CAN Message ID (11-bit or 29-bit) + unsigned char data[8]; // CAN Message Data Bytes 0-7 +}; +typedef struct CANMsg CANMsg; + +static uint32_t can_irq_ids[CAN_NUM] = {0}; +static can_irq_handler irq_handler; + +static uint32_t can_disable(can_t *obj) { + uint32_t sm = obj->dev->MOD; + obj->dev->MOD |= 1; + return sm; +} + +static inline void can_enable(can_t *obj) { + if (obj->dev->MOD & 1) { + obj->dev->MOD &= ~(1); + } +} + +int can_mode(can_t *obj, CanMode mode) +{ + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + return 0; // not implemented +} + +static inline void can_irq(uint32_t icr, uint32_t index) { + uint32_t i; + + for(i = 0; i < 8; i++) + { + if((can_irq_ids[index] != 0) && (icr & (1 << i))) + { + switch (i) { + case 0: irq_handler(can_irq_ids[index], IRQ_RX); break; + case 1: irq_handler(can_irq_ids[index], IRQ_TX); break; + case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break; + case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break; + case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break; + case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break; + case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break; + case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break; + case 8: irq_handler(can_irq_ids[index], IRQ_READY); break; + } + } + } +} + +// Have to check that the CAN block is active before reading the Interrupt +// Control Register, or the mbed hangs +void can_irq_n() { + uint32_t icr; + + if(LPC_SC->PCONP & (1 << 13)) { + icr = LPC_CAN1->ICR & 0x1FF; + can_irq(icr, 0); + } + + if(LPC_SC->PCONP & (1 << 14)) { + icr = LPC_CAN2->ICR & 0x1FF; + can_irq(icr, 1); + } +} + +// Register CAN object's irq handler +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +// Unregister CAN object's irq handler +void can_irq_free(can_t *obj) { + obj->dev->IER &= ~(1); + can_irq_ids[obj->index] = 0; + + if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +// Clear or set a irq +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { + uint32_t ier; + + switch (type) { + case IRQ_RX: ier = (1 << 0); break; + case IRQ_TX: ier = (1 << 1); break; + case IRQ_ERROR: ier = (1 << 2); break; + case IRQ_OVERRUN: ier = (1 << 3); break; + case IRQ_WAKEUP: ier = (1 << 4); break; + case IRQ_PASSIVE: ier = (1 << 5); break; + case IRQ_ARB: ier = (1 << 6); break; + case IRQ_BUS: ier = (1 << 7); break; + case IRQ_READY: ier = (1 << 8); break; + default: return; + } + + obj->dev->MOD |= 1; + if(enable == 0) { + obj->dev->IER &= ~ier; + } + else { + obj->dev->IER |= ier; + } + obj->dev->MOD &= ~(1); + + // Enable NVIC if at least 1 interrupt is active + if(((LPC_SC->PCONP & (1 << 13)) && LPC_CAN1->IER) || ((LPC_SC->PCONP & (1 << 14)) && LPC_CAN2->IER)) { + NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n); + NVIC_EnableIRQ(CAN_IRQn); + } + else { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits; + + bitwidth = (pclk / cclk); + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + if (hit) { + btr = ((timing_pts[bits][1] << 20) & 0x00700000) + | ((timing_pts[bits][0] << 16) & 0x000F0000) + | ((psjw << 14) & 0x0000C000) + | ((brp << 0) & 0x000003FF); + } else { + btr = 0xFFFFFFFF; + } + + return btr; + +} + +void can_init(can_t *obj, PinName rd, PinName td) { + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)obj->dev != NC); + + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP |= 1 << 13; break; + case CAN_2: LPC_SC->PCONP |= 1 << 14; break; + } + + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + + switch ((int)obj->dev) { + case CAN_1: obj->index = 0; break; + case CAN_2: obj->index = 1; break; + } + + can_reset(obj); + obj->dev->IER = 0; // Disable Interrupts + can_frequency(obj, 100000); + + LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter +} + +void can_free(can_t *obj) { + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break; + case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break; + } +} + +int can_frequency(can_t *obj, int f) { + int pclk = PeripheralClock; + + int btr = can_speed(pclk, (unsigned int)f, 1); + + if (btr > 0) { + uint32_t modmask = can_disable(obj); + obj->dev->BTR = btr; + obj->dev->MOD = modmask; + return 1; + } else { + return 0; + } +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + unsigned int CANStatus; + CANMsg m; + + can_enable(obj); + + m.id = msg.id ; + m.dlc = msg.len & 0xF; + m.rtr = msg.type; + m.type = msg.format; + memcpy(m.data, msg.data, msg.len); + const unsigned int *buf = (const unsigned int *)&m; + + CANStatus = obj->dev->SR; + if (CANStatus & 0x00000004) { + obj->dev->TFI1 = buf[0] & 0xC00F0000; + obj->dev->TID1 = buf[1]; + obj->dev->TDA1 = buf[2]; + obj->dev->TDB1 = buf[3]; + if(cc) { + obj->dev->CMR = 0x30; + } else { + obj->dev->CMR = 0x21; + } + return 1; + + } else if (CANStatus & 0x00000400) { + obj->dev->TFI2 = buf[0] & 0xC00F0000; + obj->dev->TID2 = buf[1]; + obj->dev->TDA2 = buf[2]; + obj->dev->TDB2 = buf[3]; + if (cc) { + obj->dev->CMR = 0x50; + } else { + obj->dev->CMR = 0x41; + } + return 1; + + } else if (CANStatus & 0x00040000) { + obj->dev->TFI3 = buf[0] & 0xC00F0000; + obj->dev->TID3 = buf[1]; + obj->dev->TDA3 = buf[2]; + obj->dev->TDB3 = buf[3]; + if (cc) { + obj->dev->CMR = 0x90; + } else { + obj->dev->CMR = 0x81; + } + return 1; + } + + return 0; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + CANMsg x; + unsigned int *i = (unsigned int *)&x; + + can_enable(obj); + + if (obj->dev->GSR & 0x1) { + *i++ = obj->dev->RFS; // Frame + *i++ = obj->dev->RID; // ID + *i++ = obj->dev->RDA; // Data A + *i++ = obj->dev->RDB; // Data B + obj->dev->CMR = 0x04; // release receive buffer + + msg->id = x.id; + msg->len = x.dlc; + msg->format = (x.type)? CANExtended : CANStandard; + msg->type = (x.rtr)? CANRemote: CANData; + memcpy(msg->data,x.data,x.dlc); + return 1; + } + + return 0; +} + +void can_reset(can_t *obj) { + can_disable(obj); + obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset +} + +unsigned char can_rderror(can_t *obj) { + return (obj->dev->GSR >> 16) & 0xFF; +} + +unsigned char can_tderror(can_t *obj) { + return (obj->dev->GSR >> 24) & 0xFF; +} + +void can_monitor(can_t *obj, int silent) { + uint32_t mod_mask = can_disable(obj); + if (silent) { + obj->dev->MOD |= (1 << 1); + } else { + obj->dev->MOD &= ~(1 << 1); + } + if (!(mod_mask & 1)) { + can_enable(obj); + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/ethernet_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/ethernet_api.c new file mode 100644 index 0000000000..0a20a10a2e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/ethernet_api.c @@ -0,0 +1,1008 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> + +#include "ethernet_api.h" +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "mbed_error.h" + +#define NEW_LOGIC 0 +#define NEW_ETH_BUFFER 0 + +#if NEW_ETH_BUFFER + +#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets) +#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets) + +#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size +#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length) + +#else + +// Memfree calculation: +// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) + +// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556 +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ +#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */ +#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */ + +const int ethernet_MTU_SIZE = 0x300; + +#endif + +#define ETHERNET_ADDR_SIZE 6 + +PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +PACKED struct RX_STAT_TypeDef { /* RX Status struct */ + unsigned int Info; + unsigned int HashCRC; +}; +typedef struct RX_STAT_TypeDef RX_STAT_TypeDef; + +PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +PACKED struct TX_STAT_TypeDef { /* TX Status struct */ + unsigned int Info; +}; +typedef struct TX_STAT_TypeDef TX_STAT_TypeDef; + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ + + +static int phy_read(unsigned int PhyReg); +static int phy_write(unsigned int PhyReg, unsigned short Data); + +static void txdscr_init(void); +static void rxdscr_init(void); + +#if defined (__ICCARM__) +# define AHBSRAM1 +#elif defined(TOOLCHAIN_GCC_CR) +# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32"))) +#else +# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned)) +#endif + +AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG]; +AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG]; +AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG]; +AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG]; + + +#if NEW_LOGIC +static int rx_consume_offset = -1; +static int tx_produce_offset = -1; +#else +static int send_doff = 0; +static int send_idx = -1; +static int send_size = 0; + +static int receive_soff = 0; +static int receive_idx = -1; +#endif + +static uint32_t phy_id = 0; + +static inline int rinc(int idx, int mod) { + ++idx; + idx %= mod; + return idx; +} + +//extern unsigned int SystemFrequency; +static inline unsigned int clockselect() { + if(SystemCoreClock < 10000000) { + return 1; + } else if(SystemCoreClock < 15000000) { + return 2; + } else if(SystemCoreClock < 20000000) { + return 3; + } else if(SystemCoreClock < 25000000) { + return 4; + } else if(SystemCoreClock < 35000000) { + return 5; + } else if(SystemCoreClock < 50000000) { + return 6; + } else if(SystemCoreClock < 70000000) { + return 7; + } else if(SystemCoreClock < 80000000) { + return 8; + } else if(SystemCoreClock < 90000000) { + return 9; + } else if(SystemCoreClock < 100000000) { + return 10; + } else if(SystemCoreClock < 120000000) { + return 11; + } else if(SystemCoreClock < 130000000) { + return 12; + } else if(SystemCoreClock < 140000000) { + return 13; + } else if(SystemCoreClock < 150000000) { + return 15; + } else if(SystemCoreClock < 160000000) { + return 16; + } else { + return 0; + } +} + +#ifndef min +#define min(x, y) (((x)<(y))?(x):(y)) +#endif + +/*---------------------------------------------------------------------------- + Ethernet Device initialize + *----------------------------------------------------------------------------*/ +int ethernet_init() { + int regv, tout; + char mac[ETHERNET_ADDR_SIZE]; + unsigned int clock = clockselect(); + + LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ + + LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ + LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ + LPC_IOCON->P1_1 &= ~0x07; + LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ + LPC_IOCON->P1_4 &= ~0x07; + LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ + LPC_IOCON->P1_8 &= ~0x07; + LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ + LPC_IOCON->P1_9 &= ~0x07; + LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ + LPC_IOCON->P1_10 &= ~0x07; + LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ + LPC_IOCON->P1_14 &= ~0x07; + LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ + LPC_IOCON->P1_15 &= ~0x07; + LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ + LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ + LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ + LPC_IOCON->P1_17 &= ~0x07; + LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ + + /* Reset all EMAC internal modules. */ + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | + MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */ + + LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */ + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + LPC_EMAC->MAXF = ETH_MAX_FLEN; + LPC_EMAC->CLRT = CLRT_DEF; + LPC_EMAC->IPGR = IPGR_DEF; + + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ + LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ + + for(tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; + LPC_EMAC->MCMD = 0; + + LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ + + for (tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->SUPP = 0; + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return -1; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) { + error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); + } + + ethernet_set_link(-1, 0); + + /* Set the Ethernet MAC Address registers */ + ethernet_address(mac); + LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4]; + LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2]; + LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0]; + + txdscr_init(); /* initialize DMA TX Descriptor */ + rxdscr_init(); /* initialize DMA RX Descriptor */ + + LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + /* Receive Broadcast, Perfect Match Packets */ + + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ + LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ + + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->MAC1 |= MAC1_REC_EN; + +#if NEW_LOGIC + rx_consume_offset = -1; + tx_produce_offset = -1; +#else + send_doff = 0; + send_idx = -1; + send_size = 0; + + receive_soff = 0; + receive_idx = -1; +#endif + + return 0; +} + +/*---------------------------------------------------------------------------- + Ethernet Device Uninitialize + *----------------------------------------------------------------------------*/ +void ethernet_free() { + LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); + LPC_EMAC->IntClear = 0xFFFF; + + LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */ + + LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ + LPC_IOCON->P1_1 &= ~0x07; + LPC_IOCON->P1_4 &= ~0x07; + LPC_IOCON->P1_8 &= ~0x07; + LPC_IOCON->P1_9 &= ~0x07; + LPC_IOCON->P1_10 &= ~0x07; + LPC_IOCON->P1_14 &= ~0x07; + LPC_IOCON->P1_15 &= ~0x07; + LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ + LPC_IOCON->P1_17 &= ~0x07; +} + +// if(TxProduceIndex == TxConsumeIndex) buffer array is empty +// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill +// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment +// TxConsumeIndex - The buffer that will/is beign sent by hardware + +int ethernet_write(const char *data, int slen) { + +#if NEW_LOGIC + + if(tx_produce_offset < 0) { // mark as active if not already + tx_produce_offset = 0; + } + + int index = LPC_EMAC->TxProduceIndex; + + int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum + int requested = slen; + int ncopy = min(remaining, requested); + + void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset); + void *psrc = (void *)(data); + + if(ncopy > 0 ){ + if(data != NULL) { + memcpy(pdst, psrc, ncopy); + } else { + memset(pdst, 0, ncopy); + } + } + + tx_produce_offset += ncopy; + + return ncopy; + +#else + void *pdst, *psrc; + const int dlen = ETH_FRAG_SIZE; + int copy = 0; + int soff = 0; + + if(send_idx == -1) { + send_idx = LPC_EMAC->TxProduceIndex; + } + + if(slen + send_doff > ethernet_MTU_SIZE) { + return -1; + } + + do { + copy = min(slen - soff, dlen - send_doff); + pdst = (void *)(txdesc[send_idx].Packet + send_doff); + psrc = (void *)(data + soff); + if(send_doff + copy > ETH_FRAG_SIZE) { + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT); + send_idx = rinc(send_idx, NUM_TX_FRAG); + send_doff = 0; + } + + if(data != NULL) { + memcpy(pdst, psrc, copy); + } else { + memset(pdst, 0, copy); + } + + soff += copy; + send_doff += copy; + send_size += copy; + } while(soff != slen); + + return soff; +#endif +} + +int ethernet_send() { + +#if NEW_LOGIC + if(tx_produce_offset < 0) { // no buffer active + return -1; + } + + // ensure there is a link + if(!ethernet_link()) { + return -2; + } + + // we have been writing in to a buffer, so finalise it + int size = tx_produce_offset; + int index = LPC_EMAC->TxProduceIndex; + txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST); + + // Increment ProduceIndex to allow it to be sent + // We can only do this if the next slot is free + int next = rinc(index, NUM_TX_FRAG); + while(next == LPC_EMAC->TxConsumeIndex) { + for(int i=0; i<1000; i++) { __NOP(); } + } + + LPC_EMAC->TxProduceIndex = next; + tx_produce_offset = -1; + return size; + +#else + int s = send_size; + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST); + send_idx = rinc(send_idx, NUM_TX_FRAG); + LPC_EMAC->TxProduceIndex = send_idx; + send_doff = 0; + send_idx = -1; + send_size = 0; + return s; +#endif +} + +// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read +// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd +// +// if(RxConsumeIndex == RxProduceIndex) buffer array is empty +// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full + +// Recevies an arrived ethernet packet. +// Receiving an ethernet packet will drop the last received ethernet packet +// and make a new ethernet packet ready to read. +// Returns size of packet, else 0 if nothing to receive + +// We read from RxConsumeIndex from position rx_consume_offset +// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading +// rx_consume_offset = -1 // no frame +// rx_consume_offset = 0 // start of frame +// Assumption: A fragment should alway be a whole frame + +int ethernet_receive() { +#if NEW_LOGIC + + // if we are currently reading a valid RxConsume buffer, increment to the next one + if(rx_consume_offset >= 0) { + LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG); + } + + // if the buffer is empty, mark it as no valid buffer + if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) { + rx_consume_offset = -1; + return 0; + } + + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + rx_consume_offset = 0; + + // check if it is not marked as last or for errors + if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) { + return -1; + } + + int size = (info & RINFO_SIZE) + 1; + return size - 4; // don't include checksum bytes + +#else + if(receive_idx == -1) { + receive_idx = LPC_EMAC->RxConsumeIndex; + } else { + while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + unsigned int info = rxstat[receive_idx].Info; + int slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + + LPC_EMAC->RxConsumeIndex = receive_idx; + } + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) { + receive_idx = -1; + return 0; + } + + return (rxstat[receive_idx].Info & RINFO_SIZE) - 3; +#endif +} + +// Read from an recevied ethernet packet. +// After receive returnd a number bigger than 0 it is +// possible to read bytes from this packet. +// Read will write up to size bytes into data. +// It is possible to use read multible times. +// Each time read will start reading after the last read byte before. + +int ethernet_read(char *data, int dlen) { +#if NEW_LOGIC + // Check we have a valid buffer to read + if(rx_consume_offset < 0) { + return 0; + } + + // Assume 1 fragment block + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum + + int remaining = size - rx_consume_offset; + int requested = dlen; + int ncopy = min(remaining, requested); + + void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset); + void *pdst = (void *)(data); + + if(data != NULL && ncopy > 0) { + memcpy(pdst, psrc, ncopy); + } + + rx_consume_offset += ncopy; + + return ncopy; +#else + int slen; + int copy = 0; + unsigned int more; + unsigned int info; + void *pdst, *psrc; + int doff = 0; + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) { + return 0; + } + + do { + info = rxstat[receive_idx].Info; + more = !(info & RINFO_LAST_FLAG); + slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } else { + + copy = min(slen - receive_soff, dlen - doff); + psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff); + pdst = (void *)(data + doff); + + if(data != NULL) { + /* check if Buffer available */ + memcpy(pdst, psrc, copy); + } + + receive_soff += copy; + doff += copy; + + if((more && (receive_soff == slen))) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + } + } + } while(more && !(doff == dlen) && !receive_soff); + + return doff; +#endif +} + +int ethernet_link(void) { + + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } + else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MWTD = Data; + + for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + return 0; + } + } + + return -1; +} + + +static int phy_read(unsigned int PhyReg) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + LPC_EMAC->MCMD = 0; + return LPC_EMAC->MRDD; /* Return a 16-bit value. */ + } + } + + return -1; +} + + +static void txdscr_init() { + int i; + + for(i = 0; i < NUM_TX_FRAG; i++) { + txdesc[i].Packet = (uint32_t)&txbuf[i]; + txdesc[i].Ctrl = 0; + txstat[i].Info = 0; + } + + LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxStatus = (uint32_t)txstat; + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; + + LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */ +} + + +static void rxdscr_init() { + int i; + + for(i = 0; i < NUM_RX_FRAG; i++) { + rxdesc[i].Packet = (uint32_t)&rxbuf[i]; + rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1); + rxstat[i].Info = 0; + rxstat[i].HashCRC = 0; + } + + LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxStatus = (uint32_t)rxstat; + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; + + LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */ +} + +void ethernet_address(char *mac) { + mbed_mac_address(mac); +} + +void ethernet_set_link(int speed, int duplex) { + unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + phy_data = PHY_AUTO_NEG; + } else { + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + switch(phy_id) { + case DP83848C_ID: + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } else { + LPC_EMAC->SUPP |= SUPP_SPEED; + } + break; + + case LAN8720_ID: + phy_data = phy_read(PHY_REG_SCSR); + + if (phy_data & PHY_SCSR_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_SCSR_100MBIT) { + LPC_EMAC->SUPP |= SUPP_SPEED; + } else { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } + + break; + } +} + +/* + * The Embedded Artists LPC4088 QuickStart Board has an eeprom with a unique + * 48 bit ID. This ID is used as MAC address. + */ + +#include "i2c_api.h" + +static int _macRetrieved = 0; +static char _macAddr[6] = {0x00,0x02,0xF7,0xF0,0x00,0x00}; +#define EEPROM_24AA02E48_ADDR (0xA0) + +void mbed_mac_address(char *mac) { + + if (_macRetrieved == 0) { + char tmp[6]; + i2c_t i2cObj; + + i2c_init(&i2cObj, P0_27, P0_28); + + do { + // the unique ID is at offset 0xFA + tmp[0] = 0xFA; + if (i2c_write(&i2cObj, EEPROM_24AA02E48_ADDR, tmp, 1, 1) != 1) { + break; // failed to write + } + + + if (i2c_read(&i2cObj, EEPROM_24AA02E48_ADDR, tmp, 6, 1) != 6) { + break; // failed to read + } + + memcpy(_macAddr, tmp, 6); + + } while(0); + + // We always consider the MAC address to be retrieved even though + // reading from the eeprom failed. If it wasn't possible to read + // from eeprom the default address will be used. + _macRetrieved = 1; + } + + memcpy(mac, _macAddr, 6); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c new file mode 100644 index 0000000000..eaa103a585 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c @@ -0,0 +1,416 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_0 , I2C_1, 3}, + {P0_10, I2C_2, 2}, + {P0_19, I2C_1, 3}, + {P0_27, I2C_0, 1}, + {P1_15, I2C_2, 3}, + {P1_30, I2C_0, 4}, + {P2_14, I2C_1, 2}, + {P2_30, I2C_2, 2}, + {P4_20, I2C_2, 4}, + {P5_2, I2C_0, 5}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_1 , I2C_1, 3}, + {P0_11, I2C_2, 2}, + {P0_20, I2C_1, 3}, + {P0_28, I2C_0, 1}, + {P1_31, I2C_0, 4}, + {P2_15, I2C_1, 2}, + {P2_31, I2C_2, 2}, + {P4_21, I2C_2, 2}, + {P4_29, I2C_2, 4}, + {P5_3, I2C_0, 5}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + switch ((int)obj->i2c) { + case I2C_0: LPC_SC->PCONP |= 1 << 7; break; + case I2C_1: LPC_SC->PCONP |= 1 << 19; break; + case I2C_2: LPC_SC->PCONP |= 1 << 26; break; + } +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); + + // OpenDrain must explicitly be enabled for p0.0 and p0.1 + if (sda == P0_0) { + pin_mode(sda, OpenDrain); + } + if (scl == P0_1) { + pin_mode(scl, OpenDrain); + } + +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if(last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + uint32_t PCLK = PeripheralClock; + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if (status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + + case 0xB8: // Slave transmit ACK + ack = 1; + break; + + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; + *((uint32_t *) addr) = mask & 0xFE; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/pwmout_api.c new file mode 100644 index 0000000000..3f34e397f9 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/pwmout_api.c @@ -0,0 +1,189 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +// PORT ID, PWM ID, Pin function +static const PinMap PinMap_PWM[] = { + {P1_2, PWM0_1, 3}, + {P1_3, PWM0_2, 3}, + {P1_5, PWM0_3, 3}, + {P1_6, PWM0_4, 3}, + {P1_7, PWM0_5, 3}, + {P1_11, PWM0_6, 3}, + {P1_18, PWM1_1, 2}, + {P1_20, PWM1_2, 2}, + {P1_21, PWM1_3, 2}, + {P1_23, PWM1_4, 2}, + {P1_24, PWM1_5, 2}, + {P1_26, PWM1_6, 2}, + {P2_0, PWM1_1, 1}, + {P2_1, PWM1_2, 1}, + {P2_2, PWM1_3, 1}, + {P2_3, PWM1_4, 1}, + {P2_4, PWM1_5, 1}, + {P2_5, PWM1_6, 1}, + {P3_16, PWM0_1, 2}, + {P3_17, PWM0_2, 2}, + {P3_18, PWM0_3, 2}, + {P3_19, PWM0_4, 2}, + {P3_20, PWM0_5, 2}, + {P3_21, PWM0_6, 2}, + {P3_24, PWM1_1, 2}, + {P3_25, PWM1_2, 2}, + {P3_26, PWM1_3, 2}, + {P3_27, PWM1_4, 2}, + {P3_28, PWM1_5, 2}, + {P3_29, PWM1_6, 2}, + {NC, NC, 0} +}; + +static const uint32_t PWM_mr_offset[7] = { + 0x18, 0x1C, 0x20, 0x24, 0x40, 0x44, 0x48 +}; + +#define TCR_PWM_EN 0x00000008 +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->channel = pwm; + obj->pwm = LPC_PWM0; + + if (obj->channel > 6) { // PWM1 is used if pwm > 6 + obj->channel -= 6; + obj->pwm = LPC_PWM1; + } + + obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]); + + // ensure the power is on + if (obj->pwm == LPC_PWM0) { + LPC_SC->PCONP |= 1 << 5; + } else { + LPC_SC->PCONP |= 1 << 6; + } + + obj->pwm->PR = 0; // no pre-scale + + // ensure single PWM mode + obj->pwm->MCR = 1 << 1; // reset TC on match 0 + + // enable the specific PWM output + obj->pwm->PCR |= 1 << (8 + obj->channel); + + pwm_clock_mhz = PeripheralClock / 1000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // set channel match to percentage + uint32_t v = (uint32_t)((float)(obj->pwm->MR0) * value); + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == obj->pwm->MR0) { + v++; + } + + *obj->MR = v; + + // accept on next period start + obj->pwm->LER |= 1 << obj->channel; +} + +float pwmout_read(pwmout_t* obj) { + float v = (float)(*obj->MR) / (float)(obj->pwm->MR0); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t ticks = pwm_clock_mhz * us; + + // set reset + obj->pwm->TCR = TCR_RESET; + + // set the global match register + obj->pwm->MR0 = ticks; + + // Scale the pulse width to preserve the duty ratio + if (obj->pwm->MR0 > 0) { + *obj->MR = (*obj->MR * ticks) / obj->pwm->MR0; + } + + // set the channel latch to update value at next period start + obj->pwm->LER |= 1 << 0; + + // enable counter and pwm, clear reset + obj->pwm->TCR = TCR_CNT_EN | TCR_PWM_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t v = pwm_clock_mhz * us; + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == obj->pwm->MR0) { + v++; + } + + // set the match register value + *obj->MR = v; + + // set the channel latch to update value at next period start + obj->pwm->LER |= 1 << obj->channel; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/serial_api.c new file mode 100644 index 0000000000..210353d11c --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/serial_api.c @@ -0,0 +1,330 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +static const PinMap PinMap_UART_TX[] = { + {P0_0, UART_3, 2}, + {P0_2, UART_0, 1}, + {P0_10, UART_2, 1}, + {P0_15, UART_1, 1}, + {P1_29, UART_4, 5}, + {P0_25, UART_3, 3}, + {P2_0 , UART_1, 2}, + {P2_8 , UART_2, 2}, + {P3_16, UART_1, 3}, + {P4_22, UART_2, 2}, + {P4_28, UART_3, 2}, + {P5_4, UART_4, 4}, + {NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_1 , UART_3, 2}, + {P0_3 , UART_0, 1}, + {P0_11, UART_2, 1}, + {P0_16, UART_1, 1}, + {P0_26, UART_3, 3}, + {P2_1 , UART_1, 2}, + {P2_9 , UART_2, 2}, + {P3_17, UART_1, 3}, + {P4_23, UART_2, 2}, + {P4_29, UART_3, 2}, + {P5_3, UART_4, 4}, + {NC , NC , 0} +}; + +#define UART_NUM 5 + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_UART_TypeDef *)uart; + // enable power + switch (uart) { + case UART_0: LPC_SC->PCONP |= 1 << 3; break; + case UART_1: LPC_SC->PCONP |= 1 << 4; break; + case UART_2: LPC_SC->PCONP |= 1 << 24; break; + case UART_3: LPC_SC->PCONP |= 1 << 25; break; + case UART_4: LPC_SC->PCONP |= 1 << 8; break; + } + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; + case UART_4: obj->index = 4; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + uint32_t PCLK = PeripheralClock; + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);} +void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);} +void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);} +void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);} +void uart4_irq() {uart_irq((LPC_UART4->IIR >> 1) & 0x7, 4);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break; + case UART_4: irq_n=UART4_IRQn; vector = (uint32_t)&uart4_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/spi_api.c new file mode 100644 index 0000000000..c88e8edd4f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/spi_api.c @@ -0,0 +1,226 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_7 , SPI_1, 2}, + {P0_15, SPI_0, 2}, + {P1_0, SPI_2, 4}, + {P1_19, SPI_1, 5}, + {P1_20, SPI_0, 5}, + {P1_31, SPI_1, 2}, + {P2_22, SPI_0, 2}, + {P4_20, SPI_1, 3}, + {P5_2, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_1, 2}, + {P0_13, SPI_1, 2}, + {P0_18, SPI_0, 2}, + {P1_1, SPI_2, 4}, + {P1_22, SPI_1, 5}, + {P1_24, SPI_0, 5}, + {P2_27, SPI_0, 2}, + {P4_23, SPI_1, 3}, + {P5_0, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_1, 2}, + {P0_12, SPI_1, 2}, + {P0_17, SPI_0, 2}, + {P1_4, SPI_2, 4}, + {P1_18, SPI_1, 5}, + {P1_23, SPI_0, 5}, + {P2_26, SPI_0, 2}, + {P4_22, SPI_1, 3}, + {P5_1, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_6 , SPI_1, 2}, + {P0_14, SPI_1, 2}, + {P0_16, SPI_0, 2}, + {P1_8, SPI_2, 4}, + {P1_21, SPI_0, 3}, + {P1_26, SPI_1, 5}, + {P1_28, SPI_0, 5}, + {P2_23, SPI_0, 2}, + {P4_21, SPI_1, 3}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: LPC_SC->PCONP |= 1 << 21; break; + case SPI_1: LPC_SC->PCONP |= 1 << 10; break; + case SPI_2: LPC_SC->PCONP |= 1 << 20; break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3))); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = PeripheralClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PeripheralNames.h new file mode 100644 index 0000000000..9d13fced6b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PeripheralNames.h @@ -0,0 +1,111 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART0_BASE, + UART_1 = (int)LPC_UART1_BASE, + UART_2 = (int)LPC_UART2_BASE, + UART_3 = (int)LPC_UART3_BASE, + UART_4 = (int)LPC_UART4_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE, + SPI_2 = (int)LPC_SSP2_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE, + I2C_2 = (int)LPC_I2C2_BASE +} I2CName; + +typedef enum { + PWM0_1 = 1, + PWM0_2, + PWM0_3, + PWM0_4, + PWM0_5, + PWM0_6, + PWM1_1, + PWM1_2, + PWM1_3, + PWM1_4, + PWM1_5, + PWM1_6 +} PWMName; + +typedef enum { + CAN_1 = (int)LPC_CAN1_BASE, + CAN_2 = (int)LPC_CAN2_BASE +} CANName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +// Default peripherals +#define MBED_SPI0 p7, p8, p9 +#define MBED_SPI1 p46, p44, p42, p45 +#define MBED_SPI2 p15, p16, p17, p18 + +#define MBED_UART3 p29, p30 +#define MBED_UART4 p19, p18 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C1 p12, p13 + +#define MBED_CAN1 p12, p13 +#define MBED_CAN2 p41, p43 + +#define MBED_ANALOGOUT0 p30 + +#define MBED_ANALOGIN2 p29 +#define MBED_ANALOGIN3 p30 + +#define MBED_PWMOUT0 p9 +#define MBED_PWMOUT1 p8 +#define MBED_PWMOUT2 p7 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PinNames.h new file mode 100644 index 0000000000..357899b4f3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/PinNames.h @@ -0,0 +1,106 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC Pin Names + P0_0 = /*LPC_GPIO0_BASE*/0, + P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15, P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23, P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31, + P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, + P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, + P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15, P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23, P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31, + P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15, P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23, P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31, + P5_0, P5_1, P5_2, P5_3, P5_4, + + // mbed DIP Pin Names + p1 = P0_30, + p2 = P2_14, + p3 = P0_29, + p4 = P2_15, + + p7 = P1_24, + p8 = P1_23, + p9 = P1_20, + p10 = P1_19, + p11 = P0_21, + p12 = P0_0, + p13 = P0_1, + p14 = P2_10, + p15 = P5_0, + p16 = P5_1, + p17 = P5_2, + p18 = P5_3, + p19 = P5_4, + p20 = P2_22, + p21 = P2_23, + p22 = P2_25, + p23 = P2_26, + p24 = P2_27, + p25 = P0_2, + p26 = P0_3, + + p29 = P0_25, + p30 = P0_26, + + p41 = P0_4, + p42 = P0_7, + p43 = P0_5, + p44 = P0_8, + p45 = P0_6, + p46 = P0_9, + + // Other mbed Pin Names + LED1 = P1_18, + LED2 = P0_13, + LED3 = P1_13, + LED4 = P2_19, + + USBTX = P0_2, + USBRX = P0_3, + + // Not connected + NC = (int)0xFFFFFFFF +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/analogin_api.c new file mode 100644 index 0000000000..e893fb60ba --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/analogin_api.c @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_25, ADC0_2, 0x01}, + {P0_26, ADC0_3, 0x01}, + {NC , NC , 0 } +}; + +#define ADC_RANGE ADC_12BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + // ensure power is turned on + LPC_SC->PCONP |= (1 << 12); + + uint32_t PCLK = PeripheralClock; + + // calculate minimum clock divider + // clkdiv = divider - 1 + uint32_t MAX_ADC_CLK = 12400000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + // Set the generic software-controlled ADC settings + LPC_ADC->CR = (0 << 0) // SEL: 0 = no channels selected + | (clkdiv << 8) // CLKDIV: + | (0 << 16) // BURST: 0 = software control + | (1 << 21) // PDN: 1 = operational + | (0 << 24) // START: 0 = no start + | (0 << 27); // EDGE: not applicable + + // must enable analog mode (ADMODE = 0) + __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); + *reg &= ~(1 << 7); + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 4) & ADC_RANGE; // 12 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/can_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/can_api.c new file mode 100644 index 0000000000..676bc27401 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/can_api.c @@ -0,0 +1,388 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "can_api.h" + +#include "cmsis.h" +#include "pinmap.h" + +#include <math.h> +#include <string.h> + +#define CAN_NUM 2 + +/* Acceptance filter mode in AFMR register */ +#define ACCF_OFF 0x01 +#define ACCF_BYPASS 0x02 +#define ACCF_ON 0x00 +#define ACCF_FULLCAN 0x04 + +/* There are several bit timing calculators on the internet. +http://www.port.de/engl/canprod/sv_req_form.html +http://www.kvaser.com/can/index.htm +*/ + +static const PinMap PinMap_CAN_RD[] = { + {P0_0 , CAN_1, 1}, + {P0_4 , CAN_2, 2}, + {P0_21, CAN_1, 4}, + {NC , NC , 0} +}; + +static const PinMap PinMap_CAN_TD[] = { + {P0_1 , CAN_1, 1}, + {P0_5 , CAN_2, 2}, + {NC , NC , 0} +}; + +// Type definition to hold a CAN message +struct CANMsg { + unsigned int reserved1 : 16; + unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter + unsigned int reserved0 : 10; + unsigned int rtr : 1; // Bit 30: Set if this is a RTR message + unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message + unsigned int id; // CAN Message ID (11-bit or 29-bit) + unsigned char data[8]; // CAN Message Data Bytes 0-7 +}; +typedef struct CANMsg CANMsg; + +static uint32_t can_irq_ids[CAN_NUM] = {0}; +static can_irq_handler irq_handler; + +static uint32_t can_disable(can_t *obj) { + uint32_t sm = obj->dev->MOD; + obj->dev->MOD |= 1; + return sm; +} + +static inline void can_enable(can_t *obj) { + if (obj->dev->MOD & 1) { + obj->dev->MOD &= ~(1); + } +} + +int can_mode(can_t *obj, CanMode mode) +{ + return 0; // not implemented +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { + return 0; // not implemented +} + +static inline void can_irq(uint32_t icr, uint32_t index) { + uint32_t i; + + for(i = 0; i < 8; i++) + { + if((can_irq_ids[index] != 0) && (icr & (1 << i))) + { + switch (i) { + case 0: irq_handler(can_irq_ids[index], IRQ_RX); break; + case 1: irq_handler(can_irq_ids[index], IRQ_TX); break; + case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break; + case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break; + case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break; + case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break; + case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break; + case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break; + case 8: irq_handler(can_irq_ids[index], IRQ_READY); break; + } + } + } +} + +// Have to check that the CAN block is active before reading the Interrupt +// Control Register, or the mbed hangs +void can_irq_n() { + uint32_t icr; + + if(LPC_SC->PCONP & (1 << 13)) { + icr = LPC_CAN1->ICR & 0x1FF; + can_irq(icr, 0); + } + + if(LPC_SC->PCONP & (1 << 14)) { + icr = LPC_CAN2->ICR & 0x1FF; + can_irq(icr, 1); + } +} + +// Register CAN object's irq handler +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +// Unregister CAN object's irq handler +void can_irq_free(can_t *obj) { + obj->dev->IER &= ~(1); + can_irq_ids[obj->index] = 0; + + if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +// Clear or set a irq +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { + uint32_t ier; + + switch (type) { + case IRQ_RX: ier = (1 << 0); break; + case IRQ_TX: ier = (1 << 1); break; + case IRQ_ERROR: ier = (1 << 2); break; + case IRQ_OVERRUN: ier = (1 << 3); break; + case IRQ_WAKEUP: ier = (1 << 4); break; + case IRQ_PASSIVE: ier = (1 << 5); break; + case IRQ_ARB: ier = (1 << 6); break; + case IRQ_BUS: ier = (1 << 7); break; + case IRQ_READY: ier = (1 << 8); break; + default: return; + } + + obj->dev->MOD |= 1; + if(enable == 0) { + obj->dev->IER &= ~ier; + } + else { + obj->dev->IER |= ier; + } + obj->dev->MOD &= ~(1); + + // Enable NVIC if at least 1 interrupt is active + if(((LPC_SC->PCONP & (1 << 13)) && LPC_CAN1->IER) || ((LPC_SC->PCONP & (1 << 14)) && LPC_CAN2->IER)) { + NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq_n); + NVIC_EnableIRQ(CAN_IRQn); + } + else { + NVIC_DisableIRQ(CAN_IRQn); + } +} + +// This table has the sampling points as close to 75% as possible. The first +// value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) { + uint32_t btr; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits; + + bitwidth = (pclk / cclk); + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + if (hit) { + btr = ((timing_pts[bits][1] << 20) & 0x00700000) + | ((timing_pts[bits][0] << 16) & 0x000F0000) + | ((psjw << 14) & 0x0000C000) + | ((brp << 0) & 0x000003FF); + } else { + btr = 0xFFFFFFFF; + } + + return btr; + +} + +void can_init(can_t *obj, PinName rd, PinName td) { + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)obj->dev != NC); + + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP |= 1 << 13; break; + case CAN_2: LPC_SC->PCONP |= 1 << 14; break; + } + + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + + switch ((int)obj->dev) { + case CAN_1: obj->index = 0; break; + case CAN_2: obj->index = 1; break; + } + + can_reset(obj); + obj->dev->IER = 0; // Disable Interrupts + can_frequency(obj, 100000); + + LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter +} + +void can_free(can_t *obj) { + switch ((int)obj->dev) { + case CAN_1: LPC_SC->PCONP &= ~(1 << 13); break; + case CAN_2: LPC_SC->PCONP &= ~(1 << 14); break; + } +} + +int can_frequency(can_t *obj, int f) { + int pclk = PeripheralClock; + + int btr = can_speed(pclk, (unsigned int)f, 1); + + if (btr > 0) { + uint32_t modmask = can_disable(obj); + obj->dev->BTR = btr; + obj->dev->MOD = modmask; + return 1; + } else { + return 0; + } +} + +int can_write(can_t *obj, CAN_Message msg, int cc) { + unsigned int CANStatus; + CANMsg m; + + can_enable(obj); + + m.id = msg.id ; + m.dlc = msg.len & 0xF; + m.rtr = msg.type; + m.type = msg.format; + memcpy(m.data, msg.data, msg.len); + const unsigned int *buf = (const unsigned int *)&m; + + CANStatus = obj->dev->SR; + if (CANStatus & 0x00000004) { + obj->dev->TFI1 = buf[0] & 0xC00F0000; + obj->dev->TID1 = buf[1]; + obj->dev->TDA1 = buf[2]; + obj->dev->TDB1 = buf[3]; + if(cc) { + obj->dev->CMR = 0x30; + } else { + obj->dev->CMR = 0x21; + } + return 1; + + } else if (CANStatus & 0x00000400) { + obj->dev->TFI2 = buf[0] & 0xC00F0000; + obj->dev->TID2 = buf[1]; + obj->dev->TDA2 = buf[2]; + obj->dev->TDB2 = buf[3]; + if (cc) { + obj->dev->CMR = 0x50; + } else { + obj->dev->CMR = 0x41; + } + return 1; + + } else if (CANStatus & 0x00040000) { + obj->dev->TFI3 = buf[0] & 0xC00F0000; + obj->dev->TID3 = buf[1]; + obj->dev->TDA3 = buf[2]; + obj->dev->TDB3 = buf[3]; + if (cc) { + obj->dev->CMR = 0x90; + } else { + obj->dev->CMR = 0x81; + } + return 1; + } + + return 0; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) { + CANMsg x; + unsigned int *i = (unsigned int *)&x; + + can_enable(obj); + + if (obj->dev->GSR & 0x1) { + *i++ = obj->dev->RFS; // Frame + *i++ = obj->dev->RID; // ID + *i++ = obj->dev->RDA; // Data A + *i++ = obj->dev->RDB; // Data B + obj->dev->CMR = 0x04; // release receive buffer + + msg->id = x.id; + msg->len = x.dlc; + msg->format = (x.type)? CANExtended : CANStandard; + msg->type = (x.rtr)? CANRemote: CANData; + memcpy(msg->data,x.data,x.dlc); + return 1; + } + + return 0; +} + +void can_reset(can_t *obj) { + can_disable(obj); + obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset +} + +unsigned char can_rderror(can_t *obj) { + return (obj->dev->GSR >> 16) & 0xFF; +} + +unsigned char can_tderror(can_t *obj) { + return (obj->dev->GSR >> 24) & 0xFF; +} + +void can_monitor(can_t *obj, int silent) { + uint32_t mod_mask = can_disable(obj); + if (silent) { + obj->dev->MOD |= (1 << 1); + } else { + obj->dev->MOD &= ~(1 << 1); + } + if (!(mod_mask & 1)) { + can_enable(obj); + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/ethernet_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/ethernet_api.c new file mode 100644 index 0000000000..5cde358b9a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/ethernet_api.c @@ -0,0 +1,964 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> + +#include "ethernet_api.h" +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "mbed_error.h" + +#define NEW_LOGIC 0 +#define NEW_ETH_BUFFER 0 + +#if NEW_ETH_BUFFER + +#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets) +#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets) + +#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size +#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length) + +#else + +// Memfree calculation: +// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) + +// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556 +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ +#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */ +#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */ + +const int ethernet_MTU_SIZE = 0x300; + +#endif + +#define ETHERNET_ADDR_SIZE 6 + +PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +PACKED struct RX_STAT_TypeDef { /* RX Status struct */ + unsigned int Info; + unsigned int HashCRC; +}; +typedef struct RX_STAT_TypeDef RX_STAT_TypeDef; + +PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +PACKED struct TX_STAT_TypeDef { /* TX Status struct */ + unsigned int Info; +}; +typedef struct TX_STAT_TypeDef TX_STAT_TypeDef; + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | \ + RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ + + +static int phy_read(unsigned int PhyReg); +static int phy_write(unsigned int PhyReg, unsigned short Data); + +static void txdscr_init(void); +static void rxdscr_init(void); + +#if defined (__ICCARM__) +# define AHBSRAM1 +#elif defined(TOOLCHAIN_GCC_CR) +# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32"))) +#else +# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned)) +#endif + +AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG]; +AHBSRAM1 volatile RX_STAT_TypeDef rxstat[NUM_RX_FRAG]; +AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG]; +AHBSRAM1 volatile TX_STAT_TypeDef txstat[NUM_TX_FRAG]; + + +#if NEW_LOGIC +static int rx_consume_offset = -1; +static int tx_produce_offset = -1; +#else +static int send_doff = 0; +static int send_idx = -1; +static int send_size = 0; + +static int receive_soff = 0; +static int receive_idx = -1; +#endif + +static uint32_t phy_id = 0; + +static inline int rinc(int idx, int mod) { + ++idx; + idx %= mod; + return idx; +} + +//extern unsigned int SystemFrequency; +static inline unsigned int clockselect() { + if(SystemCoreClock < 10000000) { + return 1; + } else if(SystemCoreClock < 15000000) { + return 2; + } else if(SystemCoreClock < 20000000) { + return 3; + } else if(SystemCoreClock < 25000000) { + return 4; + } else if(SystemCoreClock < 35000000) { + return 5; + } else if(SystemCoreClock < 50000000) { + return 6; + } else if(SystemCoreClock < 70000000) { + return 7; + } else if(SystemCoreClock < 80000000) { + return 8; + } else if(SystemCoreClock < 90000000) { + return 9; + } else if(SystemCoreClock < 100000000) { + return 10; + } else if(SystemCoreClock < 120000000) { + return 11; + } else if(SystemCoreClock < 130000000) { + return 12; + } else if(SystemCoreClock < 140000000) { + return 13; + } else if(SystemCoreClock < 150000000) { + return 15; + } else if(SystemCoreClock < 160000000) { + return 16; + } else { + return 0; + } +} + +#ifndef min +#define min(x, y) (((x)<(y))?(x):(y)) +#endif + +/*---------------------------------------------------------------------------- + Ethernet Device initialize + *----------------------------------------------------------------------------*/ +int ethernet_init() { + int regv, tout; + char mac[ETHERNET_ADDR_SIZE]; + unsigned int clock = clockselect(); + + LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ + + LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ + LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ + LPC_IOCON->P1_1 &= ~0x07; + LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ + LPC_IOCON->P1_4 &= ~0x07; + LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ + LPC_IOCON->P1_8 &= ~0x07; + LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ + LPC_IOCON->P1_9 &= ~0x07; + LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ + LPC_IOCON->P1_10 &= ~0x07; + LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ + LPC_IOCON->P1_14 &= ~0x07; + LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ + LPC_IOCON->P1_15 &= ~0x07; + LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ + LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ + LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ + LPC_IOCON->P1_17 &= ~0x07; + LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ + + /* Reset all EMAC internal modules. */ + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | + MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; + + for(tout = 100; tout; tout--) __NOP(); /* A short delay after reset. */ + + LPC_EMAC->MAC1 = MAC1_PASS_ALL; /* Initialize MAC control registers. */ + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + LPC_EMAC->MAXF = ETH_MAX_FLEN; + LPC_EMAC->CLRT = CLRT_DEF; + LPC_EMAC->IPGR = IPGR_DEF; + + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM; /* Enable Reduced MII interface. */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ + LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ + + for(tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; + LPC_EMAC->MCMD = 0; + + LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ + + for (tout = 100; tout; tout--) __NOP(); /* A short delay */ + + LPC_EMAC->SUPP = 0; + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return -1; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) { + error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); + } + + ethernet_set_link(-1, 0); + + /* Set the Ethernet MAC Address registers */ + ethernet_address(mac); + LPC_EMAC->SA0 = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4]; + LPC_EMAC->SA1 = ((uint32_t)mac[3] << 8) | (uint32_t)mac[2]; + LPC_EMAC->SA2 = ((uint32_t)mac[1] << 8) | (uint32_t)mac[0]; + + txdscr_init(); /* initialize DMA TX Descriptor */ + rxdscr_init(); /* initialize DMA RX Descriptor */ + + LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + /* Receive Broadcast, Perfect Match Packets */ + + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ + LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ + + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->MAC1 |= MAC1_REC_EN; + +#if NEW_LOGIC + rx_consume_offset = -1; + tx_produce_offset = -1; +#else + send_doff = 0; + send_idx = -1; + send_size = 0; + + receive_soff = 0; + receive_idx = -1; +#endif + + return 0; +} + +/*---------------------------------------------------------------------------- + Ethernet Device Uninitialize + *----------------------------------------------------------------------------*/ +void ethernet_free() { + LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); + LPC_EMAC->IntClear = 0xFFFF; + + LPC_SC->PCONP &= ~0x40000000; /* Power down the EMAC controller. */ + + LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ + LPC_IOCON->P1_1 &= ~0x07; + LPC_IOCON->P1_4 &= ~0x07; + LPC_IOCON->P1_8 &= ~0x07; + LPC_IOCON->P1_9 &= ~0x07; + LPC_IOCON->P1_10 &= ~0x07; + LPC_IOCON->P1_14 &= ~0x07; + LPC_IOCON->P1_15 &= ~0x07; + LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ + LPC_IOCON->P1_17 &= ~0x07; +} + +// if(TxProduceIndex == TxConsumeIndex) buffer array is empty +// if(TxProduceIndex == TxConsumeIndex - 1) buffer is full, should not fill +// TxProduceIndex - The buffer that will/is being fileld by driver, s/w increment +// TxConsumeIndex - The buffer that will/is beign sent by hardware + +int ethernet_write(const char *data, int slen) { + +#if NEW_LOGIC + + if(tx_produce_offset < 0) { // mark as active if not already + tx_produce_offset = 0; + } + + int index = LPC_EMAC->TxProduceIndex; + + int remaining = ETH_MAX_FLEN - tx_produce_offset - 4; // bytes written plus checksum + int requested = slen; + int ncopy = min(remaining, requested); + + void *pdst = (void *)(txdesc[index].Packet + tx_produce_offset); + void *psrc = (void *)(data); + + if(ncopy > 0 ){ + if(data != NULL) { + memcpy(pdst, psrc, ncopy); + } else { + memset(pdst, 0, ncopy); + } + } + + tx_produce_offset += ncopy; + + return ncopy; + +#else + void *pdst, *psrc; + const int dlen = ETH_FRAG_SIZE; + int copy = 0; + int soff = 0; + + if(send_idx == -1) { + send_idx = LPC_EMAC->TxProduceIndex; + } + + if(slen + send_doff > ethernet_MTU_SIZE) { + return -1; + } + + do { + copy = min(slen - soff, dlen - send_doff); + pdst = (void *)(txdesc[send_idx].Packet + send_doff); + psrc = (void *)(data + soff); + if(send_doff + copy > ETH_FRAG_SIZE) { + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT); + send_idx = rinc(send_idx, NUM_TX_FRAG); + send_doff = 0; + } + + if(data != NULL) { + memcpy(pdst, psrc, copy); + } else { + memset(pdst, 0, copy); + } + + soff += copy; + send_doff += copy; + send_size += copy; + } while(soff != slen); + + return soff; +#endif +} + +int ethernet_send() { + +#if NEW_LOGIC + if(tx_produce_offset < 0) { // no buffer active + return -1; + } + + // ensure there is a link + if(!ethernet_link()) { + return -2; + } + + // we have been writing in to a buffer, so finalise it + int size = tx_produce_offset; + int index = LPC_EMAC->TxProduceIndex; + txdesc[index].Ctrl = (tx_produce_offset-1) | (TCTRL_INT | TCTRL_LAST); + + // Increment ProduceIndex to allow it to be sent + // We can only do this if the next slot is free + int next = rinc(index, NUM_TX_FRAG); + while(next == LPC_EMAC->TxConsumeIndex) { + for(int i=0; i<1000; i++) { __NOP(); } + } + + LPC_EMAC->TxProduceIndex = next; + tx_produce_offset = -1; + return size; + +#else + int s = send_size; + txdesc[send_idx].Ctrl = (send_doff-1) | (TCTRL_INT | TCTRL_LAST); + send_idx = rinc(send_idx, NUM_TX_FRAG); + LPC_EMAC->TxProduceIndex = send_idx; + send_doff = 0; + send_idx = -1; + send_size = 0; + return s; +#endif +} + +// RxConsmeIndex - The index of buffer the driver will/is reading from. Driver should inc once read +// RxProduceIndex - The index of buffer that will/is being filled by MAC. H/w will inc once rxd +// +// if(RxConsumeIndex == RxProduceIndex) buffer array is empty +// if(RxConsumeIndex == RxProduceIndex + 1) buffer array is full + +// Recevies an arrived ethernet packet. +// Receiving an ethernet packet will drop the last received ethernet packet +// and make a new ethernet packet ready to read. +// Returns size of packet, else 0 if nothing to receive + +// We read from RxConsumeIndex from position rx_consume_offset +// if rx_consume_offset < 0, then we have not recieved the RxConsumeIndex packet for reading +// rx_consume_offset = -1 // no frame +// rx_consume_offset = 0 // start of frame +// Assumption: A fragment should alway be a whole frame + +int ethernet_receive() { +#if NEW_LOGIC + + // if we are currently reading a valid RxConsume buffer, increment to the next one + if(rx_consume_offset >= 0) { + LPC_EMAC->RxConsumeIndex = rinc(LPC_EMAC->RxConsumeIndex, NUM_RX_FRAG); + } + + // if the buffer is empty, mark it as no valid buffer + if(LPC_EMAC->RxConsumeIndex == LPC_EMAC->RxProduceIndex) { + rx_consume_offset = -1; + return 0; + } + + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + rx_consume_offset = 0; + + // check if it is not marked as last or for errors + if(!(info & RINFO_LAST_FLAG) || (info & RINFO_ERR_MASK)) { + return -1; + } + + int size = (info & RINFO_SIZE) + 1; + return size - 4; // don't include checksum bytes + +#else + if(receive_idx == -1) { + receive_idx = LPC_EMAC->RxConsumeIndex; + } else { + while(!(rxstat[receive_idx].Info & RINFO_LAST_FLAG) && ((uint32_t)receive_idx != LPC_EMAC->RxProduceIndex)) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + unsigned int info = rxstat[receive_idx].Info; + int slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + + LPC_EMAC->RxConsumeIndex = receive_idx; + } + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex) { + receive_idx = -1; + return 0; + } + + return (rxstat[receive_idx].Info & RINFO_SIZE) - 3; +#endif +} + +// Read from an recevied ethernet packet. +// After receive returnd a number bigger than 0 it is +// possible to read bytes from this packet. +// Read will write up to size bytes into data. +// It is possible to use read multible times. +// Each time read will start reading after the last read byte before. + +int ethernet_read(char *data, int dlen) { +#if NEW_LOGIC + // Check we have a valid buffer to read + if(rx_consume_offset < 0) { + return 0; + } + + // Assume 1 fragment block + uint32_t info = rxstat[LPC_EMAC->RxConsumeIndex].Info; + int size = (info & RINFO_SIZE) + 1 - 4; // exclude checksum + + int remaining = size - rx_consume_offset; + int requested = dlen; + int ncopy = min(remaining, requested); + + void *psrc = (void *)(rxdesc[LPC_EMAC->RxConsumeIndex].Packet + rx_consume_offset); + void *pdst = (void *)(data); + + if(data != NULL && ncopy > 0) { + memcpy(pdst, psrc, ncopy); + } + + rx_consume_offset += ncopy; + + return ncopy; +#else + int slen; + int copy = 0; + unsigned int more; + unsigned int info; + void *pdst, *psrc; + int doff = 0; + + if((uint32_t)receive_idx == LPC_EMAC->RxProduceIndex || receive_idx == -1) { + return 0; + } + + do { + info = rxstat[receive_idx].Info; + more = !(info & RINFO_LAST_FLAG); + slen = (info & RINFO_SIZE) + 1; + + if(slen > ethernet_MTU_SIZE || (info & RINFO_ERR_MASK)) { + /* Invalid frame, ignore it and free buffer. */ + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + } else { + + copy = min(slen - receive_soff, dlen - doff); + psrc = (void *)(rxdesc[receive_idx].Packet + receive_soff); + pdst = (void *)(data + doff); + + if(data != NULL) { + /* check if Buffer available */ + memcpy(pdst, psrc, copy); + } + + receive_soff += copy; + doff += copy; + + if((more && (receive_soff == slen))) { + receive_idx = rinc(receive_idx, NUM_RX_FRAG); + receive_soff = 0; + } + } + } while(more && !(doff == dlen) && !receive_soff); + + return doff; +#endif +} + +int ethernet_link(void) { + + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } + else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MWTD = Data; + + for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + return 0; + } + } + + return -1; +} + + +static int phy_read(unsigned int PhyReg) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + LPC_EMAC->MCMD = 0; + return LPC_EMAC->MRDD; /* Return a 16-bit value. */ + } + } + + return -1; +} + + +static void txdscr_init() { + int i; + + for(i = 0; i < NUM_TX_FRAG; i++) { + txdesc[i].Packet = (uint32_t)&txbuf[i]; + txdesc[i].Ctrl = 0; + txstat[i].Info = 0; + } + + LPC_EMAC->TxDescriptor = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxStatus = (uint32_t)txstat; + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1; + + LPC_EMAC->TxProduceIndex = 0; /* Tx Descriptors Point to 0 */ +} + + +static void rxdscr_init() { + int i; + + for(i = 0; i < NUM_RX_FRAG; i++) { + rxdesc[i].Packet = (uint32_t)&rxbuf[i]; + rxdesc[i].Ctrl = RCTRL_INT | (ETH_FRAG_SIZE-1); + rxstat[i].Info = 0; + rxstat[i].HashCRC = 0; + } + + LPC_EMAC->RxDescriptor = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxStatus = (uint32_t)rxstat; + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1; + + LPC_EMAC->RxConsumeIndex = 0; /* Rx Descriptors Point to 0 */ +} + +void ethernet_address(char *mac) { + mbed_mac_address(mac); +} + +void ethernet_set_link(int speed, int duplex) { + unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + phy_data = PHY_AUTO_NEG; + } else { + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + switch(phy_id) { + case DP83848C_ID: + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } else { + LPC_EMAC->SUPP |= SUPP_SPEED; + } + break; + + case LAN8720_ID: + phy_data = phy_read(PHY_REG_SCSR); + + if (phy_data & PHY_SCSR_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_SCSR_100MBIT) { + LPC_EMAC->SUPP |= SUPP_SPEED; + } else { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } + + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c new file mode 100644 index 0000000000..ef3b3ac882 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c @@ -0,0 +1,402 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_0 , I2C_1, 3}, + {P0_27, I2C_0, 1}, + {P2_14, I2C_1, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_1 , I2C_1, 3}, + {P0_28, I2C_0, 1}, + {P2_15, I2C_1, 2}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + switch ((int)obj->i2c) { + case I2C_0: LPC_SC->PCONP |= 1 << 7; break; + case I2C_1: LPC_SC->PCONP |= 1 << 19; break; + case I2C_2: LPC_SC->PCONP |= 1 << 26; break; + } +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + MBED_ASSERT((int)obj->i2c != NC); + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); + + // OpenDrain must explicitly be enabled for p0.0 and p0.1 + if (sda == P0_0) { + pin_mode(sda, OpenDrain); + } + if (scl == P0_1) { + pin_mode(scl, OpenDrain); + } + +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if(last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + uint32_t PCLK = PeripheralClock; + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if (status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + + case 0xB8: // Slave transmit ACK + ack = 1; + break; + + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; + *((uint32_t *) addr) = mask & 0xFE; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/pwmout_api.c new file mode 100644 index 0000000000..86651ba601 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/pwmout_api.c @@ -0,0 +1,163 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +// PORT ID, PWM ID, Pin function +static const PinMap PinMap_PWM[] = { + {P1_5, PWM0_3, 3}, + {P1_20, PWM1_2, 2}, + {P1_23, PWM1_4, 2}, + {P1_24, PWM1_5, 2}, + {NC, NC, 0} +}; + +static const uint32_t PWM_mr_offset[7] = { + 0x18, 0x1C, 0x20, 0x24, 0x40, 0x44, 0x48 +}; + +#define TCR_PWM_EN 0x00000008 +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT(pwm != (PWMName)NC); + + obj->channel = pwm; + obj->pwm = LPC_PWM0; + + if (obj->channel > 6) { // PWM1 is used if pwm > 6 + obj->channel -= 6; + obj->pwm = LPC_PWM1; + } + + obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]); + + // ensure the power is on + if (obj->pwm == LPC_PWM0) { + LPC_SC->PCONP |= 1 << 5; + } else { + LPC_SC->PCONP |= 1 << 6; + } + + obj->pwm->PR = 0; // no pre-scale + + // ensure single PWM mode + obj->pwm->MCR = 1 << 1; // reset TC on match 0 + + // enable the specific PWM output + obj->pwm->PCR |= 1 << (8 + obj->channel); + + pwm_clock_mhz = PeripheralClock / 1000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // set channel match to percentage + uint32_t v = (uint32_t)((float)(obj->pwm->MR0) * value); + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == obj->pwm->MR0) { + v++; + } + + *obj->MR = v; + + // accept on next period start + obj->pwm->LER |= 1 << obj->channel; +} + +float pwmout_read(pwmout_t* obj) { + float v = (float)(*obj->MR) / (float)(obj->pwm->MR0); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t ticks = pwm_clock_mhz * us; + + // set reset + obj->pwm->TCR = TCR_RESET; + + // set the global match register + obj->pwm->MR0 = ticks; + + // Scale the pulse width to preserve the duty ratio + if (obj->pwm->MR0 > 0) { + *obj->MR = (*obj->MR * ticks) / obj->pwm->MR0; + } + + // set the channel latch to update value at next period start + obj->pwm->LER |= 1 << 0; + + // enable counter and pwm, clear reset + obj->pwm->TCR = TCR_CNT_EN | TCR_PWM_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t v = pwm_clock_mhz * us; + + // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout + if (v == obj->pwm->MR0) { + v++; + } + + // set the match register value + *obj->MR = v; + + // set the channel latch to update value at next period start + obj->pwm->LER |= 1 << obj->channel; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/serial_api.c new file mode 100644 index 0000000000..f3dd6c51b4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/serial_api.c @@ -0,0 +1,317 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +static const PinMap PinMap_UART_TX[] = { + {P0_0, UART_3, 2}, + {P0_2, UART_0, 1}, + {P0_25, UART_3, 3}, + {P4_22, UART_2, 2}, + {P5_4, UART_4, 4}, + {NC , NC , 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P0_1 , UART_3, 2}, + {P0_3 , UART_0, 1}, + {P0_26, UART_3, 3}, + {P4_23, UART_2, 2}, + {P5_3, UART_4, 4}, + {NC , NC , 0} +}; + +#define UART_NUM 5 + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + MBED_ASSERT((int)uart != NC); + + obj->uart = (LPC_UART_TypeDef *)uart; + // enable power + switch (uart) { + case UART_0: LPC_SC->PCONP |= 1 << 3; break; + case UART_1: LPC_SC->PCONP |= 1 << 4; break; + case UART_2: LPC_SC->PCONP |= 1 << 24; break; + case UART_3: LPC_SC->PCONP |= 1 << 25; break; + case UART_4: LPC_SC->PCONP |= 1 << 8; break; + } + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; + case UART_4: obj->index = 4; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + uint32_t PCLK = PeripheralClock; + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((data_bits > 4) && (data_bits < 9)); // 0: 5 data bits ... 3: 8 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven) || + (parity == ParityForced1) || (parity == ParityForced0)); + + stop_bits -= 1; + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + break; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);} +void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);} +void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);} +void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);} +void uart4_irq() {uart_irq((LPC_UART4->IIR >> 1) & 0x7, 4);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break; + case UART_4: irq_n=UART4_IRQn; vector = (uint32_t)&uart4_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/spi_api.c new file mode 100644 index 0000000000..203404d0a4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/spi_api.c @@ -0,0 +1,206 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_7 , SPI_1, 2}, + {P1_19, SPI_1, 5}, + {P1_20, SPI_0, 5}, + {P2_22, SPI_0, 2}, + {P5_2, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_1, 2}, + {P1_24, SPI_0, 5}, + {P2_27, SPI_0, 2}, + {P5_0, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_1, 2}, + {P1_23, SPI_0, 5}, + {P2_26, SPI_0, 2}, + {P5_1, SPI_2, 2}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_6 , SPI_1, 2}, + {P2_23, SPI_0, 2}, + {P5_3, SPI_2, 2}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: LPC_SC->PCONP |= 1 << 21; break; + case SPI_1: LPC_SC->PCONP |= 1 << 10; break; + case SPI_2: LPC_SC->PCONP |= 1 << 20; break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT(((bits >= 4) && (bits <= 16)) && ((mode >= 0) && (mode <= 3))); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = PeripheralClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/analogout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/analogout_api.c new file mode 100644 index 0000000000..e694c2fcfb --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/analogout_api.c @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogout_api.h" +#include "cmsis.h" +#include "pinmap.h" + +static const PinMap PinMap_DAC[] = { + {P0_26, DAC_0, 2}, + {NC , NC , 0} +}; + +void analogout_init(dac_t *obj, PinName pin) { + obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); + MBED_ASSERT(obj->dac != (DACName)NC); + + // DAC enable bit must be set + LPC_IOCON->P0_26 |= (1 << 16); // DACEN + + // map out (must be done before accessing registers) + pinmap_pinout(pin, PinMap_DAC); + + analogout_write_u16(obj, 0); +} + +void analogout_free(dac_t *obj) {} + +static inline void dac_write(int value) { + value &= 0x3FF; // 10-bit + + // Set the DAC output + LPC_DAC->CR = (0 << 16) // bias = 0 + | (value << 6); +} + +static inline int dac_read() { + return (LPC_DAC->CR >> 6) & 0x3FF; +} + +void analogout_write(dac_t *obj, float value) { + if (value < 0.0f) { + dac_write(0); + } else if (value > 1.0f) { + dac_write(0x3FF); + } else { + dac_write(value * (float)0x3FF); + } +} + +void analogout_write_u16(dac_t *obj, uint16_t value) { + dac_write(value >> 6); // 10-bit +} + +float analogout_read(dac_t *obj) { + uint32_t value = dac_read(); + return (float)value * (1.0f / (float)0x3FF); +} + +uint16_t analogout_read_u16(dac_t *obj) { + uint32_t value = dac_read(); // 10-bit + return (value << 6) | ((value >> 4) & 0x003F); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/device.h new file mode 100644 index 0000000000..c9bd8d0d0d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 1 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_api.c new file mode 100644 index 0000000000..5f2f3d4c2b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_api.c @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + pin_function(pin, 0); + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *) ((int)(LPC_GPIO0_BASE+pin) & ~0x1F); + + obj->reg_set = &port_reg->SET; + obj->reg_clr = &port_reg->CLR; + obj->reg_in = &port_reg->PIN; + obj->reg_dir = &port_reg->DIR; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_irq_api.c new file mode 100644 index 0000000000..97a79de6d5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_irq_api.c @@ -0,0 +1,174 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include "cmsis.h" + +#define CHANNEL_NUM 64 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(void) { + // Read in all current interrupt registers. We do this once as the + // GPIO interrupt registers are on the APB bus, and this is slow. + uint32_t rise0 = LPC_GPIOINT->IO0IntStatR; + uint32_t fall0 = LPC_GPIOINT->IO0IntStatF; + uint32_t rise2 = LPC_GPIOINT->IO2IntStatR; + uint32_t fall2 = LPC_GPIOINT->IO2IntStatF; + + uint8_t bitloc; + + // Continue as long as there are interrupts pending + while(rise0 > 0) { + // CLZ returns number of leading zeros, 31 minus that is location of + // first pending interrupt + bitloc = 31 - __CLZ(rise0); + if (channel_ids[bitloc] != 0) + irq_handler(channel_ids[bitloc], IRQ_RISE); //Run that interrupt + + // Both clear the interrupt with clear register, and remove it from + // our local copy of the interrupt pending register + LPC_GPIOINT->IO0IntClr = 1 << bitloc; + rise0 -= 1<<bitloc; + } + + // Continue as long as there are interrupts pending + while(fall0 > 0) { + // CLZ returns number of leading zeros, 31 minus that is location of + // first pending interrupt + bitloc = 31 - __CLZ(fall0); + if (channel_ids[bitloc] != 0) + irq_handler(channel_ids[bitloc], IRQ_FALL); //Run that interrupt + + // Both clear the interrupt with clear register, and remove it from + // our local copy of the interrupt pending register + LPC_GPIOINT->IO0IntClr = 1 << bitloc; + fall0 -= 1<<bitloc; + } + + // Same for port 2 + + // Continue as long as there are interrupts pending + while(rise2 > 0) { + // CLZ returns number of leading zeros, 31 minus that is location of + // first pending interrupt + bitloc = 31 - __CLZ(rise2); + if (channel_ids[bitloc+32] != 0) + irq_handler(channel_ids[bitloc+32], IRQ_RISE); //Run that interrupt + + // Both clear the interrupt with clear register, and remove it from + // our local copy of the interrupt pending register + LPC_GPIOINT->IO2IntClr = 1 << bitloc; + rise2 -= 1<<bitloc; + } + + // Continue as long as there are interrupts pending + while(fall2 > 0) { + // CLZ returns number of leading zeros, 31 minus that is location of + // first pending interrupt + bitloc = 31 - __CLZ(fall2); + if (channel_ids[bitloc+32] != 0) + irq_handler(channel_ids[bitloc+32], IRQ_FALL); //Run that interrupt + + // Both clear the interrupt with clear register, and remove it from + // our local copy of the interrupt pending register + LPC_GPIOINT->IO2IntClr = 1 << bitloc; + fall2 -= 1<<bitloc; + } +} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + obj->port = ((int)(LPC_GPIO0_BASE+pin) & ~0x1F); + obj->pin = (int)pin % 32; + + // Interrupts available only on GPIO0 and GPIO2 + if (obj->port != LPC_GPIO0_BASE && obj->port != LPC_GPIO2_BASE) { + error("pins on this port cannot generate interrupts"); + } + + // put us in the interrupt table + int index = (obj->port == LPC_GPIO0_BASE) ? obj->pin : obj->pin + 32; + channel_ids[index] = id; + obj->ch = index; + + NVIC_SetVector(GPIO_IRQn, (uint32_t)handle_interrupt_in); + NVIC_EnableIRQ(GPIO_IRQn); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + // ensure nothing is pending + switch (obj->port) { + case LPC_GPIO0_BASE: LPC_GPIOINT->IO0IntClr = 1 << obj->pin; break; + case LPC_GPIO2_BASE: LPC_GPIOINT->IO2IntClr = 1 << obj->pin; break; + } + + // enable the pin interrupt + if (event == IRQ_RISE) { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnR &= ~(1 << obj->pin); + } + break; + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnR |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnR &= ~(1 << obj->pin); + } + break; + } + } else { + switch (obj->port) { + case LPC_GPIO0_BASE: + if (enable) { + LPC_GPIOINT->IO0IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO0IntEnF &= ~(1 << obj->pin); + } + break; + case LPC_GPIO2_BASE: + if (enable) { + LPC_GPIOINT->IO2IntEnF |= 1 << obj->pin; + } else { + LPC_GPIOINT->IO2IntEnF &= ~(1 << obj->pin); + } + break; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ(GPIO_IRQn); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ(GPIO_IRQn); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/objects.h new file mode 100644 index 0000000000..e7227ba6e4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/objects.h @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t port; + uint32_t pin; + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + __IO uint32_t *MR; + LPC_PWM_TypeDef *pwm; + uint32_t channel; +}; + +struct serial_s { + LPC_UART_TypeDef *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct dac_s { + DACName dac; +}; + +struct can_s { + LPC_CAN_TypeDef *dev; + int index; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SSP_TypeDef *spi; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/pinmap.c new file mode 100644 index 0000000000..c72389d666 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/pinmap.c @@ -0,0 +1,45 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + // drain + tmp &= ~(0x1 << 10); + tmp |= drain << 10; + + *reg = tmp; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/port_api.c new file mode 100644 index 0000000000..8fe23e6dd0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/port_api.c @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + + +PinName port_pin(PortName port, int pin_n) { + return (PinName)(((port << PORT_SHIFT) | pin_n)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20)); + + port_reg->MASK = ~mask; + + obj->reg_out = &port_reg->PIN; + obj->reg_in = &port_reg->PIN; + obj->reg_dir = &port_reg->DIR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) { + return (*obj->reg_in & obj->mask); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/rtc_api.c new file mode 100644 index 0000000000..c75bf263d8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/rtc_api.c @@ -0,0 +1,112 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "rtc_api.h" + +// ensure rtc is running (unchanged if already running) + +/* Setup the RTC based on a time structure, ensuring RTC is enabled + * + * Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock + * - We want to use the 32khz clock, allowing for sleep mode + * + * Most registers are not changed by a Reset + * - We must initialize these registers between power-on and setting the RTC into operation + + * Clock Control Register + * RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled + * RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset + * + * The RTC may already be running, so we should set it up + * without impacting if it is the case + */ +void rtc_init(void) { + LPC_SC->PCONP |= 0x200; // Ensure power is on + LPC_RTC->CCR = 0x00; + + LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled +} + +void rtc_free(void) { + // [TODO] +} + +/* + * Little check routine to see if the RTC has been enabled + * + * Clock Control Register + * RTC_CCR[0] : 0 = Disabled, 1 = Enabled + * + */ +int rtc_isenabled(void) { + return(((LPC_RTC->CCR) & 0x01) != 0); +} + +/* + * RTC Registers + * RTC_SEC Seconds 0-59 + * RTC_MIN Minutes 0-59 + * RTC_HOUR Hour 0-23 + * RTC_DOM Day of Month 1-28..31 + * RTC_DOW Day of Week 0-6 + * RTC_DOY Day of Year 1-365 + * RTC_MONTH Month 1-12 + * RTC_YEAR Year 0-4095 + * + * struct tm + * tm_sec seconds after the minute 0-61 + * tm_min minutes after the hour 0-59 + * tm_hour hours since midnight 0-23 + * tm_mday day of the month 1-31 + * tm_mon months since January 0-11 + * tm_year years since 1900 + * tm_wday days since Sunday 0-6 + * tm_yday days since January 1 0-365 + * tm_isdst Daylight Saving Time flag + */ +time_t rtc_read(void) { + // Setup a tm structure based on the RTC + struct tm timeinfo; + timeinfo.tm_sec = LPC_RTC->SEC; + timeinfo.tm_min = LPC_RTC->MIN; + timeinfo.tm_hour = LPC_RTC->HOUR; + timeinfo.tm_mday = LPC_RTC->DOM; + timeinfo.tm_mon = LPC_RTC->MONTH - 1; + timeinfo.tm_year = LPC_RTC->YEAR - 1900; + + // Convert to timestamp + time_t t = mktime(&timeinfo); + + return t; +} + +void rtc_write(time_t t) { + // Convert the time in to a tm + struct tm *timeinfo = localtime(&t); + + // Pause clock, and clear counter register (clears us count) + LPC_RTC->CCR |= 2; + + // Set the RTC + LPC_RTC->SEC = timeinfo->tm_sec; + LPC_RTC->MIN = timeinfo->tm_min; + LPC_RTC->HOUR = timeinfo->tm_hour; + LPC_RTC->DOM = timeinfo->tm_mday; + LPC_RTC->MONTH = timeinfo->tm_mon + 1; + LPC_RTC->YEAR = timeinfo->tm_year + 1900; + + // Restart clock + LPC_RTC->CCR &= ~((uint32_t)2); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/sleep.c new file mode 100644 index 0000000000..ac48218690 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/sleep.c @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + LPC_SC->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +/* +* The mbed lpc1768 does not support the deepsleep mode +* as a debugger is connected to it (the mbed interface). +* +* As mentionned in an application note from NXP: +* +* http://www.po-star.com/public/uploads/20120319123122_141.pdf +* +* {{{ +* The user should be aware of certain limitations during debugging. +* The most important is that, due to limitations of the Cortex-M3 +* integration, the LPC17xx cannot wake up in the usual manner from +* Deep Sleep and Power-down modes. It is recommended not to use these +* modes during debug. Once an application is downloaded via JTAG/SWD +* interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example) +* should be removed from the target board, and thereafter, power cycle +* the LPC17xx to allow wake-up from deep sleep and power-down modes +* }}} +* +* As the interface firmware does not reset the target when a +* mbed_interface_disconnect() semihosting call is made, the +* core cannot wake-up from deepsleep. +* +* We treat a deepsleep() as a normal sleep(). +*/ +void deepsleep(void) { + sleep(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/us_ticker.c new file mode 100644 index 0000000000..c7075b3c88 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/us_ticker.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TIM_TypeDef *)LPC_TIM3_BASE) +#define US_TICKER_TIMER_IRQn TIMER3_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SC->PCONP |= 1 << 23; // Clock TIMER_3 + + US_TICKER_TIMER->CTCR = 0x0; // timer mode + uint32_t PCLK = PeripheralClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR0 = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PeripheralNames.h new file mode 100644 index 0000000000..cba83f952d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PeripheralNames.h @@ -0,0 +1,135 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_USART0_BASE, + UART_1 = (int)LPC_UART1_BASE, + UART_2 = (int)LPC_USART2_BASE, + UART_3 = (int)LPC_USART3_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7, + ADC1_0, + ADC1_1, + ADC1_2, + ADC1_3, + ADC1_4, + ADC1_5, + ADC1_6, + ADC1_7 +} ADCName; + +typedef enum { + DAC_0 = 0 +} DACName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + I2C_0 = (int)LPC_I2C0_BASE, + I2C_1 = (int)LPC_I2C1_BASE +} I2CName; + +typedef enum { + PWM_0, + PWM_1, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11, + PWM_12, + PWM_13, + PWM_14, + PWM_15 +} PWMName; + +typedef enum { + CAN_0 = (int)LPC_C_CAN0_BASE, + CAN_1 = (int)LPC_C_CAN1_BASE +} CANName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_2 + +// Default peripherals +#define MBED_SPI0 SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SSEL +#define MBED_SPI1 SPI1_MOSI, SPI1_MISO, SPI1_SCK, SPI1_SSEL + +#define MBED_UART0 UART0_TX, UART0_RX +#define MBED_UART1 UART1_TX, UART1_RX +#define MBED_UART2 UART2_TX, UART2_RX +#define MBED_UART3 UART3_TX, UART3_RX +#define MBED_UARTUSB USBTX, USBRX + +#define COM1 MBED_UART0 +#define COM2 MBED_UART1 +#define COM3 MBED_UART2 +#define COM4 MBED_UART3 + +#define MBED_I2C0 I2C0_SDA, I2C0_SCL +#define MBED_I2C1 I2C1_SDA, I2C1_SCL + +#define MBED_CAN0 p30, p29 + +#define MBED_ANALOGOUT0 DAC0 + +#define MBED_ANALOGIN0 ADC0 +#define MBED_ANALOGIN1 ADC1 +#define MBED_ANALOGIN2 ADC2 +#define MBED_ANALOGIN3 ADC3 +#define MBED_ANALOGIN4 ADC4 +#define MBED_ANALOGIN5 ADC5 +#define MBED_ANALOGIN6 ADC6 +#define MBED_ANALOGIN7 ADC7 + +#define MBED_PWMOUT0 p26 +#define MBED_PWMOUT1 p25 +#define MBED_PWMOUT2 p24 +#define MBED_PWMOUT3 p23 +#define MBED_PWMOUT4 p22 +#define MBED_PWMOUT5 p21 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PortNames.h new file mode 100644 index 0000000000..1c2413c94d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/PortNames.h @@ -0,0 +1,37 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3, + Port4 = 4, + Port5 = 5, + Port6 = 6, + Port7 = 7 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/README.txt b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/README.txt new file mode 100644 index 0000000000..18281032a6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/README.txt @@ -0,0 +1,81 @@ +mbed port to NXP LPC43xx +======================== +Updated: 07/11/14 + +The NXP LPC43xx microcontrollers includes multiple Cortex-M cores in a single +microcontroller package. This port allows mbed developers to take advantage +of the LPC43xx in their application using APIs that they are familiar with. +Some of the key features of the LPC43xx include: + +* Dual core ARM Cortex-M4/M0 both capable of up to 204 MHz +* Up to 264 KB SRAM, 1 MB internal flash +* Two High-speed USB 2.0 interfaces +* Ethernet MAC +* LCD interface +* Quad-SPI Flash Interface (SPIFI) +* State Configurable Timer (SCT) +* Serial GPIO (SGPIO) +* Up to 164 GPIO + +The NXP LPC18xx is a single core Cortex-M3 implementation that is compatible +with the LPC43XX for cost-sensitive applications not requiring multiple cores. + +mbed port to the LPC43XX - Micromint USA <support@micromint.com> + +Compatibility +------------- +* This port has been tested with the following boards: + Board MCU RAM/Flash + Micromint Bambino 200 LPC4330 264K SRAM/4 MB SPIFI flash + Micromint Bambino 200E LPC4330 264K SRAM/8 MB SPIFI flash + Micromint Bambino 210 LPC4330 264K SRAM/4 MB SPIFI flash + Micromint Bambino 210E LPC4330 264K SRAM/8 MB SPIFI flash + +* CMSIS-DAP debugging is implemented with the Micromint Bambino 210/210E. + To debug other LPC4330 targets, use a JTAG. The NXP DFU tool can be used + for flash programming. + +* This port should support NXP LPC43XX and LPC18XX variants with a single + codebase. The core declaration specifies the binaries to be built: + mbed define CMSIS define MCU Target + __CORTEX_M4 CORE_M4 LPC43xx Cortex-M4 + __CORTEX_M0 CORE_M0 LPC43xx Cortex-M0 + __CORTEX_M3 CORE_M3 LPC18xx Cortex-M3 + These MCUs all share the peripheral IP, common driver code is feasible. + Yet each variant can have different memory segments, peripherals, etc. + Plus, each board design can integrate different external peripherals + or interfaces. A future release of the mbed SDK and its build tools will + support specifying the target board when building binaries. At this time + building binaries for different targets requires an external project or + Makefile. + +* No testing has been done with LPC18xx hardware. + +Notes +----- +* On the LPC43xx the hardware pin name and the GPIO pin name are not the same, + requiring different offsets for the SCU and GPIO registers. To simplify logic + the pin identifier encodes the offsets. Macros are used for decoding. + For example, P6_11 corresponds to GPIO3[7] and is encoded/decoded as follows: + + P6_11 = MBED_PIN(0x06, 11, 3, 7) = 0x032C0067 + + MBED_SCU_REG(P6_11) = 0x4008632C MBED_GPIO_PORT(P6_11) = 3 + MBED_GPIO_REG(P6_11) = 0x400F4000 MBED_GPIO_PIN(P6_11) = 7 + +* Pin names use multiple aliases to support Arduino naming conventions as well + as others. For example, to use pin p21 on the Bambino 210 from mbed applications + the following aliases are equivalent: p21, D0, UART0_TX, COM1_TX, P6_4. + See the board pinout graphic and the PinNames.h for available aliases. + +* The LPC43xx implements GPIO pin and group interrupts. Any pin in the 8 32-bit + GPIO ports can interrupt (LPC4350 supports up to 164). On group interrupts a + pin can only interrupt on the rising or falling edge, not both as required + by the mbed InterruptIn class. Also, group interrupts can't be cleared + individually. This implementation uses pin interrupts (8 on M4/M3, 1 on M0). + A future implementation may provide group interrupt support. + +* The LPC3xx PWM driver uses the State Configurable Timer (SCT). The default + build (PWM_MODE=0) uses the unified 32-bit times. Applications that use PWM + and require other SCT uses can use the dual 16-bit mode by changing PWM_MODE + when building the library. diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/PinNames.h new file mode 100644 index 0000000000..864703597a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/PinNames.h @@ -0,0 +1,705 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 +#define NO_GPIO 15 + +// On the LPC43xx the MCU pin name and the GPIO pin name are not the same. +// Encode SCU and GPIO offsets as a pin identifier +#define MBED_PIN(group, num, port, pin) ((SCU_OFF(group,num) << 16) + GPIO_OFF(port,pin)) + +// Decode pin identifier into register, port and pin values +#define MBED_SCU_REG(MBED_PIN) (LPC_SCU_BASE + (MBED_PIN >> 16)) +#define MBED_GPIO_REG(MBED_PIN) (LPC_GPIO_PORT_BASE + 0x2000 + ((MBED_PIN >> (PORT_SHIFT - 2)) & 0x0000003C)) +#define MBED_GPIO_PORT(MBED_PIN) ((MBED_PIN >> PORT_SHIFT) & 0x0000000F) +#define MBED_GPIO_PIN(MBED_PIN) (MBED_PIN & 0x0000001F) + +typedef enum { + // LPC43xx Pin Names + // All pins defined. Package determines which are available. + // LBGA256 TFBGA180 TFBGA100 LQFP208 LQFP144 + // GPIO0 [15:0] [15:0] [15:6] [15:0] [15:0] + // [4:0] + // GPIO1 [15:0] [15:0] [15:0] [15:0] [15:0] + // GPIO2 [15:0] [15:0] [15:0] [15:0] + // GPIO3 [15:0] [15:0] [7] [15:0] [15:0] + // [5:3] + // [1:0] + // GPIO4 [15:0] [15:0] [15:0] [11] + // GPIO5 [26:0] [26:0] [11:0] [25:0] [18] + // [16:0] + // GPIO6 [30:0] [30:28] [30:20] + // [26:25] [5:0] + // GPIO7 [25:0] [4:0] [25:23] + // [21:17] + // --- --- --- --- --- + // Total 164 117 49 131 83 + + // Groups 0x00 - 0x0F : Digital pins + // * Digital pins support up to 8 functions + // Use func=0 for GPIO0-GPIO4, func=4 for GPIO5-GPIO7 + // * High-drive pins default to 4 mA but can support 8, 14, 20 mA + P0_0 = MBED_PIN(0x00, 0, 0, 0), // GPIO0[0] + P0_1 = MBED_PIN(0x00, 1, 0, 1), // GPIO0[1] + + P1_0 = MBED_PIN(0x01, 0, 0, 4), // GPIO0[4] + P1_1 = MBED_PIN(0x01, 1, 0, 8), // GPIO0[8] + P1_2 = MBED_PIN(0x01, 2, 0, 9), // GPIO0[9] + P1_3 = MBED_PIN(0x01, 3, 0, 10), // GPIO0[10] + P1_4 = MBED_PIN(0x01, 4, 0, 11), // GPIO0[11] + P1_5 = MBED_PIN(0x01, 5, 1, 8), // GPIO1[8] + P1_6 = MBED_PIN(0x01, 6, 1, 9), // GPIO1[9] + P1_7 = MBED_PIN(0x01, 7, 1, 0), // GPIO1[0] + P1_8 = MBED_PIN(0x01, 8, 1, 1), // GPIO1[1] + P1_9 = MBED_PIN(0x01, 9, 1, 2), // GPIO1[2] + P1_10 = MBED_PIN(0x01, 10, 1, 3), // GPIO1[3] + P1_11 = MBED_PIN(0x01, 11, 1, 4), // GPIO1[4] + P1_12 = MBED_PIN(0x01, 12, 1, 5), // GPIO1[5] + P1_13 = MBED_PIN(0x01, 13, 1, 6), // GPIO1[6] + P1_14 = MBED_PIN(0x01, 14, 1, 7), // GPIO1[7] + P1_15 = MBED_PIN(0x01, 15, 0, 2), // GPIO0[2] + P1_16 = MBED_PIN(0x01, 16, 0, 3), // GPIO0[3] + P1_17 = MBED_PIN(0x01, 17, 0, 12), // GPIO0[12] high-drive + P1_18 = MBED_PIN(0x01, 18, 0, 13), // GPIO0[13] + P1_19 = MBED_PIN(0x01, 19, NO_GPIO, 0), + P1_20 = MBED_PIN(0x01, 20, 0, 15), // GPIO0[15] + + P2_0 = MBED_PIN(0x02, 0, 5, 0), // GPIO5[0] + P2_1 = MBED_PIN(0x02, 1, 5, 1), // GPIO5[1] + P2_2 = MBED_PIN(0x02, 2, 5, 2), // GPIO5[2] + P2_3 = MBED_PIN(0x02, 3, 5, 3), // GPIO5[3] high-drive + P2_4 = MBED_PIN(0x02, 4, 5, 4), // GPIO5[4] high-drive + P2_5 = MBED_PIN(0x02, 5, 5, 5), // GPIO5[5] high-drive + P2_6 = MBED_PIN(0x02, 6, 5, 6), // GPIO5[6] + P2_7 = MBED_PIN(0x02, 7, 0, 7), // GPIO0[7] + P2_8 = MBED_PIN(0x02, 8, 5, 7), // GPIO5[7] + P2_9 = MBED_PIN(0x02, 9, 1, 10), // GPIO1[10] + P2_10 = MBED_PIN(0x02, 10, 0, 14), // GPIO0[14] + P2_11 = MBED_PIN(0x02, 11, 1, 11), // GPIO1[11] + P2_12 = MBED_PIN(0x02, 12, 1, 12), // GPIO1[12] + P2_13 = MBED_PIN(0x02, 13, 1, 13), // GPIO1[13] + + P3_0 = MBED_PIN(0x03, 0, NO_GPIO, 0), + P3_1 = MBED_PIN(0x03, 1, 5, 8), // GPIO5[8] + P3_2 = MBED_PIN(0x03, 2, 5, 9), // GPIO5[9] + P3_3 = MBED_PIN(0x03, 3, NO_GPIO, 0), + P3_4 = MBED_PIN(0x03, 4, 1, 14), // GPIO1[14] + P3_5 = MBED_PIN(0x03, 5, 1, 15), // GPIO1[15] + P3_6 = MBED_PIN(0x03, 6, 0, 6), // GPIO0[6] + P3_7 = MBED_PIN(0x03, 7, 5, 10), // GPIO5[10] + P3_8 = MBED_PIN(0x03, 8, 5, 11), // GPIO5[11] + + P4_0 = MBED_PIN(0x04, 0, 2, 0), // GPIO2[0] + P4_1 = MBED_PIN(0x04, 1, 2, 1), // GPIO2[1] + P4_2 = MBED_PIN(0x04, 2, 2, 2), // GPIO2[2] + P4_3 = MBED_PIN(0x04, 3, 2, 3), // GPIO2[3] + P4_4 = MBED_PIN(0x04, 4, 2, 4), // GPIO2[4] + P4_5 = MBED_PIN(0x04, 5, 2, 5), // GPIO2[5] + P4_6 = MBED_PIN(0x04, 6, 2, 6), // GPIO2[6] + P4_7 = MBED_PIN(0x04, 7, NO_GPIO, 0), + P4_8 = MBED_PIN(0x04, 8, 5, 12), // GPIO5[12] + P4_9 = MBED_PIN(0x04, 9, 5, 13), // GPIO5[13] + P4_10 = MBED_PIN(0x04, 10, 5, 14), // GPIO5[14] + + P5_0 = MBED_PIN(0x05, 0, 2, 9), // GPIO2[9] + P5_1 = MBED_PIN(0x05, 1, 2, 10), // GPIO2[10] + P5_2 = MBED_PIN(0x05, 2, 2, 11), // GPIO2[11] + P5_3 = MBED_PIN(0x05, 3, 2, 12), // GPIO2[12] + P5_4 = MBED_PIN(0x05, 4, 2, 13), // GPIO2[13] + P5_5 = MBED_PIN(0x05, 5, 2, 14), // GPIO2[14] + P5_6 = MBED_PIN(0x05, 6, 2, 15), // GPIO2[15] + P5_7 = MBED_PIN(0x05, 7, 2, 7), // GPIO2[7] + + P6_0 = MBED_PIN(0x06, 0, NO_GPIO, 0), + P6_1 = MBED_PIN(0x06, 1, 3, 0), // GPIO3[0] + P6_2 = MBED_PIN(0x06, 2, 3, 1), // GPIO3[1] + P6_3 = MBED_PIN(0x06, 3, 3, 2), // GPIO3[2] + P6_4 = MBED_PIN(0x06, 4, 3, 3), // GPIO3[3] + P6_5 = MBED_PIN(0x06, 5, 3, 4), // GPIO3[4] + P6_6 = MBED_PIN(0x06, 6, 0, 5), // GPIO0[5] + P6_7 = MBED_PIN(0x06, 7, 5, 15), // GPIO5[15] + P6_8 = MBED_PIN(0x06, 8, 5, 16), // GPIO5[16] + P6_9 = MBED_PIN(0x06, 9, 3, 5), // GPIO3[5] + P6_10 = MBED_PIN(0x06, 10, 3, 6), // GPIO3[6] + P6_11 = MBED_PIN(0x06, 11, 3, 7), // GPIO3[7] + P6_12 = MBED_PIN(0x06, 12, 2, 8), // GPIO2[8] + + P7_0 = MBED_PIN(0x07, 0, 3, 8), // GPIO3[8] + P7_1 = MBED_PIN(0x07, 1, 3, 9), // GPIO3[9] + P7_2 = MBED_PIN(0x07, 2, 3, 10), // GPIO3[10] + P7_3 = MBED_PIN(0x07, 3, 3, 11), // GPIO3[11] + P7_4 = MBED_PIN(0x07, 4, 3, 12), // GPIO3[12] + P7_5 = MBED_PIN(0x07, 5, 3, 13), // GPIO3[13] + P7_6 = MBED_PIN(0x07, 6, 3, 14), // GPIO3[14] + P7_7 = MBED_PIN(0x07, 7, 3, 15), // GPIO3[15] + + P8_0 = MBED_PIN(0x08, 8, 4, 0), // GPIO4[0] high-drive + P8_1 = MBED_PIN(0x09, 0, 4, 1), // GPIO4[1] high-drive + P8_2 = MBED_PIN(0x09, 1, 4, 2), // GPIO4[2] high-drive + P8_3 = MBED_PIN(0x09, 2, 4, 3), // GPIO4[3] + P8_4 = MBED_PIN(0x08, 4, 4, 4), // GPIO4[4] + P8_5 = MBED_PIN(0x08, 5, 4, 5), // GPIO4[5] + P8_6 = MBED_PIN(0x08, 6, 4, 6), // GPIO4[6] + P8_7 = MBED_PIN(0x08, 7, 4, 7), // GPIO4[7] + P8_8 = MBED_PIN(0x08, 8, NO_GPIO, 0), + + P9_0 = MBED_PIN(0x09, 0, 4, 12), // GPIO4[12] + P9_1 = MBED_PIN(0x09, 1, 4, 13), // GPIO4[13] + P9_2 = MBED_PIN(0x09, 2, 4, 14), // GPIO4[14] + P9_3 = MBED_PIN(0x09, 3, 4, 15), // GPIO4[15] + P9_4 = MBED_PIN(0x09, 4, 5, 17), // GPIO5[17] + P9_5 = MBED_PIN(0x09, 5, 5, 18), // GPIO5[18] + P9_6 = MBED_PIN(0x09, 6, 4, 11), // GPIO4[11] + + PA_0 = MBED_PIN(0x0A, 0, NO_GPIO, 0), + PA_1 = MBED_PIN(0x0A, 1, 4, 8), // GPIO4[8] high-drive + PA_2 = MBED_PIN(0x0A, 2, 4, 9), // GPIO4[9] high-drive + PA_3 = MBED_PIN(0x0A, 3, 4, 10), // GPIO4[10] high-drive + PA_4 = MBED_PIN(0x0A, 4, 5, 19), // GPIO5[19] + + PB_0 = MBED_PIN(0x0B, 0, 5, 20), // GPIO5[20] + PB_1 = MBED_PIN(0x0B, 1, 5, 21), // GPIO5[21] + PB_2 = MBED_PIN(0x0B, 2, 5, 22), // GPIO5[22] + PB_3 = MBED_PIN(0x0B, 3, 5, 23), // GPIO5[23] + PB_4 = MBED_PIN(0x0B, 4, 5, 24), // GPIO5[24] + PB_5 = MBED_PIN(0x0B, 5, 5, 25), // GPIO5[25] + PB_6 = MBED_PIN(0x0B, 6, 5, 26), // GPIO5[26] + + PC_0 = MBED_PIN(0x0C, 0, NO_GPIO, 0), + PC_1 = MBED_PIN(0x0C, 1, 6, 0), // GPIO6[0] + PC_2 = MBED_PIN(0x0C, 2, 6, 1), // GPIO6[1] + PC_3 = MBED_PIN(0x0C, 3, 6, 2), // GPIO6[2] + PC_4 = MBED_PIN(0x0C, 4, 6, 3), // GPIO6[3] + PC_5 = MBED_PIN(0x0C, 5, 6, 4), // GPIO6[4] + PC_6 = MBED_PIN(0x0C, 6, 6, 5), // GPIO6[5] + PC_7 = MBED_PIN(0x0C, 7, 6, 6), // GPIO6[6] + PC_8 = MBED_PIN(0x0C, 8, 6, 7), // GPIO6[7] + PC_9 = MBED_PIN(0x0C, 9, 6, 8), // GPIO6[8] + PC_10 = MBED_PIN(0x0C, 10, 6, 9), // GPIO6[9] + PC_11 = MBED_PIN(0x0C, 11, 6, 10), // GPIO6[10] + PC_12 = MBED_PIN(0x0C, 12, 6, 11), // GPIO6[11] + PC_13 = MBED_PIN(0x0C, 13, 6, 12), // GPIO6[12] + PC_14 = MBED_PIN(0x0C, 14, 6, 13), // GPIO6[13] + + PD_0 = MBED_PIN(0x0D, 0, 6, 14), // GPIO6[14] + PD_1 = MBED_PIN(0x0D, 1, 6, 15), // GPIO6[15] + PD_2 = MBED_PIN(0x0D, 2, 6, 16), // GPIO6[16] + PD_3 = MBED_PIN(0x0D, 3, 6, 17), // GPIO6[17] + PD_4 = MBED_PIN(0x0D, 4, 6, 18), // GPIO6[18] + PD_5 = MBED_PIN(0x0D, 5, 6, 19), // GPIO6[19] + PD_6 = MBED_PIN(0x0D, 6, 6, 20), // GPIO6[20] + PD_7 = MBED_PIN(0x0D, 7, 6, 21), // GPIO6[21] + PD_8 = MBED_PIN(0x0D, 8, 6, 22), // GPIO6[22] + PD_9 = MBED_PIN(0x0D, 9, 6, 23), // GPIO6[23] + PD_10 = MBED_PIN(0x0D, 10, 6, 24), // GPIO6[24] + PD_11 = MBED_PIN(0x0D, 11, 6, 25), // GPIO6[25] + PD_12 = MBED_PIN(0x0D, 12, 6, 26), // GPIO6[26] + PD_13 = MBED_PIN(0x0D, 13, 6, 27), // GPIO6[27] + PD_14 = MBED_PIN(0x0D, 14, 6, 28), // GPIO6[28] + PD_15 = MBED_PIN(0x0D, 15, 6, 29), // GPIO6[29] + PD_16 = MBED_PIN(0x0D, 16, 6, 30), // GPIO6[30] + + PE_0 = MBED_PIN(0x0E, 0, 7, 0), // GPIO7[0] + PE_1 = MBED_PIN(0x0E, 1, 7, 1), // GPIO7[1] + PE_2 = MBED_PIN(0x0E, 2, 7, 2), // GPIO7[2] + PE_3 = MBED_PIN(0x0E, 3, 7, 3), // GPIO7[3] + PE_4 = MBED_PIN(0x0E, 4, 7, 4), // GPIO7[4] + PE_5 = MBED_PIN(0x0E, 5, 7, 5), // GPIO7[5] + PE_6 = MBED_PIN(0x0E, 6, 7, 6), // GPIO7[6] + PE_7 = MBED_PIN(0x0E, 7, 7, 7), // GPIO7[7] + PE_8 = MBED_PIN(0x0E, 8, 7, 8), // GPIO7[8] + PE_9 = MBED_PIN(0x0E, 9, 7, 9), // GPIO7[9] + PE_10 = MBED_PIN(0x0E, 10, 7, 10), // GPIO7[10] + PE_11 = MBED_PIN(0x0E, 11, 7, 11), // GPIO7[11] + PE_12 = MBED_PIN(0x0E, 12, 7, 12), // GPIO7[12] + PE_13 = MBED_PIN(0x0E, 13, 7, 13), // GPIO7[13] + PE_14 = MBED_PIN(0x0E, 14, 7, 14), // GPIO7[14] + PE_15 = MBED_PIN(0x0E, 15, 7, 15), // GPIO7[15] + + PF_0 = MBED_PIN(0x0F, 0, NO_GPIO, 0), + PF_1 = MBED_PIN(0x0F, 1, 7, 16), // GPIO7[16] + PF_2 = MBED_PIN(0x0F, 2, 7, 17), // GPIO7[17] + PF_3 = MBED_PIN(0x0F, 3, 7, 18), // GPIO7[18] + PF_4 = MBED_PIN(0x0F, 4, NO_GPIO, 0), + PF_5 = MBED_PIN(0x0F, 5, 7, 19), // GPIO7[19] + PF_6 = MBED_PIN(0x0F, 6, 7, 20), // GPIO7[20] + PF_7 = MBED_PIN(0x0F, 7, 7, 21), // GPIO7[21] + PF_8 = MBED_PIN(0x0F, 8, 7, 22), // GPIO7[22] + PF_9 = MBED_PIN(0x0F, 9, 7, 23), // GPIO7[23] + PF_10 = MBED_PIN(0x0F, 10, 7, 24), // GPIO7[24] + PF_11 = MBED_PIN(0x0F, 11, 7, 25), // GPIO7[25] + + // GPIO pins from MCU pins + GPIO0_0 = P0_0, + GPIO0_1 = P0_1 , + GPIO0_2 = P1_15, + GPIO0_3 = P1_16, + GPIO0_4 = P1_0, + GPIO0_5 = P6_6, + GPIO0_6 = P3_6, + GPIO0_7 = P2_7, + GPIO0_8 = P1_1, + GPIO0_9 = P1_2, + GPIO0_10 = P1_3, + GPIO0_11 = P1_4, + GPIO0_12 = P1_17, + GPIO0_13 = P1_18, + GPIO0_14 = P2_10, + GPIO0_15 = P1_20, + + GPIO1_0 = P1_7, + GPIO1_1 = P1_8, + GPIO1_2 = P1_9, + GPIO1_3 = P1_10, + GPIO1_4 = P1_11, + GPIO1_5 = P1_12, + GPIO1_6 = P1_13, + GPIO1_7 = P1_14, + GPIO1_8 = P1_5, + GPIO1_9 = P1_6, + GPIO1_10 = P2_9, + GPIO1_11 = P2_11, + GPIO1_12 = P2_12, + GPIO1_13 = P2_13, + GPIO1_14 = P3_4, + GPIO1_15 = P3_5, + + GPIO2_0 = P4_0, + GPIO2_1 = P4_1, + GPIO2_2 = P4_2, + GPIO2_3 = P4_3, + GPIO2_4 = P4_4, + GPIO2_5 = P4_5, + GPIO2_6 = P4_6, + GPIO2_7 = P5_7, + GPIO2_8 = P6_12, + GPIO2_9 = P5_0, + GPIO2_10 = P5_1, + GPIO2_11 = P5_2, + GPIO2_12 = P5_3, + GPIO2_13 = P5_4, + GPIO2_14 = P5_5, + GPIO2_15 = P5_6, + + GPIO3_0 = P6_1, + GPIO3_1 = P6_2, + GPIO3_2 = P6_3, + GPIO3_3 = P6_4, + GPIO3_4 = P6_5, + GPIO3_5 = P6_9, + GPIO3_6 = P6_10, + GPIO3_7 = P6_11, + GPIO3_8 = P7_0, + GPIO3_9 = P7_1, + GPIO3_10 = P7_2, + GPIO3_11 = P7_3, + GPIO3_12 = P7_4, + GPIO3_13 = P7_5, + GPIO3_14 = P7_6, + GPIO3_15 = P7_7, + + GPIO4_0 = P8_0, + GPIO4_1 = P8_1, + GPIO4_2 = P8_2, + GPIO4_3 = P8_3, + GPIO4_4 = P8_4, + GPIO4_5 = P8_5, + GPIO4_6 = P8_6, + GPIO4_7 = P8_7, + GPIO4_8 = PA_1, + GPIO4_9 = PA_2, + GPIO4_10 = PA_3, + GPIO4_11 = P9_6, + GPIO4_12 = P9_0, + GPIO4_13 = P9_1, + GPIO4_14 = P9_2, + GPIO4_15 = P9_3, + + GPIO5_0 = P2_0, + GPIO5_1 = P2_1, + GPIO5_2 = P2_2, + GPIO5_3 = P2_3, + GPIO5_4 = P2_4, + GPIO5_5 = P2_5, + GPIO5_6 = P2_6, + GPIO5_7 = P2_8, + GPIO5_8 = P3_1, + GPIO5_9 = P3_2, + GPIO5_10 = P3_7, + GPIO5_11 = P3_8, + GPIO5_12 = P4_8, + GPIO5_13 = P4_9, + GPIO5_14 = P4_10, + GPIO5_15 = P6_7, + GPIO5_16 = P6_8, + GPIO5_17 = P9_4, + GPIO5_18 = P9_5, + GPIO5_19 = PA_4, + GPIO5_20 = PB_0, + GPIO5_21 = PB_1, + GPIO5_22 = PB_2, + GPIO5_23 = PB_3, + GPIO5_24 = PB_4, + GPIO5_25 = PB_5, + GPIO5_26 = PB_6, + + GPIO6_0 = PC_1, + GPIO6_1 = PC_2, + GPIO6_2 = PC_3, + GPIO6_3 = PC_4, + GPIO6_4 = PC_5, + GPIO6_5 = PC_6, + GPIO6_6 = PC_7, + GPIO6_7 = PC_8, + GPIO6_8 = PC_9, + GPIO6_9 = PC_10, + GPIO6_10 = PC_11, + GPIO6_11 = PC_12, + GPIO6_12 = PC_13, + GPIO6_13 = PC_14, + GPIO6_14 = PD_0, + GPIO6_15 = PD_1, + GPIO6_16 = PD_2, + GPIO6_17 = PD_3, + GPIO6_18 = PD_4, + GPIO6_19 = PD_5, + GPIO6_20 = PD_6, + GPIO6_21 = PD_7, + GPIO6_22 = PD_8, + GPIO6_23 = PD_9, + GPIO6_24 = PD_10, + GPIO6_25 = PD_11, + GPIO6_26 = PD_12, + GPIO6_27 = PD_13, + GPIO6_28 = PD_14, + GPIO6_29 = PD_15, + GPIO6_30 = PD_16, + + GPIO7_0 = PE_0, + GPIO7_1 = PE_1, + GPIO7_2 = PE_2, + GPIO7_3 = PE_3, + GPIO7_4 = PE_4, + GPIO7_5 = PE_5, + GPIO7_6 = PE_5, + GPIO7_7 = PE_7, + GPIO7_8 = PE_8, + GPIO7_9 = PE_9, + GPIO7_10 = PE_10, + GPIO7_11 = PE_11, + GPIO7_12 = PE_12, + GPIO7_13 = PE_13, + GPIO7_14 = PE_14, + GPIO7_15 = PE_15, + GPIO7_16 = PF_1, + GPIO7_17 = PF_2, + GPIO7_18 = PF_3, + GPIO7_19 = PF_5, + GPIO7_20 = PF_6, + GPIO7_21 = PF_7, + GPIO7_22 = PF_8, + GPIO7_23 = PF_9, + GPIO7_24 = PF_10, + GPIO7_25 = PF_11, + + // Map mbed pin names to LPC43xx board signals + + // Group 0x18 : CLKn pins + SFP_CLK0 = MBED_PIN(0x18, 0, 0, 0), + SFP_CLK1 = MBED_PIN(0x18, 1, 0, 0), + SFP_CLK2 = MBED_PIN(0x18, 2, 0, 0), + SFP_CLK3 = MBED_PIN(0x18, 3, 0, 0), + + // Group 0x19 : USB1, I2C0, ADC0, ADC1 + SFP_USB1 = MBED_PIN(0x19, 0, 0, 0), + SFP_I2C0 = MBED_PIN(0x19, 1, 0, 0), + SFP_AIO0 = MBED_PIN(0x19, 2, 0, 0), // ADC0 function select register + SFP_AIO1 = MBED_PIN(0x19, 3, 0, 0), // ADC1 function select register + SFP_AIO2 = MBED_PIN(0x19, 4, 0, 0), // Analog function select register + + SFP_EMCD = MBED_PIN(0x1A, 0, 0, 0), // EMC clock delay register + + SFP_INS0 = MBED_PIN(0x1C, 0, 0, 0), // Interrupt select for pin interrupts 0 to 3 + SFP_INS1 = MBED_PIN(0x1C, 1, 0, 0), // Interrupt select for pin interrupts 4 to 7 + + // Dedicated pin (no GPIO) + P_DED = MBED_PIN(0, 0, NO_GPIO, 0), + + // Not connected + NC = (int)0xFFFFFFFF, + + // ---------- Micromint Bambino 200/200E/210/210E (LQFP144) ---------- + // Base headers - J8, J9, J10 on Bambino 210/210E + // n/p = not populated, n/a = not available + // 210E 210 200E 200 + // ---- ---- ---- ---- + p15 = P7_4, // J8-1 J8-1 S4-3 S4-3 + p16 = P7_5, // J8-2 J8-2 S4-4 S4-4 + p17 = P4_1, // J8-3 J8-3 S3-4 S3-4 + p18 = P7_7, // J8-4 J8-4 S4-5 S4-5 + p19 = P4_3, // J8-5* J8-5* S3-4 S3-3 + p20 = P4_4, // J8-6* J8-6* S1-5 S1-5 + p20b = PF_8, // J8-6** J8-6** S3-5 S3-5 + // (*) if p20 is configured as DAC, ADC is not available for p19 + // (**) requires JP2 mod + + p21 = P6_5, // J9-1 J9-1 S2-5 S2-5 + p22 = P6_4, // J9-2 J9-2 S2=4 S2-4 + p23 = P1_7, // J9-3 J9-3 S2-3 S2-3 + p24 = P4_0, // J9-4 J9-4 S3-7 S3-7 + p25 = P6_9, // J9-5 J9-5 S8-7 n/p + p26 = P5_5, // J9-6 J9-6 S3-8 S3-8 + p27 = P5_7, // J9-7 J9-7 S3-9 S3-9 + p28 = P7_6, // J9-8 J9-8 S4-6 S4-6 + + p29 = P6_12, // J10-1 J10-1 S10-3 n/p + p30 = P5_0, // J10-2 J10-2 S1-4 S1-4 + p31 = P4_6, // J10-3 J10-3 S2-6 S2-6 + p32 = P4_8, // J10-4 J10-4 S2-7 S2-7 + p33 = P4_9, // J10-5 J10-5 S2-8 S2-8 + p34 = P4_10, // J10-6 J10-6 S2-9 S2-9 + p37 = P2_3, // J10-9 J10-9 S4-8 S4-8 + p38 = P2_4, // J10-10 J10-10 S4-9 S4-9 + + // Extended headers - J11, J12, J13, J14 on Bambino 210E + // 210E 210 200E 200 + // ---- ---- ---- ---- + p47 = P6_3, // J11-1 n/p S7-5 n/p + p48 = P6_6, // J11-2 n/p S6-7 n/p + p49 = P6_7, // J11-3 n/p S6-8 n/p + p50 = P6_8, // J11-4 n/p S6-9 n/p + p53 = P2_2, // J11-7 n/p S7-7 n/p + p54 = P2_1, // J11-8 n/p S7-3 n/p + + p55 = PF_10, // J12-1 n/p n/a n/a + p56 = PF_7, // J12-2 n/p n/a n/a + p57 = P2_6, // J12-3 n/p S8-6 n/p + p58 = P2_8, // J12-4 n/p S8-3 n/p + p59 = P6_10, // J12-5 n/p S7-8 n/p + p60 = P2_9, // J12-6 n/p S9-3 n/p + + p61 = P7_3, // J13-1 n/p S7-9 n/p + p62 = P3_2, // J13-2 n/p S9-4 n/p + p63 = P7_2, // J13-3 n/p S4-7 S4-7 + p64 = P3_1, // J13-4 n/p S9-5 n/p + p65 = P7_1, // J13-5 n/p S9-8 n/p + p66 = P7_0, // J13-6 n/p S9-9 n/p + p67 = P4_2, // J13-7 n/p S4-6 S4-6 + p68 = P4_5, // J13-8 n/p S1-3 S1-3 + + p69 = P2_13, // J14-1 n/p S9-7 n/p + p70 = P2_12, // J14-2 n/p S9-6 n/p + p71 = P9_6, // J14-3 n/p S6-6 n/p + p72 = P9_5, // J14-4 n/p S7-4 n/p + p73 = P5_3, // J14-5 n/p S6-5 n/p + p74 = P1_8, // J14-6 n/p S6-4 n/p + p75 = P1_5, // J14-7 n/p S10-6 n/p + p76 = P1_4, // J14-8 n/p S10-7 n/p + p77 = P1_3, // J14-9 n/p S10-8 n/p + p78 = PF_4, // J14-10 n/p S10-9 n/p + + // J16 - PMOD-SSP header (not populated, field installable) + p80 = P1_0, // J16-1 J16-1 S1-6 S1-6 + p81 = P1_2, // J16-2 J16-2 S1-7 S1-7 + p82 = P1_1, // J16-3 J16-3 S1-8 S1-8 + p83 = P3_0, // J16-4 J16-4 S1-9 S1-9 + + // Arduino pins - J8, J9, J10 + // 210E 210 200E 200 + // ---- ---- ---- ---- + D0 = p21, // J9-1 J9-1 S2-5 S2-5 + D1 = p22, // J9-2 J9-2 S2-4 S2-4 + D2 = p23, // J9-3 J9-3 S2-3 S2-3 + D3 = p24, // J9-4 J9-4 S3-7 S3-7 + D4 = p25, // J9-5 J9-5 S8-7 n/p + D5 = p26, // J9-6 J9-6 S3-8 S3-8 + D6 = p27, // J9-7 J9-7 S3-9 S3-9 + D7 = p28, // J9-8 J9-8 S4-6 S4-6 + + D8 = p29, // J10-1 J10-1 S10-1 n/p + D9 = p30, // J10-2 J10-2 S1-4 S1-4 + D10 = p31, // J10-3 J10-3 S2-6 S2-6 + D11 = p32, // J10-4 J10-4 S2-7 S2-7 + D12 = p33, // J10-5 J10-5 S2-8 S2-8 + D13 = p34, // J10-6 J10-6 S2-9 S2-9 + D16 = p37, // J10-9 J10-9 S4-8 S4-8 + D17 = p38, // J10-10 J10-10 S4-9 S4-9 + + A0 = p15, // J8-1 J8-1 S4-3 S4-3 + A1 = p16, // J8-2 J8-2 S4-4 S4-4 + A2 = p17, // J8-3 J8-3 S3-4 S3-4 + A3 = p18, // J8-4 J8-4 S3-4 S3-4 + A4 = p19, // J8-5* J8-5* S3-3 S3-3 + A5 = p20, // J8-6* J8-6* S1-5 S1-5 + A5b = p20b, // J8-6** J8-6** S3-5 S3-5 + // (*) if A5 is configured as DAC, ADC is not available for A4 + // (**) requires JP2 mod + + // Extended Arduino pins - J11, J12, J13, J14 + // 210E 210 200E 200 + // ---- ---- ---- ---- + D20 = p61, // J13-1 n/p S7-9 n/p + D21 = p62, // J13-2 n/p S9-4 n/p + D22 = p63, // J13-3 n/p S4-7 S4-7 + D23 = p64, // J13-4 n/p S9-5 n/p + D24 = p65, // J13-5 n/p S9-8 n/p + D25 = p66, // J13-6 n/p S9-9 n/p + D26 = p67, // J13-7 n/p S3-7 S3-7 + D27 = p68, // J13-8 n/p S1-3 S1-3 + + D30 = p69, // J14-1 n/p S9-7 n/p + D31 = p70, // J14-2 n/p S9-6 n/p + D32 = p71, // J14-3 n/p S6-6 n/p + D33 = p72, // J14-4 n/p S7-4 n/p + D34 = p73, // J14-5 n/p S6-5 n/p + D35 = p74, // J14-6 n/p S6-4 n/p + D36 = p75, // J14-7 n/p S10-6 n/p + D37 = p76, // J14-8 n/p S10-7 n/p + D38 = p77, // J14-9 n/p S10-8 n/p + D39 = p78, // J14-10 n/p S10-9 n/p + + D40 = p47, // J11-1 n/p S7-5 n/p + D41 = p48, // J11-2 n/p S6-7 n/p + D42 = p49, // J11-3 n/p S6-8 n/p + D43 = p50, // J11-4 n/p S6-9 n/p + D46 = p53, // J11-7 n/p S7-7 n/p + D47 = p54, // J11-8 n/p S7-3 n/p + + D52 = p57, // J12-3 n/p S8-6 n/p + D53 = p58, // J12-4 n/p S8-3 n/p + D54 = p59, // J12-5 n/p S7-8 n/p + D55 = p60, // J12-6 n/p S9-3 n/p + + A6 = p55, // J12-1 n/p n/a n/a + A7 = p56, // J12-2 n/p n/a n/a + + // User interfaces: LEDs, buttons + // 210E 210 200E 200 + // ---- ---- ---- ---- + LED1 = P6_11, // 210/210E/200e/200 + LED2 = P2_5, // 210/210E/200e/200 + LED3 = P6_1, // 210/210E only S6-3 n/p + LED4 = P6_2, // 210/210E only S7-6 n/p + + LED_YELLOW = LED1, + LED_GREEN = LED2, + LED_RED = LED3, + LED_BLUE = LED4, + + BTN1 = P2_7, + + // Serial pins - UART, SPI, I2C + // 210E 210 200E 200 + // ---- ---- ---- ---- + UART0_TX = P6_4, // J9-2 J9-2 S2-4 S2-4 + UART0_RX = P6_5, // J9-1 J9-1 S2-5 S2-5 + UART1_TX = P5_6, // XBEE n/p S5-4/XBEE S5-4 + UART1_RX = P1_14, // XBEE n/p S5-5/XBEE S5-5 + UART2_TX = P2_10, // MBEDHDK MBEDHDK S10-4 n/p + UART2_RX = P2_11, // MBEDHDK MBEDHDK S10-5 n/p + UART3_TX = P2_3, // J10-9 n/p S4-8 S4-8 + UART3_RX = P2_4, // J10-10 n/p S4-9 S4-9 + + COM1_TX = UART0_TX, + COM1_RX = UART0_RX, + COM2_TX = UART1_TX, + COM2_RX = UART1_RX, + COM3_TX = UART2_TX, + COM3_RX = UART2_RX, + COM4_TX = UART3_TX, + COM4_RX = UART3_RX, + + // 210E 210 200E 200 + // ---- ---- ---- ---- + SPI0_SCK = P3_0, // J16-4 n/p S1-9 S1-9 + SPI0_MISO = P1_1, // J16-3 n/p S1-8 S1-8 + SPI0_MOSI = P1_2, // J16-2 n/p S1-7 S1-7 + SPI0_SSEL = P1_0, // J16-1 n/p S1-6 S1-6 + SPI1_SCK = PF_4, // J14-10 n/p S10-9 n/p + SPI1_MISO = P1_3, // J14-9 n/p S10-8 n/p + SPI1_MOSI = P1_4, // J14-8 n/p S10-7 n/p + SPI1_SSEL = P1_5, // J14-7 n/p S10-6 n/p + + I2C0_SDA = P_DED, // J15-3 J15-3 S8-8 n/p + I2C0_SCL = P_DED, // J15-1 J15-1 S8-9 n/p + I2C1_SDA = P2_3, // J10-9 J10-9 S4-8 S4-8 + I2C1_SCL = P2_4, // J10-10 J10-10 S4-9 S4-9 + + // Analog pins + ADC0 = P7_4, // J8-1 J8-1 S4-3 S4-3 + ADC1 = P7_5, // J8-2 J8-2 S4-4 S4-4 + ADC2 = P4_1, // J8-3 J8-3 S3-4 S3-4 + ADC3 = P7_7, // J8-4 J8-4 S3-4 S3-4 + ADC4 = P4_3, // J8-5* J8-5* S3-3 S3-3 + ADC5 = PF_8, // J8-6** J8-6** S1-5 S1-5 + ADC6 = PF_10, // J12-1 n/p n/a n/a + ADC7 = PF_7, // J12-2 n/p n/a n/a + DAC0 = P4_4, // J8-6* J8-6* S3-5 S3-5 + // (*) if DAC0 is configured, ADC4 is not available + // (**) ADC5 requires JP2 mod + + // USB pins + // 210E 210 200E 200 + // ---- ---- ---- ---- + USBTX = UART2_TX, // MBEDHDK MBEDHDK S10-4 n/p + USBRX = UART2_RX, // MBEDHDK MBEDHDK S10-5 n/p + + // PWM pins + // 210E 210 200E 200 + // ---- ---- ---- ---- + PWM1 = P1_7, // J9-3 J9-3 S2-3 S2-3 + PWM2 = P7_6, // J9-8 J9-8 S4-6 S4-6 + PWM3 = P6_12, // J10-1 J10-1 S10-3 n/p + PWM4 = P4_6, // J10-3 J10-3 S2-6 S2-6 + PWM5 = P7_5, // J8-2 J8-2 S4-4 S4-4 + PWM6 = P4_1, // J8-3 J8-3 S3-4 S3-4 + PWM7 = P7_7, // J8-4 J8-4 S4-5 S4-5 + PWM8 = P2_8, // J12-4 n/p S8-3 n/p + PWM9 = P2_9, // J12-6 n/p S9-3 n/p + PWM10 = P7_1, // J13-5 n/p S9-8 n/p + PWM11 = P7_0, // J13-6 n/p S9-9 n/p + PWM12 = P1_5, // J14-7 n/p S10-6 n/p + + // ---------- End of Micromint Bambino ---------- +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + Repeater = 1, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/device.h new file mode 100644 index 0000000000..b16eeced0e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4330/device.h @@ -0,0 +1,60 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 +//#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/PinNames.h new file mode 100644 index 0000000000..10e2e837a4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/PinNames.h @@ -0,0 +1,621 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define BOARD_REV_B + +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 +#define NO_GPIO 15 + +// On the LPC43xx the MCU pin name and the GPIO pin name are not the same. +// Encode SCU and GPIO offsets as a pin identifier +#define MBED_PIN(group, num, port, pin) ((SCU_OFF(group,num) << 16) + GPIO_OFF(port,pin)) + +// Decode pin identifier into register, port and pin values +#define MBED_SCU_REG(MBED_PIN) (LPC_SCU_BASE + (MBED_PIN >> 16)) +#define MBED_GPIO_REG(MBED_PIN) (LPC_GPIO_PORT_BASE + 0x2000 + ((MBED_PIN >> (PORT_SHIFT - 2)) & 0x0000003C)) +#define MBED_GPIO_PORT(MBED_PIN) ((MBED_PIN >> PORT_SHIFT) & 0x0000000F) +#define MBED_GPIO_PIN(MBED_PIN) (MBED_PIN & 0x0000001F) + +typedef enum { + // LPC43xx Pin Names + // All pins defined. Package determines which are available. + // LBGA256 TFBGA180 TFBGA100 LQFP208 LQFP144 + // GPIO0 [15:0] [15:0] [15:6] [15:0] [15:0] + // [4:0] + // GPIO1 [15:0] [15:0] [15:0] [15:0] [15:0] + // GPIO2 [15:0] [15:0] [15:0] [15:0] + // GPIO3 [15:0] [15:0] [7] [15:0] [15:0] + // [5:3] + // [1:0] + // GPIO4 [15:0] [15:0] [15:0] [11] + // GPIO5 [26:0] [26:0] [11:0] [25:0] [18] + // [16:0] + // GPIO6 [30:0] [30:28] [30:20] + // [26:25] [5:0] + // GPIO7 [25:0] [4:0] [25:23] + // [21:17] + // --- --- --- --- --- + // Total 164 117 49 131 83 + + // Groups 0x00 - 0x0F : Digital pins + // * Digital pins support up to 8 functions + // Use func=0 for GPIO0-GPIO4, func=4 for GPIO5-GPIO7 + // * High-drive pins default to 4 mA but can support 8, 14, 20 mA + P0_0 = MBED_PIN(0x00, 0, 0, 0), // GPIO0[0] + P0_1 = MBED_PIN(0x00, 1, 0, 1), // GPIO0[1] + + P1_0 = MBED_PIN(0x01, 0, 0, 4), // GPIO0[4] + P1_1 = MBED_PIN(0x01, 1, 0, 8), // GPIO0[8] + P1_2 = MBED_PIN(0x01, 2, 0, 9), // GPIO0[9] + P1_3 = MBED_PIN(0x01, 3, 0, 10), // GPIO0[10] + P1_4 = MBED_PIN(0x01, 4, 0, 11), // GPIO0[11] + P1_5 = MBED_PIN(0x01, 5, 1, 8), // GPIO1[8] + P1_6 = MBED_PIN(0x01, 6, 1, 9), // GPIO1[9] + P1_7 = MBED_PIN(0x01, 7, 1, 0), // GPIO1[0] + P1_8 = MBED_PIN(0x01, 8, 1, 1), // GPIO1[1] + P1_9 = MBED_PIN(0x01, 9, 1, 2), // GPIO1[2] + P1_10 = MBED_PIN(0x01, 10, 1, 3), // GPIO1[3] + P1_11 = MBED_PIN(0x01, 11, 1, 4), // GPIO1[4] + P1_12 = MBED_PIN(0x01, 12, 1, 5), // GPIO1[5] + P1_13 = MBED_PIN(0x01, 13, 1, 6), // GPIO1[6] + P1_14 = MBED_PIN(0x01, 14, 1, 7), // GPIO1[7] + P1_15 = MBED_PIN(0x01, 15, 0, 2), // GPIO0[2] + P1_16 = MBED_PIN(0x01, 16, 0, 3), // GPIO0[3] + P1_17 = MBED_PIN(0x01, 17, 0, 12), // GPIO0[12] high-drive + P1_18 = MBED_PIN(0x01, 18, 0, 13), // GPIO0[13] + P1_19 = MBED_PIN(0x01, 19, NO_GPIO, 0), + P1_20 = MBED_PIN(0x01, 20, 0, 15), // GPIO0[15] + + P2_0 = MBED_PIN(0x02, 0, 5, 0), // GPIO5[0] + P2_1 = MBED_PIN(0x02, 1, 5, 1), // GPIO5[1] + P2_2 = MBED_PIN(0x02, 2, 5, 2), // GPIO5[2] + P2_3 = MBED_PIN(0x02, 3, 5, 3), // GPIO5[3] high-drive + P2_4 = MBED_PIN(0x02, 4, 5, 4), // GPIO5[4] high-drive + P2_5 = MBED_PIN(0x02, 5, 5, 5), // GPIO5[5] high-drive + P2_6 = MBED_PIN(0x02, 6, 5, 6), // GPIO5[6] + P2_7 = MBED_PIN(0x02, 7, 0, 7), // GPIO0[7] + P2_8 = MBED_PIN(0x02, 8, 5, 7), // GPIO5[7] + P2_9 = MBED_PIN(0x02, 9, 1, 10), // GPIO1[10] + P2_10 = MBED_PIN(0x02, 10, 0, 14), // GPIO0[14] + P2_11 = MBED_PIN(0x02, 11, 1, 11), // GPIO1[11] + P2_12 = MBED_PIN(0x02, 12, 1, 12), // GPIO1[12] + P2_13 = MBED_PIN(0x02, 13, 1, 13), // GPIO1[13] + + P3_0 = MBED_PIN(0x03, 0, NO_GPIO, 0), + P3_1 = MBED_PIN(0x03, 1, 5, 8), // GPIO5[8] + P3_2 = MBED_PIN(0x03, 2, 5, 9), // GPIO5[9] + P3_3 = MBED_PIN(0x03, 3, NO_GPIO, 0), + P3_4 = MBED_PIN(0x03, 4, 1, 14), // GPIO1[14] + P3_5 = MBED_PIN(0x03, 5, 1, 15), // GPIO1[15] + P3_6 = MBED_PIN(0x03, 6, 0, 6), // GPIO0[6] + P3_7 = MBED_PIN(0x03, 7, 5, 10), // GPIO5[10] + P3_8 = MBED_PIN(0x03, 8, 5, 11), // GPIO5[11] + + P4_0 = MBED_PIN(0x04, 0, 2, 0), // GPIO2[0] + P4_1 = MBED_PIN(0x04, 1, 2, 1), // GPIO2[1] + P4_2 = MBED_PIN(0x04, 2, 2, 2), // GPIO2[2] + P4_3 = MBED_PIN(0x04, 3, 2, 3), // GPIO2[3] + P4_4 = MBED_PIN(0x04, 4, 2, 4), // GPIO2[4] + P4_5 = MBED_PIN(0x04, 5, 2, 5), // GPIO2[5] + P4_6 = MBED_PIN(0x04, 6, 2, 6), // GPIO2[6] + P4_7 = MBED_PIN(0x04, 7, NO_GPIO, 0), + P4_8 = MBED_PIN(0x04, 8, 5, 12), // GPIO5[12] + P4_9 = MBED_PIN(0x04, 9, 5, 13), // GPIO5[13] + P4_10 = MBED_PIN(0x04, 10, 5, 14), // GPIO5[14] + + P5_0 = MBED_PIN(0x05, 0, 2, 9), // GPIO2[9] + P5_1 = MBED_PIN(0x05, 1, 2, 10), // GPIO2[10] + P5_2 = MBED_PIN(0x05, 2, 2, 11), // GPIO2[11] + P5_3 = MBED_PIN(0x05, 3, 2, 12), // GPIO2[12] + P5_4 = MBED_PIN(0x05, 4, 2, 13), // GPIO2[13] + P5_5 = MBED_PIN(0x05, 5, 2, 14), // GPIO2[14] + P5_6 = MBED_PIN(0x05, 6, 2, 15), // GPIO2[15] + P5_7 = MBED_PIN(0x05, 7, 2, 7), // GPIO2[7] + + P6_0 = MBED_PIN(0x06, 0, NO_GPIO, 0), + P6_1 = MBED_PIN(0x06, 1, 3, 0), // GPIO3[0] + P6_2 = MBED_PIN(0x06, 2, 3, 1), // GPIO3[1] + P6_3 = MBED_PIN(0x06, 3, 3, 2), // GPIO3[2] + P6_4 = MBED_PIN(0x06, 4, 3, 3), // GPIO3[3] + P6_5 = MBED_PIN(0x06, 5, 3, 4), // GPIO3[4] + P6_6 = MBED_PIN(0x06, 6, 0, 5), // GPIO0[5] + P6_7 = MBED_PIN(0x06, 7, 5, 15), // GPIO5[15] + P6_8 = MBED_PIN(0x06, 8, 5, 16), // GPIO5[16] + P6_9 = MBED_PIN(0x06, 9, 3, 5), // GPIO3[5] + P6_10 = MBED_PIN(0x06, 10, 3, 6), // GPIO3[6] + P6_11 = MBED_PIN(0x06, 11, 3, 7), // GPIO3[7] + P6_12 = MBED_PIN(0x06, 12, 2, 8), // GPIO2[8] + + P7_0 = MBED_PIN(0x07, 0, 3, 8), // GPIO3[8] + P7_1 = MBED_PIN(0x07, 1, 3, 9), // GPIO3[9] + P7_2 = MBED_PIN(0x07, 2, 3, 10), // GPIO3[10] + P7_3 = MBED_PIN(0x07, 3, 3, 11), // GPIO3[11] + P7_4 = MBED_PIN(0x07, 4, 3, 12), // GPIO3[12] + P7_5 = MBED_PIN(0x07, 5, 3, 13), // GPIO3[13] + P7_6 = MBED_PIN(0x07, 6, 3, 14), // GPIO3[14] + P7_7 = MBED_PIN(0x07, 7, 3, 15), // GPIO3[15] + + P8_0 = MBED_PIN(0x08, 8, 4, 0), // GPIO4[0] high-drive + P8_1 = MBED_PIN(0x09, 0, 4, 1), // GPIO4[1] high-drive + P8_2 = MBED_PIN(0x09, 1, 4, 2), // GPIO4[2] high-drive + P8_3 = MBED_PIN(0x09, 2, 4, 3), // GPIO4[3] + P8_4 = MBED_PIN(0x08, 4, 4, 4), // GPIO4[4] + P8_5 = MBED_PIN(0x08, 5, 4, 5), // GPIO4[5] + P8_6 = MBED_PIN(0x08, 6, 4, 6), // GPIO4[6] + P8_7 = MBED_PIN(0x08, 7, 4, 7), // GPIO4[7] + P8_8 = MBED_PIN(0x08, 8, NO_GPIO, 0), + + P9_0 = MBED_PIN(0x09, 0, 4, 12), // GPIO4[12] + P9_1 = MBED_PIN(0x09, 1, 4, 13), // GPIO4[13] + P9_2 = MBED_PIN(0x09, 2, 4, 14), // GPIO4[14] + P9_3 = MBED_PIN(0x09, 3, 4, 15), // GPIO4[15] + P9_4 = MBED_PIN(0x09, 4, 5, 17), // GPIO5[17] + P9_5 = MBED_PIN(0x09, 5, 5, 18), // GPIO5[18] + P9_6 = MBED_PIN(0x09, 6, 4, 11), // GPIO4[11] + + PA_0 = MBED_PIN(0x0A, 0, NO_GPIO, 0), + PA_1 = MBED_PIN(0x0A, 1, 4, 8), // GPIO4[8] high-drive + PA_2 = MBED_PIN(0x0A, 2, 4, 9), // GPIO4[9] high-drive + PA_3 = MBED_PIN(0x0A, 3, 4, 10), // GPIO4[10] high-drive + PA_4 = MBED_PIN(0x0A, 4, 5, 19), // GPIO5[19] + + PB_0 = MBED_PIN(0x0B, 0, 5, 20), // GPIO5[20] + PB_1 = MBED_PIN(0x0B, 1, 5, 21), // GPIO5[21] + PB_2 = MBED_PIN(0x0B, 2, 5, 22), // GPIO5[22] + PB_3 = MBED_PIN(0x0B, 3, 5, 23), // GPIO5[23] + PB_4 = MBED_PIN(0x0B, 4, 5, 24), // GPIO5[24] + PB_5 = MBED_PIN(0x0B, 5, 5, 25), // GPIO5[25] + PB_6 = MBED_PIN(0x0B, 6, 5, 26), // GPIO5[26] + + PC_0 = MBED_PIN(0x0C, 0, NO_GPIO, 0), + PC_1 = MBED_PIN(0x0C, 1, 6, 0), // GPIO6[0] + PC_2 = MBED_PIN(0x0C, 2, 6, 1), // GPIO6[1] + PC_3 = MBED_PIN(0x0C, 3, 6, 2), // GPIO6[2] + PC_4 = MBED_PIN(0x0C, 4, 6, 3), // GPIO6[3] + PC_5 = MBED_PIN(0x0C, 5, 6, 4), // GPIO6[4] + PC_6 = MBED_PIN(0x0C, 6, 6, 5), // GPIO6[5] + PC_7 = MBED_PIN(0x0C, 7, 6, 6), // GPIO6[6] + PC_8 = MBED_PIN(0x0C, 8, 6, 7), // GPIO6[7] + PC_9 = MBED_PIN(0x0C, 9, 6, 8), // GPIO6[8] + PC_10 = MBED_PIN(0x0C, 10, 6, 9), // GPIO6[9] + PC_11 = MBED_PIN(0x0C, 11, 6, 10), // GPIO6[10] + PC_12 = MBED_PIN(0x0C, 12, 6, 11), // GPIO6[11] + PC_13 = MBED_PIN(0x0C, 13, 6, 12), // GPIO6[12] + PC_14 = MBED_PIN(0x0C, 14, 6, 13), // GPIO6[13] + + PD_0 = MBED_PIN(0x0D, 0, 6, 14), // GPIO6[14] + PD_1 = MBED_PIN(0x0D, 1, 6, 15), // GPIO6[15] + PD_2 = MBED_PIN(0x0D, 2, 6, 16), // GPIO6[16] + PD_3 = MBED_PIN(0x0D, 3, 6, 17), // GPIO6[17] + PD_4 = MBED_PIN(0x0D, 4, 6, 18), // GPIO6[18] + PD_5 = MBED_PIN(0x0D, 5, 6, 19), // GPIO6[19] + PD_6 = MBED_PIN(0x0D, 6, 6, 20), // GPIO6[20] + PD_7 = MBED_PIN(0x0D, 7, 6, 21), // GPIO6[21] + PD_8 = MBED_PIN(0x0D, 8, 6, 22), // GPIO6[22] + PD_9 = MBED_PIN(0x0D, 9, 6, 23), // GPIO6[23] + PD_10 = MBED_PIN(0x0D, 10, 6, 24), // GPIO6[24] + PD_11 = MBED_PIN(0x0D, 11, 6, 25), // GPIO6[25] + PD_12 = MBED_PIN(0x0D, 12, 6, 26), // GPIO6[26] + PD_13 = MBED_PIN(0x0D, 13, 6, 27), // GPIO6[27] + PD_14 = MBED_PIN(0x0D, 14, 6, 28), // GPIO6[28] + PD_15 = MBED_PIN(0x0D, 15, 6, 29), // GPIO6[29] + PD_16 = MBED_PIN(0x0D, 16, 6, 30), // GPIO6[30] + + PE_0 = MBED_PIN(0x0E, 0, 7, 0), // GPIO7[0] + PE_1 = MBED_PIN(0x0E, 1, 7, 1), // GPIO7[1] + PE_2 = MBED_PIN(0x0E, 2, 7, 2), // GPIO7[2] + PE_3 = MBED_PIN(0x0E, 3, 7, 3), // GPIO7[3] + PE_4 = MBED_PIN(0x0E, 4, 7, 4), // GPIO7[4] + PE_5 = MBED_PIN(0x0E, 5, 7, 5), // GPIO7[5] + PE_6 = MBED_PIN(0x0E, 6, 7, 6), // GPIO7[6] + PE_7 = MBED_PIN(0x0E, 7, 7, 7), // GPIO7[7] + PE_8 = MBED_PIN(0x0E, 8, 7, 8), // GPIO7[8] + PE_9 = MBED_PIN(0x0E, 9, 7, 9), // GPIO7[9] + PE_10 = MBED_PIN(0x0E, 10, 7, 10), // GPIO7[10] + PE_11 = MBED_PIN(0x0E, 11, 7, 11), // GPIO7[11] + PE_12 = MBED_PIN(0x0E, 12, 7, 12), // GPIO7[12] + PE_13 = MBED_PIN(0x0E, 13, 7, 13), // GPIO7[13] + PE_14 = MBED_PIN(0x0E, 14, 7, 14), // GPIO7[14] + PE_15 = MBED_PIN(0x0E, 15, 7, 15), // GPIO7[15] + + PF_0 = MBED_PIN(0x0F, 0, NO_GPIO, 0), + PF_1 = MBED_PIN(0x0F, 1, 7, 16), // GPIO7[16] + PF_2 = MBED_PIN(0x0F, 2, 7, 17), // GPIO7[17] + PF_3 = MBED_PIN(0x0F, 3, 7, 18), // GPIO7[18] + PF_4 = MBED_PIN(0x0F, 4, NO_GPIO, 0), + PF_5 = MBED_PIN(0x0F, 5, 7, 19), // GPIO7[19] + PF_6 = MBED_PIN(0x0F, 6, 7, 20), // GPIO7[20] + PF_7 = MBED_PIN(0x0F, 7, 7, 21), // GPIO7[21] + PF_8 = MBED_PIN(0x0F, 8, 7, 22), // GPIO7[22] + PF_9 = MBED_PIN(0x0F, 9, 7, 23), // GPIO7[23] + PF_10 = MBED_PIN(0x0F, 10, 7, 24), // GPIO7[24] + PF_11 = MBED_PIN(0x0F, 11, 7, 25), // GPIO7[25] + + // GPIO pins from MCU pins + GPIO0_0 = P0_0, + GPIO0_1 = P0_1 , + GPIO0_2 = P1_15, + GPIO0_3 = P1_16, + GPIO0_4 = P1_0, + GPIO0_5 = P6_6, + GPIO0_6 = P3_6, + GPIO0_7 = P2_7, + GPIO0_8 = P1_1, + GPIO0_9 = P1_2, + GPIO0_10 = P1_3, + GPIO0_11 = P1_4, + GPIO0_12 = P1_17, + GPIO0_13 = P1_18, + GPIO0_14 = P2_10, + GPIO0_15 = P1_20, + + GPIO1_0 = P1_7, + GPIO1_1 = P1_8, + GPIO1_2 = P1_9, + GPIO1_3 = P1_10, + GPIO1_4 = P1_11, + GPIO1_5 = P1_12, + GPIO1_6 = P1_13, + GPIO1_7 = P1_14, + GPIO1_8 = P1_5, + GPIO1_9 = P1_6, + GPIO1_10 = P2_9, + GPIO1_11 = P2_11, + GPIO1_12 = P2_12, + GPIO1_13 = P2_13, + GPIO1_14 = P3_4, + GPIO1_15 = P3_5, + + GPIO2_0 = P4_0, + GPIO2_1 = P4_1, + GPIO2_2 = P4_2, + GPIO2_3 = P4_3, + GPIO2_4 = P4_4, + GPIO2_5 = P4_5, + GPIO2_6 = P4_6, + GPIO2_7 = P5_7, + GPIO2_8 = P6_12, + GPIO2_9 = P5_0, + GPIO2_10 = P5_1, + GPIO2_11 = P5_2, + GPIO2_12 = P5_3, + GPIO2_13 = P5_4, + GPIO2_14 = P5_5, + GPIO2_15 = P5_6, + + GPIO3_0 = P6_1, + GPIO3_1 = P6_2, + GPIO3_2 = P6_3, + GPIO3_3 = P6_4, + GPIO3_4 = P6_5, + GPIO3_5 = P6_9, + GPIO3_6 = P6_10, + GPIO3_7 = P6_11, + GPIO3_8 = P7_0, + GPIO3_9 = P7_1, + GPIO3_10 = P7_2, + GPIO3_11 = P7_3, + GPIO3_12 = P7_4, + GPIO3_13 = P7_5, + GPIO3_14 = P7_6, + GPIO3_15 = P7_7, + + GPIO4_0 = P8_0, + GPIO4_1 = P8_1, + GPIO4_2 = P8_2, + GPIO4_3 = P8_3, + GPIO4_4 = P8_4, + GPIO4_5 = P8_5, + GPIO4_6 = P8_6, + GPIO4_7 = P8_7, + GPIO4_8 = PA_1, + GPIO4_9 = PA_2, + GPIO4_10 = PA_3, + GPIO4_11 = P9_6, + GPIO4_12 = P9_0, + GPIO4_13 = P9_1, + GPIO4_14 = P9_2, + GPIO4_15 = P9_3, + + GPIO5_0 = P2_0, + GPIO5_1 = P2_1, + GPIO5_2 = P2_2, + GPIO5_3 = P2_3, + GPIO5_4 = P2_4, + GPIO5_5 = P2_5, + GPIO5_6 = P2_6, + GPIO5_7 = P2_8, + GPIO5_8 = P3_1, + GPIO5_9 = P3_2, + GPIO5_10 = P3_7, + GPIO5_11 = P3_8, + GPIO5_12 = P4_8, + GPIO5_13 = P4_9, + GPIO5_14 = P4_10, + GPIO5_15 = P6_7, + GPIO5_16 = P6_8, + GPIO5_17 = P9_4, + GPIO5_18 = P9_5, + GPIO5_19 = PA_4, + GPIO5_20 = PB_0, + GPIO5_21 = PB_1, + GPIO5_22 = PB_2, + GPIO5_23 = PB_3, + GPIO5_24 = PB_4, + GPIO5_25 = PB_5, + GPIO5_26 = PB_6, + + GPIO6_0 = PC_1, + GPIO6_1 = PC_2, + GPIO6_2 = PC_3, + GPIO6_3 = PC_4, + GPIO6_4 = PC_5, + GPIO6_5 = PC_6, + GPIO6_6 = PC_7, + GPIO6_7 = PC_8, + GPIO6_8 = PC_9, + GPIO6_9 = PC_10, + GPIO6_10 = PC_11, + GPIO6_11 = PC_12, + GPIO6_12 = PC_13, + GPIO6_13 = PC_14, + GPIO6_14 = PD_0, + GPIO6_15 = PD_1, + GPIO6_16 = PD_2, + GPIO6_17 = PD_3, + GPIO6_18 = PD_4, + GPIO6_19 = PD_5, + GPIO6_20 = PD_6, + GPIO6_21 = PD_7, + GPIO6_22 = PD_8, + GPIO6_23 = PD_9, + GPIO6_24 = PD_10, + GPIO6_25 = PD_11, + GPIO6_26 = PD_12, + GPIO6_27 = PD_13, + GPIO6_28 = PD_14, + GPIO6_29 = PD_15, + GPIO6_30 = PD_16, + + GPIO7_0 = PE_0, + GPIO7_1 = PE_1, + GPIO7_2 = PE_2, + GPIO7_3 = PE_3, + GPIO7_4 = PE_4, + GPIO7_5 = PE_5, + GPIO7_6 = PE_5, + GPIO7_7 = PE_7, + GPIO7_8 = PE_8, + GPIO7_9 = PE_9, + GPIO7_10 = PE_10, + GPIO7_11 = PE_11, + GPIO7_12 = PE_12, + GPIO7_13 = PE_13, + GPIO7_14 = PE_14, + GPIO7_15 = PE_15, + GPIO7_16 = PF_1, + GPIO7_17 = PF_2, + GPIO7_18 = PF_3, + GPIO7_19 = PF_5, + GPIO7_20 = PF_6, + GPIO7_21 = PF_7, + GPIO7_22 = PF_8, + GPIO7_23 = PF_9, + GPIO7_24 = PF_10, + GPIO7_25 = PF_11, + + // Map mbed pin names to LPC43xx board signals + + // Group 0x18 : CLKn pins + SFP_CLK0 = MBED_PIN(0x18, 0, 0, 0), + SFP_CLK1 = MBED_PIN(0x18, 1, 0, 0), + SFP_CLK2 = MBED_PIN(0x18, 2, 0, 0), + SFP_CLK3 = MBED_PIN(0x18, 3, 0, 0), + + // Group 0x19 : USB1, I2C0, ADC0, ADC1 + SFP_USB1 = MBED_PIN(0x19, 0, 0, 0), + SFP_I2C0 = MBED_PIN(0x19, 1, 0, 0), + SFP_AIO0 = MBED_PIN(0x19, 2, 0, 0), // ADC0 function select register + SFP_AIO1 = MBED_PIN(0x19, 3, 0, 0), // ADC1 function select register + SFP_AIO2 = MBED_PIN(0x19, 4, 0, 0), // Analog function select register + + SFP_EMCD = MBED_PIN(0x1A, 0, 0, 0), // EMC clock delay register + + SFP_INS0 = MBED_PIN(0x1C, 0, 0, 0), // Interrupt select for pin interrupts 0 to 3 + SFP_INS1 = MBED_PIN(0x1C, 1, 0, 0), // Interrupt select for pin interrupts 4 to 7 + +/* +#define MBED_ADC_NUM(MBED_PIN) ((MBED_PIN >> 5) & 0x0000000F) +#define MBED_ADC_CHAN(MBED_PIN) (MBED_PIN & 0x0000001F) + + // Use pseudo-pin ID also for ADCs, although with special handling + SFP_ADC0_0 = MBED_PIN(0x19, 2, 0, 0), // ADC0_0 + SFP_ADC0_1 = MBED_PIN(0x19, 2, 0, 1), // ADC0_1 + SFP_ADC0_2 = MBED_PIN(0x19, 2, 0, 2), // ADC0_2 + SFP_ADC0_3 = MBED_PIN(0x19, 2, 0, 3), // ADC0_3 + SFP_ADC0_4 = MBED_PIN(0x19, 2, 0, 4), // ADC0_4 + SFP_ADC0_5 = MBED_PIN(0x19, 2, 0, 5), // ADC0_5 + SFP_ADC0_6 = MBED_PIN(0x19, 2, 0, 6), // ADC0_6 + + SFP_ADC1_0 = MBED_PIN(0x19, 3, 1, 0), // ADC1_0 + SFP_ADC1_1 = MBED_PIN(0x19, 3, 1, 1), // ADC1_1 + SFP_ADC1_2 = MBED_PIN(0x19, 3, 1, 2), // ADC1_2 + SFP_ADC1_3 = MBED_PIN(0x19, 3, 1, 3), // ADC1_3 + SFP_ADC1_4 = MBED_PIN(0x19, 3, 1, 4), // ADC1_4 + SFP_ADC1_5 = MBED_PIN(0x19, 3, 1, 5), // ADC1_5 + SFP_ADC1_6 = MBED_PIN(0x19, 3, 1, 6), // ADC1_6 + SFP_ADC1_7 = MBED_PIN(0x19, 3, 1, 7), // ADC1_7 +*/ + + // Dedicated pin (no GPIO) + P_DED = MBED_PIN(0, 0, NO_GPIO, 0), + + // Not connected + NC = (int)0xFFFFFFFF, + + // ---------- LPCXpresso 4337 pins ---------- + +#ifdef BOARD_REV_A // for Rev.A + D0 = P2_1, + D1 = P2_0, + D2 = P1_20, + D3 = P1_18, + D4 = P1_16, + D5 = P1_15, + D6 = P1_4, + D7 = P2_2, + D8 = P1_0, + D9 = P1_3, + D10 = P1_5, + D11 = P0_1, + D12 = P0_0, + D13 = P1_19, + SDA = P2_3, + SCL = P2_4, + + A0 = P4_3, + A1 = P4_1, + A2 = PF_8, + A3 = P7_5, + A4 = P1_14, + A5 = P2_5, + + LED_GREEN = GPIO0_14, + LED_RED = GPIO3_7, + LED_BLUE = GPIO3_5, + + // Serial pins + UART0_TX = P2_0, + UART0_RX = P2_1, + USBTX = UART0_TX, + USBRX = UART0_RX, +#else // for Rev.B + D0 = P1_14, + D1 = P3_4, + D2 = P2_13, + D3 = P1_8, + D4 = P2_6, + D5 = P1_7, + D6 = P2_9, + D7 = P2_2, + D8 = P3_5, + D9 = P1_2, + D10 = P1_5, + D11 = P1_4, + D12 = P1_3, + D13 = PF_4, + SDA = P2_3, + SCL = P2_4, + + A0 = P4_3, + A1 = P4_1, + A2 = PF_8, + A3 = P7_5, + A4 = P2_11, + A5 = P2_5, + + LED_GREEN = P2_10, + LED_RED = P6_11, + LED_BLUE = P6_9, + + // Serial pins + UART0_TX = P6_4, + UART0_RX = P2_1, + UART1_TX = D1, + UART1_RX = D0, + USBTX = UART0_TX, + USBRX = UART0_RX, +#endif + + I2C_SDA = SDA, + I2C_SDL = SCL, + + LED1 = LED_RED, + LED2 = LED_BLUE, + LED3 = LED_GREEN, + LED4 = LED_RED, + +// UART1_TX = P5_6, +// UART1_RX = P1_14, +// UART2_TX = P2_10, +// UART2_RX = P2_11, +// UART3_TX = P2_3, +// UART3_RX = P2_4, + +/* + // Analog pins + ADC4 = P4_3, + ADC2 = P4_1, + ADC0 = P7_4, + ADC1 = P7_5, + ADC3 = P7_7, + DAC0 = P4_4, +*/ + + // USB pins + //P_USB0_TX = SFP_USB1, + //P_USB0_RX = SFP_USB1, + + +/* + // PWM pins + // 210E 210 200E 200 + // ---- ---- ---- ---- + PWM1 = P1_7, // J9-3 J9-3 S2-3 S2-3 + PWM2 = P7_6, // J9-8 J9-8 S4-6 S4-6 + PWM3 = P6_12, // J10-1 J10-1 S10-3 n/p + PWM4 = P4_6, // J10-3 J10-3 S2-6 S2-6 + PWM5 = P7_5, // J8-2 J8-2 S4-4 S4-4 + PWM6 = P4_1, // J8-3 J8-3 S3-4 S3-4 + PWM7 = P7_7, // J8-4 J8-4 S4-5 S4-5 + PWM8 = P2_8, // J12-4 n/p S8-3 n/p + PWM9 = P2_9, // J12-6 n/p S9-3 n/p + PWM10 = P7_1, // J13-5 n/p S9-8 n/p + PWM11 = P7_0, // J13-6 n/p S9-9 n/p + PWM12 = P1_5, // J14-7 n/p S10-6 n/p +*/ + + // ---------- End of LPCXpresso 4337 pins ---------- +} PinName; + +typedef enum { + PullUp = 0, + PullDown = 3, + PullNone = 2, + Repeater = 1, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/device.h new file mode 100644 index 0000000000..8bc6661696 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/TARGET_LPC4337/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 1 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogin_api.c new file mode 100644 index 0000000000..f564717ac9 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogin_api.c @@ -0,0 +1,134 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "gpio_api.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P4_3, ADC0_0, 0}, + {P4_1, ADC0_1, 0}, + {PF_8, ADC0_2, 0}, + {P7_5, ADC0_3, 0}, + {P7_4, ADC0_4, 0}, + {PF_10, ADC0_5, 0}, + {PB_6, ADC0_6, 0}, + {PC_3, ADC1_0, 0}, + {PC_0, ADC1_1, 0}, + {PF_9, ADC1_2, 0}, + {PF_6, ADC1_3, 0}, + {PF_5, ADC1_4, 0}, + {PF_11, ADC1_5, 0}, + {P7_7, ADC1_6, 0}, + {PF_7, ADC1_7, 0}, + {NC, NC, 0 } +}; + +void analogin_init(analogin_t *obj, PinName pin) { + ADCName name; + + name = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (LPC_ADC_T *)NC); + + // Set ADC register, number and channel + obj->num = (name >> ADC0_7) ? 1 : 0; + obj->ch = name % (ADC0_7 + 1); + obj->adc = (LPC_ADC_T *) (obj->num > 0) ? LPC_ADC1 : LPC_ADC0; + + // Reset pin function to GPIO + gpio_set(pin); + // Select ADC on analog function select register in SCU + LPC_SCU->ENAIO[obj->num] |= (1 << obj->ch); + + // Calculate minimum clock divider + // clkdiv = divider - 1 + uint32_t PCLK = SystemCoreClock; + uint32_t adcRate = 400000; + uint32_t clkdiv = div_round_up(PCLK, adcRate) - 1; + + // Set the generic software-controlled ADC settings + obj->adc->CR = (0 << 0) // SEL: 0 = no channels selected + | (clkdiv << 8) // CLKDIV: + | (0 << 16) // BURST: 0 = software control + | (1 << 21) // PDN: 1 = operational + | (0 << 24) // START: 0 = no start + | (0 << 27); // EDGE: not applicable +} + +static inline uint32_t adc_read(analogin_t *obj) { + uint32_t temp; + uint8_t channel = obj->ch; + LPC_ADC_T *pADC = obj->adc; + + // Select the appropriate channel and start conversion + pADC->CR |= ADC_CR_CH_SEL(channel); + temp = pADC->CR & ~ADC_CR_START_MASK; + pADC->CR = temp | (ADC_CR_START_MODE_SEL(ADC_START_NOW)); + + // Wait for DONE bit and read data + while (!(pADC->STAT & ADC_CR_CH_SEL(channel))); + temp = pADC->DR[channel]; + + // Deselect channel and return result + pADC->CR &= ~ADC_CR_START_MASK; + pADC->CR &= ~ADC_CR_CH_SEL(channel); + return ADC_DR_RESULT(temp); +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogout_api.c new file mode 100644 index 0000000000..518cfd1ce7 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/analogout_api.c @@ -0,0 +1,86 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "analogout_api.h" + +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "gpio_api.h" + +static const PinMap PinMap_DAC[] = { +#ifdef TARGET_LPC4337 + {P4_3, DAC_0, 0}, +#else + {P4_4, DAC_0, 0}, +#endif + {NC, NC, 0} +}; + +void analogout_init(dac_t *obj, PinName pin) { + obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); + MBED_ASSERT(obj->dac != (DACName)NC); + + // Reset pin function to GPIO + gpio_set(pin); + // Select DAC on analog function select register in SCU + LPC_SCU->ENAIO[2] |= 1; // Sets pin as DAC + + // Set bias=0 for maximum DAC update rate (1 MHz) + LPC_DAC->CR &= ~DAC_BIAS_EN; + // Enable DAC and DMA + LPC_DAC->CTRL |= DAC_DMA_ENA; + + analogout_write_u16(obj, 0); +} + +void analogout_free(dac_t *obj) {} + +static inline void dac_write(int value) { + + // Set the DAC output + LPC_DAC->CR = DAC_SET(value); +} + +static inline int dac_read() { + return (DAC_GET(LPC_DAC->CR)); +} + +void analogout_write(dac_t *obj, float value) { + if (value < 0.0f) { + dac_write(0); + } else if (value > 1.0f) { + dac_write(DAC_RANGE); + } else { + dac_write(value * (float)DAC_RANGE); + } +} + +void analogout_write_u16(dac_t *obj, uint16_t value) { + dac_write(value >> 6); // 10-bit +} + +float analogout_read(dac_t *obj) { + uint32_t value = dac_read(); + return (float)value * (1.0f / (float)DAC_RANGE); +} + +uint16_t analogout_read_u16(dac_t *obj) { + uint32_t value = dac_read(); // 10-bit + return (value << 6) | ((value >> 4) & 0x003F); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c new file mode 100644 index 0000000000..be390f7a71 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/ethernet_api.c @@ -0,0 +1,528 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contribution by Nitin Bhaskar(nitin.bhaskar.27.09@gmail.com) + */ +#include "ethernet_api.h" + +#include <string.h> +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "mbed_error.h" +#include "pinmap.h" + +#define NEW_LOGIC 0 +#define NEW_ETH_BUFFER 0 + +#if NEW_ETH_BUFFER + +#define NUM_RX_FRAG 4 // Number of Rx Fragments (== packets) +#define NUM_TX_FRAG 3 // Number of Tx Fragments (== packets) + +#define ETH_MAX_FLEN 1536 // Maximum Ethernet Frame Size +#define ETH_FRAG_SIZE ETH_MAX_FLEN // Packet Fragment size (same as packet length) + +#else + +// Memfree calculation: +// (16 * 1024) - ((2 * 4 * NUM_RX) + (2 * 4 * NUM_RX) + (0x300 * NUM_RX) + +// (2 * 4 * NUM_TX) + (1 * 4 * NUM_TX) + (0x300 * NUM_TX)) = 8556 +/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */ +#define NUM_RX_FRAG 4 /* Num.of RX Fragments 4*1536= 6.0kB */ +#define NUM_TX_FRAG 3 /* Num.of TX Fragments 3*1536= 4.6kB */ +//#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +//#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ +#define ETH_FRAG_SIZE 0x300 /* Packet Fragment size 1536/2 Bytes */ +#define ETH_MAX_FLEN 0x300 /* Max. Ethernet Frame Size */ + +const int ethernet_MTU_SIZE = 0x300; + +#endif + +#define ETHERNET_ADDR_SIZE 6 + +/* Descriptors Fields bits */ +#define TRDES_OWN_BIT (1U<<31) /* Own bit in RDES0 & TDES0 */ +#define RX_END_RING (1<<15) /* Receive End of Ring bit in RDES1 */ +#define RX_NXTDESC_FLAG (1<<14) /* Second Address Chained bit in RDES1 */ +#define TX_LAST_SEGM (1<<29) /* Last Segment bit in TDES0 */ +#define TX_FIRST_SEGM (1<<28) /* First Segment bit in TDES0 */ +#define TX_END_RING (1<<21) /* Transmit End of Ring bit in TDES0 */ +#define TX_NXTDESC_FLAG (1<<20) /* Second Address Chained bit in TDES0 */ + +PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Status; + unsigned int Ctrl; + unsigned int BufAddr1; + unsigned int NextDescAddr; +}; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Status; + unsigned int Ctrl; + unsigned int BufAddr1; + unsigned int NextDescAddr; +}; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +/* ETHMODE RMII SELECT */ +#define RMII_SELECT 0x04 +/* define to tell PHY about write operation */ +#define MII_WRITE (1 << 1) +/* define to tell PHY about read operation */ +#define MII_READ (0 << 1) +/* define to enable duplex mode */ +#define MAC_DUPLEX_MODE (1 << 11) + +/* MAC_FRAME_FILTER register bit defines */ +#define MAC_FRAME_FILTER_PR (1 << 0) /* Promiscuous Mode */ +#define MAC_FRAME_FILTER_RA (1UL << 31) /* Receive all */ + +/* MAC_CONFIG register bit defines */ +#define MAC_CONFIG_RE (1 << 2) /* Receiver enable */ +#define MAC_CONFIG_TE (1 << 3) /* Transmitter Enable */ + +/* DMA_OP_MODE register bit defines */ +#define DMA_OP_MODE_SSR (1 << 1) /* Start/stop receive */ +#define DMA_OP_MODE_SST (1 << 13) /* Start/Stop Transmission Command */ + +/* DMA_INT_EN register bit defines */ +#define DMA_INT_EN_TIE (1 << 0) /* Transmit interrupt enable */ +#define DMA_INT_EN_TSE (1 << 1) /* Transmit stopped enable */ +#define DMA_INT_EN_TUE (1 << 2) /* Transmit buffer unavailable enable */ +#define DMA_INT_EN_TJE (1 << 3) /* Transmit jabber timeout enable */ +#define DMA_INT_EN_OVE (1 << 4) /* Overflow interrupt enable */ +#define DMA_INT_EN_UNE (1 << 5) /* Underflow interrupt enable */ +#define DMA_INT_EN_RIE (1 << 6) /* Receive interrupt enable */ +#define DMA_INT_EN_RUE (1 << 7) /* Receive buffer unavailable enable */ +#define DMA_INT_EN_RSE (1 << 8) /* Received stopped enable */ +#define DMA_INT_EN_RWE (1 << 9) /* Receive watchdog timeout enable */ +#define DMA_INT_EN_ETE (1 << 10) /* Early transmit interrupt enable */ +#define DMA_INT_EN_FBE (1 << 13) /* Fatal bus error enable */ +#define DMA_INT_EN_ERE (1 << 14) /* Early receive interrupt enable */ +#define DMA_INT_EN_AIE (1 << 15) /* Abnormal interrupt summary enable */ +#define DMA_INT_EN_NIE (1 << 16) /* Normal interrupt summary enable */ + + + +/* PHY Support Register */ +#define SUPP_SPEED 0x00004000 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x1000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x01 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ + +static int phy_read(unsigned int PhyReg); +static int phy_write(unsigned int PhyReg, unsigned short Data); + +static void txdscr_init(void); +static void rxdscr_init(void); + +#if defined (__ICCARM__) +# define AHBSRAM1 +#elif defined(TOOLCHAIN_GCC_CR) +# define AHBSRAM1 __attribute__((section(".data.$RamPeriph32"))) +#else +# define AHBSRAM1 __attribute__((section("AHBSRAM1"),aligned)) +#endif + +AHBSRAM1 volatile uint8_t rxbuf[NUM_RX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile uint8_t txbuf[NUM_TX_FRAG][ETH_FRAG_SIZE]; +AHBSRAM1 volatile RX_DESC_TypeDef rxdesc[NUM_RX_FRAG]; +AHBSRAM1 volatile TX_DESC_TypeDef txdesc[NUM_TX_FRAG]; + +#ifndef min +#define min(x, y) (((x)<(y))?(x):(y)) +#endif + +static uint32_t phy_id = 0; +static uint32_t TxDescIndex = 0; +static uint32_t RxDescIndex = 0; +static uint32_t RxOffset = 0; + +/*---------------------------------------------------------------------------- + Ethernet Device initialize + *----------------------------------------------------------------------------*/ +int ethernet_init() +{ + int regv, tout; + char mac[ETHERNET_ADDR_SIZE]; + + pin_function(PC_0, (SCU_MODE_INACT | FUNC3)); /* Enable ENET RX CLK */ + pin_function(P1_19, (SCU_MODE_INACT | FUNC0)); /* Enable ENET TX CLK */ + + /* Ethernet pinmuxing */ + pin_function(P2_0, SCU_PINIO_FAST | FUNC7); /* ENET_MDC */ + pin_function(P1_17, SCU_PINIO_FAST | FUNC3); /* ENET_MDIO */ + pin_function(P1_18, SCU_PINIO_FAST | FUNC3); /* ENET_TXD0 */ + pin_function(P1_20, SCU_PINIO_FAST | FUNC3); /* ENET_TXD1 */ + pin_function(P1_19, SCU_PINIO_FAST | FUNC0); /* ENET_REF */ + pin_function(P0_1, SCU_PINIO_FAST | FUNC6); /* ENET_TX_EN */ + pin_function(P1_15, SCU_PINIO_FAST | FUNC3); /* ENET_RXD0 */ + pin_function(P0_0, SCU_PINIO_FAST | FUNC2); /* ENET_RXD1 */ + pin_function(P1_16, SCU_PINIO_FAST | FUNC3); /* ENET_CRS */ + pin_function(PC_9, SCU_PINIO_FAST | FUNC3); /* ENET_RX_ER */ + pin_function(P1_16, SCU_PINIO_FAST | FUNC7); /* ENET_RXDV */ + + LPC_CREG->CREG6 |= RMII_SELECT; + + /* perform RGU soft reset */ + LPC_RGU->RESET_CTRL0 = 1 << 22; + LPC_RGU->RESET_CTRL0 = 0; + + /* Wait until reset is performed */ + while(1) { + if (LPC_RGU->RESET_ACTIVE_STATUS0 & (1 << 22)) + break; + } + + /* Reset MAC DMA Controller */ + LPC_ETHERNET->DMA_BUS_MODE |= 0x01; + while(LPC_ETHERNET->DMA_BUS_MODE & 0x01); + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return -1; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + if (phy_id != DP83848C_ID && phy_id != LAN8720_ID) { + error("Unknown Ethernet PHY (%x)", (unsigned int)phy_id); + } + + ethernet_set_link(-1, 0); + + /* Set the Ethernet MAC Address registers */ + ethernet_address(mac); + LPC_ETHERNET->MAC_ADDR0_HIGH = (mac[5] << 8) | mac[4]; + LPC_ETHERNET->MAC_ADDR0_LOW = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0]; + + txdscr_init(); /* initialize DMA TX Descriptor */ + rxdscr_init(); /* initialize DMA RX Descriptor */ + + /* Configure Filter */ + LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FRAME_FILTER_PR | MAC_FRAME_FILTER_RA; + + /* Enable Receiver and Transmitter */ + LPC_ETHERNET->MAC_CONFIG |= (MAC_CONFIG_RE | MAC_CONFIG_TE); + + //LPC_ETHERNET->DMA_INT_EN = DMA_INT_EN_NIE | DMA_INT_EN_RIE | DMA_INT_EN_TJE; /* Enable EMAC interrupts. */ + + /* Start Transmission & Receive processes */ + LPC_ETHERNET->DMA_OP_MODE |= (DMA_OP_MODE_SST | DMA_OP_MODE_SSR); + + return 0; +} + +/*---------------------------------------------------------------------------- + Ethernet Device Uninitialize + *----------------------------------------------------------------------------*/ +void ethernet_free() +{ +} + +/*---------------------------------------------------------------------------- + Ethernet write + *----------------------------------------------------------------------------*/ +int ethernet_write(const char *data, int slen) +{ + if (slen > ETH_FRAG_SIZE) + return -1; + + txdesc[TxDescIndex].Ctrl = slen; + memcpy((void *)txdesc[TxDescIndex].BufAddr1, data, slen); + return slen; +} + +/*---------------------------------------------------------------------------- + Ethernet Send + *----------------------------------------------------------------------------*/ +int ethernet_send() +{ + int s = txdesc[TxDescIndex].Ctrl; + txdesc[TxDescIndex].Status |= TRDES_OWN_BIT; + LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1; // Wake Up the DMA if it's in Suspended Mode + TxDescIndex++; + if (TxDescIndex == NUM_TX_FRAG) + TxDescIndex = 0; + + return s; +} + +/*---------------------------------------------------------------------------- + Ethernet receive + *----------------------------------------------------------------------------*/ +int ethernet_receive() +{ + int i, slen = 0; + for (i = RxDescIndex;; i++) { + if (rxdesc[i].Status & TRDES_OWN_BIT) + return (slen - RxOffset); + else + slen += (rxdesc[i].Status >> 16) & 0x03FFF; + } + return 0; +} + + +/*---------------------------------------------------------------------------- + Ethernet read + *----------------------------------------------------------------------------*/ +int ethernet_read(char *data, int dlen) +{ + int copylen; + uint32_t *pSrc = (uint32_t *)rxdesc[RxDescIndex].BufAddr1; + copylen = (rxdesc[RxDescIndex].Status >> 16) & 0x03FFF; + if (rxdesc[RxDescIndex].Status & TRDES_OWN_BIT || (dlen + RxOffset) > copylen) + return -1; + + if ((dlen + RxOffset) == copylen) { + memcpy(&pSrc[RxOffset], data, copylen); + rxdesc[RxDescIndex].Status = TRDES_OWN_BIT; + RxDescIndex++; + RxOffset = 0; + if (RxDescIndex == NUM_RX_FRAG) + RxDescIndex = 0; + } else if ((dlen + RxOffset) < copylen) { + copylen = dlen; + memcpy(&pSrc[RxOffset], data, copylen); + RxOffset += dlen; + } + return copylen; +} + +int ethernet_link(void) +{ + + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) +{ + unsigned int timeOut; + + while(LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY); + LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | MII_WRITE; + LPC_ETHERNET->MAC_MII_DATA = Data; + LPC_ETHERNET->MAC_MII_ADDR |= MIND_BUSY; // Start PHY Write Cycle + + /* Wait utill operation completed */ + for (timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { + if ((LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY) == 0) { + break; + } + } + + return -1; +} + +static int phy_read(unsigned int PhyReg) +{ + unsigned int timeOut; + + while(LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY); + LPC_ETHERNET->MAC_MII_ADDR = (DP83848C_DEF_ADR<<11) | (PhyReg<<6) | MII_READ; + LPC_ETHERNET->MAC_MII_ADDR |= MIND_BUSY; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_ETHERNET->MAC_MII_ADDR & MIND_BUSY) == 0) { + return LPC_ETHERNET->MAC_MII_DATA; /* Return a 16-bit value. */ + } + } + + return -1; +} + +static void txdscr_init() +{ + int i; + + for(i = 0; i < NUM_TX_FRAG; i++) { + txdesc[i].Status = TX_LAST_SEGM | TX_FIRST_SEGM;; + txdesc[i].Ctrl = 0; + txdesc[i].BufAddr1 = (uint32_t)&txbuf[i]; + if (i == (NUM_RX_FRAG - 1)) { + txdesc[i].Status |= TX_END_RING; + } + } + + LPC_ETHERNET->DMA_TRANS_DES_ADDR = (uint32_t)txdesc; /* Set EMAC Transmit Descriptor Registers. */ +} + + +static void rxdscr_init() +{ + int i; + + for(i = 0; i < NUM_RX_FRAG; i++) { + rxdesc[i].Status = TRDES_OWN_BIT; + rxdesc[i].Ctrl = ETH_FRAG_SIZE; + rxdesc[i].BufAddr1 = (uint32_t)&rxbuf[i]; + if (i == (NUM_RX_FRAG - 1)) { + rxdesc[i].Ctrl |= RX_END_RING; + } + } + + LPC_ETHERNET->DMA_REC_DES_ADDR = (uint32_t)rxdesc; /* Set EMAC Receive Descriptor Registers. */ +} + +void ethernet_address(char *mac) +{ + mbed_mac_address(mac); +} + +void ethernet_set_link(int speed, int duplex) +{ + volatile unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + + phy_data = PHY_AUTO_NEG; + + } else { + + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for(tout = 100; tout; tout--) { + __NOP(); /* A short delay */ + } + + switch(phy_id) { + case DP83848C_ID: + + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + /* Full duplex is enabled. */ + LPC_ETHERNET->MAC_CONFIG |= MAC_DUPLEX_MODE; + } else { + LPC_ETHERNET->MAC_CONFIG &= ~MAC_DUPLEX_MODE; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_ETHERNET->MAC_CONFIG &= ~SUPP_SPEED; + } else { + LPC_ETHERNET->MAC_CONFIG |= SUPP_SPEED; + } + break; + + case LAN8720_ID: + + for(tout = 100; tout; tout--) { + phy_data = phy_read(PHY_REG_BMSR); + if (phy_data & PHY_STS_DUPLEX) + break; + } + + if (phy_data & PHY_STS_DUPLEX) { + /* Full duplex is enabled. */ + LPC_ETHERNET->MAC_CONFIG |= MAC_DUPLEX_MODE; + } else { + LPC_ETHERNET->MAC_CONFIG &= ~MAC_DUPLEX_MODE; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_ETHERNET->MAC_CONFIG &= ~SUPP_SPEED; + } else { + LPC_ETHERNET->MAC_CONFIG |= SUPP_SPEED; + } + break; + } +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_api.c new file mode 100644 index 0000000000..7c27b19661 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_api.c @@ -0,0 +1,63 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + MBED_ASSERT(pin != (PinName)NC); + int f = 0; + unsigned int port = (unsigned int)MBED_GPIO_PORT(pin); + + f = SCU_PINIO_FAST | ((port > 4) ? (4) : (0)); + pin_function(pin, f); + + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + LPC_GPIO_T *port_reg = (LPC_GPIO_T *)(LPC_GPIO_PORT_BASE); + unsigned int port = (unsigned int)MBED_GPIO_PORT(pin); + + obj->reg_set = &port_reg->SET[port]; + obj->reg_clr = &port_reg->CLR[port]; + obj->reg_in = &port_reg->PIN[port]; + obj->reg_dir = &port_reg->DIR[port]; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_irq_api.c new file mode 100644 index 0000000000..11979304ae --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_irq_api.c @@ -0,0 +1,154 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include <stddef.h> +#include "gpio_irq_api.h" +#include "mbed_error.h" +#include "cmsis.h" + +/* The LPC43xx implements GPIO pin and group interrupts. Any pin in the + * 8 32-bit GPIO ports can interrupt. On group interrupts a pin can + * only interrupt on the rising or falling edge, not both as required + * by mbed. Also, group interrupts can't be cleared individually. + * This implementation uses pin interrupts (8 on M4/M3, 1 on M0). + * A future implementation may provide group interrupt support. + */ +#if !defined(CORE_M0) +#define CHANNEL_MAX 8 +#else +#define CHANNEL_MAX 1 +#endif + +static uint32_t channel_ids[CHANNEL_MAX] = {0}; +static uint8_t channel = 0; +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(void) { + uint32_t rise = LPC_GPIO_PIN_INT->RISE; + uint32_t fall = LPC_GPIO_PIN_INT->FALL; + uint32_t pmask; + int i; + + for (i = 0; i < CHANNEL_MAX; i++) { + pmask = (1 << i); + if (rise & pmask) { + /* Rising edge interrupts */ + if (channel_ids[i] != 0) { + irq_handler(channel_ids[i], IRQ_RISE); + } + /* Clear rising edge detected */ + LPC_GPIO_PIN_INT->RISE = pmask; + } + if (fall & pmask) { + /* Falling edge interrupts */ + if (channel_ids[i] != 0) { + irq_handler(channel_ids[i], IRQ_FALL); + } + /* Clear falling edge detected */ + LPC_GPIO_PIN_INT->FALL = pmask; + } + } +} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + uint32_t portnum, pinnum; //, pmask; + + if (pin == NC) return -1; + + irq_handler = handler; + + /* Set port and pin numbers */ + obj->port = portnum = MBED_GPIO_PORT(pin); + obj->pin = pinnum = MBED_GPIO_PIN(pin); + + /* Add to channel table */ + channel_ids[channel] = id; + obj->ch = channel; + + /* Clear rising and falling edge detection */ + //pmask = (1 << channel); + //LPC_GPIO_PIN_INT->IST = pmask; + + /* Set SCU */ + if (channel < 4) { + LPC_SCU->PINTSEL0 &= ~(0xFF << (portnum << 3)); + LPC_SCU->PINTSEL0 |= (((portnum << 5) | pinnum) << (channel << 3)); + } else { + LPC_SCU->PINTSEL1 &= ~(0xFF << ((portnum - 4) << 3)); + LPC_SCU->PINTSEL1 |= (((portnum << 5) | pinnum) << ((channel - 4) << 3)); + } + +#if !defined(CORE_M0) + NVIC_SetVector((IRQn_Type)(PIN_INT0_IRQn + channel), (uint32_t)handle_interrupt_in); + NVIC_EnableIRQ((IRQn_Type)(PIN_INT0_IRQn + channel)); +#else + NVIC_SetVector((IRQn_Type)PIN_INT4_IRQn, (uint32_t)handle_interrupt_in); + NVIC_EnableIRQ((IRQn_Type)PIN_INT4_IRQn); +#endif + + // Increment channel number + channel++; + channel %= CHANNEL_MAX; + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + uint32_t pmask; + + /* Clear pending interrupts */ + pmask = (1 << obj->ch); + LPC_GPIO_PIN_INT->IST = pmask; + + /* Configure pin interrupt */ + LPC_GPIO_PIN_INT->ISEL &= ~pmask; + if (event == IRQ_RISE) { + /* Rising edge interrupts */ + if (enable) { + LPC_GPIO_PIN_INT->SIENR |= pmask; + } else { + LPC_GPIO_PIN_INT->CIENR |= pmask; + } + } else { + /* Falling edge interrupts */ + if (enable) { + LPC_GPIO_PIN_INT->SIENF |= pmask; + } else { + LPC_GPIO_PIN_INT->CIENF |= pmask; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { +#if !defined(CORE_M0) + NVIC_EnableIRQ((IRQn_Type)(PIN_INT0_IRQn + obj->ch)); +#else + NVIC_EnableIRQ((IRQn_Type)(PIN_INT4_IRQn + obj->ch)); +#endif +} + +void gpio_irq_disable(gpio_irq_t *obj) { +#if !defined(CORE_M0) + NVIC_DisableIRQ((IRQn_Type)(PIN_INT0_IRQn + obj->ch)); +#else + NVIC_DisableIRQ((IRQn_Type)(PIN_INT4_IRQn + obj->ch)); +#endif +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c new file mode 100644 index 0000000000..5515e85e84 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c @@ -0,0 +1,395 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +// SCU mode for I2C SCL/SDA pins +#define SCU_PINIO_I2C SCU_PINIO_PULLNONE + +static const PinMap PinMap_I2C_SDA[] = { + {P_DED, I2C_0, 0}, + {P2_3, I2C_1, (SCU_PINIO_I2C | 1)}, + {PE_13, I2C_1, (SCU_PINIO_I2C | 2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P_DED, I2C_0, 0}, + {P2_4, I2C_1, (SCU_PINIO_I2C | 1)}, + {PE_14, I2C_1, (SCU_PINIO_I2C | 2)}, + {NC, NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[2][4] = { + {0x0C, 0x20, 0x24, 0x28}, + {0x30, 0x34, 0x38, 0x3C} +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_T *)pinmap_merge(i2c_sda, i2c_scl); + + if ((int)obj->i2c == NC) { + error("I2C pin mapping failed"); + } + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + // Set SCU functions + if (scl == P_DED) { + // Enable dedicated I2C0 SDA and SCL pins (open drain) + LPC_SCU->SFSI2C0 = (1 << 11) | (1 << 3); + } else { + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); + } +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if(last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // [TODO] set pclk to /4 + uint32_t PCLK = SystemCoreClock / 4; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return count; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return length - 1; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return I2C_ERROR_BUS_BUSY; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if(status != 0x28) { + i2c_stop(obj); + return i; + } + } + + // clearing the serial interrupt here might cause an unintended rewrite of the last byte + // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 + // i2c_clear_SI(obj); + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 0x18: case 0x28: // Master transmit ACKs + ack = 1; + break; + case 0x40: // Master receive address transmitted ACK + ack = 1; + break; + case 0xB8: // Slave transmit ACK + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + if (enable_slave != 0) { + i2c_conclr(obj, 1, 1, 1, 0); + i2c_conset(obj, 0, 0, 0, 1); + } else { + i2c_conclr(obj, 1, 1, 1, 1); + } +} + +int i2c_slave_receive(i2c_t *obj) { + int status; + int retval; + + status = i2c_status(obj); + switch(status) { + case 0x60: retval = 3; break; + case 0x70: retval = 2; break; + case 0xA8: retval = 1; break; + default : retval = 0; break; + } + + return(retval); +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count = 0; + int status; + + do { + i2c_clear_SI(obj); + i2c_wait_SI(obj); + status = i2c_status(obj); + if((status == 0x80) || (status == 0x90)) { + data[count] = I2C_DAT(obj) & 0xFF; + } + count++; + } while (((status == 0x80) || (status == 0x90) || + (status == 0x060) || (status == 0x70)) && (count < length)); + + if(status != 0xA0) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return count; +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count = 0; + int status; + + if(length <= 0) { + return(0); + } + + do { + status = i2c_do_write(obj, data[count], 0); + count++; + } while ((count < length) && (status == 0xB8)); + + if ((status != 0xC0) && (status != 0xC8)) { + i2c_stop(obj); + } + + i2c_clear_SI(obj); + + return(count); +} + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + uint32_t addr; + + if ((idx >= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; + *((uint32_t *) addr) = address & 0xFF; + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; + *((uint32_t *) addr) = mask & 0xFE; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/objects.h new file mode 100644 index 0000000000..189b1b5aa5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/objects.h @@ -0,0 +1,79 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "gpio_object.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t port; + uint32_t pin; + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_out; + __I uint32_t *reg_in; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + PWMName pwm; + uint8_t mr; +}; + +struct serial_s { + LPC_USART_T *uart; + int index; +}; + +struct analogin_s { + LPC_ADC_T *adc; + uint8_t num; + uint8_t ch; +}; + +struct dac_s { + DACName dac; +}; + +struct can_s { + LPC_CCAN_T *dev; +}; + +struct i2c_s { + LPC_I2C_T *i2c; +}; + +struct spi_s { + LPC_SSP_T *spi; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pinmap.c new file mode 100644 index 0000000000..fd3ff7532e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pinmap.c @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +void pin_function(PinName pin, int function) { + MBED_ASSERT(pin != (PinName)NC); + + __IO uint32_t *reg = (__IO uint32_t*) MBED_SCU_REG(pin); + + // Set pin function + *reg = function; +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); // && (mode != OpenDrain)); + + __IO uint32_t *reg = (__IO uint32_t*) MBED_SCU_REG(pin); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + *reg = tmp; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/port_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/port_api.c new file mode 100644 index 0000000000..b25ec5d816 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/port_api.c @@ -0,0 +1,146 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +// Lookup table to determine SCU offset for GPIO [port][pin] +// Supports eight 16-bit ports to limit table size +#define _SO(MBED_PIN) (MBED_PIN >> 18) + +static const uint8_t _scu_off[][16] = +{ // GPIO0 to GPIO3 + { _SO(GPIO0_0), _SO(GPIO0_1), _SO(GPIO0_2), _SO(GPIO0_3), + _SO(GPIO0_4), _SO(GPIO0_5), _SO(GPIO0_6), _SO(GPIO0_7), + _SO(GPIO0_8), _SO(GPIO0_9), _SO(GPIO0_10), _SO(GPIO0_11), + _SO(GPIO0_12), _SO(GPIO0_13), _SO(GPIO0_14), _SO(GPIO0_15) + }, + { _SO(GPIO1_0), _SO(GPIO1_1), _SO(GPIO1_2), _SO(GPIO1_3), + _SO(GPIO1_4), _SO(GPIO1_5), _SO(GPIO1_6), _SO(GPIO1_7), + _SO(GPIO1_8), _SO(GPIO1_9), _SO(GPIO1_10), _SO(GPIO1_11), + _SO(GPIO1_12), _SO(GPIO1_13), _SO(GPIO1_14), _SO(GPIO1_15) + }, + { _SO(GPIO2_0), _SO(GPIO2_1), _SO(GPIO2_2), _SO(GPIO2_3), + _SO(GPIO2_4), _SO(GPIO2_5), _SO(GPIO2_6), _SO(GPIO2_7), + _SO(GPIO2_8), _SO(GPIO2_9), _SO(GPIO2_10), _SO(GPIO2_11), + _SO(GPIO2_12), _SO(GPIO2_13), _SO(GPIO2_14), _SO(GPIO2_15) + }, + { _SO(GPIO3_0), _SO(GPIO3_1), _SO(GPIO3_2), _SO(GPIO3_3), + _SO(GPIO3_4), _SO(GPIO3_5), _SO(GPIO3_6), _SO(GPIO3_7), + _SO(GPIO3_8), _SO(GPIO3_9), _SO(GPIO3_10), _SO(GPIO3_11), + _SO(GPIO3_12), _SO(GPIO3_13), _SO(GPIO3_14), _SO(GPIO3_15) + }, +}; + +// Use alternate encoding for ports 4 to 7 so lookup stays within uint8 +#define _S2(MBED_PIN) (((MBED_PIN >> 19) & 0xf0) | ((MBED_PIN >> 18) & 0x0f)) + +static const uint8_t _scu_off2[][16] = +{ // GPIO4 to GPIO7 + { _S2(GPIO4_0), _S2(GPIO4_1), _S2(GPIO4_2), _S2(GPIO4_3), + _S2(GPIO4_4), _S2(GPIO4_5), _S2(GPIO4_6), _S2(GPIO4_7), + _S2(GPIO4_8), _S2(GPIO4_9), _S2(GPIO4_10), _S2(GPIO4_11), + _S2(GPIO4_12), _S2(GPIO4_13), _S2(GPIO4_14), _S2(GPIO4_15) + }, + { _S2(GPIO5_0), _S2(GPIO5_1), _S2(GPIO5_2), _S2(GPIO5_3), + _S2(GPIO5_4), _S2(GPIO5_5), _S2(GPIO5_6), _S2(GPIO5_7), + _S2(GPIO5_8), _S2(GPIO5_9), _S2(GPIO5_10), _S2(GPIO5_11), + _S2(GPIO5_12), _S2(GPIO5_13), _S2(GPIO5_14), _S2(GPIO5_15) + }, + { _S2(GPIO6_0), _S2(GPIO6_1), _S2(GPIO6_2), _S2(GPIO6_3), + _S2(GPIO6_4), _S2(GPIO6_5), _S2(GPIO6_6), _S2(GPIO6_7), + _S2(GPIO6_8), _S2(GPIO6_9), _S2(GPIO6_10), _S2(GPIO6_11), + _S2(GPIO6_12), _S2(GPIO6_13), _S2(GPIO6_14), _S2(GPIO6_15) + }, + { _S2(GPIO7_0), _S2(GPIO7_1), _S2(GPIO7_2), _S2(GPIO7_3), + _S2(GPIO7_4), _S2(GPIO7_5), _S2(GPIO7_6), _S2(GPIO7_7), + _S2(GPIO7_8), _S2(GPIO7_9), _S2(GPIO7_10), _S2(GPIO7_11), + _S2(GPIO7_12), _S2(GPIO7_13), _S2(GPIO7_14), _S2(GPIO7_15) + }, +}; + +PinName port_pin(PortName port, int pin_n) { + MBED_ASSERT((port <= Port7) && (pin_n < 32)); + int offset = 0; + + // Lookup table only maps pins 0 to 15 + if (pin_n > 15) { + return NC; + } + + // Lookup SCU offset + if (port < Port4) { + offset = _scu_off[port][pin_n]; + } else { + offset = _scu_off2[port - Port4][pin_n]; + offset = ((offset & 0xf0) << 1) | (offset & 0x0f); + } + + // Return pin name + return (PinName)((offset << 18) | GPIO_OFF(port, pin_n)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_T *port_reg = (LPC_GPIO_T *)(LPC_GPIO_PORT_BASE); + + // Do not use masking, because it prevents the use of the unmasked pins + // port_reg->MASK[port] = ~mask; + + obj->reg_out = &port_reg->PIN[port]; + obj->reg_in = &port_reg->PIN[port]; + obj->reg_dir = &port_reg->DIR[port]; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + gpio_set(port_pin(obj->port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<<i)) { + pin_mode(port_pin(obj->port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_out = (*obj->reg_in & ~obj->mask) | (value & obj->mask); +} + +int port_read(port_t *obj) { + return (*obj->reg_in & obj->mask); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pwmout_api.c new file mode 100644 index 0000000000..d8f18a4786 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/pwmout_api.c @@ -0,0 +1,266 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +// PWM implementation for the LPC43xx using State Configurable Timer (SCT) +// * PWM_0 to PWM_15 on mbed use CTOUT_0 to CTOUT_15 outputs on LPC43xx +// * Event 0 is PWM period, events 1 to PWM_EVENT_MAX are PWM channels +// * Default is unified 32-bit timer, but could be configured to use +// a 16-bit timer so a timer is available for other SCT functions + +// configuration options +#define PWM_FREQ_BASE 1000000 // Base frequency 1 MHz = 1000000 +#define PWM_MODE 1 // 0 = 32-bit, 1 = 16-bit low, 2 = 16-bit high + +// macros +#define PWM_SETCOUNT(x) (x - 1) // set count value +#define PWM_GETCOUNT(x) (x + 1) // get count value +#if (PWM_MODE == 0) // unified 32-bit counter, events 1 to 15 + #define PWM_EVENT_MAX (CONFIG_SCT_nEV - 1) // Max PWM channels + #define PWM_CONFIG SCT_CONFIG_32BIT_COUNTER // default config + #define PWM_CTRL &LPC_SCT->CTRL_U // control register + #define PWM_HALT SCT_CTRL_HALT_L // halt counter + #define PWM_CLEAR SCT_CTRL_CLRCTR_L // clock clear + #define PWM_PRE(x) SCT_CTRL_PRE_L(x) // clock prescale + #define PWM_EVT_MASK (1 << 12) // event control mask + #define PWM_LIMIT &LPC_SCT->LIMIT_L // limit register + #define PWM_MATCH(x) &LPC_SCT->MATCH[x].U // match register + #define PWM_MR(x) &LPC_SCT->MATCHREL[x].U // 32-bit match reload register +#elif (PWM_MODE == 1) // 16-bit low counter, events 1 to 7 + #define PWM_EVENT_MAX (CONFIG_SCT_nEV/2 - 1) // Max PWM channels + #define PWM_CONFIG SCT_CONFIG_16BIT_COUNTER // default config + #define PWM_CTRL &LPC_SCT->CTRL_L // control register + #define PWM_HALT SCT_CTRL_HALT_L // halt counter + #define PWM_CLEAR SCT_CTRL_CLRCTR_L // clock clear + #define PWM_PRE(x) SCT_CTRL_PRE_L(x) // clock prescale + #define PWM_EVT_MASK (1 << 12) // event control mask + #define PWM_LIMIT &LPC_SCT->LIMIT_L // limit register + #define PWM_MATCH(x) &LPC_SCT->MATCH[x].L // match register + #define PWM_MR(x) &LPC_SCT->MATCHREL[x].L // 16-bit match reload register +#elif (PWM_MODE == 2) // 16-bit high counter, events 1 to 7 + // [TODO] use events 8 to 15 on mode 2 + #define PWM_EVENT_MAX (CONFIG_SCT_nEV/2 - 1) // Max PWM channels + #define PWM_CONFIG SCT_CONFIG_16BIT_COUNTER // default config + #define PWM_CTRL &LPC_SCT->CTRL_H // control register + #define PWM_HALT SCT_CTRL_HALT_L // halt counter + #define PWM_CLEAR SCT_CTRL_CLRCTR_L // clock clear + #define PWM_PRE(x) SCT_CTRL_PRE_L(x) // clock prescale + #define PWM_EVT_MASK ((1 << 4) | (1 << 12)) // event control mask + #define PWM_LIMIT &LPC_SCT->LIMIT_H // limit register + #define PWM_MATCH(x) &LPC_SCT->MATCH[x].H // match register + #define PWM_MR(x) &LPC_SCT->MATCHREL[x].H // 16-bit match reload register +#else + #error "PWM mode not implemented" +#endif +#define PWM_MR0 PWM_MR(0) // MR register 0 is for period + +static uint8_t event = 0; + +// PORT ID, PWM ID, Pin function +static const PinMap PinMap_PWM[] = { + {P1_1, PWM_7, (SCU_PINIO_FAST | 1)}, + {P1_2, PWM_6, (SCU_PINIO_FAST | 1)}, + {P1_3, PWM_8, (SCU_PINIO_FAST | 1)}, + {P1_4, PWM_9, (SCU_PINIO_FAST | 1)}, + {P1_5, PWM_10, (SCU_PINIO_FAST | 1)}, + {P1_7, PWM_13, (SCU_PINIO_FAST | 2)}, + {P1_8, PWM_12, (SCU_PINIO_FAST | 2)}, + {P1_9, PWM_11, (SCU_PINIO_FAST | 2)}, + {P1_10, PWM_14, (SCU_PINIO_FAST | 2)}, + {P1_11, PWM_15, (SCU_PINIO_FAST | 2)}, + {P2_7, PWM_1, (SCU_PINIO_FAST | 1)}, + {P2_8, PWM_0, (SCU_PINIO_FAST | 1)}, + {P2_9, PWM_3, (SCU_PINIO_FAST | 1)}, + {P2_10, PWM_2, (SCU_PINIO_FAST | 1)}, + {P2_11, PWM_5, (SCU_PINIO_FAST | 1)}, + {P2_12, PWM_4, (SCU_PINIO_FAST | 1)}, + {P4_1, PWM_1, (SCU_PINIO_FAST | 1)}, + {P4_2, PWM_0, (SCU_PINIO_FAST | 1)}, + {P4_3, PWM_3, (SCU_PINIO_FAST | 1)}, + {P4_4, PWM_2, (SCU_PINIO_FAST | 1)}, + {P4_5, PWM_5, (SCU_PINIO_FAST | 1)}, + {P4_6, PWM_4, (SCU_PINIO_FAST | 1)}, + {P6_5, PWM_6, (SCU_PINIO_FAST | 1)}, + {P6_12, PWM_7, (SCU_PINIO_FAST | 1)}, + {P7_0, PWM_14, (SCU_PINIO_FAST | 1)}, + {P7_1, PWM_15, (SCU_PINIO_FAST | 1)}, + {P7_4, PWM_13, (SCU_PINIO_FAST | 1)}, + {P7_5, PWM_12, (SCU_PINIO_FAST | 1)}, + {P7_6, PWM_11, (SCU_PINIO_FAST | 1)}, + {P7_7, PWM_8, (SCU_PINIO_FAST | 1)}, + {PA_4, PWM_9, (SCU_PINIO_FAST | 1)}, + {PB_0, PWM_10, (SCU_PINIO_FAST | 1)}, + {PB_1, PWM_6, (SCU_PINIO_FAST | 5)}, + {PB_2, PWM_7, (SCU_PINIO_FAST | 5)}, + {PB_3, PWM_8, (SCU_PINIO_FAST | 5)}, + {PD_0, PWM_15, (SCU_PINIO_FAST | 1)}, + {PD_2, PWM_7, (SCU_PINIO_FAST | 1)}, + {PD_3, PWM_6, (SCU_PINIO_FAST | 1)}, + {PD_4, PWM_8, (SCU_PINIO_FAST | 1)}, + {PD_5, PWM_9, (SCU_PINIO_FAST | 1)}, + {PD_6, PWM_10, (SCU_PINIO_FAST | 1)}, + {PD_9, PWM_13, (SCU_PINIO_FAST | 1)}, + {PD_11, PWM_14, (SCU_PINIO_FAST | 6)}, + {PD_12, PWM_10, (SCU_PINIO_FAST | 6)}, + {PD_13, PWM_13, (SCU_PINIO_FAST | 6)}, + {PD_14, PWM_11, (SCU_PINIO_FAST | 6)}, + {PD_15, PWM_8, (SCU_PINIO_FAST | 6)}, + {PD_16, PWM_12, (SCU_PINIO_FAST | 6)}, + {PE_5, PWM_3, (SCU_PINIO_FAST | 1)}, + {PE_6, PWM_2, (SCU_PINIO_FAST | 1)}, + {PE_7, PWM_5, (SCU_PINIO_FAST | 1)}, + {PE_8, PWM_4, (SCU_PINIO_FAST | 1)}, + {PE_11, PWM_12, (SCU_PINIO_FAST | 1)}, + {PE_12, PWM_11, (SCU_PINIO_FAST | 1)}, + {PE_13, PWM_14, (SCU_PINIO_FAST | 1)}, + {PE_15, PWM_0, (SCU_PINIO_FAST | 1)}, + {PF_9, PWM_1, (SCU_PINIO_FAST | 2)}, + {NC, NC, 0} +}; + +static unsigned int pwm_clock_mhz; + +static void _pwmout_dev_init() { + uint32_t i; + + // set SCT clock and config + LPC_CCU1->CLKCCU[CLK_MX_SCT].CFG = (1 << 0); // enable SCT clock in CCU1 + LPC_SCT->CONFIG |= PWM_CONFIG; // set config options + *PWM_CTRL |= PWM_HALT; // set HALT bit to stop counter + // clear counter and set prescaler for desired freq + *PWM_CTRL |= PWM_CLEAR | PWM_PRE(SystemCoreClock / PWM_FREQ_BASE - 1); + pwm_clock_mhz = PWM_FREQ_BASE / 1000000; + + // configure SCT events + for (i = 0; i < PWM_EVENT_MAX; i++) { + *PWM_MATCH(i) = 0; // match register + *PWM_MR(i) = 0; // match reload register + LPC_SCT->EVENT[i].STATE = 0xFFFFFFFF; // event happens in all states + LPC_SCT->EVENT[i].CTRL = (i << 0) | PWM_EVT_MASK; // match condition only + } + *PWM_LIMIT = (1 << 0) ; // set event 0 as limit + // initialize period to 20ms: standard for servos, and fine for e.g. brightness control + *PWM_MR0 = PWM_SETCOUNT((uint32_t)(((20 * PWM_FREQ_BASE) / 1000000) * 1000)); + + // initialize SCT outputs + for (i = 0; i < CONFIG_SCT_nOU; i++) { + LPC_SCT->OUT[i].SET = (1 << 0); // event 0 will set SCTOUT_xx + LPC_SCT->OUT[i].CLR = 0; // set clear event when duty cycle + } + LPC_SCT->OUTPUT = 0; // default outputs to clear + + *PWM_CTRL &= ~PWM_HALT; // clear HALT bit to start counter +} + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + MBED_ASSERT((pwm != (PWMName)NC) && (event < PWM_EVENT_MAX)); + + // init SCT clock and outputs on first PWM init + if (event == 0) { + _pwmout_dev_init(); + } + // init PWM object + event++; + obj->pwm = pwm; // pwm output + obj->mr = event; // index of match reload register + + // initial duty cycle is 0 + pwmout_write(obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // set new pulse width + uint32_t us = (uint32_t)((float)PWM_GETCOUNT(*PWM_MR0) * value) * pwm_clock_mhz; + pwmout_pulsewidth_us(obj, us); +} + +float pwmout_read(pwmout_t* obj) { + float v = (float)PWM_GETCOUNT(*PWM_MR(obj->mr)) / (float)PWM_GETCOUNT(*PWM_MR0); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t ticks = pwm_clock_mhz * us; + uint32_t old_ticks = PWM_GETCOUNT(*PWM_MR0); + uint32_t i, v; + + // set new period + *PWM_MR0 = PWM_SETCOUNT(ticks); + + // Scale pulse widths to preserve the duty ratio + for (i = 1; i < PWM_EVENT_MAX; i++) { + v = PWM_GETCOUNT(*PWM_MR(i)); + if (v > 1) { + v = (v * ticks) / old_ticks; + *PWM_MR(i) = PWM_SETCOUNT(v); + } + } +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + // calculate number of ticks + uint32_t v = pwm_clock_mhz * us; + //MBED_ASSERT(PWM_GETCOUNT(*PWM_MR0) >= v); + + if (v > 0) { + // set new match register value and enable SCT output + *PWM_MR(obj->mr) = PWM_SETCOUNT(v); + LPC_SCT->OUT[obj->pwm].CLR = (1 << obj->mr); // on event will clear PWM_XX + } else { + // set match to zero and disable SCT output + *PWM_MR(obj->mr) = 0; + LPC_SCT->OUT[obj->pwm].CLR = 0; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/rtc_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/rtc_api.c new file mode 100644 index 0000000000..aea7e86c13 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/rtc_api.c @@ -0,0 +1,128 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "rtc_api.h" + +// ensure rtc is running (unchanged if already running) + +/* Setup the RTC based on a time structure, ensuring RTC is enabled + * + * Can be clocked by a 32.768KHz oscillator or prescale divider based on the APB clock + * - We want to use the 32khz clock, allowing for sleep mode + * + * Most registers are not changed by a Reset + * - We must initialize these registers between power-on and setting the RTC into operation + + * Clock Control Register + * RTC_CCR[0] : Enable - 0 = Disabled, 1 = Enabled + * RTC_CCR[1] : Reset - 0 = Normal, 1 = Reset + * RTC_CCR[4] : Clock Source - 0 = Prescaler, 1 = 32k Xtal + * + * The RTC may already be running, so we should set it up + * without impacting if it is the case + */ + +void rtc_init(void) { + // Return, if already enabled + if (LPC_RTC->CCR & 1) + return; + + // Enable 1kHz output of 32kHz oscillator + LPC_CREG->CREG0 &= ~((1 << 3) | (1 << 2)); + LPC_CREG->CREG0 |= (0x03 << 6) | (1 << 1) | (1 << 0); + + // Enable RTC + do { + LPC_RTC->CCR |= 1 << 0; + } while ((LPC_RTC->CCR & 1) == 0); +} + +void rtc_free(void) { + // [TODO] +} + +/* + * Little check routine to see if the RTC has been enabled + * + * Clock Control Register + * RTC_CCR[0] : 0 = Disabled, 1 = Enabled + * + */ +int rtc_isenabled(void) { + return(((LPC_RTC->CCR) & 0x01) != 0); +} + +/* + * RTC Registers + * RTC_SEC Seconds 0-59 + * RTC_MIN Minutes 0-59 + * RTC_HOUR Hour 0-23 + * RTC_DOM Day of Month 1-28..31 + * RTC_DOW Day of Week 0-6 + * RTC_DOY Day of Year 1-365 + * RTC_MONTH Month 1-12 + * RTC_YEAR Year 0-4095 + * + * struct tm + * tm_sec seconds after the minute 0-61 + * tm_min minutes after the hour 0-59 + * tm_hour hours since midnight 0-23 + * tm_mday day of the month 1-31 + * tm_mon months since January 0-11 + * tm_year years since 1900 + * tm_wday days since Sunday 0-6 + * tm_yday days since January 1 0-365 + * tm_isdst Daylight Saving Time flag + */ +time_t rtc_read(void) { + // Setup a tm structure based on the RTC + struct tm timeinfo; + timeinfo.tm_sec = LPC_RTC->TIME[RTC_TIMETYPE_SECOND]; + timeinfo.tm_min = LPC_RTC->TIME[RTC_TIMETYPE_MINUTE]; + timeinfo.tm_hour = LPC_RTC->TIME[RTC_TIMETYPE_HOUR]; + timeinfo.tm_mday = LPC_RTC->TIME[RTC_TIMETYPE_DAYOFMONTH]; + timeinfo.tm_wday = LPC_RTC->TIME[RTC_TIMETYPE_DAYOFWEEK]; + timeinfo.tm_yday = LPC_RTC->TIME[RTC_TIMETYPE_DAYOFYEAR]; + timeinfo.tm_mon = LPC_RTC->TIME[RTC_TIMETYPE_MONTH] - 1; + timeinfo.tm_year = LPC_RTC->TIME[RTC_TIMETYPE_YEAR] - 1900; + + // Convert to timestamp + time_t t = mktime(&timeinfo); + + return t; +} + +void rtc_write(time_t t) { + // Convert the time in to a tm + struct tm *timeinfo = localtime(&t); + + // Pause clock, and clear counter register (clears us count) + LPC_RTC->CCR |= 2; + + // Set the RTC + LPC_RTC->TIME[RTC_TIMETYPE_SECOND] = timeinfo->tm_sec; + LPC_RTC->TIME[RTC_TIMETYPE_MINUTE] = timeinfo->tm_min; + LPC_RTC->TIME[RTC_TIMETYPE_HOUR] = timeinfo->tm_hour; + LPC_RTC->TIME[RTC_TIMETYPE_DAYOFMONTH] = timeinfo->tm_mday; + LPC_RTC->TIME[RTC_TIMETYPE_DAYOFWEEK] = timeinfo->tm_wday; + LPC_RTC->TIME[RTC_TIMETYPE_DAYOFYEAR] = timeinfo->tm_yday; + LPC_RTC->TIME[RTC_TIMETYPE_MONTH] = timeinfo->tm_mon + 1; + LPC_RTC->TIME[RTC_TIMETYPE_YEAR] = timeinfo->tm_year + 1900; + + // Restart clock + LPC_RTC->CCR &= ~((uint32_t)2); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/serial_api.c new file mode 100644 index 0000000000..b7202613c5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/serial_api.c @@ -0,0 +1,410 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +// math.h required for floating point operations for baud rate calculation +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "gpio_api.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 4 + +// SCU mode for UART pins +#define SCU_PINIO_UART_TX SCU_MODE_PULLDOWN +#define SCU_PINIO_UART_RX SCU_PINIO_PULLNONE + +static const PinMap PinMap_UART_TX[] = { + {P1_13, UART_1, (SCU_PINIO_UART_TX | 1)}, + {P1_15, UART_2, (SCU_PINIO_UART_TX | 1)}, + {P2_0, UART_0, (SCU_PINIO_UART_TX | 1)}, + {P2_3, UART_3, (SCU_PINIO_UART_TX | 2)}, + {P2_10, UART_2, (SCU_PINIO_UART_TX | 2)}, + {P3_4, UART_1, (SCU_PINIO_UART_TX | 4)}, + {P4_1, UART_3, (SCU_PINIO_UART_TX | 6)}, + {P5_6, UART_1, (SCU_PINIO_UART_TX | 4)}, + {P6_4, UART_0, (SCU_PINIO_UART_TX | 2)}, + {P7_1, UART_2, (SCU_PINIO_UART_TX | 6)}, + {P9_3, UART_3, (SCU_PINIO_UART_TX | 7)}, + {P9_5, UART_0, (SCU_PINIO_UART_TX | 7)}, + {PA_1, UART_2, (SCU_PINIO_UART_TX | 3)}, + {PC_13, UART_1, (SCU_PINIO_UART_TX | 2)}, + {PE_11, UART_1, (SCU_PINIO_UART_TX | 2)}, + {PF_2, UART_3, (SCU_PINIO_UART_TX | 1)}, + {PF_10, UART_0, (SCU_PINIO_UART_TX | 1)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {P1_14, UART_1, (SCU_PINIO_UART_RX | 1)}, + {P1_16, UART_2, (SCU_PINIO_UART_RX | 1)}, + {P2_1, UART_0, (SCU_PINIO_UART_RX | 1)}, + {P2_4, UART_3, (SCU_PINIO_UART_RX | 2)}, + {P2_11, UART_2, (SCU_PINIO_UART_RX | 2)}, + {P3_5, UART_1, (SCU_PINIO_UART_RX | 4)}, + {P4_2, UART_3, (SCU_PINIO_UART_RX | 6)}, + {P5_7, UART_1, (SCU_PINIO_UART_RX | 4)}, + {P6_5, UART_0, (SCU_PINIO_UART_RX | 2)}, + {P7_2, UART_2, (SCU_PINIO_UART_RX | 6)}, + {P9_4, UART_3, (SCU_PINIO_UART_RX | 7)}, + {P9_6, UART_0, (SCU_PINIO_UART_RX | 7)}, + {PA_2, UART_2, (SCU_PINIO_UART_RX | 3)}, + {PC_14, UART_1, (SCU_PINIO_UART_RX | 2)}, + {PE_12, UART_1, (SCU_PINIO_UART_RX | 2)}, + {PF_3, UART_3, (SCU_PINIO_UART_RX | 1)}, + {PF_11, UART_0, (SCU_PINIO_UART_RX | 1)}, + {NC, NC, 0} +}; + +#if (DEVICE_SERIAL_FC) +// RTS/CTS PinMap for flow control +static const PinMap PinMap_UART_RTS[] = { + {P1_9, UART_1, (SCU_PINIO_FAST | 1)}, + {P5_2, UART_1, (SCU_PINIO_FAST | 4)}, + {PC_3, UART_1, (SCU_PINIO_FAST | 2)}, + {PE_5, UART_1, (SCU_PINIO_FAST | 2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_UART_CTS[] = { + {P1_11, UART_1, (SCU_PINIO_FAST | 1)}, + {P5_4, UART_1, (SCU_PINIO_FAST | 4), + {PC_2, UART_1, (SCU_PINIO_FAST | 2)}, + {PE_7, UART_1, (SCU_PINIO_FAST | 2)}, + {NC, NC, 0} +}; +#endif + +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +struct serial_global_data_s { + uint32_t serial_irq_id; + gpio_t sw_rts, sw_cts; + uint8_t count, rx_irq_set_flow, rx_irq_set_api; +}; + +static struct serial_global_data_s uart_data[UART_NUM]; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + if ((int)uart == NC) { + error("Serial pinout mapping failed"); + } + + obj->uart = (LPC_USART_T *)uart; + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + serial_baud (obj, is_stdio_uart ? 115200 : 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + if (tx != NC) { + pin_mode(tx, PullUp); + } + if (rx != NC) { + pin_mode(rx, PullUp); + } + + switch (uart) { + case UART_0: obj->index = 0; break; + case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; + } + uart_data[obj->index].sw_rts.pin = NC; + uart_data[obj->index].sw_cts.pin = NC; + serial_set_flow_control(obj, FlowControlNone, NC, NC); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + uart_data[obj->index].serial_irq_id = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + uint32_t PCLK = SystemCoreClock; + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + // 0: 1 stop bits, 1: 2 stop bits + if (stop_bits != 1 && stop_bits != 2) { + error("Invalid stop bits specified"); + } + stop_bits -= 1; + + // 0: 5 data bits ... 3: 8 data bits + if (data_bits < 5 || data_bits > 8) { + error("Invalid number of bits (%d) in serial format, should be 5..8", data_bits); + } + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + error("Invalid serial parity setting"); + return; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index, LPC_USART_T *puart) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) { + gpio_write(&uart_data[index].sw_rts, 1); + // Disable interrupt if it wasn't enabled by other part of the application + if (!uart_data[index].rx_irq_set_api) + puart->IER &= ~(1 << RxIrq); + } + if (uart_data[index].serial_irq_id != 0) + if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api)) + irq_handler(uart_data[index].serial_irq_id, irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART0->IIR >> 1) & 0x7, 0, (LPC_USART_T*)LPC_USART0);} +void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_USART_T*)LPC_UART1);} +void uart2_irq() {uart_irq((LPC_USART2->IIR >> 1) & 0x7, 2, (LPC_USART_T*)LPC_USART2);} +void uart3_irq() {uart_irq((LPC_USART3->IIR >> 1) & 0x7, 3, (LPC_USART_T*)LPC_USART3);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + uart_data[obj->index].serial_irq_id = id; +} + +static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: irq_n=USART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case UART_2: irq_n=USART2_IRQn; vector = (uint32_t)&uart2_irq; break; + case UART_3: irq_n=USART3_IRQn; vector = (uint32_t)&uart3_irq; break; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + if (RxIrq == irq) + uart_data[obj->index].rx_irq_set_api = enable; + serial_irq_set_internal(obj, irq, enable); +} + +#if (DEVICE_SERIAL_FC) +static void serial_flow_irq_set(serial_t *obj, uint32_t enable) { + uart_data[obj->index].rx_irq_set_flow = enable; + serial_irq_set_internal(obj, RxIrq, enable); +} +#endif + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + int data = obj->uart->RBR; + if (NC != uart_data[obj->index].sw_rts.pin) { + gpio_write(&uart_data[obj->index].sw_rts, 0); + obj->uart->IER |= 1 << RxIrq; + } + return data; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; + uart_data[obj->index].count++; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + int isWritable = 1; + if (NC != uart_data[obj->index].sw_cts.pin) + isWritable = (gpio_read(&uart_data[obj->index].sw_cts) == 0) && (obj->uart->LSR & 0x40); //If flow control: writable if CTS low + UART done + else { + if (obj->uart->LSR & 0x20) + uart_data[obj->index].count = 0; + else if (uart_data[obj->index].count >= 16) + isWritable = 0; + } + return isWritable; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) { + obj->uart->LCR |= (1 << 6); +} + +void serial_break_clear(serial_t *obj) { + obj->uart->LCR &= ~(1 << 6); +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { +#if (DEVICE_SERIAL_FC) +#endif +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/sleep.c new file mode 100644 index 0000000000..dd6949f75d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/sleep.c @@ -0,0 +1,36 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +/* + * ToDo: Implement deepsleep() + */ +void deepsleep(void) { + sleep(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/spi_api.c new file mode 100644 index 0000000000..90be127a0f --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/spi_api.c @@ -0,0 +1,225 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +// SCU mode for SPI pins +#define SCU_PINIO_SPI SCU_PINIO_FAST + +static const PinMap PinMap_SPI_SCLK[] = { + {P1_19, SPI_1, (SCU_PINIO_SPI | 1)}, + {P3_0, SPI_0, (SCU_PINIO_SPI | 4)}, + {P3_3, SPI_0, (SCU_PINIO_SPI | 2)}, + {PF_0, SPI_0, (SCU_PINIO_SPI | 0)}, + {PF_4, SPI_1, (SCU_PINIO_SPI | 0)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_1, SPI_1, (SCU_PINIO_SPI | 1)}, + {P1_2, SPI_0, (SCU_PINIO_SPI | 5)}, + {P1_4, SPI_1, (SCU_PINIO_SPI | 5)}, + {P3_7, SPI_0, (SCU_PINIO_SPI | 5)}, + {P3_8, SPI_0, (SCU_PINIO_SPI | 2)}, + {P9_2, SPI_0, (SCU_PINIO_SPI | 7)}, + {PF_3, SPI_0, (SCU_PINIO_SPI | 2)}, + {PF_7, SPI_1, (SCU_PINIO_SPI | 2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_0, SPI_1, (SCU_PINIO_SPI | 1)}, + {P1_1, SPI_0, (SCU_PINIO_SPI | 5)}, + {P1_3, SPI_1, (SCU_PINIO_SPI | 5)}, + {P3_6, SPI_0, (SCU_PINIO_SPI | 5)}, + {P3_7, SPI_0, (SCU_PINIO_SPI | 2)}, + {P9_1, SPI_0, (SCU_PINIO_SPI | 7)}, + {PF_2, SPI_0, (SCU_PINIO_SPI | 2)}, + {PF_6, SPI_1, (SCU_PINIO_SPI | 2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P1_0, SPI_0, (SCU_PINIO_SPI | 5)}, + {P1_5, SPI_1, (SCU_PINIO_SPI | 5)}, + {P1_20, SPI_1, (SCU_PINIO_SPI | 2)}, + {P3_6, SPI_0, (SCU_PINIO_SPI | 2)}, + {P3_8, SPI_0, (SCU_PINIO_SPI | 5)}, + {P9_0, SPI_0, (SCU_PINIO_SPI | 7)}, + {PF_1, SPI_0, (SCU_PINIO_SPI | 2)}, + {PF_5, SPI_1, (SCU_PINIO_SPI | 2)}, + {NC, NC, 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSP_T*)pinmap_merge(spi_data, spi_cntl); + MBED_ASSERT((int)obj->spi != NC); + + // enable clocking + switch ((int)obj->spi) { + case SPI_0: LPC_CGU->BASE_CLK[CLK_BASE_SSP0] = (1 << 11) | (CLKIN_MAINPLL << 24); break; + case SPI_1: LPC_CGU->BASE_CLK[CLK_BASE_SSP1] = (1 << 11) | (CLKIN_MAINPLL << 24); break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT(((bits >= 4) && (bits <= 16)) || ((mode >= 0) && (mode <= 3))); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/us_ticker.c new file mode 100644 index 0000000000..417bc4ebe1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC43XX/us_ticker.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Ported to NXP LPC43XX by Micromint USA <support@micromint.com> + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TIMER_T *)LPC_TIMER3_BASE) +#define US_TICKER_TIMER_IRQn TIMER3_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + US_TICKER_TIMER->CTCR = 0x0; // timer mode + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(timestamp_t timestamp) { + // set match value + US_TICKER_TIMER->MR[0] = (uint32_t)timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/PortNames.h new file mode 100644 index 0000000000..bbd5b31103 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/PortNames.h @@ -0,0 +1,30 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PeripheralNames.h new file mode 100644 index 0000000000..988c1cb898 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PeripheralNames.h @@ -0,0 +1,30 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PinNames.h new file mode 100644 index 0000000000..7edc5a6a8b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/PinNames.h @@ -0,0 +1,81 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + + dp1 = P0_5, + dp2 = P0_4, + dp3 = P0_3, + dp4 = P0_2, + dp5 = P0_1, + dp8 = P0_0, + + // mbed original LED naming + LED1 = P0_2, + LED2 = P0_2, + LED3 = P0_2, + LED4 = P0_2, + LED_RED = P0_2, + + // Serial to USB pins + USBTX = P0_4, + USBRX = P0_0, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX + +typedef struct { + unsigned char n; + unsigned char offset; +} SWM_Map; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PeripheralNames.h new file mode 100644 index 0000000000..55ca9e3d2d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PeripheralNames.h @@ -0,0 +1,37 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Default peripherals +#define MBED_SPI0 P0_14, P0_15, P0_12, P0_13 + +#define MBED_UART0 P0_4, P0_0 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 P0_10, P0_11 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PinNames.h new file mode 100644 index 0000000000..8696c143df --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/TARGET_LPC812/PinNames.h @@ -0,0 +1,109 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +typedef enum { + P0_0 = 0, + P0_1 = 1, + P0_2 = 2, + P0_3 = 3, + P0_4 = 4, + P0_5 = 5, + P0_6 = 6, + P0_7 = 7, + P0_8 = 8, + P0_9 = 9, + P0_10 = 10, + P0_11 = 11, + P0_12 = 12, + P0_13 = 13, + P0_14 = 14, + P0_15 = 15, + P0_16 = 16, + P0_17 = 17, + + D0 = P0_0, + D1 = P0_4, + D2 = P0_6, + D3 = P0_8, + D4 = P0_9, + + D7 = P0_7, + D8 = P0_17, + D9 = P0_16, + D10 = P0_13, + D11 = P0_14, + D12 = P0_15, + D13 = P0_12, + D14 = P0_10, + D15 = P0_11, + + A4 = P0_10, + A5 = P0_11, + + // LPC800-MAX board + LED_RED = P0_7, + LED_GREEN = P0_17, + LED_BLUE = P0_16, + + // mbed original LED naming + LED1 = LED_BLUE, + LED2 = LED_GREEN, + LED3 = LED_RED, + LED4 = LED_RED, + + // Serial to USB pins + USBTX = P0_6, + USBRX = P0_1, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX + +typedef struct { + unsigned char n; + unsigned char offset; +} SWM_Map; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/device.h new file mode 100644 index 0000000000..491694096b --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/device.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 0 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_api.c new file mode 100644 index 0000000000..2059675243 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_api.c @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +static int gpio_enabled = 0; +static void gpio_enable(void) { + gpio_enabled = 1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + /* Peripheral reset control to GPIO and GPIO INT, a "1" bring it out of reset. */ + LPC_SYSCON->PRESETCTRL &= ~(0x1<<10); + LPC_SYSCON->PRESETCTRL |= (0x1<<10); +} + +uint32_t gpio_set(PinName pin) { + int f = 0; + + if (!gpio_enabled) + gpio_enable(); + + pin_function(pin, f); + + return (1 << ((int)pin & 0x1F)); +} + +void gpio_init(gpio_t *obj, PinName pin) { + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + obj->reg_set = &LPC_GPIO_PORT->SET0; + obj->reg_clr = &LPC_GPIO_PORT->CLR0; + obj->reg_in = &LPC_GPIO_PORT->PIN0; + obj->reg_dir = &LPC_GPIO_PORT->DIR0; +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_irq_api.c new file mode 100644 index 0000000000..cdc510cbe6 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_irq_api.c @@ -0,0 +1,135 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> + +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_PIN_INT +#define PININT_IRQ PININT0_IRQn + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + LPC_SYSCON->PINTSEL[obj->ch] = pin; + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= 1 << obj->ch; + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_object.h new file mode 100644 index 0000000000..fe6d6c1e05 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/gpio_object.h @@ -0,0 +1,56 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) { + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/i2c_api.c new file mode 100644 index 0000000000..916242f3bd --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/i2c_api.c @@ -0,0 +1,513 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#if DEVICE_I2C + +static const SWM_Map SWM_I2C_SDA[] = { + {7, 24}, +}; + +static const SWM_Map SWM_I2C_SCL[] = { + {8, 0}, +}; + +static uint8_t repeated_start = 0; + +#define I2C_DAT(x) (x->i2c->MSTDAT) +#define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07)) + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(obj->i2c->STAT & (1 << 0))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + obj->i2c->CFG |= (1 << 0); +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); + LPC_SYSCON->PRESETCTRL &= ~(0x1<<6); + LPC_SYSCON->PRESETCTRL |= (0x1<<6); +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + obj->i2c = (LPC_I2C_TypeDef *)LPC_I2C; + + const SWM_Map *swm; + uint32_t regVal; + + swm = &SWM_I2C_SDA[0]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (sda << swm->offset); + + swm = &SWM_I2C_SCL[0]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (scl << swm->offset); + + // enable power + i2c_power_enable(obj); + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_interface_enable(obj); +} + +//Actually Wrong. Spec says: First store Address in DAT before setting STA ! +//Undefined state when using single byte I2C operations and too much delay +//between i2c_start and do_i2c_write(Address). +//Also note that lpc812 will immediately continue reading a byte when Address b0 == 1 +inline int i2c_start(i2c_t *obj) { + int status = 0; + if (repeated_start) { + obj->i2c->MSTCTL = (1 << 1) | (1 << 0); + repeated_start = 0; + } else { + obj->i2c->MSTCTL = (1 << 1); + } + return status; +} + +//Generate Stop condition and wait until bus is Idle +//Will also send NAK for previous RD +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + obj->i2c->MSTCTL = (1 << 2) | (1 << 0); // STP bit and Continue bit. Sends NAK to complete previous RD + + //Spin until Ready (b0 == 1)and Status is Idle (b3..b1 == 000) + while ((obj->i2c->STAT & ((7 << 1) | (1 << 0))) != ((0 << 1) | (1 << 0))) { + timeout ++; + if (timeout > 100000) return 1; + } + + return 0; +} + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + if (!addr) + obj->i2c->MSTCTL = (1 << 0); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // wait for it to arrive + i2c_wait_SI(obj); + if (!last) + obj->i2c->MSTCTL = (1 << 0); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t clkdiv = PCLK / (hz * 4) - 1; + + obj->i2c->DIV = clkdiv; + obj->i2c->MSTTIME = 0; +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +//New version WH, Tested OK for Start and Repeated Start +//Old version was Wrong: Calls i2c_start without setting address, i2c_do_read continues before checking status, status check for wrong value +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + //Store the address+RD and then generate STA + I2C_DAT(obj) = address | 0x01; + i2c_start(obj); + + // Wait for completion of STA and Sending of SlaveAddress+RD and first Read byte + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK on SlaveAddress + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length-1); count++) { + + // Wait for it to arrive, note that first byte read after address+RD is already waiting + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store read byte + + obj->i2c->MSTCTL = (1 << 0); // Send ACK and Continue to read + } + + // Read final byte + // Wait for it to arrive + i2c_wait_SI(obj); + + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store final read byte + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); // Also sends NAK for last read byte + } else { + repeated_start = 1; + } + + return length; +} + + + +//New version WH, Tested OK for Start and Repeated Start +//Old version was Wrong: Calls i2c_start without setting address first +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + //Store the address+/WR and then generate STA + I2C_DAT(obj) = address & 0xFE; + i2c_start(obj); + + // Wait for completion of STA and Sending of SlaveAddress+/WR + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK SlaveAddress + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + //Write all bytes + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if (status != 0x02) { // TX RDY. Handles a Slave NAK on datawrite + i2c_stop(obj); + return i; + } + } + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } else { + repeated_start = 1; + } + + return length; +} + + + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 2: + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + +#if DEVICE_I2CSLAVE + +#define I2C_SLVDAT(x) (x->i2c->SLVDAT) +#define I2C_SLVSTAT(x) ((x->i2c->STAT >> 9) & (0x03)) +#define I2C_SLVSI(x) ((x->i2c->STAT >> 8) & (0x01)) +//#define I2C_SLVCNT(x) (x->i2c->SLVCTL = (1 << 0)) +//#define I2C_SLVNAK(x) (x->i2c->SLVCTL = (1 << 1)) + +#if(0) +// Wait until the Slave Serial Interrupt (SI) is set +// Timeout when it takes too long. +static int i2c_wait_slave_SI(i2c_t *obj) { + int timeout = 0; + while (!(obj->i2c->STAT & (1 << 8))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} +#endif + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + + if (enable_slave) { +// obj->i2c->CFG &= ~(1 << 0); //Disable Master mode + obj->i2c->CFG |= (1 << 1); //Enable Slave mode + } + else { +// obj->i2c->CFG |= (1 << 0); //Enable Master mode + obj->i2c->CFG &= ~(1 << 1); //Disable Slave mode + } +} + +// Wait for next I2C event and find out what is going on +// +int i2c_slave_receive(i2c_t *obj) { + int addr; + + // Check if there is any data pending + if (! I2C_SLVSI(obj)) { + return 0; //NoData + }; + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + + // Get the received address + addr = I2C_SLVDAT(obj) & 0xFF; + // Send ACK on address and Continue + obj->i2c->SLVCTL = (1 << 0); + + if (addr == 0x00) { + return 2; //WriteGeneral + } + //check the RW bit + if ((addr & 0x01) == 0x01) { + return 1; //ReadAddressed + } + else { + return 3; //WriteAddressed + } + //break; + + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Oops, should never get here... + obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data, try to recover... + return 0; //NoData + + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + // Oops, should never get here... + I2C_SLVDAT(obj) = 0xFF; // Send dummy data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover... + return 0; //NoData + + case 0x3: // Reserved. + default: // Oops, should never get here... + obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover... + return 0; //NoData + //break; + } //switch status +} + +// The dedicated I2C Slave byte read and byte write functions need to be called +// from 'common' mbed I2CSlave API for devices that have separate Master and +// Slave engines such as the lpc812 and lpc1549. + +//Called when Slave is addressed for Write, Slave will receive Data in polling mode +//Parameter last=1 means received byte will be NACKed. +int i2c_slave_byte_read(i2c_t *obj, int last) { + int data; + + // Wait for data + while (!I2C_SLVSI(obj)); // Wait forever +//if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Dont bother to check State, were not returning it anyhow.. +//if (I2C_SLVSTAT(obj)) == 0x01) { + // Slave receive. Received data is available (Slave Receiver mode). +//}; + + data = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data + if (last) { + obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data and Continue + } + else { + obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read + } + + return data; +} + + +//Called when Slave is addressed for Read, Slave will send Data in polling mode +// +int i2c_slave_byte_write(i2c_t *obj, int data) { + + // Wait until Ready + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Should not get here... + return -2; + //break; + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + I2C_SLVDAT(obj) = data & 0xFF; // Store the data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue to send + + return 1; + //break; + case 0x3: // Reserved. + default: + // Should not get here... + return -3; + //break; + } // switch status +} + + +//Called when Slave is addressed for Write, Slave will receive Data in polling mode +//Parameter length (>=1) is the maximum allowable number of bytes. All bytes will be ACKed. +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count=0; + + // Read and ACK all expected bytes + while (count < length) { + // Wait for data + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + data[count] = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data + obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read + break; + + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + case 0x3: // Reserved. + default: // Should never get here... + return -2; + //break; + } // switch status + + count++; + } // for all bytes + + return count; // Received the expected number of bytes +} + + +//Called when Slave is addressed for Read, Slave will send Data in polling mode +//Parameter length (>=1) is the maximum number of bytes. Exit when Slave byte is NACKed. +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count; + + // Send and all bytes or Exit on NAK + for (count=0; count < length; count++) { + // Wait until Ready for data + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Should not get here... + return -2; + //break; + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + I2C_SLVDAT(obj) = data[count] & 0xFF; // Store the data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue to send + break; + case 0x3: // Reserved. + default: + // Should not get here... + return -3; + //break; + } // switch status + } // for all bytes + + return length; // Transmitted the max number of bytes +} + + +// Set the four slave addresses. +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + obj->i2c->SLVADR0 = (address & 0xFE); // Store address in address 0 register + obj->i2c->SLVADR1 = (0x00 & 0xFE); // Store general call write address in address 1 register + obj->i2c->SLVADR2 = (0x01); // Disable address 2 register + obj->i2c->SLVADR3 = (0x01); // Disable address 3 register + obj->i2c->SLVQUAL0 = (mask & 0xFE); // Qualifier mask for address 0 register. Any maskbit that is 1 will always be a match +} + +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/objects.h new file mode 100644 index 0000000000..819420f9a5 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/objects.h @@ -0,0 +1,57 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct serial_s { + LPC_USART_TypeDef *uart; + unsigned char index; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SPI_TypeDef *spi; + unsigned char spi_n; +}; + +struct pwmout_s { + LPC_SCT_TypeDef* pwm; + uint32_t pwm_ch; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pinmap.c new file mode 100644 index 0000000000..b68317d44a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pinmap.c @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + +__IO uint32_t* IOCON_REGISTERS[18] = { + &LPC_IOCON->PIO0_0 , &LPC_IOCON->PIO0_1 , &LPC_IOCON->PIO0_2 , + &LPC_IOCON->PIO0_3 , &LPC_IOCON->PIO0_4 , &LPC_IOCON->PIO0_5 , + &LPC_IOCON->PIO0_6 , &LPC_IOCON->PIO0_7 , &LPC_IOCON->PIO0_8 , + &LPC_IOCON->PIO0_9 , &LPC_IOCON->PIO0_10, &LPC_IOCON->PIO0_11, + &LPC_IOCON->PIO0_12, &LPC_IOCON->PIO0_13, &LPC_IOCON->PIO0_14, + &LPC_IOCON->PIO0_15, &LPC_IOCON->PIO0_16, &LPC_IOCON->PIO0_17, +}; + +void pin_function(PinName pin, int function) { + +} + +void pin_mode(PinName pin, PinMode mode) { + MBED_ASSERT(pin != (PinName)NC); + + if ((pin == 10) || (pin == 11)) { + // True open-drain pins can be configured for different I2C-bus speeds + return; + } + + __IO uint32_t *reg = IOCON_REGISTERS[pin]; + + if (mode == OpenDrain) { + *reg |= (1 << 10); + } else { + uint32_t tmp = *reg; + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + *reg = tmp; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c new file mode 100644 index 0000000000..393d51981a --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/pwmout_api.c @@ -0,0 +1,227 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +// Ported from LPC824 and adapted. + +#if DEVICE_PWMOUT + +#define PWM_IRQn SCT_IRQn + +// Bit flags for used SCT Outputs +static unsigned char sct_used = 0; +static int sct_inited = 0; + +// Find available output channel +// Max number of PWM outputs is 4 on LPC812 +static int get_available_sct() { + int i; + +// Find available output channel 0..3 +// Also need one Match register per channel + for (i = 0; i < CONFIG_SCT_nOU; i++) { +// for (i = 0; i < 4; i++) { + if ((sct_used & (1 << i)) == 0) + return i; + } + return -1; +} + +// Any Port pin may be used for PWM. +// Max number of PWM outputs is 4 +void pwmout_init(pwmout_t* obj, PinName pin) { + MBED_ASSERT(pin != (uint32_t)NC); + + int sct_n = get_available_sct(); + if (sct_n == -1) { + error("No available SCT Output"); + } + + sct_used |= (1 << sct_n); + + obj->pwm = (LPC_SCT_TypeDef*)LPC_SCT; + obj->pwm_ch = sct_n; + + LPC_SCT_TypeDef* pwm = obj->pwm; + + // Init SCT on first use + if (! sct_inited) { + sct_inited = 1; + + // Enable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8); + + // Clear peripheral reset the SCT: + LPC_SYSCON->PRESETCTRL |= (1 << 8); + + // Two 16-bit counters, autolimit (ie reset on Match_0) + //pwm->CONFIG &= ~(0x1); + //pwm->CONFIG |= (1 << 17); + pwm->CONFIG |= ((0x3 << 17) | 0x01); + + // halt and clear the counter + pwm->CTRL_U |= (1 << 2) | (1 << 3); + + // System Clock (30 Mhz) -> Prescaler -> us_ticker (1 MHz) + pwm->CTRL_U &= ~(0x7F << 5); + pwm->CTRL_U |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5); + + pwm->EVENT[0].CTRL = (1 << 12) | 0; // Event_0 on Match_0 + pwm->EVENT[0].STATE = 0xFFFFFFFF; // All states + + // unhalt the counter: + // - clearing bit 2 of the CTRL register + pwm->CTRL_U &= ~(1 << 2); + + // Not using IRQs + //NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler); + //NVIC_EnableIRQ(PWM_IRQn); + } + + // LPC81x has only one SCT and 4 Outputs + // LPC82x has only one SCT and 6 Outputs + // LPC1549 has 4 SCTs and 16 Outputs + switch(sct_n) { + case 0: + // SCTx_OUT0 + LPC_SWM->PINASSIGN[6] &= ~0xFF000000; + LPC_SWM->PINASSIGN[6] |= (pin << 24); + break; + case 1: + // SCTx_OUT1 + LPC_SWM->PINASSIGN[7] &= ~0x000000FF; + LPC_SWM->PINASSIGN[7] |= (pin); + break; + case 2: + // SCTx_OUT2 + LPC_SWM->PINASSIGN[7] &= ~0x0000FF00; + LPC_SWM->PINASSIGN[7] |= (pin << 8); + break; + case 3: + // SCTx_OUT3 + LPC_SWM->PINASSIGN[7] &= ~0x00FF0000; + LPC_SWM->PINASSIGN[7] |= (pin << 16); + break; + default: + break; + } + + pwm->EVENT[sct_n + 1].CTRL = (1 << 12) | (sct_n + 1); // Event_n on Match_n + pwm->EVENT[sct_n + 1].STATE = 0xFFFFFFFF; // All states + + pwm->OUT[sct_n].SET = (1 << 0); // All PWM channels are SET on Event_0 + pwm->OUT[sct_n].CLR = (1 << (sct_n + 1)); // PWM ch is CLRed on Event_(ch+1) + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); // 20ms period + pwmout_write (obj, 0.0); // 0ms pulsewidth, dutycycle 0 +} + +void pwmout_free(pwmout_t* obj) { + // PWM channel is now free + sct_used &= ~(1 << obj->pwm_ch); + + // Disable the SCT clock when all channels free + if (sct_used == 0) { + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8); + sct_inited = 0; + }; +} + +// Set new dutycycle (0.0 .. 1.0) +void pwmout_write(pwmout_t* obj, float value) { + //value is new dutycycle + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + // Match_0 is PWM period. Compute new endtime of pulse for current channel + uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].U) * value); + obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = t_off; // New endtime +} + +// Get dutycycle (0.0 .. 1.0) +float pwmout_read(pwmout_t* obj) { + uint32_t t_period = obj->pwm->MATCHREL[0].U; + + //Sanity check + if (t_period == 0) { + return 0.0; + }; + + uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U; + float v = (float)t_off/(float)t_period; + //Sanity check + return (v > 1.0f) ? (1.0f) : (v); +} + +// Set the PWM period, keeping the duty cycle the same (for this channel only!). +void pwmout_period(pwmout_t* obj, float seconds){ + pwmout_period_us(obj, seconds * 1000000.0f); +} + +// Set the PWM period, keeping the duty cycle the same (for this channel only!). +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same (for this channel only!). +void pwmout_period_us(pwmout_t* obj, int us) { + + uint32_t t_period = obj->pwm->MATCHREL[0].U; // Current PWM period + obj->pwm->MATCHREL[0].U = (uint32_t)us; // New PWM period + + //Keep the dutycycle for the new PWM period + //Should really do this for all active channels!! + //This problem exists in all mbed libs. + + //Sanity check + if (t_period == 0) { + return; +// obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = 0; // New endtime for this channel + } + else { + uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U; + float v = (float)t_off/(float)t_period; + obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)((float)us * (float)v); // New endtime for this channel + } +} + + +//Set pulsewidth +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +//Set pulsewidth +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms){ + pwmout_pulsewidth_us(obj, ms * 1000); +} + +//Set pulsewidth +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + +//Should add Sanity check to make sure pulsewidth < period! + obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)us; // New endtime for this channel +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/serial_api.c new file mode 100644 index 0000000000..19473496ec --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/serial_api.c @@ -0,0 +1,320 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 3 + +static const SWM_Map SWM_UART_TX[] = { + {0, 0}, + {1, 8}, + {2, 16}, +}; + +static const SWM_Map SWM_UART_RX[] = { + {0, 8}, + {1, 16}, + {2, 24}, +}; + +static const SWM_Map SWM_UART_RTS[] = { + {0, 16}, + {1, 24}, + {3, 0}, +}; + +static const SWM_Map SWM_UART_CTS[] = { + {0, 24}, + {2, 0}, + {3, 8} +}; + +// bit flags for used UARTs +static unsigned char uart_used = 0; +static int get_available_uart(void) { + int i; + for (i=0; i<3; i++) { + if ((uart_used & (1 << i)) == 0) + return i; + } + return -1; +} + +#define UART_EN (0x01<<0) + +#define CTS_DELTA (0x01<<5) +#define RXBRK (0x01<<10) +#define DELTA_RXBRK (0x01<<11) + +#define RXRDY (0x01<<0) +#define TXRDY (0x01<<2) + +#define TXBRKEN (0x01<<1) +#define CTSEN (0x01<<9) + +static uint32_t UARTSysClk; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + int uart_n = get_available_uart(); + if (uart_n == -1) { + error("No available UART"); + } + obj->index = uart_n; + obj->uart = (LPC_USART_TypeDef *)(LPC_USART0_BASE + (0x4000 * uart_n)); + uart_used |= (1 << uart_n); + + const SWM_Map *swm; + uint32_t regVal; + + swm = &SWM_UART_TX[uart_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (tx << swm->offset); + + swm = &SWM_UART_RX[uart_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (rx << swm->offset); + + /* uart clock divided by 1 */ + LPC_SYSCON->UARTCLKDIV = 1; + + /* disable uart interrupts */ + NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (14 + uart_n)); + + /* Peripheral reset control to UART, a "1" bring it out of reset. */ + LPC_SYSCON->PRESETCTRL &= ~(0x1 << (3 + uart_n)); + LPC_SYSCON->PRESETCTRL |= (0x1 << (3 + uart_n)); + + // Derive UART Clock from MainClock + UARTSysClk = MainClock / LPC_SYSCON->UARTCLKDIV; + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + /* Clear all status bits. */ + obj->uart->STAT = CTS_DELTA | DELTA_RXBRK; + + /* enable uart interrupts */ + NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART interrupt */ + // obj->uart->INTENSET = RXRDY | TXRDY | DELTA_RXBRK; + + /* Enable UART */ + obj->uart->CFG |= UART_EN; + + is_stdio_uart = ((tx == USBTX) && (rx == USBRX)); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + uart_used &= ~(1 << obj->index); + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + /* Integer divider: + BRG = UARTSysClk/(Baudrate * 16) - 1 + + Frational divider: + FRG = ((UARTSysClk / (Baudrate * 16 * (BRG + 1))) - 1) + + where + FRG = (LPC_SYSCON->UARTFRDADD + 1) / (LPC_SYSCON->UARTFRDSUB + 1) + + (1) The easiest way is set SUB value to 256, -1 encoded, thus SUB + register is 0xFF. + (2) In ADD register value, depending on the value of UartSysClk, + baudrate, BRG register value, and SUB register value, be careful + about the order of multiplier and divider and make sure any + multiplier doesn't exceed 32-bit boundary and any divider doesn't get + down below one(integer 0). + (3) ADD should be always less than SUB. + */ + obj->uart->BRG = UARTSysClk / 16 / baudrate - 1; + + LPC_SYSCON->UARTFRGDIV = 0xFF; + LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) / + (baudrate * (obj->uart->BRG + 1)) + ) - (LPC_SYSCON->UARTFRGDIV + 1); + +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); + MBED_ASSERT((data_bits > 6) && (data_bits < 10)); // 0: 7 data bits ... 2: 9 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityEven) || (parity == ParityOdd)); + stop_bits -= 1; + data_bits -= 7; + + int paritysel; + switch (parity) { + case ParityNone: paritysel = 0; break; + case ParityEven: paritysel = 2; break; + case ParityOdd : paritysel = 3; break; + default: + break; + } + + obj->uart->CFG = (data_bits << 2) + | (paritysel << 4) + | (stop_bits << 6); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART0->STAT & (1 << 2)) ? 2 : 1, 0);} +void uart1_irq() {uart_irq((LPC_USART1->STAT & (1 << 2)) ? 2 : 1, 1);} +void uart2_irq() {uart_irq((LPC_USART2->STAT & (1 << 2)) ? 2 : 1, 2);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + } + + if (enable) { + obj->uart->INTENSET = (1 << ((irq == RxIrq) ? 0 : 2)); + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + obj->uart->INTENSET &= ~(1 << ((irq == RxIrq) ? 0 : 2)); + all_disabled = (obj->uart->INTENSET & (1 << ((other_irq == RxIrq) ? 0 : 2))) == 0; + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RXDATA; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->TXDATA = c; +} + +int serial_readable(serial_t *obj) { + return obj->uart->STAT & RXRDY; +} + +int serial_writable(serial_t *obj) { + return obj->uart->STAT & TXRDY; +} + +void serial_clear(serial_t *obj) { + // [TODO] +} + +void serial_pinout_tx(PinName tx) { + +} + +void serial_break_set(serial_t *obj) { + obj->uart->CTRL |= TXBRKEN; +} + +void serial_break_clear(serial_t *obj) { + obj->uart->CTRL &= ~TXBRKEN; +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) { + const SWM_Map *swm_rts, *swm_cts; + uint32_t regVal_rts, regVal_cts; + + swm_rts = &SWM_UART_RTS[obj->index]; + swm_cts = &SWM_UART_CTS[obj->index]; + regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset); + regVal_cts = LPC_SWM->PINASSIGN[swm_cts->n] & ~(0xFF << swm_cts->offset); + + if (FlowControlNone == type) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); + obj->uart->CFG &= ~CTSEN; + return; + } + if ((FlowControlRTS == type || FlowControlRTSCTS == type) && (rxflow != NC)) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (rxflow << swm_rts->offset); + if (FlowControlRTS == type) { + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); + obj->uart->CFG &= ~CTSEN; + } + } + if ((FlowControlCTS == type || FlowControlRTSCTS == type) && (txflow != NC)) { + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (txflow << swm_cts->offset); + obj->uart->CFG |= CTSEN; + if (FlowControlCTS == type) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); + } + } +} + diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/sleep.c new file mode 100644 index 0000000000..4d2232a86d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/sleep.c @@ -0,0 +1,82 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" + + +//#define DEEPSLEEP +#define POWERDOWN + +void sleep(void) { + //Normal sleep mode for PCON: + LPC_PMU->PCON &= ~0x03; + + //Normal sleep mode for ARM core: + SCB->SCR = 0; + + //And go to sleep + __WFI(); +} + + + +//Deepsleep/powerdown modes assume the device is configured to use its internal RC oscillator directly + +#ifdef DEEPSLEEP +void deepsleep(void) { + //Deep sleep in PCON + LPC_PMU->PCON &= ~0x03; + LPC_PMU->PCON |= 0x01; + + //If brownout detection and WDT are enabled, keep them enabled during sleep + LPC_SYSCON->PDSLEEPCFG = LPC_SYSCON->PDRUNCFG; + + //After wakeup same stuff as currently enabled: + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + + //All interrupts may wake up: + LPC_SYSCON->STARTERP0 = 0xFF; + LPC_SYSCON->STARTERP1 = 0xFFFF; + + //Deep sleep for ARM core: + SCB->SCR = 1<<2; + + __WFI(); +} +#endif + +#ifdef POWERDOWN +void deepsleep(void) { + //Powerdown in PCON + LPC_PMU->PCON &= ~0x03; + LPC_PMU->PCON |= 0x02; + + //If brownout detection and WDT are enabled, keep them enabled during sleep + LPC_SYSCON->PDSLEEPCFG = LPC_SYSCON->PDRUNCFG; + + //After wakeup same stuff as currently enabled: + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + + //All interrupts may wake up: + LPC_SYSCON->STARTERP0 = 0xFF; + LPC_SYSCON->STARTERP1 = 0xFFFF; + + //Deep sleep for ARM core: + SCB->SCR = 1<<2; + + __WFI(); +} +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/spi_api.c new file mode 100644 index 0000000000..21a6432c0e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/spi_api.c @@ -0,0 +1,207 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include <math.h> + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +static const SWM_Map SWM_SPI_SSEL[] = { + {4, 16}, + {5, 16}, +}; + +static const SWM_Map SWM_SPI_SCLK[] = { + {3, 24}, + {4, 24}, +}; + +static const SWM_Map SWM_SPI_MOSI[] = { + {4, 0}, + {5, 0}, +}; + +static const SWM_Map SWM_SPI_MISO[] = { + {4, 8}, + {5, 16}, +}; + +// bit flags for used SPIs +static unsigned char spi_used = 0; +static int get_available_spi(void) { + int i; + for (i=0; i<2; i++) { + if ((spi_used & (1 << i)) == 0) + return i; + } + return -1; +} + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + int spi_n = get_available_spi(); + if (spi_n == -1) { + error("No available SPI"); + } + obj->spi_n = spi_n; + spi_used |= (1 << spi_n); + + obj->spi = (spi_n) ? (LPC_SPI_TypeDef *)(LPC_SPI1_BASE) : (LPC_SPI_TypeDef *)(LPC_SPI0_BASE); + + const SWM_Map *swm; + uint32_t regVal; + + swm = &SWM_SPI_SCLK[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (sclk << swm->offset); + + swm = &SWM_SPI_MOSI[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (mosi << swm->offset); + + swm = &SWM_SPI_MISO[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (miso << swm->offset); + + swm = &SWM_SPI_SSEL[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | (ssel << swm->offset); + + // clear interrupts + obj->spi->INTENCLR = 0x3f; + + // enable power and clocking + switch (obj->spi_n) { + case 0: + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11); + LPC_SYSCON->PRESETCTRL &= ~(0x1<<0); + LPC_SYSCON->PRESETCTRL |= (0x1<<0); + break; + case 1: + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + LPC_SYSCON->PRESETCTRL &= ~(0x1<<1); + LPC_SYSCON->PRESETCTRL |= (0x1<<1); + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + MBED_ASSERT(((bits >= 1) && (bits <= 16)) && ((mode >= 0) && (mode <= 3))); + ssp_disable(obj); + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + uint32_t tmp = obj->spi->CFG; + tmp &= ~((1 << 2) | (1 << 4) | (1 << 5)); + tmp |= (SPH << 4) | (SPO << 5) | ((slave ? 0 : 1) << 2); + obj->spi->CFG = tmp; + + // select frame length + tmp = obj->spi->TXDATCTL; + tmp &= ~(0xf << 24); + tmp |= (DSS << 24); + obj->spi->TXDATCTL = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + obj->spi->DIV = PCLK/hz - 1; + obj->spi->DLY = 0; + ssp_enable(obj); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CFG &= ~(1 << 0); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CFG |= (1 << 0); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->STAT & (1 << 0); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->STAT & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + // end of transfer + obj->spi->TXDATCTL |= (1 << 20); + obj->spi->TXDAT = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->RXDAT; +} + +static inline int ssp_busy(spi_t *obj) { + // checking RXOV(Receiver Overrun interrupt flag) + return obj->spi->STAT & (1 << 2); + } + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) { + return obj->spi->RXDAT; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->TXDAT = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/us_ticker.c new file mode 100644 index 0000000000..838b614be1 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC81X/us_ticker.c @@ -0,0 +1,121 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +//New, using MRT instead of SCT, needed to free up SCT for PWM +//Ported from LPC824 libs +static int us_ticker_inited = 0; +unsigned int ticker_fullcount_us; +unsigned long int ticker_expired_count_us = 0; +int MRT_Clock_MHz; + +#define US_TICKER_TIMER_IRQn MRT_IRQn + +void us_ticker_init(void) { + + if (us_ticker_inited) + return; + + us_ticker_inited = 1; + + // Calculate MRT clock value (MRT has no prescaler) + MRT_Clock_MHz = (SystemCoreClock / 1000000); + // Calculate fullcounter value in us (MRT has 31 bits and clock is 30 MHz) + ticker_fullcount_us = 0x80000000UL/MRT_Clock_MHz; + + // Enable the MRT clock + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10); + + // Clear peripheral reset the MRT + LPC_SYSCON->PRESETCTRL |= (1 << 7); + + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + LPC_MRT->INTVAL0 = 0xFFFFFFFFUL; + // Enable Ch0 interrupt, Mode 0 is Repeat Interrupt + LPC_MRT->CTRL0 = (0x0 << 1) | (0x1 << 0); + + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + LPC_MRT->INTVAL1 = 0x80000000UL; + // Disable ch1 interrupt, Mode 0 is Repeat Interrupt + LPC_MRT->CTRL1 = (0x0 << 1) | (0x0 << 0); + + // Set MRT interrupt vector + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +//TIMER0 is used for us ticker and timers (Timer, wait(), wait_us() etc) +uint32_t us_ticker_read() { + + if (!us_ticker_inited) + us_ticker_init(); + + // Generate ticker value + // MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer + // Calculate expected value using current count and number of expired times to mimic a 32bit timer @ 1 MHz + // + // ticker_expired_count_us + // The variable ticker_expired_count_us keeps track of the number of 31bits overflows (counted by TIMER0) and + // corrects that back to us counts. + // + // (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_Clock_MHz + // The counter is a 31bit downcounter from 7FFFFFFF so correct to actual count-up value and correct + // for 30 counts per us. + // + // Added up these 2 parts result in current us time returned as 32 bits. + return (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_Clock_MHz + ticker_expired_count_us; +} + +//TIMER1 is used for Timestamped interrupts (Ticker(), Timeout()) +void us_ticker_set_interrupt(timestamp_t timestamp) { + + // MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + // Note: The MRT has less counter headroom available than the typical mbed 32bit timer @ 1 MHz. + // The calculated counter interval until the next timestamp will be truncated and an + // 'early' interrupt will be generated in case the max required count interval exceeds + // the available 31 bits space. However, the mbed us_ticker interrupt handler will + // check current time against the next scheduled timestamp and simply re-issue the + // same interrupt again when needed. The calculated counter interval will now be smaller. + LPC_MRT->INTVAL1 = (((timestamp - us_ticker_read()) * MRT_Clock_MHz) | 0x80000000UL); + + // Enable interrupt + LPC_MRT->CTRL1 |= 1; +} + +//Disable Timestamped interrupts triggered by TIMER1 +void us_ticker_disable_interrupt() { + //Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock) + LPC_MRT->CTRL1 &= ~1; +} + +void us_ticker_clear_interrupt() { + + //Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock) + if (LPC_MRT->STAT1 & 1) + LPC_MRT->STAT1 = 1; + + //Timer0 for us counter (31 bits downcounter @ SystemCoreClock) + if (LPC_MRT->STAT0 & 1) { + LPC_MRT->STAT0 = 1; + // ticker_expired_count_us = (ticker_expired * 0x80000000UL) / MRT_Clock_MHz + // The variable ticker_expired_count_us keeps track of the number of 31bits overflows (counted by TIMER0) and + // the multiplication/division corrects that back to us counts. + ticker_expired_count_us += ticker_fullcount_us; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/PortNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/PortNames.h new file mode 100644 index 0000000000..bbd5b31103 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/PortNames.h @@ -0,0 +1,30 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PeripheralNames.h new file mode 100644 index 0000000000..9cef1835a0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PeripheralNames.h @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Default peripherals + +// SPI: MOSI, MISO, CLK, SEL +#define MBED_SPI0 P0_26, P0_25, P0_24, P0_15 + +#define MBED_UART0 P0_7, P0_18 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 P0_11, P0_10 + +typedef enum { + ADC_0 = 0, + ADC_1, + ADC_2, + ADC_3, + ADC_4, + ADC_5, + ADC_6, + ADC_7, + ADC_8, + ADC_9, + ADC_10, + ADC_11, +} ADCName; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PinNames.h new file mode 100644 index 0000000000..a63498be03 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/PinNames.h @@ -0,0 +1,135 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PIN_SHIFT 8 + +typedef enum { +// LPC824 Pin Names (PIN[11:8] + IOCON offset[7:0]) + + P0_0 = ( 0 << PIN_SHIFT) | 0x44, + P0_1 = ( 1 << PIN_SHIFT) | 0x2C, + P0_2 = ( 2 << PIN_SHIFT) | 0x18, + P0_3 = ( 3 << PIN_SHIFT) | 0x14, + P0_4 = ( 4 << PIN_SHIFT) | 0x10, + P0_5 = ( 5 << PIN_SHIFT) | 0x0C, + P0_6 = ( 6 << PIN_SHIFT) | 0x40, + P0_7 = ( 7 << PIN_SHIFT) | 0x3C, + P0_8 = ( 8 << PIN_SHIFT) | 0x38, + P0_9 = ( 9 << PIN_SHIFT) | 0x34, + P0_10 = (10 << PIN_SHIFT) | 0x20, + P0_11 = (11 << PIN_SHIFT) | 0x1C, + P0_12 = (12 << PIN_SHIFT) | 0x08, + P0_13 = (13 << PIN_SHIFT) | 0x04, + P0_14 = (14 << PIN_SHIFT) | 0x48, + P0_15 = (15 << PIN_SHIFT) | 0x28, + P0_16 = (16 << PIN_SHIFT) | 0x24, + P0_17 = (17 << PIN_SHIFT) | 0x00, + P0_18 = (18 << PIN_SHIFT) | 0x78, + P0_19 = (19 << PIN_SHIFT) | 0x74, + P0_20 = (20 << PIN_SHIFT) | 0x70, + P0_21 = (21 << PIN_SHIFT) | 0x6C, + P0_22 = (22 << PIN_SHIFT) | 0x68, + P0_23 = (23 << PIN_SHIFT) | 0x64, + P0_24 = (24 << PIN_SHIFT) | 0x60, + P0_25 = (25 << PIN_SHIFT) | 0x5C, + P0_26 = (26 << PIN_SHIFT) | 0x58, + P0_27 = (27 << PIN_SHIFT) | 0x54, + P0_28 = (28 << PIN_SHIFT) | 0x50, + + D0 = P0_0, + D1 = P0_4, + D2 = P0_19, + D3 = P0_12, // LED_RED + D4 = P0_18, + D5 = P0_28, + D6 = P0_16, // LED_GREEN + D7 = P0_17, + D8 = P0_13, + D9 = P0_27, // LED_BLUE + D10 = P0_15, + D11 = P0_26, + D12 = P0_25, + D13 = P0_24, + D14 = P0_11, + D15 = P0_10, + + A0 = P0_6, + A1 = P0_14, + A2 = P0_23, + A3 = P0_22, + A4 = P0_21, + A5 = P0_20, + + // LPC824-MAX board + LED_RED = P0_12, + LED_GREEN = P0_16, + LED_BLUE = P0_27, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_BLUE, + + // Serial to USB pins + USBTX = P0_7, + USBRX = P0_18, + + // I2C pins + SCL = P0_10, + SDA = P0_11, + I2C_SCL = P0_10, + I2C_SDA = P0_11, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX + +typedef struct { + unsigned char n; + unsigned char offset; +} SWM_Map; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/device.h new file mode 100644 index 0000000000..52d2e95d0e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_LPC824/device.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 0 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PeripheralNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PeripheralNames.h new file mode 100644 index 0000000000..9cef1835a0 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PeripheralNames.h @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Default peripherals + +// SPI: MOSI, MISO, CLK, SEL +#define MBED_SPI0 P0_26, P0_25, P0_24, P0_15 + +#define MBED_UART0 P0_7, P0_18 +#define MBED_UARTUSB USBTX, USBRX + +#define MBED_I2C0 P0_11, P0_10 + +typedef enum { + ADC_0 = 0, + ADC_1, + ADC_2, + ADC_3, + ADC_4, + ADC_5, + ADC_6, + ADC_7, + ADC_8, + ADC_9, + ADC_10, + ADC_11, +} ADCName; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PinNames.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PinNames.h new file mode 100644 index 0000000000..e2fb12338d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/PinNames.h @@ -0,0 +1,135 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PIN_SHIFT 8 + +typedef enum { +// LPC824 Pin Names (PIN[11:8] + IOCON offset[7:0]) + + P0_0 = ( 0 << PIN_SHIFT) | 0x44, + P0_1 = ( 1 << PIN_SHIFT) | 0x2C, + P0_2 = ( 2 << PIN_SHIFT) | 0x18, + P0_3 = ( 3 << PIN_SHIFT) | 0x14, + P0_4 = ( 4 << PIN_SHIFT) | 0x10, + P0_5 = ( 5 << PIN_SHIFT) | 0x0C, + P0_6 = ( 6 << PIN_SHIFT) | 0x40, + P0_7 = ( 7 << PIN_SHIFT) | 0x3C, + P0_8 = ( 8 << PIN_SHIFT) | 0x38, + P0_9 = ( 9 << PIN_SHIFT) | 0x34, + P0_10 = (10 << PIN_SHIFT) | 0x20, + P0_11 = (11 << PIN_SHIFT) | 0x1C, + P0_12 = (12 << PIN_SHIFT) | 0x08, + P0_13 = (13 << PIN_SHIFT) | 0x04, + P0_14 = (14 << PIN_SHIFT) | 0x48, + P0_15 = (15 << PIN_SHIFT) | 0x28, + P0_16 = (16 << PIN_SHIFT) | 0x24, + P0_17 = (17 << PIN_SHIFT) | 0x00, + P0_18 = (18 << PIN_SHIFT) | 0x78, + P0_19 = (19 << PIN_SHIFT) | 0x74, + P0_20 = (20 << PIN_SHIFT) | 0x70, + P0_21 = (21 << PIN_SHIFT) | 0x6C, + P0_22 = (22 << PIN_SHIFT) | 0x68, + P0_23 = (23 << PIN_SHIFT) | 0x64, + P0_24 = (24 << PIN_SHIFT) | 0x60, + P0_25 = (25 << PIN_SHIFT) | 0x5C, + P0_26 = (26 << PIN_SHIFT) | 0x58, + P0_27 = (27 << PIN_SHIFT) | 0x54, + P0_28 = (28 << PIN_SHIFT) | 0x50, + + dp2 = P0_4, + dp3 = P0_28, + dp4 = P0_11, + dp5 = P0_10, + dp6 = P0_16, + dp7 = P0_27, + dp8 = P0_26, + dp9 = P0_25, + dp10 = P0_24, + dp11 = P0_15, + dp12 = P0_1, + + dp15 = P0_6, + dp16 = P0_0, + dp17 = P0_14, + dp18 = P0_23, + dp19 = P0_22, + dp20 = P0_21, + dp21 = P0_20, + dp22 = P0_19, + dp23 = P0_17, + dp24 = P0_13, + dp25 = P0_12, + dp26 = P0_5, + + LED_RED = P0_20, + LED_GREEN = P0_21, + LED_BLUE = P0_22, + + // mbed original LED naming + LED1 = LED_RED, + LED2 = LED_GREEN, + LED3 = LED_BLUE, + LED4 = LED_BLUE, + + // Serial to USB pins + USBTX = P0_7, + USBRX = P0_18, + + // I2C pins + SCL = P0_10, + SDA = P0_11, + I2C_SCL = P0_10, + I2C_SDA = P0_11, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4, + PullDefault = PullDown +} PinMode; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX + +typedef struct { + unsigned char n; + unsigned char offset; +} SWM_Map; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/device.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/device.h new file mode 100644 index 0000000000..52d2e95d0e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/TARGET_SSCI824/device.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 +#define DEVICE_SERIAL_FC 0 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 0 +#define DEVICE_LOCALFILESYSTEM 0 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 0 + +#define DEVICE_ERROR_RED 1 + +#include "objects.h" + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/analogin_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/analogin_api.c new file mode 100644 index 0000000000..786be8ba06 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/analogin_api.c @@ -0,0 +1,131 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralNames.h" + +#if DEVICE_ANALOGIN + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_RANGE 0xFFF + +static const PinMap PinMap_ADC[] = { + {P0_7 , ADC_0, 0}, + {P0_6 , ADC_1, 0}, + {P0_14, ADC_2, 0}, + {P0_23, ADC_3, 0}, + {P0_22, ADC_4, 0}, + {P0_21, ADC_5, 0}, + {P0_20, ADC_6, 0}, + {P0_19, ADC_7, 0}, + {P0_18, ADC_8, 0}, + {P0_17, ADC_9, 0}, + {P0_13, ADC_10,0}, + {P0_4 , ADC_11,0}, +}; + +void analogin_init(analogin_t *obj, PinName pin) +{ + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + MBED_ASSERT(obj->adc != (ADCName)NC); + + LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6); + // pin enable + LPC_SWM->PINENABLE0 &= ~(1UL << (13 + obj->adc)); + // configure GPIO as input + LPC_GPIO_PORT->DIR0 &= ~(1UL << (pin >> PIN_SHIFT)); + + LPC_SYSCON->PDRUNCFG &= ~(1 << 4); + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 24); + + __IO LPC_ADC_Type *adc_reg = LPC_ADC; + + // determine the system clock divider for a 500kHz ADC clock during calibration + uint32_t clkdiv = (SystemCoreClock / 500000) - 1; + + // perform a self-calibration + adc_reg->CTRL = (1UL << 30) | (clkdiv & 0xFF); + while ((adc_reg->CTRL & (1UL << 30)) != 0); +} + +static inline uint32_t adc_read(analogin_t *obj) +{ + uint32_t channels; + __IO LPC_ADC_Type *adc_reg = LPC_ADC; + + channels = (obj->adc & 0x1F); + + // select channel + adc_reg->SEQA_CTRL &= ~(0xFFF); + adc_reg->SEQA_CTRL |= (1UL << channels); + + // start conversion and sequence enable + adc_reg->SEQA_CTRL |= ((1UL << 26) | (1UL << 31)); + + // Repeatedly get the sample data until DONE bit + volatile uint32_t data; + do { + data = adc_reg->SEQA_GDAT; + } while ((data & (1UL << 31)) == 0); + + // Stop conversion + adc_reg->SEQA_CTRL &= ~(1UL << 31); + + return ((data >> 4) & ADC_RANGE); +} + +static inline void order(uint32_t *a, uint32_t *b) +{ + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) +{ + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) +{ + uint32_t value = adc_read_u32(obj); + return (value << 4) | ((value >> 8) & 0x000F); // 12 bit +} + +float analogin_read(analogin_t *obj) +{ + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_api.c new file mode 100644 index 0000000000..8eb2a2b2f4 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_api.c @@ -0,0 +1,72 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "gpio_api.h" +#include "pinmap.h" + +static int gpio_enabled = 0; + +static void gpio_enable(void) +{ + gpio_enabled = 1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6); + + /* Peripheral reset control to GPIO and GPIO INT, a "1" bring it out of reset. */ + LPC_SYSCON->PRESETCTRL &= ~(1 << 10); + LPC_SYSCON->PRESETCTRL |= (1 << 10); +} + +uint32_t gpio_set(PinName pin) +{ + if (!gpio_enabled) + gpio_enable(); + + return (1 << ((int)pin >> PIN_SHIFT)); +} + +void gpio_init(gpio_t *obj, PinName pin) +{ + obj->pin = pin; + if (pin == (PinName)NC) + return; + + obj->mask = gpio_set(pin); + + obj->reg_set = &LPC_GPIO_PORT->SET0; + obj->reg_clr = &LPC_GPIO_PORT->CLR0; + obj->reg_in = &LPC_GPIO_PORT->PIN0; + obj->reg_dir = &LPC_GPIO_PORT->DIR0; +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) +{ + MBED_ASSERT(obj->pin != (PinName)NC); + switch (direction) { + case PIN_INPUT : + *obj->reg_dir &= ~obj->mask; + break; + case PIN_OUTPUT: + *obj->reg_dir |= obj->mask; + break; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_irq_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_irq_api.c new file mode 100644 index 0000000000..a8f7ab4cd8 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_irq_api.c @@ -0,0 +1,145 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> + +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "mbed_error.h" + +#if DEVICE_INTERRUPTIN + +#define CHANNEL_NUM 8 +#define LPC_GPIO_X LPC_PIN_INT +#define PININT_IRQ PIN_INT0_IRQn + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; + +static inline void handle_interrupt_in(uint32_t channel) +{ + uint32_t ch_bit = (1 << channel); + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((LPC_GPIO_X->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (LPC_GPIO_X->ISEL & ch_bit ) ) return; + + if ((LPC_GPIO_X->IENR & ch_bit) && (LPC_GPIO_X->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + LPC_GPIO_X->RISE = ch_bit; + } + if ((LPC_GPIO_X->IENF & ch_bit) && (LPC_GPIO_X->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + LPC_GPIO_X->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} +void gpio_irq4(void) {handle_interrupt_in(4);} +void gpio_irq5(void) {handle_interrupt_in(5);} +void gpio_irq6(void) {handle_interrupt_in(6);} +void gpio_irq7(void) {handle_interrupt_in(7);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) +{ + if (pin == NC) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; i<CHANNEL_NUM; i++) { + if (channel_ids[i] == 0) { + channel_ids[i] = id; + obj->ch = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + LPC_SYSCON->PINTSEL[obj->ch] = (pin >> PIN_SHIFT); + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= 1 << obj->ch; + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + case 4: channels_irq = &gpio_irq4; break; + case 5: channels_irq = &gpio_irq5; break; + case 6: channels_irq = &gpio_irq6; break; + case 7: channels_irq = &gpio_irq7; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ + obj->ch), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + unsigned int ch_bit = (1 << obj->ch); + + // Clear interrupt + if (!(LPC_GPIO_X->ISEL & ch_bit)) + LPC_GPIO_X->IST = ch_bit; + + // Edge trigger + LPC_GPIO_X->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + LPC_GPIO_X->IENR |= ch_bit; + } else { + LPC_GPIO_X->IENR &= ~ch_bit; + } + } else { + if (enable) { + LPC_GPIO_X->IENF |= ch_bit; + } else { + LPC_GPIO_X->IENF &= ~ch_bit; + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch)); +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_object.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_object.h new file mode 100644 index 0000000000..eac21ab67e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/gpio_object.h @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + __IO uint32_t *reg_dir; + __IO uint32_t *reg_set; + __IO uint32_t *reg_clr; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) +{ + MBED_ASSERT(obj->pin != (PinName)NC); + if (value) + *obj->reg_set = obj->mask; + else + *obj->reg_clr = obj->mask; +} + +static inline int gpio_read(gpio_t *obj) +{ + MBED_ASSERT(obj->pin != (PinName)NC); + return ((*obj->reg_in & obj->mask) ? 1 : 0); +} + +static inline int gpio_is_connected(const gpio_t *obj) { + return obj->pin != (PinName)NC; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/i2c_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/i2c_api.c new file mode 100644 index 0000000000..91044d4ab3 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/i2c_api.c @@ -0,0 +1,598 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdlib.h> +#include <string.h> + +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" + +#define LPC824_I2C0_FMPLUS 1 + +#if DEVICE_I2C + +static const SWM_Map SWM_I2C_SDA[] = { + //PINASSIGN Register ID, Pinselect bitfield position + { 9, 8}, + { 9, 24}, + {10, 8}, +}; + +static const SWM_Map SWM_I2C_SCL[] = { + //PINASSIGN Register ID, Pinselect bitfield position + { 9, 16}, + {10, 0}, + {10, 16}, +}; + + +static int i2c_used = 0; +static uint8_t repeated_start = 0; + +#define I2C_DAT(x) (x->i2c->MSTDAT) +#define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07)) + +static inline void i2c_power_enable(int ch) +{ + switch(ch) { + case 0: + // I2C0, Same as for LPC812 + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); + LPC_SYSCON->PRESETCTRL &= ~(1 << 6); + LPC_SYSCON->PRESETCTRL |= (1 << 6); + break; + case 1: + case 2: + case 3: + // I2C1,I2C2 or I2C3. Not available for LPC812 + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (20 + ch)); + LPC_SYSCON->PRESETCTRL &= ~(1 << (13 + ch)); + LPC_SYSCON->PRESETCTRL |= (1 << (13 + ch)); + break; + default: + break; + } +} + + +static inline void i2c_interface_enable(i2c_t *obj) { + obj->i2c->CFG |= (1 << 0); // Enable Master mode +// obj->i2c->CFG &= ~(1 << 1); // Disable Slave mode +} + + +static int get_available_i2c(void) { + int i; + for (i=0; i<3; i++) { + if ((i2c_used & (1 << i)) == 0) + return i+1; + } + return -1; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) +{ + const SWM_Map *swm; + uint32_t regVal; + int i2c_ch = 0; + + //LPC824 + //I2C0 can support FM+ but only on P0_11 and P0_10 + if (sda == I2C_SDA && scl == I2C_SCL) { + //Select I2C mode for P0_11 and P0_10 + LPC_SWM->PINENABLE0 &= ~(0x3 << 11); + +#if(LPC824_I2C0_FMPLUS == 1) + // Enable FM+ mode on P0_11, P0_10 + LPC_IOCON->PIO0_10 &= ~(0x3 << 8); + LPC_IOCON->PIO0_10 |= (0x2 << 8); //FM+ mode + LPC_IOCON->PIO0_11 &= ~(0x3 << 8); + LPC_IOCON->PIO0_11 |= (0x2 << 8); //FM+ mode +#endif + } + else { + //Select any other pin for I2C1, I2C2 or I2C3 + i2c_ch = get_available_i2c(); + if (i2c_ch == -1) + return; + i2c_used |= (1 << (i2c_ch - 1)); + + swm = &SWM_I2C_SDA[i2c_ch - 1]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((sda >> PIN_SHIFT) << swm->offset); + + swm = &SWM_I2C_SCL[i2c_ch - 1]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((scl >> PIN_SHIFT) << swm->offset); + } + + switch(i2c_ch) { + case 0: + obj->i2c = (LPC_I2C0_Type *)LPC_I2C0; + break; + case 1: + obj->i2c = (LPC_I2C0_Type *)LPC_I2C1; + break; + case 2: + obj->i2c = (LPC_I2C0_Type *)LPC_I2C2; + break; + case 3: + obj->i2c = (LPC_I2C0_Type *)LPC_I2C3; + break; + default: + break; + } + + // enable power + i2c_power_enable(i2c_ch); + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_interface_enable(obj); +} + + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Master Serial Interrupt (SI) is set +// Timeout when it takes too long. +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(obj->i2c->STAT & (1 << 0))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + + +//Attention. Spec says: First store Address in DAT before setting STA ! +//Undefined state when using single byte I2C operations and too much delay +//between i2c_start and do_i2c_write(Address). +//Also note that lpc812/824 will immediately continue reading a byte when Address b0 == 1 +inline int i2c_start(i2c_t *obj) { + int status = 0; + if (repeated_start) { + obj->i2c->MSTCTL = (1 << 1) | (1 << 0); // STA bit and Continue bit to complete previous RD or WR + repeated_start = 0; + } else { + obj->i2c->MSTCTL = (1 << 1); // STA bit + } + return status; +} + +//Generate Stop condition and wait until bus is Idle +//Will also send NAK for previous RD +inline int i2c_stop(i2c_t *obj) { + int timeout = 0; + + // STP bit and Continue bit. Sends NAK to complete previous RD + obj->i2c->MSTCTL = (1 << 2) | (1 << 0); + + //Spin until Ready (b0 == 1)and Status is Idle (b3..b1 == 000) + while ((obj->i2c->STAT & ((7 << 1) | (1 << 0))) != ((0 << 1) | (1 << 0))) { + timeout ++; + if (timeout > 100000) return 1; + } + + // repeated_start = 0; // bus free + return 0; +} + +//Spec says: first check Idle and status is Ok +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + if (!addr) + obj->i2c->MSTCTL = (1 << 0); //Set continue for data. Should not be set for addr since that uses STA + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + + +//Attention, correct Order: wait for data ready, read data, read status, continue, return +//Dont read DAT or STAT when not ready, so dont read after setting continue. +//Results may be invalid when next read is underway. +static inline int i2c_do_read(i2c_t *obj, int last) { + // wait for it to arrive + i2c_wait_SI(obj); + if (!last) + obj->i2c->MSTCTL = (1 << 0); //ACK and Continue + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t clkdiv = PCLK / (hz * 4) - 1; + + obj->i2c->CLKDIV = clkdiv; + obj->i2c->MSTTIME = 0; +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + //Store the address+RD and then generate STA + I2C_DAT(obj) = address | 0x01; + i2c_start(obj); + + // Wait for completion of STA and Sending of SlaveAddress+RD and first Read byte + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK on SlaveAddress + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + // Read in all except last byte + for (count = 0; count < (length-1); count++) { + + // Wait for it to arrive, note that first byte read after address+RD is already waiting + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store read byte + + obj->i2c->MSTCTL = (1 << 0); // Send ACK and Continue to read + } + + // Read final byte + // Wait for it to arrive + i2c_wait_SI(obj); + + status = i2c_status(obj); + if (status != 0x01) { // RX RDY + i2c_stop(obj); + return count; + } + data[count] = I2C_DAT(obj) & 0xFF; // Store final read byte + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); // Also sends NAK for last read byte + } else { + repeated_start = 1; + } + + return length; +} + + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + //Store the address+/WR and then generate STA + I2C_DAT(obj) = address & 0xFE; + i2c_start(obj); + + // Wait for completion of STA and Sending of SlaveAddress+/WR + i2c_wait_SI(obj); + status = i2c_status(obj); + if (status == 0x03) { // NAK SlaveAddress + i2c_stop(obj); + return I2C_ERROR_NO_SLAVE; + } + + //Write all bytes + for (i=0; i<length; i++) { + status = i2c_do_write(obj, data[i], 0); + if (status != 0x02) { // TX RDY. Handles a Slave NAK on datawrite + i2c_stop(obj); + return i; + } + } + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } else { + repeated_start = 1; + } + + return length; +} + +void i2c_reset(i2c_t *obj) { + i2c_stop(obj); +} + +int i2c_byte_read(i2c_t *obj, int last) { + return (i2c_do_read(obj, last) & 0xFF); +// return (i2c_do_read(obj, last, 0) & 0xFF); +} + +int i2c_byte_write(i2c_t *obj, int data) { + int ack; + int status = i2c_do_write(obj, (data & 0xFF), 0); + + switch(status) { + case 2: // TX RDY. Handles a Slave NAK on datawrite + ack = 1; + break; + default: + ack = 0; + break; + } + + return ack; +} + + +#if DEVICE_I2CSLAVE + +#define I2C_SLVDAT(x) (x->i2c->SLVDAT) +#define I2C_SLVSTAT(x) ((x->i2c->STAT >> 9) & (0x03)) +#define I2C_SLVSI(x) ((x->i2c->STAT >> 8) & (0x01)) +//#define I2C_SLVCNT(x) (x->i2c->SLVCTL = (1 << 0)) +//#define I2C_SLVNAK(x) (x->i2c->SLVCTL = (1 << 1)) + +#if(0) +// Wait until the Slave Serial Interrupt (SI) is set +// Timeout when it takes too long. +static int i2c_wait_slave_SI(i2c_t *obj) { + int timeout = 0; + while (!(obj->i2c->STAT & (1 << 8))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} +#endif + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + + if (enable_slave) { +// obj->i2c->CFG &= ~(1 << 0); //Disable Master mode + obj->i2c->CFG |= (1 << 1); //Enable Slave mode + } + else { +// obj->i2c->CFG |= (1 << 0); //Enable Master mode + obj->i2c->CFG &= ~(1 << 1); //Disable Slave mode + } +} + +// Wait for next I2C event and find out what is going on +// +int i2c_slave_receive(i2c_t *obj) { + int addr; + + // Check if there is any data pending + if (! I2C_SLVSI(obj)) { + return 0; //NoData + }; + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + + // Get the received address + addr = I2C_SLVDAT(obj) & 0xFF; + // Send ACK on address and Continue + obj->i2c->SLVCTL = (1 << 0); + + if (addr == 0x00) { + return 2; //WriteGeneral + } + //check the RW bit + if ((addr & 0x01) == 0x01) { + return 1; //ReadAddressed + } + else { + return 3; //WriteAddressed + } + //break; + + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Oops, should never get here... + obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data, try to recover... + return 0; //NoData + + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + // Oops, should never get here... + I2C_SLVDAT(obj) = 0xFF; // Send dummy data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover... + return 0; //NoData + + case 0x3: // Reserved. + default: // Oops, should never get here... + obj->i2c->SLVCTL = (1 << 0); // Continue and try to recover... + return 0; //NoData + //break; + } //switch status +} + +// The dedicated I2C Slave byte read and byte write functions need to be called +// from 'common' mbed I2CSlave API for devices that have separate Master and +// Slave engines such as the lpc812 and lpc1549. + +//Called when Slave is addressed for Write, Slave will receive Data in polling mode +//Parameter last=1 means received byte will be NACKed. +int i2c_slave_byte_read(i2c_t *obj, int last) { + int data; + + // Wait for data + while (!I2C_SLVSI(obj)); // Wait forever +//if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Dont bother to check State, were not returning it anyhow.. +//if (I2C_SLVSTAT(obj)) == 0x01) { + // Slave receive. Received data is available (Slave Receiver mode). +//}; + + data = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data + if (last) { + obj->i2c->SLVCTL = (1 << 1); // Send NACK on received data and Continue + } + else { + obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read + } + + return data; +} + + +//Called when Slave is addressed for Read, Slave will send Data in polling mode +// +int i2c_slave_byte_write(i2c_t *obj, int data) { + + // Wait until Ready + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Should not get here... + return -2; + //break; + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + I2C_SLVDAT(obj) = data & 0xFF; // Store the data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue to send + + return 1; + //break; + case 0x3: // Reserved. + default: + // Should not get here... + return -3; + //break; + } // switch status +} + + +//Called when Slave is addressed for Write, Slave will receive Data in polling mode +//Parameter length (>=1) is the maximum allowable number of bytes. All bytes will be ACKed. +int i2c_slave_read(i2c_t *obj, char *data, int length) { + int count=0; + + // Read and ACK all expected bytes + while (count < length) { + // Wait for data + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + data[count] = I2C_SLVDAT(obj) & 0xFF; // Get and store the received data + obj->i2c->SLVCTL = (1 << 0); // Send ACK on data and Continue to read + break; + + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + case 0x3: // Reserved. + default: // Should never get here... + return -2; + //break; + } // switch status + + count++; + } // for all bytes + + return count; // Received the expected number of bytes +} + + +//Called when Slave is addressed for Read, Slave will send Data in polling mode +//Parameter length (>=1) is the maximum number of bytes. Exit when Slave byte is NACKed. +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + int count; + + // Send and all bytes or Exit on NAK + for (count=0; count < length; count++) { + // Wait until Ready for data + while (!I2C_SLVSI(obj)); // Wait forever +// if (i2c_wait_slave_SI(obj) != 0) {return -2;} // Wait with timeout + + // Check State + switch(I2C_SLVSTAT(obj)) { + case 0x0: // Slave address plus R/W received + // At least one of the four slave addresses has been matched by hardware. + // You can figure out which address by checking Slave address match Index in STAT register. + // I2C Restart occurred + return -1; + //break; + case 0x1: // Slave receive. Received data is available (Slave Receiver mode). + // Should not get here... + return -2; + //break; + case 0x2: // Slave transmit. Data can be transmitted (Slave Transmitter mode). + I2C_SLVDAT(obj) = data[count] & 0xFF; // Store the data for transmission + obj->i2c->SLVCTL = (1 << 0); // Continue to send + break; + case 0x3: // Reserved. + default: + // Should not get here... + return -3; + //break; + } // switch status + } // for all bytes + + return length; // Transmitted the max number of bytes +} + + +// Set the four slave addresses. +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + obj->i2c->SLVADR0 = (address & 0xFE); // Store address in address 0 register + obj->i2c->SLVADR1 = (0x00 & 0xFE); // Store general call write address in address 1 register + obj->i2c->SLVADR2 = (0x01); // Disable address 2 register + obj->i2c->SLVADR3 = (0x01); // Disable address 3 register + obj->i2c->SLVQUAL0 = (mask & 0xFE); // Qualifier mask for address 0 register. Any maskbit that is 1 will always be a match +} + +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/objects.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/objects.h new file mode 100644 index 0000000000..2454b4dc10 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/objects.h @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct serial_s { + LPC_USART0_Type *uart; + unsigned char index; +}; + +struct i2c_s { + LPC_I2C0_Type *i2c; + void *handler; +}; + +struct spi_s { + LPC_SPI0_Type *spi; + unsigned char spi_n; +}; + +struct analogin_s { + ADCName adc; +}; + +struct pwmout_s { + LPC_SCT_Type* pwm; + uint32_t pwm_ch; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pinmap.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pinmap.c new file mode 100644 index 0000000000..41b2144d8e --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pinmap.c @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pinmap.h" +#include "mbed_error.h" + + +void pin_function(PinName pin, int function) +{ + // do nothing + return; +} + +void pin_mode(PinName pin, PinMode mode) +{ + MBED_ASSERT(pin != (PinName)NC); + + if ((pin == P0_10) || (pin == P0_11)) { + // True open-drain pins can be configured for different I2C-bus speeds + return; + } + + __IO uint32_t *reg = (uint32_t *)(LPC_IOCON_BASE + (pin & 0xFF)); + + if (mode == OpenDrain) { + *reg |= (1 << 10); + } else { + uint32_t tmp = *reg; + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + *reg = tmp; + } +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c new file mode 100644 index 0000000000..05c5113e46 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c @@ -0,0 +1,172 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_PWMOUT + +// bit flags for used SCTs +static unsigned char sct_used = 0; + +static int get_available_sct() +{ + int i; + for (i = 0; i < 4; i++) { + if ((sct_used & (1 << i)) == 0) + return i; + } + return -1; +} + +void pwmout_init(pwmout_t* obj, PinName pin) +{ + MBED_ASSERT(pin != (uint32_t)NC); + + int sct_n = get_available_sct(); + if (sct_n == -1) { + error("No available SCT"); + } + + sct_used |= (1 << sct_n); + + obj->pwm = (LPC_SCT_Type*)LPC_SCT; + obj->pwm_ch = sct_n; + + LPC_SCT_Type* pwm = obj->pwm; + + // Enable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8); + + // Clear peripheral reset the SCT: + LPC_SYSCON->PRESETCTRL |= (1 << 8); + + switch(sct_n) { + case 0: + // SCT_OUT0 + LPC_SWM->PINASSIGN[7] &= ~0xFF000000; + LPC_SWM->PINASSIGN[7] |= ((pin >> PIN_SHIFT) << 24); + break; + case 1: + // SCT_OUT1 + LPC_SWM->PINASSIGN[8] &= ~0x000000FF; + LPC_SWM->PINASSIGN[8] |= (pin >> PIN_SHIFT); + break; + case 2: + // SCT2_OUT2 + LPC_SWM->PINASSIGN[8] &= ~0x0000FF00; + LPC_SWM->PINASSIGN[8] |= ((pin >> PIN_SHIFT) << 8); + break; + case 3: + // SCT3_OUT3 + LPC_SWM->PINASSIGN[8] &= ~0x00FF0000; + LPC_SWM->PINASSIGN[8] |= ((pin >> PIN_SHIFT) << 16); + break; + default: + break; + } + + // Unified 32-bit counter, autolimit + pwm->CONFIG |= ((0x3 << 17) | 0x01); + + // halt and clear the counter + pwm->CTRL |= (1 << 2) | (1 << 3); + + // System Clock -> us_ticker (1)MHz + pwm->CTRL &= ~(0x7F << 5); + pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5); + + pwm->OUT[sct_n].SET = (1 << ((sct_n * 2) + 0)); + pwm->OUT[sct_n].CLR = (1 << ((sct_n * 2) + 1)); + + pwm->EVENT[(sct_n * 2) + 0].CTRL = (1 << 12) | ((sct_n * 2) + 0); // match event + pwm->EVENT[(sct_n * 2) + 0].STATE = 0xFFFFFFFF; + pwm->EVENT[(sct_n * 2) + 1].CTRL = (1 << 12) | ((sct_n * 2) + 1); + pwm->EVENT[(sct_n * 2) + 1].STATE = 0xFFFFFFFF; + + // unhalt the counter: + // - clearing bit 2 of the CTRL register + pwm->CTRL &= ~(1 << 2); + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); +} + +void pwmout_free(pwmout_t* obj) +{ + // Disable the SCT clock + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8); + sct_used &= ~(1 << obj->pwm_ch); +} + +void pwmout_write(pwmout_t* obj, float value) +{ + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL[obj->pwm_ch * 2]) * value); + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on; +} + +float pwmout_read(pwmout_t* obj) +{ + uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0]; + uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1]; + float v = (float)t_on/(float)t_off; + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) +{ + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) +{ + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) +{ + uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0]; + uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1]; + float v = (float)t_on/(float)t_off; + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint32_t)us; + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)((float)us * (float)v); +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) +{ + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) +{ + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) +{ + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us; +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/rom_i2c_8xx.h b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/rom_i2c_8xx.h new file mode 100644 index 0000000000..8969a6dd56 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/rom_i2c_8xx.h @@ -0,0 +1,127 @@ +/* + * @brief LPC8xx I2C ROM API declarations and functions + * + * @note + * Copyright(C) NXP Semiconductors, 2012 + * All rights reserved. + * + * @par + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * LPC products. This software is supplied "AS IS" without any warranties of + * any kind, and NXP Semiconductors and its licensor disclaim any and + * all warranties, express or implied, including all implied warranties of + * merchantability, fitness for a particular purpose and non-infringement of + * intellectual property rights. NXP Semiconductors assumes no responsibility + * or liability for the use of the software, conveys no license or rights under any + * patent, copyright, mask work right, or any other intellectual property rights in + * or to any products. NXP Semiconductors reserves the right to make changes + * in the software without notification. NXP Semiconductors also makes no + * representation or warranty that such application will be suitable for the + * specified use without further testing or modification. + * + * @par + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, under NXP Semiconductors' and its + * licensor's relevant copyrights in the software, without fee, provided that it + * is used in conjunction with NXP Semiconductors microcontrollers. This + * copyright, permission, and disclaimer notice must appear in all copies of + * this code. + */ + +#ifndef __ROM_I2C_8XX_H_ +#define __ROM_I2C_8XX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup CHIP_I2CROM_8XX CHIP: LPC8xx I2C ROM API declarations and functions + * @ingroup CHIP_8XX_Drivers + * @{ + */ + +/** + * @brief LPC8xx I2C ROM driver handle structure + */ +typedef void *I2C_HANDLE_T; + +typedef uint32_t ErrorCode_t; + +/** + * @brief LPC8xx I2C ROM driver callback function + */ +typedef void (*I2C_CALLBK_T)(uint32_t err_code, uint32_t n); + +/** + * LPC8xx I2C ROM driver parameter structure + */ +typedef struct I2C_PARAM { + uint32_t num_bytes_send; /*!< No. of bytes to send */ + uint32_t num_bytes_rec; /*!< No. of bytes to receive */ + uint8_t *buffer_ptr_send; /*!< Pointer to send buffer */ + uint8_t *buffer_ptr_rec; /*!< Pointer to receive buffer */ + I2C_CALLBK_T func_pt; /*!< Callback function */ + uint8_t stop_flag; /*!< Stop flag */ + uint8_t dummy[3]; +} I2C_PARAM_T; + +/** + * LPC8xx I2C ROM driver result structure + */ +typedef struct I2C_RESULT { + uint32_t n_bytes_sent; /*!< No. of bytes sent */ + uint32_t n_bytes_recd; /*!< No. of bytes received */ +} I2C_RESULT_T; + +/** + * LPC8xx I2C ROM driver modes enum + */ +typedef enum CHIP_I2C_MODE { + IDLE, /*!< IDLE state */ + MASTER_SEND, /*!< Master send state */ + MASTER_RECEIVE, /*!< Master Receive state */ + SLAVE_SEND, /*!< Slave send state */ + SLAVE_RECEIVE /*!< Slave receive state */ +} CHIP_I2C_MODE_T; + +/** + * LPC8xx I2C ROM driver APIs structure + */ +typedef struct I2CD_API { + /*!< Interrupt Support Routine */ + void (*i2c_isr_handler)(I2C_HANDLE_T *handle); + + /*!< MASTER functions */ + ErrorCode_t (*i2c_master_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_tx_rx_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_master_tx_rx_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + + /*!< SLAVE functions */ + ErrorCode_t (*i2c_slave_receive_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_transmit_poll)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_receive_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_slave_transmit_intr)(I2C_HANDLE_T *handle, I2C_PARAM_T *param, I2C_RESULT_T *result); + ErrorCode_t (*i2c_set_slave_addr)(I2C_HANDLE_T *handle, uint32_t slave_addr_0_3, uint32_t slave_mask_0_3); + + /*!< OTHER support functions */ + uint32_t (*i2c_get_mem_size)(void); + I2C_HANDLE_T * (*i2c_setup)( uint32_t i2c_base_addr, uint32_t * start_of_ram); + ErrorCode_t (*i2c_set_bitrate)(I2C_HANDLE_T *handle, uint32_t p_clk_in_hz, uint32_t bitrate_in_bps); + uint32_t (*i2c_get_firmware_version)(void); + CHIP_I2C_MODE_T (*i2c_get_status)(I2C_HANDLE_T *handle); + ErrorCode_t (*i2c_set_timeout)(I2C_HANDLE_T *handle, uint32_t timeout); +} I2CD_API_T; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ROM_I2C_8XX_H_ */ diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/serial_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/serial_api.c new file mode 100644 index 0000000000..a6fa658d04 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/serial_api.c @@ -0,0 +1,357 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// math.h required for floating point operations for baud rate calculation +#include "mbed_assert.h" +#include <math.h> +#include <string.h> + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_SERIAL + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 3 + +static const SWM_Map SWM_UART_TX[] = { + {0, 0}, + {1, 8}, + {2, 16}, +}; + +static const SWM_Map SWM_UART_RX[] = { + {0, 8}, + {1, 16}, + {2, 24}, +}; + +static const SWM_Map SWM_UART_RTS[] = { + {0, 16}, + {1, 24}, + {3, 0}, +}; + +static const SWM_Map SWM_UART_CTS[] = { + {0, 24}, + {2, 0}, + {3, 8} +}; + +// bit flags for used UARTs +static unsigned char uart_used = 0; + +static int get_available_uart(void) +{ + int i; + for (i=0; i<UART_NUM; i++) { + if ((uart_used & (1 << i)) == 0) + return i; + } + return -1; +} + +#define UART_EN (0x01<<0) + +#define CTS_DELTA (0x01<<5) +#define RXBRK (0x01<<10) +#define DELTA_RXBRK (0x01<<11) + +#define RXRDY (0x01<<0) +#define TXRDY (0x01<<2) + +#define RXRDYEN RXRDY +#define TXRDYEN TXRDY + +#define TXBRKEN (0x01<<1) +#define CTSEN (0x01<<9) + +static uint32_t UARTSysClk; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +static int check_duplication(serial_t *obj, PinName tx, PinName rx) +{ + if (uart_used == 0) + return 0; + + const SWM_Map *swm; + uint32_t assigned_tx, assigned_rx; + int ch; + for (ch=0; ch<UART_NUM; ch++) { + // read assigned TX in the UART channel of switch matrix + swm = &SWM_UART_TX[ch]; + assigned_tx = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + assigned_tx = assigned_tx >> swm->offset; + // read assigned RX in the UART channel of switch matrix + swm = &SWM_UART_RX[ch]; + assigned_rx = LPC_SWM->PINASSIGN[swm->n] & (0xFF << swm->offset); + assigned_rx = assigned_rx >> swm->offset; + if ((assigned_tx == (uint32_t)(tx >> PIN_SHIFT)) && (assigned_rx == (uint32_t)(rx >> PIN_SHIFT))) { + obj->index = ch; + obj->uart = (LPC_USART0_Type *)(LPC_USART0_BASE + (0x4000 * ch)); + return 1; + } + } + return 0; +} + +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + int is_stdio_uart = 0; + + if (check_duplication(obj, tx, rx) == 1) + return; + + int uart_n = get_available_uart(); + if (uart_n == -1) { + error("No available UART"); + } + obj->index = uart_n; + obj->uart = (LPC_USART0_Type *)(LPC_USART0_BASE + (0x4000 * uart_n)); + uart_used |= (1 << uart_n); + + const SWM_Map *swm; + uint32_t regVal; + + swm = &SWM_UART_TX[uart_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((tx >> PIN_SHIFT) << swm->offset); + + swm = &SWM_UART_RX[uart_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((rx >> PIN_SHIFT) << swm->offset); + + /* uart clock divided by 1 */ + LPC_SYSCON->UARTCLKDIV = 1; + + /* disable uart interrupts */ + NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART clock */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (14 + uart_n)); + + /* Peripheral reset control to UART, a "1" bring it out of reset. */ + LPC_SYSCON->PRESETCTRL &= ~(0x1 << (3 + uart_n)); + LPC_SYSCON->PRESETCTRL |= (0x1 << (3 + uart_n)); + + UARTSysClk = MainClock / LPC_SYSCON->UARTCLKDIV; + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + /* Clear all status bits. */ + obj->uart->STAT = CTS_DELTA | DELTA_RXBRK; + + /* enable uart interrupts */ + NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + uart_n)); + + /* Enable UART */ + obj->uart->CFG |= UART_EN; + + is_stdio_uart = ((tx == USBTX) && (rx == USBRX)); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) +{ + uart_used &= ~(1 << obj->index); + serial_irq_ids[obj->index] = 0; +} + +void serial_baud(serial_t *obj, int baudrate) +{ + /* Integer divider: + BRG = UARTSysClk/(Baudrate * 16) - 1 + + Frational divider: + FRG = ((UARTSysClk / (Baudrate * 16 * (BRG + 1))) - 1) + + where + FRG = (LPC_SYSCON->UARTFRDADD + 1) / (LPC_SYSCON->UARTFRDSUB + 1) + + (1) The easiest way is set SUB value to 256, -1 encoded, thus SUB + register is 0xFF. + (2) In ADD register value, depending on the value of UartSysClk, + baudrate, BRG register value, and SUB register value, be careful + about the order of multiplier and divider and make sure any + multiplier doesn't exceed 32-bit boundary and any divider doesn't get + down below one(integer 0). + (3) ADD should be always less than SUB. + */ + obj->uart->BRG = UARTSysClk / 16 / baudrate - 1; + + LPC_SYSCON->UARTFRGDIV = 0xFF; + LPC_SYSCON->UARTFRGMULT = ( ((UARTSysClk / 16) * (LPC_SYSCON->UARTFRGDIV + 1)) / + (baudrate * (obj->uart->BRG + 1)) + ) - (LPC_SYSCON->UARTFRGDIV + 1); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + // 0: 1 stop bits, 1: 2 stop bits + MBED_ASSERT((stop_bits == 1) || (stop_bits == 2)); + MBED_ASSERT((data_bits > 6) && (data_bits < 10)); // 0: 7 data bits ... 2: 9 data bits + MBED_ASSERT((parity == ParityNone) || (parity == ParityEven) || (parity == ParityOdd)); + stop_bits -= 1; + data_bits -= 7; + + int paritysel = 0; + switch (parity) { + case ParityNone: paritysel = 0; break; + case ParityEven: paritysel = 2; break; + case ParityOdd : paritysel = 3; break; + default: + break; + } + + obj->uart->CFG = (data_bits << 2) + | (paritysel << 4) + | (stop_bits << 6); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(SerialIrq irq_type, uint32_t index) +{ + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_USART0->INTSTAT & RXRDY) ? RxIrq : TxIrq, 0);} +void uart1_irq() {uart_irq((LPC_USART1->INTSTAT & RXRDY) ? RxIrq : TxIrq, 1);} +void uart2_irq() {uart_irq((LPC_USART2->INTSTAT & RXRDY) ? RxIrq : TxIrq, 2);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case LPC_USART0_BASE: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; + case LPC_USART1_BASE: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; + case LPC_USART2_BASE: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; + } + + if (enable) { + NVIC_DisableIRQ(irq_n); + obj->uart->INTENSET |= (1 << ((irq == RxIrq) ? 0 : 2)); + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + obj->uart->INTENCLR |= (1 << ((irq == RxIrq) ? 0 : 2)); + if ( (obj->uart->INTENSET & (RXRDYEN | TXRDYEN)) == 0) { + NVIC_DisableIRQ(irq_n); + } + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) +{ + while (!serial_readable(obj)); + return obj->uart->RXDAT; +} + +void serial_putc(serial_t *obj, int c) +{ + while (!serial_writable(obj)); + obj->uart->TXDAT = c; +} + +int serial_readable(serial_t *obj) +{ + return obj->uart->STAT & RXRDY; +} + +int serial_writable(serial_t *obj) +{ + return obj->uart->STAT & TXRDY; +} + +void serial_clear(serial_t *obj) +{ + // [TODO] +} + +void serial_pinout_tx(PinName tx) +{ + +} + +void serial_break_set(serial_t *obj) +{ + obj->uart->CTL |= TXBRKEN; +} + +void serial_break_clear(serial_t *obj) +{ + obj->uart->CTL &= ~TXBRKEN; +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) +{ + const SWM_Map *swm_rts, *swm_cts; + uint32_t regVal_rts, regVal_cts; + + swm_rts = &SWM_UART_RTS[obj->index]; + swm_cts = &SWM_UART_CTS[obj->index]; + regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset); + regVal_cts = LPC_SWM->PINASSIGN[swm_cts->n] & ~(0xFF << swm_cts->offset); + + if (FlowControlNone == type) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); + obj->uart->CFG &= ~CTSEN; + return; + } + if ((FlowControlRTS == type || FlowControlRTSCTS == type) && (rxflow != NC)) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | ((rxflow >> PIN_SHIFT) << swm_rts->offset); + if (FlowControlRTS == type) { + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset); + obj->uart->CFG &= ~CTSEN; + } + } + if ((FlowControlCTS == type || FlowControlRTSCTS == type) && (txflow != NC)) { + LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | ((txflow >> PIN_SHIFT) << swm_cts->offset); + obj->uart->CFG |= CTSEN; + if (FlowControlCTS == type) { + LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset); + } + } +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/sleep.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/sleep.c new file mode 100644 index 0000000000..64115a2055 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/sleep.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sleep_api.h" +#include "cmsis.h" + + +//#define DEEPSLEEP +#define POWERDOWN + +void sleep(void) +{ + //Normal sleep mode for PCON: + LPC_PMU->PCON &= ~0x03; + + //Normal sleep mode for ARM core: + SCB->SCR = 0; + + //And go to sleep + __WFI(); +} + +// Deepsleep/powerdown modes assume the device is configured to use its internal RC oscillator directly + +void deepsleep(void) +{ + //Deep sleep in PCON + LPC_PMU->PCON &= ~0x03; + +#if defined(DEEPSLEEP) + LPC_PMU->PCON |= 0x01; +#elif defined(POWERDOWN) + LPC_PMU->PCON |= 0x02; +#endif + + //If brownout detection and WDT are enabled, keep them enabled during sleep + LPC_SYSCON->PDSLEEPCFG = LPC_SYSCON->PDRUNCFG; + + //After wakeup same stuff as currently enabled: + LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG; + + //All interrupts may wake up: + LPC_SYSCON->STARTERP0 = 0xFF; + LPC_SYSCON->STARTERP1 = 0xFFFF; + + //Deep sleep for ARM core: + SCB->SCR = 1<<2; + + __WFI(); +} diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/spi_api.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/spi_api.c new file mode 100644 index 0000000000..9b9b29103d --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/spi_api.c @@ -0,0 +1,209 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed_assert.h" + +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" + +#if DEVICE_SPI + +static const SWM_Map SWM_SPI_SSEL[] = { + {4, 16}, + {6, 8}, +}; + +static const SWM_Map SWM_SPI_SCLK[] = { + {3, 24}, + {5, 16}, +}; + +static const SWM_Map SWM_SPI_MOSI[] = { + {4, 0}, + {5, 24}, +}; + +static const SWM_Map SWM_SPI_MISO[] = { + {4, 8}, + {6, 0}, +}; + +// bit flags for used SPIs +static unsigned char spi_used = 0; + +static int get_available_spi(void) +{ + int i; + for (i=0; i<2; i++) { + if ((spi_used & (1 << i)) == 0) + return i; + } + return -1; +} + +static inline void spi_disable(spi_t *obj); +static inline void spi_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + int spi_n = get_available_spi(); + if (spi_n == -1) { + error("No available SPI"); + } + obj->spi_n = spi_n; + spi_used |= (1 << spi_n); + + obj->spi = (spi_n) ? (LPC_SPI0_Type *)(LPC_SPI1_BASE) : (LPC_SPI0_Type *)(LPC_SPI0_BASE); + + const SWM_Map *swm; + uint32_t regVal; + + if (sclk != (PinName)NC) { + swm = &SWM_SPI_SCLK[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((sclk >> PIN_SHIFT) << swm->offset); + } + + if (mosi != (PinName)NC) { + swm = &SWM_SPI_MOSI[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((mosi >> PIN_SHIFT) << swm->offset); + } + + if (miso != (PinName)NC) { + swm = &SWM_SPI_MISO[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((miso >> PIN_SHIFT) << swm->offset); + } + + if (ssel != (PinName)NC) { + swm = &SWM_SPI_SSEL[obj->spi_n]; + regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); + LPC_SWM->PINASSIGN[swm->n] = regVal | ((ssel >> PIN_SHIFT) << swm->offset); + } + + // clear interrupts + obj->spi->INTENCLR = 0x3f; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << (11 + obj->spi_n)); + LPC_SYSCON->PRESETCTRL &= ~(1 << obj->spi_n); + LPC_SYSCON->PRESETCTRL |= (1 << obj->spi_n); + + // set default format and frequency + if (ssel == (PinName)NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + obj->spi->DLY = 2; // 2 SPI clock times pre-delay + + // enable the ssp channel + spi_enable(obj); +} + +void spi_free(spi_t *obj) +{ +} + +void spi_format(spi_t *obj, int bits, int mode, int slave) +{ + MBED_ASSERT(((bits >= 1) && (bits <= 16)) && ((mode >= 0) && (mode <= 3))); + spi_disable(obj); + + obj->spi->CFG &= ~((0x3 << 4) | (1 << 2)); + obj->spi->CFG |= ((mode & 0x3) << 4) | ((slave ? 0 : 1) << 2); + + obj->spi->TXCTL &= ~( 0xF << 24); + obj->spi->TXCTL |= ((bits - 1) << 24); + + spi_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) +{ + spi_disable(obj); + + // rise DIV value if it cannot be divided + obj->spi->DIV = (SystemCoreClock + (hz - 1))/hz - 1; + + spi_enable(obj); +} + +static inline void spi_disable(spi_t *obj) +{ + obj->spi->CFG &= ~(1 << 0); +} + +static inline void spi_enable(spi_t *obj) +{ + obj->spi->CFG |= (1 << 0); +} + +static inline int spi_readable(spi_t *obj) +{ + return obj->spi->STAT & (1 << 0); +} + +static inline int spi_writeable(spi_t *obj) +{ + return obj->spi->STAT & (1 << 1); +} + +static inline void spi_write(spi_t *obj, int value) +{ + while (!spi_writeable(obj)); + // end of transfer + obj->spi->TXCTL |= (1 << 20); + obj->spi->TXDAT = (value & 0xffff); +} + +static inline int spi_read(spi_t *obj) +{ + while (!spi_readable(obj)); + return (obj->spi->RXDAT & 0xFFFF); +} + +int spi_master_write(spi_t *obj, int value) +{ + spi_write(obj, value); + return spi_read(obj); +} + +int spi_busy(spi_t *obj) +{ + // checking RXOV(Receiver Overrun interrupt flag) + return obj->spi->STAT & (1 << 2); +} + +int spi_slave_receive(spi_t *obj) +{ + return (spi_readable(obj) && !spi_busy(obj)) ? (1) : (0); +} + +int spi_slave_read(spi_t *obj) +{ + return (obj->spi->RXDAT & 0xFFFF); +} + +void spi_slave_write(spi_t *obj, int value) +{ + while (spi_writeable(obj) == 0); + obj->spi->TXDAT = value; +} + +#endif diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/us_ticker.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/us_ticker.c new file mode 100644 index 0000000000..dfb8debe52 --- /dev/null +++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC82X/us_ticker.c @@ -0,0 +1,106 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +static int us_ticker_inited = 0; +int MRT_Clock_MHz; +unsigned int ticker_fullcount_us; +unsigned long int ticker_expired_count_us = 0; + +#define US_TICKER_TIMER_IRQn MRT_IRQn + +void us_ticker_init(void) { + + if (us_ticker_inited) + return; + + us_ticker_inited = 1; + + // Calculate MRT clock value (MRT has no prescaler) + MRT_Clock_MHz = (SystemCoreClock / 1000000); + // Calculate fullcounter value in us (MRT has 31 bits and clock is 30MHz) + ticker_fullcount_us = 0x80000000UL/MRT_Clock_MHz; + + // Enable the MRT clock + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10); + + // Clear peripheral reset the MRT + LPC_SYSCON->PRESETCTRL |= (1 << 7); + + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + LPC_MRT->INTVAL0 = 0xFFFFFFFFUL; + // Enable Ch0 interrupt, Mode 0 is Repeat Interrupt + LPC_MRT->CTRL0 = (0x0 << 1) | (0x1 << 0); + + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + LPC_MRT->INTVAL1 = 0x80000000UL; + // Disable ch1 interrupt, Mode 0 is Repeat Interrupt + LPC_MRT->CTRL1 = (0x0 << 1) | (0x0 << 0); + + // Set MRT interrupt vector + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +//TIMER0 is used for us ticker and timers (Timer, wait(), wait_us() etc) +uint32_t us_ticker_read() { + + if (!us_ticker_inited) + us_ticker_init(); + + // Generate ticker value + // MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer + // Calculate expected value using number of expired times to mimic a 32bit timer @ 1 MHz + return (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_Clock_MHz + ticker_expired_count_us; +} + +//TIMER1 is used for Timestamped interrupts (Ticker(), Timeout()) +void us_ticker_set_interrupt(timestamp_t timestamp) { + + // MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer + // Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit) + // Note: The MRT has less counter headroom available than the typical mbed 32bit timer @ 1 MHz. + // The calculated counter interval until the next timestamp will be truncated and an + // 'early' interrupt will be generated in case the max required count interval exceeds + // the available 31 bits space. However, the mbed us_ticker interrupt handler will + // check current time against the next scheduled timestamp and simply re-issue the + // same interrupt again when needed. The calculated counter interval will now be smaller. + LPC_MRT->INTVAL1 = (((timestamp - us_ticker_read()) * MRT_Clock_MHz) | 0x80000000UL); + + // Enable interrupt + LPC_MRT->CTRL1 |= 1; +} + +//Disable Timestamped interrupts triggered by TIMER1 +void us_ticker_disable_interrupt() { + //Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock) + LPC_MRT->CTRL1 &= ~1; +} + +void us_ticker_clear_interrupt() { + + //Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock) + if (LPC_MRT->STAT1 & 1) + LPC_MRT->STAT1 = 1; + + //Timer0 for us counter (31 bits downcounter @ SystemCoreClock) + if (LPC_MRT->STAT0 & 1) { + LPC_MRT->STAT0 = 1; + ticker_expired_count_us += ticker_fullcount_us; + } +} |