diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h index 9cbce7807a..742d7a7818 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/PeripheralNames.h @@ -49,6 +49,9 @@ typedef enum { ADC1_11, } ADCName; +typedef enum { + DAC0_0 = 0, +} DACName; #ifdef __cplusplus } diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.c new file mode 100644 index 0000000000..e2c6acf9ef --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/analogout_api.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 "analogout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +void analogout_init(dac_t *obj, PinName pin) { + if (pin != P0_12) { + error("DAC pin mapping failed"); + } + + 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/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h index 06135b43f0..b49c645971 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h @@ -23,7 +23,7 @@ #define DEVICE_INTERRUPTIN 1 #define DEVICE_ANALOGIN 1 -#define DEVICE_ANALOGOUT 0 +#define DEVICE_ANALOGOUT 1 #define DEVICE_SERIAL 1 #define DEVICE_SERIAL_FC 1 diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c index 51d5ca6ee3..394b65ae89 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c @@ -29,7 +29,7 @@ static inline int i2c_status(i2c_t *obj) { // Wait until the Serial Interrupt (SI) is set static int i2c_wait_SI(i2c_t *obj) { - int timeout = 0; + volatile int timeout = 0; while (!(LPC_I2C0->STAT & (1 << 0))) { timeout++; if (timeout > 100000) return -1; @@ -41,25 +41,21 @@ static inline void i2c_interface_enable(i2c_t *obj) { LPC_I2C0->CFG |= (1 << 0); } -static inline void i2c_power_enable(i2c_t *obj) { - // Enables clock for I2C0 - LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<13); -// LPC_SYSCON->PRESETCTRL1 &= ~(0x1<<13); - LPC_SYSCON->PRESETCTRL1 |= (0x1<<13); - LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << 13); - -} - void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + if ((sda != P0_23) | (scl != P0_22)) { + error("I2C pin mapping failed"); + } - // ピン定義の確認どうしよう… - - - // enable power - i2c_power_enable(obj); + // 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 100k + + // set default frequency at 100kHz i2c_frequency(obj, 100000); i2c_interface_enable(obj); } @@ -76,7 +72,7 @@ inline int i2c_start(i2c_t *obj) { } inline int i2c_stop(i2c_t *obj) { - int timeout = 0; + volatile int timeout = 0; LPC_I2C0->MSTCTL = (1 << 2) | (1 << 0); while ((LPC_I2C0->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) { @@ -107,14 +103,12 @@ static inline int i2c_do_read(i2c_t *obj, int last) { LPC_I2C0->MSTCTL = (1 << 0); // return the data - //return (I2C_DAT(obj) & 0xFF); 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; @@ -123,19 +117,15 @@ void i2c_frequency(i2c_t *obj, int hz) { int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int count, status; - int timeout = 0; i2c_start(obj); - //status = i2c_do_write(obj, (address | 0x01), 1); LPC_I2C0->MSTDAT = (address | 0x01); LPC_I2C0->MSTCTL |= 0x20; - while (!(LPC_I2C0->STAT & (1 << 0))) { - timeout++; - if (timeout > 100000) return -1; - } + 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; @@ -143,39 +133,27 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { // Read in all except last byte for (count = 0; count < (length - 1); count++) { - //int value = i2c_do_read(obj, 0); - while (!(LPC_I2C0->STAT & (1 << 0))) { - timeout++; - if (timeout > 100000) return -1; - } - if (!0) - LPC_I2C0->MSTCTL = (1 << 0); - data[count] = (LPC_I2C0->MSTDAT & 0xFF); - // - status = ((LPC_I2C0->STAT >> 1) & (0x07)); + 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 != 0x00) { i2c_stop(obj); return count; } - //data[count] = (char) value; } // read in last byte - //int value = i2c_do_read(obj, 1); - while (!(LPC_I2C0->STAT & (1 << 0))) { - timeout++; - if (timeout > 100000) return -1; - } + 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; } - - //data[count] = (char) value; - // If not repeated start, send stop. if (stop) { i2c_stop(obj); @@ -188,35 +166,27 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int i, status; - int timeout = 0; i2c_start(obj); - //status = i2c_do_write(obj, (address & 0xFE), 1); LPC_I2C0->MSTDAT = (address & 0xFE); LPC_I2C0->MSTCTL |= 0x20; - // wait and return status - while (!(LPC_I2C0->STAT & (1 << 0))) { - timeout++; - if (timeout > 100000) return -1; - } + 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; iMSTDAT = data[i]; LPC_I2C0->MSTCTL = (1 << 0); - // wait and return status - while (!(LPC_I2C0->STAT & (1 << 0))) { - timeout++; - if (timeout > 100000) return -1; - } - status = ((LPC_I2C0->STAT >> 1) & (0x07)); + if (i2c_wait_SI(obj) == -1) + return -1; + + status = ((LPC_I2C0->STAT >> 1) & (0x07)); if (status != 0x02) { i2c_stop(obj); return i; @@ -242,17 +212,9 @@ int i2c_byte_read(i2c_t *obj, int last) { } 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; + if (i2c_do_write(obj, (data & 0xFF), 0) == 2) { + return 1; + } else { + return 0; } - - return ack; } diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h index d69a8e5fea..edbb15105b 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/objects.h @@ -43,6 +43,10 @@ struct analogin_s { ADCName adc; }; +struct dac_s { + DACName dac; +}; + struct i2c_s { LPC_I2C0_Type *i2c; }; diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c index 394408d20f..2ebcf155ba 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/pwmout_api.c @@ -30,8 +30,7 @@ static LPC_SCT0_Type *SCTs[4] = { static unsigned char sct_used = 0; static int get_available_sct(void) { int i; - // start from 1, since 0 is used by ticker at the moment - for (i=1; i<4; i++) { + for (i=0; i<4; i++) { if ((sct_used & (1 << i)) == 0) return i; } @@ -61,6 +60,11 @@ void pwmout_init(pwmout_t* obj, PinName pin) { 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; diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c index 1954a7d612..005188578b 100644 --- a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/us_ticker.c @@ -17,7 +17,7 @@ #include "us_ticker_api.h" #include "PeripheralNames.h" -#define US_TICKER_TIMER_IRQn SCT0_IRQn +#define US_TICKER_TIMER_IRQn RIT_IRQn int us_ticker_inited = 0; @@ -25,25 +25,24 @@ void us_ticker_init(void) { if (us_ticker_inited) return; us_ticker_inited = 1; - // Enable the SCT0 clock - LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 2); + // Enable the RIT clock + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 1); - // Clear peripheral reset the SCT0: - LPC_SYSCON->PRESETCTRL1 |= (1 << 2); - LPC_SYSCON->PRESETCTRL1 &= ~(1 << 2); + // Clear peripheral reset the RIT + LPC_SYSCON->PRESETCTRL1 |= (1 << 1); + LPC_SYSCON->PRESETCTRL1 &= ~(1 << 1); - // Unified counter (32 bits) - LPC_SCT0->CONFIG |= 1; + LPC_RIT->MASK = 0; + LPC_RIT->MASK_H = 0; - // halt and clear the counter - LPC_SCT0->CTRL |= (1 << 2) | (1 << 3); - - // System Clock (12)MHz -> us_ticker (1)MHz - LPC_SCT0->CTRL |= ((SystemCoreClock/1000000 - 1) << 5); - - // unhalt the counter: - // - clearing bit 2 of the CTRL register - LPC_SCT0->CTRL &= ~(1 << 2); + 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); @@ -53,42 +52,22 @@ uint32_t us_ticker_read() { if (!us_ticker_inited) us_ticker_init(); - return LPC_SCT0->COUNT; + 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(unsigned int timestamp) { - // halt the counter: - // - setting bit 2 of the CTRL register - LPC_SCT0->CTRL |= (1 << 2); - - // set timestamp in compare register - LPC_SCT0->MATCH0 = timestamp; - - // unhalt the counter: - // - clearing bit 2 of the CTRL register - LPC_SCT0->CTRL &= ~(1 << 2); - - // if events are not enabled, enable them - if (!(LPC_SCT0->EVEN & 0x01)) { - - // comb mode = match only - LPC_SCT0->EV0_CTRL = (1 << 12); - - // ref manual: - // In simple applications that do not - // use states, write 0x01 to this - // register to enable an event - LPC_SCT0->EV0_STATE |= 0x1; - - // enable events - LPC_SCT0->EVEN |= 0x1; - } + 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_SCT0->EVEN &= ~1; + LPC_RIT->CTRL |= (1 << 3); } void us_ticker_clear_interrupt(void) { - LPC_SCT0->EVFLAG = 1; + LPC_RIT->CTRL |= (1 << 0); }