summaryrefslogtreecommitdiff
path: root/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX')
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h60
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PinNames.h103
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PortNames.h32
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogin_api.c158
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c71
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/can_api.c437
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h58
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_api.c66
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_irq_api.c139
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/gpio_object.h57
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c217
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h69
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pinmap.c41
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c170
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/rtc_api.c64
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/serial_api.c316
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/spi_api.c276
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c73
18 files changed, 2407 insertions, 0 deletions
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);
+}