Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Original commit of example sketch.

  • Loading branch information...
commit 0c07b213811d891851c75e0382e928f15c9b8d77 0 parents
Nathan Seidle nseidle authored
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
163 .gitignore
@@ -0,0 +1,163 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+*.dotCover
+
+## TODO: If you have NuGet Package Restore enabled, uncomment this
+#packages/
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+*.Cache
+ClientBin
+stylecop.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
+
+
+############
+## Windows
+############
+
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist
+build
+eggs
+parts
+bin
+var
+sdist
+develop-eggs
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
+
+# Mac crap
+.DS_Store
372 MMA8452Q_Example/MMA8452Q_Example.ino
@@ -0,0 +1,372 @@
+/* MMA8452Q Example Code
+ by: Jim Lindblom
+ SparkFun Electronics
+ date: November 17, 2011
+ license: Beerware - Use this code however you'd like. If you
+ find it useful you can buy me a beer some time.
+
+ This code should provide example usage for most features of
+ the MMA8452Q 3-axis, I2C accelerometer. In the loop function
+ the accelerometer interrupt outputs will be polled, and either
+ the x/y/z accel data will be output, or single/double-taps,
+ portrait/landscape changes will be announced to the serial port.
+ Feel free to comment/uncomment out some of the Serial.print
+ lines so you can see the information you're most intereseted in.
+
+ The skeleton is here, feel free to cut/paste what code you need.
+ Play around with the settings in initMMA8452Q. Try running the
+ code without printing the accel values, to really appreciate
+ the single/double-tap and portrait landscape functions. The
+ P/L stuff is really neat, something not many accelerometers have.
+
+ Hardware setup:
+ MMA8452 Breakout ------------ Arduino
+ 3.3V --------------------- 3.3V
+ SDA ----------------------- A4
+ SCL ----------------------- A5
+ INT2 ---------------------- D3
+ INT1 ---------------------- D2
+ GND ---------------------- GND
+
+ SDA and SCL should have external pull-up resistors (to 3.3V).
+ 10k resistors worked for me. They should be on the breakout
+ board.
+
+ Note: The MMA8452 is an I2C sensor, however this code does
+ not make use of the Arduino Wire library. Because the sensor
+ is not 5V tolerant, we can't use the internal pull-ups used
+ by the Wire library. Instead use the included i2c.h, defs.h and types.h files.
+ */
+#include "i2c.h" // not the wire library, can't use pull-ups
+
+// the SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
+#define SA0 1
+#if SA0
+#define MMA8452_ADDRESS 0x1D // SA0 is high, 0x1C if low
+#else
+#define MMA8452_ADDRESS 0x1C
+#endif
+
+/* Set the scale below either 2, 4 or 8*/
+const byte SCALE = 2; // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
+/* Set the output data rate below. Value should be between 0 and 7*/
+const byte dataRate = 0; // 0=800Hz, 1=400, 2=200, 3=100, 4=50, 5=12.5, 6=6.25, 7=1.56
+
+/* Pin definitions */
+int int1Pin = 2; // These can be changed, 2 and 3 are the Arduinos ext int pins
+int int2Pin = 3;
+
+int accelCount[3]; // Stores the 12-bit signed value
+float accelG[3]; // Stores the real accel value in g's
+
+void setup()
+{
+ byte c;
+
+ Serial.begin(115200);
+
+ /* Set up the interrupt pins, they're set as active high, push-pull */
+ pinMode(int1Pin, INPUT);
+ digitalWrite(int1Pin, LOW);
+ pinMode(int2Pin, INPUT);
+ digitalWrite(int2Pin, LOW);
+
+ /* Read the WHO_AM_I register, this is a good test of communication */
+ c = readRegister(0x0D); // Read WHO_AM_I register
+ if (c == 0x2A) // WHO_AM_I should always be 0x2A
+ {
+ initMMA8452(SCALE, dataRate); // init the accelerometer if communication is OK
+ Serial.println("MMA8452Q is online...");
+ }
+ else
+ {
+ Serial.print("Could not connect to MMA8452Q: 0x");
+ Serial.println(c, HEX);
+ while(1) ; // Loop forever if communication doesn't happen
+ }
+}
+
+void loop()
+{
+ static byte source;
+
+ /* If int1 goes high, all data registers have new data */
+ if (digitalRead(int1Pin)==1) // Interrupt pin, should probably attach to interrupt function
+ {
+ readAccelData(accelCount); // Read the x/y/z adc values
+
+ /* Below we'll print out the ADC values for acceleration
+ for (int i=0; i<3; i++)
+ {
+ Serial.print(accelCount[i]);
+ Serial.print("\t\t");
+ }
+ Serial.println();*/
+
+ /* Now we'll calculate the accleration value into actual g's */
+ for (int i=0; i<3; i++)
+ accelG[i] = (float) accelCount[i]/((1<<12)/(2*SCALE)); // get actual g value, this depends on scale being set
+ /* print out values */
+ for (int i=0; i<3; i++)
+ {
+ Serial.print(accelG[i], 4); // Print g values
+ Serial.print("\t\t"); // tabs in between axes
+ }
+ Serial.println();
+ }
+
+ /* If int2 goes high, either p/l has changed or there's been a single/double tap */
+ if (digitalRead(int2Pin)==1)
+ {
+ source = readRegister(0x0C); // Read the interrupt source reg.
+ if ((source & 0x10)==0x10) // If the p/l bit is set, go check those registers
+ portraitLandscapeHandler();
+ else if ((source & 0x08)==0x08) // Otherwise, if tap register is set go check that
+ tapHandler();
+ }
+ delay(100); // Delay here for visibility
+}
+
+void readAccelData(int * destination)
+{
+ byte rawData[6]; // x/y/z accel register data stored here
+
+ readRegisters(0x01, 6, &rawData[0]); // Read the six raw data registers into data array
+
+ /* loop to calculate 12-bit ADC and g value for each axis */
+ for (int i=0; i<6; i+=2)
+ {
+ destination[i/2] = ((rawData[i] << 8) | rawData[i+1]) >> 4; // Turn the MSB and LSB into a 12-bit value
+ if (rawData[i] > 0x7F)
+ { // If the number is negative, we have to make it so manually (no 12-bit data type)
+ destination[i/2] = ~destination[i/2] + 1;
+ destination[i/2] *= -1; // Transform into negative 2's complement #
+ }
+ }
+}
+
+/* This function will read the status of the tap source register.
+ And print if there's been a single or double tap, and on what
+ axis. */
+void tapHandler()
+{
+ byte source = readRegister(0x22); // Reads the PULSE_SRC register
+
+ if ((source & 0x10)==0x10) // If AxX bit is set
+ {
+ if ((source & 0x08)==0x08) // If DPE (double puls) bit is set
+ Serial.print(" Double Tap (2) on X"); // tabbing here for visibility
+ else
+ Serial.print("Single (1) tap on X");
+
+ if ((source & 0x01)==0x01) // If PoIX is set
+ Serial.println(" +");
+ else
+ Serial.println(" -");
+ }
+ if ((source & 0x20)==0x20) // If AxY bit is set
+ {
+ if ((source & 0x08)==0x08) // If DPE (double puls) bit is set
+ Serial.print(" Double Tap (2) on Y");
+ else
+ Serial.print("Single (1) tap on Y");
+
+ if ((source & 0x02)==0x02) // If PoIY is set
+ Serial.println(" +");
+ else
+ Serial.println(" -");
+ }
+ if ((source & 0x40)==0x40) // If AxZ bit is set
+ {
+ if ((source & 0x08)==0x08) // If DPE (double puls) bit is set
+ Serial.print(" Double Tap (2) on Z");
+ else
+ Serial.print("Single (1) tap on Z");
+ if ((source & 0x04)==0x04) // If PoIZ is set
+ Serial.println(" +");
+ else
+ Serial.println(" -");
+ }
+}
+
+/* This function will read the p/l source register and
+ print what direction the sensor is now facing */
+void portraitLandscapeHandler()
+{
+ byte pl = readRegister(0x10); // Reads the PL_STATUS register
+ switch((pl&0x06)>>1) // Check on the LAPO[1:0] bits
+ {
+ case 0:
+ Serial.print("Portrait up, ");
+ break;
+ case 1:
+ Serial.print("Portrait Down, ");
+ break;
+ case 2:
+ Serial.print("Landscape Right, ");
+ break;
+ case 3:
+ Serial.print("Landscape Left, ");
+ break;
+ }
+ if (pl&0x01) // Check the BAFRO bit
+ Serial.print("Back");
+ else
+ Serial.print("Front");
+ if (pl&0x40) // Check the LO bit
+ Serial.print(", Z-tilt!");
+ Serial.println();
+}
+
+/* Initialize the MMA8452 registers
+ See the many application notes for more info on setting
+ all of these registers:
+ http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q
+
+ Feel free to modify any values, these are settings that work well for me.
+ */
+void initMMA8452(byte fsr, byte dataRate)
+{
+ MMA8452Standby(); // Must be in standby to change registers
+
+ /* Set up the full scale range to 2, 4, or 8g. */
+ if ((fsr==2)||(fsr==4)||(fsr==8))
+ writeRegister(0x0E, fsr >> 2);
+ else
+ writeRegister(0x0E, 0);
+
+ /* Setup the 3 data rate bits, from 0 to 7 */
+ writeRegister(0x2A, readRegister(0x2A) & ~(0x38));
+ if (dataRate <= 7)
+ writeRegister(0x2A, readRegister(0x2A) | (dataRate << 3));
+
+ /* Set up portrait/landscap registers - 4 steps:
+ 1. Enable P/L
+ 2. Set the back/front angle trigger points (z-lock)
+ 3. Set the threshold/hysteresis angle
+ 4. Set the debouce rate
+ // For more info check out this app note: http://cache.freescale.com/files/sensors/doc/app_note/AN4068.pdf */
+ writeRegister(0x11, 0x40); // 1. Enable P/L
+ writeRegister(0x13, 0x44); // 2. 29deg z-lock (don't think this register is actually writable)
+ writeRegister(0x14, 0x84); // 3. 45deg thresh, 14deg hyst (don't think this register is writable either)
+ writeRegister(0x12, 0x50); // 4. debounce counter at 100ms (at 800 hz)
+
+ /* Set up single and double tap - 5 steps:
+ 1. Set up single and/or double tap detection on each axis individually.
+ 2. Set the threshold - minimum required acceleration to cause a tap.
+ 3. Set the time limit - the maximum time that a tap can be above the threshold
+ 4. Set the pulse latency - the minimum required time between one pulse and the next
+ 5. Set the second pulse window - maximum allowed time between end of latency and start of second pulse
+ for more info check out this app note: http://cache.freescale.com/files/sensors/doc/app_note/AN4072.pdf */
+ writeRegister(0x21, 0x7F); // 1. enable single/double taps on all axes
+ // writeRegister(0x21, 0x55); // 1. single taps only on all axes
+ // writeRegister(0x21, 0x6A); // 1. double taps only on all axes
+ writeRegister(0x23, 0x20); // 2. x thresh at 2g, multiply the value by 0.0625g/LSB to get the threshold
+ writeRegister(0x24, 0x20); // 2. y thresh at 2g, multiply the value by 0.0625g/LSB to get the threshold
+ writeRegister(0x25, 0x08); // 2. z thresh at .5g, multiply the value by 0.0625g/LSB to get the threshold
+ writeRegister(0x26, 0x30); // 3. 30ms time limit at 800Hz odr, this is very dependent on data rate, see the app note
+ writeRegister(0x27, 0xA0); // 4. 200ms (at 800Hz odr) between taps min, this also depends on the data rate
+ writeRegister(0x28, 0xFF); // 5. 318ms (max value) between taps max
+
+ /* Set up interrupt 1 and 2 */
+ writeRegister(0x2C, 0x02); // Active high, push-pull interrupts
+ writeRegister(0x2D, 0x19); // DRDY, P/L and tap ints enabled
+ writeRegister(0x2E, 0x01); // DRDY on INT1, P/L and taps on INT2
+
+ MMA8452Active(); // Set to active to start reading
+}
+
+/* Sets the MMA8452 to standby mode.
+ It must be in standby to change most register settings */
+void MMA8452Standby()
+{
+ byte c = readRegister(0x2A);
+ writeRegister(0x2A, c & ~(0x01));
+}
+
+/* Sets the MMA8452 to active mode.
+ Needs to be in this mode to output data */
+void MMA8452Active()
+{
+ byte c = readRegister(0x2A);
+ writeRegister(0x2A, c | 0x01);
+}
+
+/* Read i registers sequentially, starting at address
+ into the dest byte arra */
+void readRegisters(byte address, int i, byte * dest)
+{
+ i2cSendStart();
+ i2cWaitForComplete();
+
+ i2cSendByte((MMA8452_ADDRESS<<1)); // write 0xB4
+ i2cWaitForComplete();
+
+ i2cSendByte(address); // write register address
+ i2cWaitForComplete();
+
+ i2cSendStart();
+ i2cSendByte((MMA8452_ADDRESS<<1)|0x01); // write 0xB5
+ i2cWaitForComplete();
+ for (int j=0; j<i; j++)
+ {
+ i2cReceiveByte(TRUE);
+ i2cWaitForComplete();
+ dest[j] = i2cGetReceivedByte(); // Get MSB result
+ }
+ i2cWaitForComplete();
+ i2cSendStop();
+
+ cbi(TWCR, TWEN); // Disable TWI
+ sbi(TWCR, TWEN); // Enable TWI
+}
+
+/* read a single byte from address and return it as a byte */
+byte readRegister(uint8_t address)
+{
+ byte data;
+
+ i2cSendStart();
+ i2cWaitForComplete();
+
+ i2cSendByte((MMA8452_ADDRESS<<1)); // write 0xB4
+ i2cWaitForComplete();
+
+ i2cSendByte(address); // write register address
+ i2cWaitForComplete();
+
+ i2cSendStart();
+
+ i2cSendByte((MMA8452_ADDRESS<<1)|0x01); // write 0xB5
+ i2cWaitForComplete();
+ i2cReceiveByte(TRUE);
+ i2cWaitForComplete();
+
+ data = i2cGetReceivedByte(); // Get MSB result
+ i2cWaitForComplete();
+ i2cSendStop();
+
+ cbi(TWCR, TWEN); // Disable TWI
+ sbi(TWCR, TWEN); // Enable TWI
+
+ return data;
+}
+
+/* Writes a single byte (data) into address */
+void writeRegister(unsigned char address, unsigned char data)
+{
+ i2cSendStart();
+ i2cWaitForComplete();
+
+ i2cSendByte((MMA8452_ADDRESS<<1));// write 0xB4
+ i2cWaitForComplete();
+
+ i2cSendByte(address); // write register address
+ i2cWaitForComplete();
+
+ i2cSendByte(data);
+ i2cWaitForComplete();
+
+ i2cSendStop();
+}
+
86 MMA8452Q_Example/defs.h
@@ -0,0 +1,86 @@
+/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */
+//*****************************************************************************
+//
+// File Name : 'avrlibdefs.h'
+// Title : AVRlib global defines and macros include file
+// Author : Pascal Stang
+// Created : 7/12/2001
+// Revised : 9/30/2002
+// Version : 1.1
+// Target MCU : Atmel AVR series
+// Editor Tabs : 4
+//
+// Description : This include file is designed to contain items useful to all
+// code files and projects, regardless of specific implementation.
+//
+// This code is distributed under the GNU Public License
+// which can be found at http://www.gnu.org/licenses/gpl.txt
+//
+//*****************************************************************************
+
+
+#ifndef AVRLIBDEFS_H
+#define AVRLIBDEFS_H
+
+//#define F_CPU 4000000
+#define MEM_TYPE 1
+
+// Code compatibility to new AVR-libc
+// outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli()
+#ifndef outb
+ #define outb(addr, data) addr = (data)
+#endif
+#ifndef inb
+ #define inb(addr) (addr)
+#endif
+#ifndef outw
+ #define outw(addr, data) addr = (data)
+#endif
+#ifndef inw
+ #define inw(addr) (addr)
+#endif
+#ifndef BV
+ #define BV(bit) (1<<(bit))
+#endif
+//#ifndef cbi
+// #define cbi(reg,bit) reg &= ~(BV(bit))
+//#endif
+//#ifndef sbi
+// #define sbi(reg,bit) reg |= (BV(bit))
+//#endif
+#ifndef cli
+ #define cli() __asm__ __volatile__ ("cli" ::)
+#endif
+#ifndef sei
+ #define sei() __asm__ __volatile__ ("sei" ::)
+#endif
+
+// support for individual port pin naming in the mega128
+// see port128.h for details
+#ifdef __AVR_ATmega128__
+// not currently necessary due to inclusion
+// of these defines in newest AVR-GCC
+// do a quick test to see if include is needed
+#ifndef PD0
+ //#include "port128.h"
+#endif
+#endif
+
+// use this for packed structures
+// (this is seldom necessary on an 8-bit architecture like AVR,
+// but can assist in code portability to AVR)
+#define GNUC_PACKED __attribute__((packed))
+
+// port address helpers
+#define DDR(x) ((x)-1) // address of data direction register of port x
+#define PIN(x) ((x)-2) // address of input register of port x
+
+// MIN/MAX/ABS macros
+#define MIN(a,b) ((a<b)?(a):(b))
+#define MAX(a,b) ((a>b)?(a):(b))
+#define ABS(x) ((x>0)?(x):(-x))
+
+// constants
+#define PI 3.14159265359
+
+#endif
190 MMA8452Q_Example/i2c.h
@@ -0,0 +1,190 @@
+// This library provides the high-level functions needed to use the I2C
+// serial interface supported by the hardware of several AVR processors.
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "types.h"
+#include "defs.h"
+
+// TWSR values (not bits)
+// (taken from avr-libc twi.h - thank you Marek Michalkiewicz)
+// Master
+#define TW_START 0x08
+#define TW_REP_START 0x10
+// Master Transmitter
+#define TW_MT_SLA_ACK 0x18
+#define TW_MT_SLA_NACK 0x20
+#define TW_MT_DATA_ACK 0x28
+#define TW_MT_DATA_NACK 0x30
+#define TW_MT_ARB_LOST 0x38
+// Master Receiver
+#define TW_MR_ARB_LOST 0x38
+#define TW_MR_SLA_ACK 0x40
+#define TW_MR_SLA_NACK 0x48
+#define TW_MR_DATA_ACK 0x50
+#define TW_MR_DATA_NACK 0x58
+// Slave Transmitter
+#define TW_ST_SLA_ACK 0xA8
+#define TW_ST_ARB_LOST_SLA_ACK 0xB0
+#define TW_ST_DATA_ACK 0xB8
+#define TW_ST_DATA_NACK 0xC0
+#define TW_ST_LAST_DATA 0xC8
+// Slave Receiver
+#define TW_SR_SLA_ACK 0x60
+#define TW_SR_ARB_LOST_SLA_ACK 0x68
+#define TW_SR_GCALL_ACK 0x70
+#define TW_SR_ARB_LOST_GCALL_ACK 0x78
+#define TW_SR_DATA_ACK 0x80
+#define TW_SR_DATA_NACK 0x88
+#define TW_SR_GCALL_DATA_ACK 0x90
+#define TW_SR_GCALL_DATA_NACK 0x98
+#define TW_SR_STOP 0xA0
+// Misc
+#define TW_NO_INFO 0xF8
+#define TW_BUS_ERROR 0x00
+
+// defines and constants
+#define TWCR_CMD_MASK 0x0F
+#define TWSR_STATUS_MASK 0xF8
+
+// return values
+#define I2C_OK 0x00
+#define I2C_ERROR_NODEV 0x01
+
+#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
+#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
+
+#define WRITE_sda() DDRC = DDRC | 0b00010000 //SDA must be output when writing
+#define READ_sda() DDRC = DDRC & 0b11101111 //SDA must be input when reading - don't forget the resistor on SDA!!
+
+// functions
+
+//! Initialize I2C (TWI) interface
+void i2cInit(void);
+
+//! Set the I2C transaction bitrate (in KHz)
+void i2cSetBitrate(unsigned short bitrateKHz);
+
+// Low-level I2C transaction commands
+//! Send an I2C start condition in Master mode
+void i2cSendStart(void);
+//! Send an I2C stop condition in Master mode
+void i2cSendStop(void);
+//! Wait for current I2C operation to complete
+void i2cWaitForComplete(void);
+//! Send an (address|R/W) combination or a data byte over I2C
+void i2cSendByte(unsigned char data);
+//! Receive a data byte over I2C
+// ackFlag = TRUE if recevied data should be ACK'ed
+// ackFlag = FALSE if recevied data should be NACK'ed
+void i2cReceiveByte(unsigned char ackFlag);
+//! Pick up the data that was received with i2cReceiveByte()
+unsigned char i2cGetReceivedByte(void);
+//! Get current I2c bus status from TWSR
+unsigned char i2cGetStatus(void);
+void delay_ms(uint16_t x);
+
+// high-level I2C transaction commands
+
+//! send I2C data to a device on the bus (non-interrupt based)
+unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data);
+//! receive I2C data from a device on the bus (non-interrupt based)
+unsigned char i2cMasterReceiveNI(unsigned char deviceAddr, unsigned char length, unsigned char *data);
+
+/*********************
+ ****I2C Functions****
+ *********************/
+
+void i2cInit(void)
+{
+ // set i2c bit rate to 40KHz
+ i2cSetBitrate(100);
+ // enable TWI (two-wire interface)
+ sbi(TWCR, TWEN); // Enable TWI
+}
+
+void i2cSetBitrate(unsigned short bitrateKHz)
+{
+ unsigned char bitrate_div;
+ // set i2c bitrate
+ // SCL freq = F_CPU/(16+2*TWBR))
+ cbi(TWSR, TWPS0);
+ cbi(TWSR, TWPS1);
+
+ //calculate bitrate division
+ bitrate_div = ((F_CPU/4000l)/bitrateKHz);
+ if(bitrate_div >= 16)
+ bitrate_div = (bitrate_div-16)/2;
+ outb(TWBR, bitrate_div);
+}
+
+void i2cSendStart(void)
+{
+ WRITE_sda();
+ // send start condition
+ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
+}
+
+void i2cSendStop(void)
+{
+ // transmit stop condition
+ TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
+}
+
+void i2cWaitForComplete(void)
+{
+ int i = 0; //time out variable
+
+ // wait for i2c interface to complete operation
+ while ((!(TWCR & (1<<TWINT))) && (i < 90))
+ i++;
+}
+
+void i2cSendByte(unsigned char data)
+{
+ delay_ms(1);
+ //printf("sending 0x%x\n", data);
+ WRITE_sda();
+ // save data to the TWDR
+ TWDR = data;
+ // begin send
+ TWCR = (1<<TWINT)|(1<<TWEN);
+}
+
+void i2cReceiveByte(unsigned char ackFlag)
+{
+ // begin receive over i2c
+ if( ackFlag )
+ {
+ // ackFlag = TRUE: ACK the recevied data
+ outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
+ }
+ else
+ {
+ // ackFlag = FALSE: NACK the recevied data
+ outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
+ }
+}
+
+unsigned char i2cGetReceivedByte(void)
+{
+ // retieve received data byte from i2c TWDR
+ return( inb(TWDR) );
+}
+
+unsigned char i2cGetStatus(void)
+{
+ // retieve current i2c status from i2c TWSR
+ return( inb(TWSR) );
+}
+
+void delay_ms(uint16_t x)
+{
+ uint8_t y, z;
+ for ( ; x > 0 ; x--){
+ for ( y = 0 ; y < 90 ; y++){
+ for ( z = 0 ; z < 6 ; z++){
+ asm volatile ("nop");
+ }
+ }
+ }
+}
65 MMA8452Q_Example/types.h
@@ -0,0 +1,65 @@
+//useful things to include in code
+
+#ifndef TYPES_H
+#define TYPES_H
+
+#ifndef WIN32
+ // true/false defines
+ #define FALSE 0
+ #define TRUE -1
+#endif
+
+// datatype definitions macros
+typedef unsigned char u08;
+typedef signed char s08;
+typedef unsigned short u16;
+typedef signed short s16;
+typedef unsigned long u32;
+typedef signed long s32;
+typedef unsigned long long u64;
+typedef signed long long s64;
+
+/* use inttypes.h instead
+// C99 standard integer type definitions
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+typedef unsigned long uint32_t;
+typedef signed long int32_t;
+typedef unsigned long uint64_t;
+typedef signed long int64_t;
+*/
+// maximum value that can be held
+// by unsigned data types (8,16,32bits)
+#define MAX_U08 255
+#define MAX_U16 65535
+#define MAX_U32 4294967295
+
+// maximum values that can be held
+// by signed data types (8,16,32bits)
+#define MIN_S08 -128
+#define MAX_S08 127
+#define MIN_S16 -32768
+#define MAX_S16 32767
+#define MIN_S32 -2147483648
+#define MAX_S32 2147483647
+
+#ifndef WIN32
+ // more type redefinitions
+ typedef unsigned char BOOL;
+ typedef unsigned char BYTE;
+ typedef unsigned int WORD;
+ typedef unsigned long DWORD;
+
+ typedef unsigned char UCHAR;
+ typedef unsigned int UINT;
+ typedef unsigned short USHORT;
+ typedef unsigned long ULONG;
+
+ typedef char CHAR;
+ typedef int INT;
+ typedef long LONG;
+#endif
+
+#endif
Please sign in to comment.
Something went wrong with that request. Please try again.