Skip to content

[LPC1549] Added AnalogOut API and PWM improvement #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ typedef enum {
ADC1_11,
} ADCName;

typedef enum {
DAC0_0 = 0,
} DACName;

#ifdef __cplusplus
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
106 changes: 34 additions & 72 deletions libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/i2c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
if ((sda != P0_23) | (scl != P0_22)) {
error("I2C pin mapping failed");
}

// Enables clock for I2C0
LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<13);
// LPC_SYSCON->PRESETCTRL1 &= ~(0x1<<13);
LPC_SYSCON->PRESETCTRL1 |= (0x1<<13);
LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << 13);
LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 13);

}
LPC_SYSCON->PRESETCTRL1 |= (1 << 13);
LPC_SYSCON->PRESETCTRL1 &= ~(1 << 13);

void i2c_init(i2c_t *obj, PinName sda, PinName scl) {

// �s����`�̊m�F�ǂ����悤�c


// enable power
i2c_power_enable(obj);
// 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);
}
Expand All @@ -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))) {
Expand Down Expand Up @@ -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;
Expand All @@ -123,59 +117,43 @@ 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;
}

// 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);
Expand All @@ -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; i<length; i++) {
//status = i2c_do_write(obj, data[i], 0);
LPC_I2C0->MSTDAT = 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;
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ struct analogin_s {
ADCName adc;
};

struct dac_s {
DACName dac;
};

struct i2c_s {
LPC_I2C0_Type *i2c;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
Loading