diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/ao_hmc5883.c | 139 | ||||
| -rw-r--r-- | src/drivers/ao_hmc5883.h | 41 | ||||
| -rw-r--r-- | src/drivers/ao_mpu6000.c | 97 | ||||
| -rw-r--r-- | src/drivers/ao_mpu6000.h | 30 | 
4 files changed, 307 insertions, 0 deletions
| diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c new file mode 100644 index 00000000..0077daf9 --- /dev/null +++ b/src/drivers/ao_hmc5883.c @@ -0,0 +1,139 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_hmc5883.h> +#include <ao_exti.h> + +static uint8_t	ao_hmc5883_wake; +static uint8_t	ao_hmc5883_configured; + +static void +ao_hmc5883_isr(void) +{ +	ao_exti_disable(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN); +	ao_hmc5883_wake = 1; +	ao_wakeup(&ao_hmc5883_wake); +} + +static uint8_t	ao_hmc5883_addr_reg; + +static void +ao_hmc5883_update_addr (uint8_t len) +{ +	ao_hmc5883_addr_reg += len; +	if (ao_hmc5883_addr_reg == 9) +		ao_hmc5883_addr_reg = 3; +	else if (ao_hmc5883_addr_reg > 12) +		ao_hmc5883_addr_reg = 0; +		     +} + +static void +ao_hmc5883_write(uint8_t addr, uint8_t *data, uint8_t len) +{ +	ao_i2c_get(AO_HMC5883_I2C_INDEX); +	ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_WRITE); +	ao_i2c_send(&addr, 1, AO_HMC5883_I2C_INDEX); +	ao_hmc5883_addr_reg = addr; +	if (len) { +		ao_i2c_send(data, len, AO_HMC5883_I2C_INDEX); +		ao_hmc5883_update_addr(len); +	} +	ao_i2c_stop(AO_HMC5883_I2C_INDEX); +	ao_i2c_put(AO_HMC5883_I2C_INDEX); +} + +static void +ao_hmc5883_read(uint8_t addr, uint8_t *data, uint8_t len) +{ +	ao_i2c_get(AO_HMC5883_I2C_INDEX); +	if (addr != ao_hmc5883_addr_reg) { +		ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_WRITE); +		ao_i2c_send(&addr, 1, AO_HMC5883_I2C_INDEX); +		ao_hmc5883_addr_reg = addr; +	} +	ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_READ); +	if (len) { +		ao_i2c_recv(data, len, AO_HMC5883_I2C_INDEX); +		ao_hmc5883_update_addr(len); +	} +	ao_i2c_stop(AO_HMC5883_I2C_INDEX); +	ao_i2c_put(AO_HMC5883_I2C_INDEX); +} + +static uint8_t +ao_hmc5883_setup(void) +{ +	uint8_t	present; +	if (ao_hmc5883_configured) +		return 1; + +	/* Enable the EXTI interrupt for the appropriate pin */ +	ao_enable_port(AO_HMC5883_INT_PORT); +	ao_exti_setup(&AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN, +		      AO_EXTI_MODE_FALLING, ao_hmc5883_isr); + +	ao_hmc5883_addr_reg = 0xff; + +	ao_i2c_get(AO_HMC5883_I2C_INDEX); +	present = ao_i2c_start(AO_HMC5883_I2C_INDEX, HMC5883_ADDR_READ); +	ao_i2c_stop(AO_HMC5883_I2C_INDEX); +	ao_i2c_put(AO_HMC5883_I2C_INDEX); +	if (!present) +		return 0; +	ao_hmc5883_configured = 1; +	return 1; +} + +static void +ao_hmc5883_show(void) +{ +	uint8_t	addr, data; + +	for (addr = 0x00; addr <= 0x7f; addr++) +	{ +		ao_i2c_get(AO_HMC5883_I2C_INDEX); +		data = ao_i2c_start(AO_HMC5883_I2C_INDEX, addr << 1); +		ao_i2c_stop(AO_HMC5883_I2C_INDEX); +		ao_i2c_put(AO_HMC5883_I2C_INDEX); +		if (data) +			printf("address %02x responds\n", addr << 1); +	} +	if (!ao_hmc5883_setup()) { +		printf("hmc5883 not present\n"); +		return; +	} +	for (addr = 0; addr <= 12; addr++) { +		ao_hmc5883_read(addr, &data, 1); +		printf ("hmc5883 register %2d: %02x\n", +			addr, data); +	} +} + +static const struct ao_cmds ao_hmc5883_cmds[] = { +	{ ao_hmc5883_show,	"M\0Show HMC5883 status" }, +	{ 0, NULL } +}; + +void +ao_hmc5883_init(void) +{ +	ao_hmc5883_configured = 0; + +	ao_cmd_register(&ao_hmc5883_cmds[0]); +} diff --git a/src/drivers/ao_hmc5883.h b/src/drivers/ao_hmc5883.h new file mode 100644 index 00000000..399ddcdd --- /dev/null +++ b/src/drivers/ao_hmc5883.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_HMC5883_H_ +#define _AO_HMC5883_H_ + +#define HMC5883_ADDR_WRITE	0x3c +#define HMC5883_ADDR_READ	0x3d + +#define HMC5883_CONFIG_A	0 +#define HMC5883_CONFIG_B	1 +#define HMC5883_MODE		2 +#define HMC5883_X_MSB		3 +#define HMC5883_X_LSB		4 +#define HMC5883_Y_MSB		5 +#define HMC5883_Y_LSB		6 +#define HMC5883_Z_MSB		7 +#define HMC5883_Z_LSB		8 +#define HMC5883_STATUS		9 +#define HMC5883_ID_A		10 +#define HMC5883_ID_B		11 +#define HMC5883_ID_C		12 + +void +ao_hmc5883_init(void); + +#endif /* _AO_HMC5883_H_ */ diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c new file mode 100644 index 00000000..290f1390 --- /dev/null +++ b/src/drivers/ao_mpu6000.c @@ -0,0 +1,97 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_mpu6000.h> +#include <ao_exti.h> + +static uint8_t	ao_mpu6000_wake; +static uint8_t	ao_mpu6000_configured; + +static void +ao_mpu6000_isr(void) +{ +	ao_exti_disable(&AO_MPU6000_INT_PORT, AO_MPU6000_INT_PIN); +	ao_mpu6000_wake = 1; +	ao_wakeup(&ao_mpu6000_wake); +} + +static void +ao_mpu6000_write(uint8_t addr, uint8_t *data, uint8_t len) +{ +	ao_i2c_get(AO_MPU6000_I2C_INDEX); +	ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_WRITE); +	ao_i2c_send(&addr, 1, AO_MPU6000_I2C_INDEX); +	if (len) +		ao_i2c_send(data, len, AO_MPU6000_I2C_INDEX); +	ao_i2c_stop(AO_MPU6000_I2C_INDEX); +	ao_i2c_put(AO_MPU6000_I2C_INDEX); +} + +static void +ao_mpu6000_read(uint8_t addr, uint8_t *data, uint8_t len) +{ +	ao_i2c_get(AO_MPU6000_I2C_INDEX); +	ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_WRITE); +	ao_i2c_send(&addr, 1, AO_MPU6000_I2C_INDEX); +	ao_i2c_start(AO_MPU6000_I2C_INDEX, MPU6000_ADDR_READ); +	if (len) +		ao_i2c_recv(data, len, AO_MPU6000_I2C_INDEX); +	ao_i2c_stop(AO_MPU6000_I2C_INDEX); +	ao_i2c_put(AO_MPU6000_I2C_INDEX); +} + +static void +ao_mpu6000_setup(void) +{ +	if (ao_mpu6000_configured) +		return; + +	/* Enable the EXTI interrupt for the appropriate pin */ +	ao_enable_port(AO_MPU6000_INT_PORT); +	ao_exti_setup(&AO_MPU6000_INT_PORT, AO_MPU6000_INT_PIN, +		      AO_EXTI_MODE_FALLING, ao_mpu6000_isr); + +	ao_mpu6000_configured = 1; +} + +static void +ao_mpu6000_show(void) +{ +	uint8_t	addr; +	uint8_t	data[14]; +	uint8_t i; + +	ao_mpu6000_read(MPU6000_WHO_AM_I, data, 1); +	printf ("mpu6000 WHO_AM_I: %02x\n", data[0]); +	ao_mpu6000_read(MPU6000_ACCEL_XOUT_H, data, 1); +	for (i = 0; i < 14; i++) +		printf ("reg %02x: %02x\n", i + MPU6000_ACCEL_XOUT_H, data[i]); +} + +static const struct ao_cmds ao_mpu6000_cmds[] = { +	{ ao_mpu6000_show,	"I\0Show MPU6000 status" }, +	{ 0, NULL } +}; + +void +ao_mpu6000_init(void) +{ +	ao_mpu6000_configured = 0; + +	ao_cmd_register(&ao_mpu6000_cmds[0]); +} diff --git a/src/drivers/ao_mpu6000.h b/src/drivers/ao_mpu6000.h new file mode 100644 index 00000000..d436a3e0 --- /dev/null +++ b/src/drivers/ao_mpu6000.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_MPU6000_H_ +#define _AO_MPU6000_H_ + +#define MPU6000_ADDR_WRITE	0xd0 +#define MPU6000_ADDR_READ	0xd1 + +#define MPU6000_ACCEL_XOUT_H	0x3b +#define MPU6000_WHO_AM_I	0x75 + +void +ao_mpu6000_init(void); + +#endif /* _AO_MPU6000_H_ */ | 
