diff options
| author | Keith Packard <keithp@keithp.com> | 2012-08-18 21:26:34 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-08-18 21:26:34 -0700 | 
| commit | 93db8febda03d9a02c5c1ccdc6ad44eaf00a433b (patch) | |
| tree | 51f8f0991ef9cb5b19921520a589ebc620ec9013 | |
| parent | 8457ca81adc9d62a7ffe56a7c0c36f2fcadaa682 (diff) | |
altos: Add MMA655X driver
Just debug code at this point, will complete on real hardware
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | src/drivers/ao_mma655x.c | 210 | ||||
| -rw-r--r-- | src/drivers/ao_mma655x.h | 85 | ||||
| -rw-r--r-- | src/megametrum-v0.1/Makefile | 2 | ||||
| -rw-r--r-- | src/megametrum-v0.1/ao_megametrum.c | 4 | ||||
| -rw-r--r-- | src/megametrum-v0.1/ao_pins.h | 9 | 
5 files changed, 310 insertions, 0 deletions
| diff --git a/src/drivers/ao_mma655x.c b/src/drivers/ao_mma655x.c new file mode 100644 index 00000000..e4e41627 --- /dev/null +++ b/src/drivers/ao_mma655x.c @@ -0,0 +1,210 @@ +/* + * 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_mma655x.h> + +static uint8_t	mma655x_configured; +uint8_t		ao_mma655x_valid; + +static void +ao_mma655x_start(void) { +	ao_spi_get_bit(AO_MMA655X_CS_GPIO, +		       AO_MMA655X_CS, +		       AO_MMA655X_CS_PIN, +		       AO_MMA655X_SPI_INDEX, +		       AO_SPI_SPEED_FAST); +} + +static void +ao_mma655x_stop(void) { +	ao_spi_put_bit(AO_MMA655X_CS_GPIO, +		       AO_MMA655X_CS, +		       AO_MMA655X_CS_PIN, +		       AO_MMA655X_SPI_INDEX); +} + +static uint8_t +ao_parity(uint8_t v) +{ +	/* down to four bits */ +	v = (v ^ (v >> 4)) & 0xf; + +	/* Cute lookup hack -- 0x6996 encodes the sixteen +	 * even parity values in order. +	 */ +	return (~0x6996 >> v) & 1; +} + +static void +ao_mma655x_cmd(uint8_t d[2]) +{ +	ao_mma655x_start(); +	ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX); +	ao_spi_recv(d, 2, AO_MMA655X_SPI_INDEX); +	ao_mma655x_stop(); +} + +static uint8_t +ao_mma655x_reg_write(uint8_t addr, uint8_t value) +{ +	uint8_t	d[2]; + +	addr |= (1 << 6);	/* write mode */ +	d[0] = addr | (ao_parity(addr^value) << 7); +	d[1] = value; +	ao_mma655x_cmd(d); +	return d[1]; +} + +static uint8_t +ao_mma655x_reg_read(uint8_t addr) +{ +	uint8_t	d[2]; + +	d[0] = addr | (ao_parity(addr) << 7); +	d[1] = 0; +	ao_mma655x_cmd(d); +	return d[1]; +} + +static uint16_t +ao_mma655x_value(void) +{ +	uint8_t		d[2]; +	uint16_t	v; + +	d[0] = ((0 << 7) |	/* Axis selection (X) */ +		(1 << 6) |	/* Acceleration operation */ +		(1 << 5));	/* Raw data */ +	d[1] = ((1 << 3) |	/* must be one */ +		(1 << 2) |	/* Unsigned data */ +		(0 << 1) |	/* Arm disabled */ +		(1 << 0));	/* Odd parity */ +	ao_mma655x_cmd(d); +	v = (uint16_t) d[1] << 2; +	v |= d[0] >> 6; +	v |= (uint16_t) (d[0] & 3) << 10; +	return v; +} + +static void +ao_mma655x_reset(void) { +	ao_mma655x_reg_write(AO_MMA655X_DEVCTL, +			     (0 << AO_MMA655X_DEVCTL_RES_1) | +			     (0 << AO_MMA655X_DEVCTL_RES_1)); +	ao_mma655x_reg_write(AO_MMA655X_DEVCTL, +			     (1 << AO_MMA655X_DEVCTL_RES_1) | +			     (1 << AO_MMA655X_DEVCTL_RES_1)); +	ao_mma655x_reg_write(AO_MMA655X_DEVCTL, +			     (0 << AO_MMA655X_DEVCTL_RES_1) | +			     (1 << AO_MMA655X_DEVCTL_RES_1)); +} + +#define DEVCFG_VALUE	(\ +	(1 << AO_MMA655X_DEVCFG_OC) |		/* Disable offset cancelation */ \ +	(1 << AO_MMA655X_DEVCFG_SD) |		/* Receive unsigned data */ \ +	(0 << AO_MMA655X_DEVCFG_OFMON) |	/* Disable offset monitor */ \ +	(AO_MMA655X_DEVCFG_A_CFG_DISABLE << AO_MMA655X_DEVCFG_A_CFG)) + +#define AXISCFG_VALUE	(\ +		(0 << AO_MMA655X_AXISCFG_LPF))	/* 100Hz 4-pole filter */ + + +static void +ao_mma655x_setup(void) +{ +	uint8_t		v; +	uint16_t	a, a_st; +	uint8_t		stdefl; + +	if (mma655x_configured) +		return; +	mma655x_configured = 1; +	ao_delay(AO_MS_TO_TICKS(10));	/* Top */ +	ao_mma655x_reset(); +	ao_delay(AO_MS_TO_TICKS(10));	/* Top */ +	(void) ao_mma655x_reg_read(AO_MMA655X_DEVSTAT); +	v = ao_mma655x_reg_read(AO_MMA655X_DEVSTAT); + +	/* Configure R/W register values. +	 * Most of them relate to the arming feature, which +	 * we don't use, so the only registers we need to +	 * write are DEVCFG and AXISCFG +	 */ + +	ao_mma655x_reg_write(AO_MMA655X_DEVCFG, +			     DEVCFG_VALUE | (0 << AO_MMA655X_DEVCFG_ENDINIT)); + +	/* Test X axis +	 */ +	 +	ao_mma655x_reg_write(AO_MMA655X_AXISCFG, +			     AXISCFG_VALUE | +			     (1 << AO_MMA655X_AXISCFG_ST)); +	a_st = ao_mma655x_value(); + +	stdefl = ao_mma655x_reg_read(AO_MMA655X_STDEFL); + +	ao_mma655x_reg_write(AO_MMA655X_AXISCFG, +			     AXISCFG_VALUE | +			     (0 << AO_MMA655X_AXISCFG_ST)); +	a = ao_mma655x_value(); +	printf ("normal: %u self_test: %u stdefl: %u\n", +		a, a_st, stdefl); + +	ao_mma655x_reg_write(AO_MMA655X_DEVCFG, +			     DEVCFG_VALUE | (1 << AO_MMA655X_DEVCFG_ENDINIT)); +} + +static void +ao_mma655x_dump(void) +{ +	uint8_t	s0, s1, s2, s3; +	uint32_t	lot; +	uint16_t	serial; + +	ao_mma655x_setup(); + +	s0 = ao_mma655x_reg_read(AO_MMA655X_SN0); +	s1 = ao_mma655x_reg_read(AO_MMA655X_SN1); +	s2 = ao_mma655x_reg_read(AO_MMA655X_SN2); +	s3 = ao_mma655x_reg_read(AO_MMA655X_SN3); +	lot = ((uint32_t) s3 << 24) | ((uint32_t) s2 << 16) | +		((uint32_t) s1 << 8) | ((uint32_t) s0); +	serial = lot & 0x1fff; +	lot >>= 12; +	printf ("MMA655X lot %d serial %d\n", lot, serial); +	mma655x_configured = 0; +} + +__code struct ao_cmds ao_mma655x_cmds[] = { +	{ ao_mma655x_dump,	"A\0Display MMA655X data" }, +	{ 0, NULL }, +}; + +void +ao_mma655x_init(void) +{ +	mma655x_configured = 0; +	ao_mma655x_valid = 0; + +	ao_cmd_register(&ao_mma655x_cmds[0]); +	ao_spi_init_cs(AO_MMA655X_CS_GPIO, (1 << AO_MMA655X_CS)); + +//	ao_add_task(&ao_mma655x_task, ao_mma655x, "mma655x"); +} diff --git a/src/drivers/ao_mma655x.h b/src/drivers/ao_mma655x.h new file mode 100644 index 00000000..9c0c59dc --- /dev/null +++ b/src/drivers/ao_mma655x.h @@ -0,0 +1,85 @@ +/* + * 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_MMA655X_H_ +#define _AO_MMA655X_H_ + + +#define AO_MMA655X_SN0		0x00 +#define AO_MMA655X_SN1		0x01 +#define AO_MMA655X_SN2		0x02 +#define AO_MMA655X_SN3		0x03 +#define AO_MMA655X_SN3		0x03 +#define AO_MMA655X_STDEFL	0x04 +#define AO_MMA655X_FCTCFG	0x06 +# define AO_MMA655X_FCTCFG_STMAG	7 + +#define AO_MMA655X_PN		0x08 +#define AO_MMA655X_DEVCTL	0x0a +#define AO_MMA655X_DEVCTL_RES_1		7 +#define AO_MMA655X_DEVCTL_RES_0		6 +#define AO_MMA655X_DEVCTL_OCPHASE	4 +#define AO_MMA655X_DEVCTL_OCPHASE_MASK	3 +#define AO_MMA655X_DEVCTL_OFFCFG_EN	3 + +#define AO_MMA655X_DEVCFG	0x0b +#define AO_MMA655X_DEVCFG_OC		7 +#define AO_MMA655X_DEVCFG_ENDINIT	5 +#define AO_MMA655X_DEVCFG_SD		4 +#define AO_MMA655X_DEVCFG_OFMON		3 +#define AO_MMA655X_DEVCFG_A_CFG		0 +#define AO_MMA655X_DEVCFG_A_CFG_DISABLE		0 +#define AO_MMA655X_DEVCFG_A_CFG_PCM		1 +#define AO_MMA655X_DEVCFG_A_CFG_MOVING_AVG_HIGH	2 +#define AO_MMA655X_DEVCFG_A_CFG_MOVING_AVG_LOW	3 +#define AO_MMA655X_DEVCFG_A_CFG_COUNT_HIGH	4 +#define AO_MMA655X_DEVCFG_A_CFG_COUNT_LOW	5 +#define AO_MMA655X_DEVCFG_A_CFG_UNFILTERED_HIGH	6 +#define AO_MMA655X_DEVCFG_A_CFG_UNFILTERED_LOW	7 +#define AO_MMA655X_DEVCFG_A_CFG_MASK		7 + +#define AO_MMA655X_AXISCFG	0x0c +#define AO_MMA655X_AXISCFG_ST		7 +#define AO_MMA655X_AXISCFG_LPF		0 +#define AO_MMA655X_AXISCFG_LPF_MASK	0xf + +#define AO_MMA655X_ARMCFG	0x0e +#define AO_MMA655X_ARMCFG_APS		4 +#define AO_MMA655X_ARMCFG_APS_MASK	3 +#define AO_MMA655X_ARMCFG_AWS_N		2 +#define AO_MMA655X_ARMCFG_AWS_N_MASK	3 +#define AO_MMA655X_ARMCFG_AWS_P		0 +#define AO_MMA655X_ARMCFG_AWS_P_MASK	3 + +#define AO_MMA655X_ARMT_P	0x10 +#define AO_MMA655X_ARMT_N	0x12 + +#define AO_MMA655X_DEVSTAT	0x14 +#define AO_MMA655X_DEVSTAT_IDE		6 +#define AO_MMA655X_DEVSTAT_DEVINIT	4 +#define AO_MMA655X_DEVSTAT_MISOERR	3 +#define AO_MMA655X_DEVSTAT_OFFSET	1 +#define AO_MMA655X_DEVSTAT_DEVRES	0 + +#define AO_MMA655X_COUNT	0x15 +#define AO_MMA655X_OFFCORR	0x16 + + +void +ao_mma655x_init(void); + +#endif /* _AO_MMA655X_H_ */ diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile index 4a4c983a..1dfebca0 100644 --- a/src/megametrum-v0.1/Makefile +++ b/src/megametrum-v0.1/Makefile @@ -19,6 +19,7 @@ INC = \  	ao_ms5607.h \  	ao_hmc5883.h \  	ao_mpu6000.h \ +	ao_mma655x.h \  	ao_cc1120_CC1120.h \  	ao_profile.h \  	ao_whiten.h \ @@ -56,6 +57,7 @@ ALTOS_SRC = \  	ao_fec_tx.c \  	ao_fec_rx.c \  	ao_ms5607.c \ +	ao_mma655x.c \  	ao_adc_stm.c \  	ao_beep_stm.c \  	ao_storage.c \ diff --git a/src/megametrum-v0.1/ao_megametrum.c b/src/megametrum-v0.1/ao_megametrum.c index 55324514..d3ae4690 100644 --- a/src/megametrum-v0.1/ao_megametrum.c +++ b/src/megametrum-v0.1/ao_megametrum.c @@ -18,6 +18,7 @@  #include <ao.h>  #include <ao_hmc5883.h>  #include <ao_mpu6000.h> +#include <ao_mma655x.h>  #include <ao_log.h>  #include <ao_exti.h>  #include <ao_packet.h> @@ -53,6 +54,9 @@ main(void)  #if HAS_MPU6000  	ao_mpu6000_init();  #endif +#if HAS_MMA655X +	ao_mma655x_init(); +#endif  	ao_storage_init(); diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 42715968..6256d2f6 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -305,6 +305,15 @@ struct ao_adc {  #define HAS_HIGHG_ACCEL		0 +/* + * mma655x + */ + +#define HAS_MMA655X		1 +#define AO_MMA655X_SPI_INDEX	AO_SPI_1_PA5_PA6_PA7 +#define AO_MMA655X_CS_GPIO	(&stm_gpiod) +#define AO_MMA655X_CS		4 +  #define NUM_CMDS		16  /* | 
