1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,405 @@
/**
* @author Aaron Berk
*
* @section LICENSE
*
* Copyright (c) 2010 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* ADXL345, triple axis, digital interface, accelerometer.
*
* Datasheet:
*
* http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
*/
/**
* Includes
*/
#include "ADXL345.h"
ADXL345::ADXL345(PinName mosi,
PinName miso,
PinName sck,
PinName cs) : spi_(mosi, miso, sck), nCS_(cs) {
//2MHz, allowing us to use the fastest data rates.
spi_.frequency(2000000);
spi_.format(8,3);
nCS_ = 1;
wait_us(500);
}
int ADXL345::getDevId(void) {
return oneByteRead(ADXL345_DEVID_REG);
}
int ADXL345::getTapThreshold(void) {
return oneByteRead(ADXL345_THRESH_TAP_REG);
}
void ADXL345::setTapThreshold(int threshold) {
oneByteWrite(ADXL345_THRESH_TAP_REG, threshold);
}
int ADXL345::getOffset(int axis) {
int address = 0;
if (axis == ADXL345_X) {
address = ADXL345_OFSX_REG;
} else if (axis == ADXL345_Y) {
address = ADXL345_OFSY_REG;
} else if (axis == ADXL345_Z) {
address = ADXL345_OFSZ_REG;
}
return oneByteRead(address);
}
void ADXL345::setOffset(int axis, char offset) {
int address = 0;
if (axis == ADXL345_X) {
address = ADXL345_OFSX_REG;
} else if (axis == ADXL345_Y) {
address = ADXL345_OFSY_REG;
} else if (axis == ADXL345_Z) {
address = ADXL345_OFSZ_REG;
}
return oneByteWrite(address, offset);
}
int ADXL345::getTapDuration(void) {
return oneByteRead(ADXL345_DUR_REG)*625;
}
void ADXL345::setTapDuration(int duration_us) {
int tapDuration = duration_us / 625;
oneByteWrite(ADXL345_DUR_REG, tapDuration);
}
float ADXL345::getTapLatency(void) {
return oneByteRead(ADXL345_LATENT_REG)*1.25;
}
void ADXL345::setTapLatency(int latency_ms) {
int tapLatency = latency_ms / 1.25;
oneByteWrite(ADXL345_LATENT_REG, tapLatency);
}
float ADXL345::getWindowTime(void) {
return oneByteRead(ADXL345_WINDOW_REG)*1.25;
}
void ADXL345::setWindowTime(int window_ms) {
int windowTime = window_ms / 1.25;
oneByteWrite(ADXL345_WINDOW_REG, windowTime);
}
int ADXL345::getActivityThreshold(void) {
return oneByteRead(ADXL345_THRESH_ACT_REG);
}
void ADXL345::setActivityThreshold(int threshold) {
oneByteWrite(ADXL345_THRESH_ACT_REG, threshold);
}
int ADXL345::getInactivityThreshold(void) {
return oneByteRead(ADXL345_THRESH_INACT_REG);
}
void ADXL345::setInactivityThreshold(int threshold) {
return oneByteWrite(ADXL345_THRESH_INACT_REG, threshold);
}
int ADXL345::getTimeInactivity(void) {
return oneByteRead(ADXL345_TIME_INACT_REG);
}
void ADXL345::setTimeInactivity(int timeInactivity) {
oneByteWrite(ADXL345_TIME_INACT_REG, timeInactivity);
}
int ADXL345::getActivityInactivityControl(void) {
return oneByteRead(ADXL345_ACT_INACT_CTL_REG);
}
void ADXL345::setActivityInactivityControl(int settings) {
oneByteWrite(ADXL345_ACT_INACT_CTL_REG, settings);
}
int ADXL345::getFreefallThreshold(void) {
return oneByteRead(ADXL345_THRESH_FF_REG);
}
void ADXL345::setFreefallThreshold(int threshold) {
oneByteWrite(ADXL345_THRESH_FF_REG, threshold);
}
int ADXL345::getFreefallTime(void) {
return oneByteRead(ADXL345_TIME_FF_REG)*5;
}
void ADXL345::setFreefallTime(int freefallTime_ms) {
int freefallTime = freefallTime_ms / 5;
oneByteWrite(ADXL345_TIME_FF_REG, freefallTime);
}
int ADXL345::getTapAxisControl(void) {
return oneByteRead(ADXL345_TAP_AXES_REG);
}
void ADXL345::setTapAxisControl(int settings) {
oneByteWrite(ADXL345_TAP_AXES_REG, settings);
}
int ADXL345::getTapSource(void) {
return oneByteRead(ADXL345_ACT_TAP_STATUS_REG);
}
void ADXL345::setPowerMode(char mode) {
//Get the current register contents, so we don't clobber the rate value.
char registerContents = oneByteRead(ADXL345_BW_RATE_REG);
registerContents = (mode << 4) | registerContents;
oneByteWrite(ADXL345_BW_RATE_REG, registerContents);
}
int ADXL345::getPowerControl(void) {
return oneByteRead(ADXL345_POWER_CTL_REG);
}
void ADXL345::setPowerControl(int settings) {
oneByteWrite(ADXL345_POWER_CTL_REG, settings);
}
int ADXL345::getInterruptEnableControl(void) {
return oneByteRead(ADXL345_INT_ENABLE_REG);
}
void ADXL345::setInterruptEnableControl(int settings) {
oneByteWrite(ADXL345_INT_ENABLE_REG, settings);
}
int ADXL345::getInterruptMappingControl(void) {
return oneByteRead(ADXL345_INT_MAP_REG);
}
void ADXL345::setInterruptMappingControl(int settings) {
oneByteWrite(ADXL345_INT_MAP_REG, settings);
}
int ADXL345::getInterruptSource(void){
return oneByteRead(ADXL345_INT_SOURCE_REG);
}
int ADXL345::getDataFormatControl(void){
return oneByteRead(ADXL345_DATA_FORMAT_REG);
}
void ADXL345::setDataFormatControl(int settings){
oneByteWrite(ADXL345_DATA_FORMAT_REG, settings);
}
void ADXL345::setDataRate(int rate) {
//Get the current register contents, so we don't clobber the power bit.
char registerContents = oneByteRead(ADXL345_BW_RATE_REG);
registerContents &= 0x10;
registerContents |= rate;
oneByteWrite(ADXL345_BW_RATE_REG, registerContents);
}
void ADXL345::getOutput(int* readings){
char buffer[6];
multiByteRead(ADXL345_DATAX0_REG, buffer, 6);
readings[0] = (int)buffer[1] << 8 | (int)buffer[0];
readings[1] = (int)buffer[3] << 8 | (int)buffer[2];
readings[2] = (int)buffer[5] << 8 | (int)buffer[4];
}
int ADXL345::getFifoControl(void){
return oneByteRead(ADXL345_FIFO_CTL);
}
void ADXL345::setFifoControl(int settings){
oneByteWrite(ADXL345_FIFO_STATUS, settings);
}
int ADXL345::getFifoStatus(void){
return oneByteRead(ADXL345_FIFO_STATUS);
}
int ADXL345::oneByteRead(int address) {
int tx = (ADXL345_SPI_READ | (address & 0x3F));
int rx = 0;
nCS_ = 0;
//Send address to read from.
spi_.write(tx);
//Read back contents of address.
rx = spi_.write(0x00);
nCS_ = 1;
return rx;
}
void ADXL345::oneByteWrite(int address, char data) {
int tx = (ADXL345_SPI_WRITE | (address & 0x3F));
nCS_ = 0;
//Send address to write to.
spi_.write(tx);
//Send data to be written.
spi_.write(data);
nCS_ = 1;
}
void ADXL345::multiByteRead(int startAddress, char* buffer, int size) {
int tx = (ADXL345_SPI_READ | ADXL345_MULTI_BYTE | (startAddress & 0x3F));
nCS_ = 0;
//Send address to start reading from.
spi_.write(tx);
for (int i = 0; i < size; i++) {
buffer[i] = spi_.write(0x00);
}
nCS_ = 1;
}
void ADXL345::multiByteWrite(int startAddress, char* buffer, int size) {
int tx = (ADXL345_SPI_WRITE | ADXL345_MULTI_BYTE | (startAddress & 0x3F));
nCS_ = 0;
//Send address to start reading from.
spi_.write(tx);
for (int i = 0; i < size; i++) {
buffer[i] = spi_.write(0x00);
}
nCS_ = 1;
}

View file

@ -0,0 +1,537 @@
/**
* @author Aaron Berk
*
* @section LICENSE
*
* Copyright (c) 2010 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* ADXL345, triple axis, digital interface, accelerometer.
*
* Datasheet:
*
* http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
*/
#ifndef ADXL345_H
#define ADXL345_H
/**
* Includes
*/
#include "mbed.h"
/**
* Defines
*/
//Registers.
#define ADXL345_DEVID_REG 0x00
#define ADXL345_THRESH_TAP_REG 0x1D
#define ADXL345_OFSX_REG 0x1E
#define ADXL345_OFSY_REG 0x1F
#define ADXL345_OFSZ_REG 0x20
#define ADXL345_DUR_REG 0x21
#define ADXL345_LATENT_REG 0x22
#define ADXL345_WINDOW_REG 0x23
#define ADXL345_THRESH_ACT_REG 0x24
#define ADXL345_THRESH_INACT_REG 0x25
#define ADXL345_TIME_INACT_REG 0x26
#define ADXL345_ACT_INACT_CTL_REG 0x27
#define ADXL345_THRESH_FF_REG 0x28
#define ADXL345_TIME_FF_REG 0x29
#define ADXL345_TAP_AXES_REG 0x2A
#define ADXL345_ACT_TAP_STATUS_REG 0x2B
#define ADXL345_BW_RATE_REG 0x2C
#define ADXL345_POWER_CTL_REG 0x2D
#define ADXL345_INT_ENABLE_REG 0x2E
#define ADXL345_INT_MAP_REG 0x2F
#define ADXL345_INT_SOURCE_REG 0x30
#define ADXL345_DATA_FORMAT_REG 0x31
#define ADXL345_DATAX0_REG 0x32
#define ADXL345_DATAX1_REG 0x33
#define ADXL345_DATAY0_REG 0x34
#define ADXL345_DATAY1_REG 0x35
#define ADXL345_DATAZ0_REG 0x36
#define ADXL345_DATAZ1_REG 0x37
#define ADXL345_FIFO_CTL 0x38
#define ADXL345_FIFO_STATUS 0x39
//Data rate codes.
#define ADXL345_3200HZ 0x0F
#define ADXL345_1600HZ 0x0E
#define ADXL345_800HZ 0x0D
#define ADXL345_400HZ 0x0C
#define ADXL345_200HZ 0x0B
#define ADXL345_100HZ 0x0A
#define ADXL345_50HZ 0x09
#define ADXL345_25HZ 0x08
#define ADXL345_12HZ5 0x07
#define ADXL345_6HZ25 0x06
#define ADXL345_SPI_READ 0x80
#define ADXL345_SPI_WRITE 0x00
#define ADXL345_MULTI_BYTE 0x60
#define ADXL345_X 0x00
#define ADXL345_Y 0x01
#define ADXL345_Z 0x02
/**
* ADXL345 triple axis, digital interface, accelerometer.
*/
class ADXL345 {
public:
/**
* Constructor.
*
* @param mosi mbed pin to use for MOSI line of SPI interface.
* @param miso mbed pin to use for MISO line of SPI interface.
* @param sck mbed pin to use for SCK line of SPI interface.
* @param cs mbed pin to use for not chip select line of SPI interface.
*/
ADXL345(PinName mosi, PinName miso, PinName sck, PinName cs);
/**
* Read the device ID register on the device.
*
* @return The device ID code [0xE5]
*/
int getDevId(void);
/**
* Read the tap threshold on the device.
*
* @return The tap threshold as an 8-bit number with a scale factor of
* 62.5mg/LSB.
*/
int getTapThreshold(void);
/**
* Set the tap threshold.
*
* @param The tap threshold as an 8-bit number with a scale factor of
* 62.5mg/LSB.
*/
void setTapThreshold(int threshold);
/**
* Get the current offset for a particular axis.
*
* @param axis 0x00 -> X-axis
* 0x01 -> Y-axis
* 0x02 -> Z-axis
* @return The current offset as an 8-bit 2's complement number with scale
* factor 15.6mg/LSB.
*/
int getOffset(int axis);
/**
* Set the offset for a particular axis.
*
* @param axis 0x00 -> X-axis
* 0x01 -> Y-axis
* 0x02 -> Z-axis
* @param offset The offset as an 8-bit 2's complement number with scale
* factor 15.6mg/LSB.
*/
void setOffset(int axis, char offset);
/**
* Get the tap duration required to trigger an event.
*
* @return The max time that an event must be above the tap threshold to
* qualify as a tap event, in microseconds.
*/
int getTapDuration(void);
/**
* Set the tap duration required to trigger an event.
*
* @param duration_us The max time that an event must be above the tap
* threshold to qualify as a tap event, in microseconds.
* Time will be normalized by the scale factor which is
* 625us/LSB. A value of 0 disables the single/double
* tap functions.
*/
void setTapDuration(int duration_us);
/**
* Get the tap latency between the detection of a tap and the time window.
*
* @return The wait time from the detection of a tap event to the start of
* the time window during which a possible second tap event can be
* detected in milliseconds.
*/
float getTapLatency(void);
/**
* Set the tap latency between the detection of a tap and the time window.
*
* @param latency_ms The wait time from the detection of a tap event to the
* start of the time window during which a possible
* second tap event can be detected in milliseconds.
* A value of 0 disables the double tap function.
*/
void setTapLatency(int latency_ms);
/**
* Get the time of window between tap latency and a double tap.
*
* @return The amount of time after the expiration of the latency time
* during which a second valid tap can begin, in milliseconds.
*/
float getWindowTime(void);
/**
* Set the time of the window between tap latency and a double tap.
*
* @param window_ms The amount of time after the expiration of the latency
* time during which a second valid tap can begin,
* in milliseconds.
*/
void setWindowTime(int window_ms);
/**
* Get the threshold value for detecting activity.
*
* @return The threshold value for detecting activity as an 8-bit number.
* Scale factor is 62.5mg/LSB.
*/
int getActivityThreshold(void);
/**
* Set the threshold value for detecting activity.
*
* @param threshold The threshold value for detecting activity as an 8-bit
* number. Scale factor is 62.5mg/LSB. A value of 0 may
* result in undesirable behavior if the activity
* interrupt is enabled.
*/
void setActivityThreshold(int threshold);
/**
* Get the threshold value for detecting inactivity.
*
* @return The threshold value for detecting inactivity as an 8-bit number.
* Scale factor is 62.5mg/LSB.
*/
int getInactivityThreshold(void);
/**
* Set the threshold value for detecting inactivity.
*
* @param threshold The threshold value for detecting inactivity as an
* 8-bit number. Scale factor is 62.5mg/LSB.
*/
void setInactivityThreshold(int threshold);
/**
* Get the time required for inactivity to be declared.
*
* @return The amount of time that acceleration must be less than the
* inactivity threshold for inactivity to be declared, in
* seconds.
*/
int getTimeInactivity(void);
/**
* Set the time required for inactivity to be declared.
*
* @param inactivity The amount of time that acceleration must be less than
* the inactivity threshold for inactivity to be
* declared, in seconds. A value of 0 results in an
* interrupt when the output data is less than the
* threshold inactivity.
*/
void setTimeInactivity(int timeInactivity);
/**
* Get the activity/inactivity control settings.
*
* D7 D6 D5 D4
* +-----------+--------------+--------------+--------------+
* | ACT ac/dc | ACT_X enable | ACT_Y enable | ACT_Z enable |
* +-----------+--------------+--------------+--------------+
*
* D3 D2 D1 D0
* +-------------+----------------+----------------+----------------+
* | INACT ac/dc | INACT_X enable | INACT_Y enable | INACT_Z enable |
* +-------------+----------------+----------------+----------------+
*
* See datasheet for details.
*
* @return The contents of the ACT_INACT_CTL register.
*/
int getActivityInactivityControl(void);
/**
* Set the activity/inactivity control settings.
*
* D7 D6 D5 D4
* +-----------+--------------+--------------+--------------+
* | ACT ac/dc | ACT_X enable | ACT_Y enable | ACT_Z enable |
* +-----------+--------------+--------------+--------------+
*
* D3 D2 D1 D0
* +-------------+----------------+----------------+----------------+
* | INACT ac/dc | INACT_X enable | INACT_Y enable | INACT_Z enable |
* +-------------+----------------+----------------+----------------+
*
* See datasheet for details.
*
* @param settings The control byte to write to the ACT_INACT_CTL register.
*/
void setActivityInactivityControl(int settings);
/**
* Get the threshold for free fall detection.
*
* @return The threshold value for free-fall detection, as an 8-bit number,
* with scale factor 62.5mg/LSB.
*/
int getFreefallThreshold(void);
/**
* Set the threshold for free fall detection.
*
* @return The threshold value for free-fall detection, as an 8-bit number,
* with scale factor 62.5mg/LSB. A value of 0 may result in
* undesirable behavior if the free-fall interrupt is enabled.
* Values between 300 mg and 600 mg (0x05 to 0x09) are recommended.
*/
void setFreefallThreshold(int threshold);
/**
* Get the time required to generate a free fall interrupt.
*
* @return The minimum time that the value of all axes must be less than
* the freefall threshold to generate a free-fall interrupt, in
* milliseconds.
*/
int getFreefallTime(void);
/**
* Set the time required to generate a free fall interrupt.
*
* @return The minimum time that the value of all axes must be less than
* the freefall threshold to generate a free-fall interrupt, in
* milliseconds. A value of 0 may result in undesirable behavior
* if the free-fall interrupt is enabled. Values between 100 ms
* and 350 ms (0x14 to 0x46) are recommended.
*/
void setFreefallTime(int freefallTime_ms);
/**
* Get the axis tap settings.
*
* D3 D2 D1 D0
* +----------+--------------+--------------+--------------+
* | Suppress | TAP_X enable | TAP_Y enable | TAP_Z enable |
* +----------+--------------+--------------+--------------+
*
* (D7-D4 are 0s).
*
* See datasheet for more details.
*
* @return The contents of the TAP_AXES register.
*/
int getTapAxisControl(void);
/**
* Set the axis tap settings.
*
* D3 D2 D1 D0
* +----------+--------------+--------------+--------------+
* | Suppress | TAP_X enable | TAP_Y enable | TAP_Z enable |
* +----------+--------------+--------------+--------------+
*
* (D7-D4 are 0s).
*
* See datasheet for more details.
*
* @param The control byte to write to the TAP_AXES register.
*/
void setTapAxisControl(int settings);
/**
* Get the source of a tap.
*
* @return The contents of the ACT_TAP_STATUS register.
*/
int getTapSource(void);
/**
* Set the power mode.
*
* @param mode 0 -> Normal operation.
* 1 -> Reduced power operation.
*/
void setPowerMode(char mode);
/**
* Set the data rate.
*
* @param rate The rate code (see #defines or datasheet).
*/
void setDataRate(int rate);
/**
* Get the power control settings.
*
* See datasheet for details.
*
* @return The contents of the POWER_CTL register.
*/
int getPowerControl(void);
/**
* Set the power control settings.
*
* See datasheet for details.
*
* @param The control byte to write to the POWER_CTL register.
*/
void setPowerControl(int settings);
/**
* Get the interrupt enable settings.
*
* @return The contents of the INT_ENABLE register.
*/
int getInterruptEnableControl(void);
/**
* Set the interrupt enable settings.
*
* @param settings The control byte to write to the INT_ENABLE register.
*/
void setInterruptEnableControl(int settings);
/**
* Get the interrupt mapping settings.
*
* @return The contents of the INT_MAP register.
*/
int getInterruptMappingControl(void);
/**
* Set the interrupt mapping settings.
*
* @param settings The control byte to write to the INT_MAP register.
*/
void setInterruptMappingControl(int settings);
/**
* Get the interrupt source.
*
* @return The contents of the INT_SOURCE register.
*/
int getInterruptSource(void);
/**
* Get the data format settings.
*
* @return The contents of the DATA_FORMAT register.
*/
int getDataFormatControl(void);
/**
* Set the data format settings.
*
* @param settings The control byte to write to the DATA_FORMAT register.
*/
void setDataFormatControl(int settings);
/**
* Get the output of all three axes.
*
* @param Pointer to a buffer to hold the accelerometer value for the
* x-axis, y-axis and z-axis [in that order].
*/
void getOutput(int* readings);
/**
* Get the FIFO control settings.
*
* @return The contents of the FIFO_CTL register.
*/
int getFifoControl(void);
/**
* Set the FIFO control settings.
*
* @param The control byte to write to the FIFO_CTL register.
*/
void setFifoControl(int settings);
/**
* Get FIFO status.
*
* @return The contents of the FIFO_STATUS register.
*/
int getFifoStatus(void);
private:
SPI spi_;
DigitalOut nCS_;
/**
* Read one byte from a register on the device.
*
* @param address Address of the register to read.
*
* @return The contents of the register address.
*/
int oneByteRead(int address);
/**
* Write one byte to a register on the device.
*
* @param address Address of the register to write to.
* @param data The data to write into the register.
*/
void oneByteWrite(int address, char data);
/**
* Read several consecutive bytes on the device.
*
* @param startAddress The address of the first register to read from.
* @param buffer Pointer to a buffer to store data read from the device.
* @param size The number of bytes to read.
*/
void multiByteRead(int startAddress, char* buffer, int size);
/**
* Write several consecutive bytes on the device.
*
* @param startAddress The address of the first register to write to.
* @param buffer Pointer to a buffer which contains the data to write.
* @param size The number of bytes to write.
*/
void multiByteWrite(int startAddress, char* buffer, int size);
};
#endif /* ADXL345_H */

View file

@ -0,0 +1,534 @@
/* mbed AX-12+ Servo Library
*
* Copyright (c) 2010, cstyles (http://mbed.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "AX12.h"
#include "mbed.h"
AX12::AX12(PinName tx, PinName rx, int ID, int baud)
: _ax12(tx,rx) {
_baud = baud;
_ID = ID;
_ax12.baud(_baud);
}
// Set the mode of the servo
// 0 = Positional (0-300 degrees)
// 1 = Rotational -1 to 1 speed
int AX12::SetMode(int mode) {
if (mode == 1) { // set CR
SetCWLimit(0);
SetCCWLimit(0);
SetCRSpeed(0.0);
} else {
SetCWLimit(0);
SetCCWLimit(300);
SetCRSpeed(0.0);
}
return(0);
}
// if flag[0] is set, were blocking
// if flag[1] is set, we're registering
// they are mutually exclusive operations
int AX12::SetGoal(int degrees, int flags) {
char reg_flag = 0;
char data[2];
// set the flag is only the register bit is set in the flag
if (flags == 0x2) {
reg_flag = 1;
}
// 1023 / 300 * degrees
short goal = (1023 * degrees) / 300;
#ifdef AX12_DEBUG
printf("SetGoal to 0x%x\n",goal);
#endif
data[0] = goal & 0xff; // bottom 8 bits
data[1] = goal >> 8; // top 8 bits
// write the packet, return the error code
int rVal = write(_ID, AX12_REG_GOAL_POSITION, 2, data, reg_flag);
if (flags == 1) {
// block until it comes to a halt
while (isMoving()) {}
}
return(rVal);
}
// Set continuous rotation speed from -1 to 1
int AX12::SetCRSpeed(float speed) {
// bit 10 = direction, 0 = CCW, 1=CW
// bits 9-0 = Speed
char data[2];
int goal = (0x3ff * abs(speed));
// Set direction CW if we have a negative speed
if (speed < 0) {
goal |= (0x1 << 10);
}
data[0] = goal & 0xff; // bottom 8 bits
data[1] = goal >> 8; // top 8 bits
// write the packet, return the error code
int rVal = write(_ID, 0x20, 2, data);
return(rVal);
}
int AX12::SetCWLimit (int degrees) {
char data[2];
// 1023 / 300 * degrees
short limit = (1023 * degrees) / 300;
#ifdef AX12_DEBUG
printf("SetCWLimit to 0x%x\n",limit);
#endif
data[0] = limit & 0xff; // bottom 8 bits
data[1] = limit >> 8; // top 8 bits
// write the packet, return the error code
return (write(_ID, AX12_REG_CW_LIMIT, 2, data));
}
int AX12::SetCCWLimit (int degrees) {
char data[2];
// 1023 / 300 * degrees
short limit = (1023 * degrees) / 300;
#ifdef AX12_DEBUG
printf("SetCCWLimit to 0x%x\n",limit);
#endif
data[0] = limit & 0xff; // bottom 8 bits
data[1] = limit >> 8; // top 8 bits
// write the packet, return the error code
return (write(_ID, AX12_REG_CCW_LIMIT, 2, data));
}
int AX12::SetID (int CurrentID, int NewID) {
char data[1];
data[0] = NewID;
#ifdef AX12_DEBUG
printf("Setting ID from 0x%x to 0x%x\n",CurrentID,NewID);
#endif
return (write(CurrentID, AX12_REG_ID, 1, data));
}
int AX12::SetBaud (int baud) {
char data[1];
data[0] = baud;
#ifdef AX12_DEBUG
printf("Setting Baud rate to %d\n",baud);
#endif
return (write(0xFE, AX12_REG_BAUD, 1, data));
}
// return 1 is the servo is still in flight
int AX12::isMoving(void) {
char data[1];
read(_ID,AX12_REG_MOVING,1,data);
return(data[0]);
}
void AX12::trigger(void) {
char TxBuf[16];
char sum = 0;
#ifdef AX12_TRIGGER_DEBUG
// Build the TxPacket first in RAM, then we'll send in one go
printf("\nTriggered\n");
printf("\nTrigger Packet\n Header : 0xFF, 0xFF\n");
#endif
TxBuf[0] = 0xFF;
TxBuf[1] = 0xFF;
// ID - Broadcast
TxBuf[2] = 0xFE;
sum += TxBuf[2];
#ifdef AX12_TRIGGER_DEBUG
printf(" ID : %d\n",TxBuf[2]);
#endif
// Length
TxBuf[3] = 0x02;
sum += TxBuf[3];
#ifdef AX12_TRIGGER_DEBUG
printf(" Length %d\n",TxBuf[3]);
#endif
// Instruction - ACTION
TxBuf[4] = 0x04;
sum += TxBuf[4];
#ifdef AX12_TRIGGER_DEBUG
printf(" Instruction 0x%X\n",TxBuf[5]);
#endif
// Checksum
TxBuf[5] = 0xFF - sum;
#ifdef AX12_TRIGGER_DEBUG
printf(" Checksum 0x%X\n",TxBuf[5]);
#endif
// Transmit the packet in one burst with no pausing
for (int i = 0; i < 6 ; i++) {
_ax12.putc(TxBuf[i]);
}
// This is a broadcast packet, so there will be no reply
return;
}
float AX12::GetPosition(void) {
#ifdef AX12_DEBUG
printf("\nGetPosition(%d)",_ID);
#endif
char data[2];
int ErrorCode = read(_ID, AX12_REG_POSITION, 2, data);
short position = data[0] + (data[1] << 8);
float angle = (position * 300)/1024;
return (angle);
}
float AX12::GetTemp (void) {
#ifdef AX12_DEBUG
printf("\nGetTemp(%d)",_ID);
#endif
char data[1];
int ErrorCode = read(_ID, AX12_REG_TEMP, 1, data);
float temp = data[0];
return(temp);
}
float AX12::GetVolts (void) {
#ifdef AX12_DEBUG
printf("\nGetVolts(%d)",_ID);
#endif
char data[1];
int ErrorCode = read(_ID, AX12_REG_VOLTS, 1, data);
float volts = data[0]/10.0;
return(volts);
}
int AX12::read(int ID, int start, int bytes, char* data) {
char PacketLength = 0x4;
char TxBuf[16];
char sum = 0;
char Status[16];
Status[4] = 0xFE; // return code
#ifdef AX12_READ_DEBUG
printf("\nread(%d,0x%x,%d,data)\n",ID,start,bytes);
#endif
// Build the TxPacket first in RAM, then we'll send in one go
#ifdef AX12_READ_DEBUG
printf("\nInstruction Packet\n Header : 0xFF, 0xFF\n");
#endif
TxBuf[0] = 0xff;
TxBuf[1] = 0xff;
// ID
TxBuf[2] = ID;
sum += TxBuf[2];
#ifdef AX12_READ_DEBUG
printf(" ID : %d\n",TxBuf[2]);
#endif
// Packet Length
TxBuf[3] = PacketLength; // Length = 4 ; 2 + 1 (start) = 1 (bytes)
sum += TxBuf[3]; // Accululate the packet sum
#ifdef AX12_READ_DEBUG
printf(" Length : 0x%x\n",TxBuf[3]);
#endif
// Instruction - Read
TxBuf[4] = 0x2;
sum += TxBuf[4];
#ifdef AX12_READ_DEBUG
printf(" Instruction : 0x%x\n",TxBuf[4]);
#endif
// Start Address
TxBuf[5] = start;
sum += TxBuf[5];
#ifdef AX12_READ_DEBUG
printf(" Start Address : 0x%x\n",TxBuf[5]);
#endif
// Bytes to read
TxBuf[6] = bytes;
sum += TxBuf[6];
#ifdef AX12_READ_DEBUG
printf(" No bytes : 0x%x\n",TxBuf[6]);
#endif
// Checksum
TxBuf[7] = 0xFF - sum;
#ifdef AX12_READ_DEBUG
printf(" Checksum : 0x%x\n",TxBuf[7]);
#endif
// Transmit the packet in one burst with no pausing
for (int i = 0; i<8 ; i++) {
_ax12.putc(TxBuf[i]);
}
// Wait for the bytes to be transmitted
wait (0.00002);
// Skip if the read was to the broadcast address
if (_ID != 0xFE) {
// response packet is always 6 + bytes
// 0xFF, 0xFF, ID, Length Error, Param(s) Checksum
// timeout is a little more than the time to transmit
// the packet back, i.e. (6+bytes)*10 bit periods
int timeout = 0;
int plen = 0;
while ((timeout < ((6+bytes)*10)) && (plen<(6+bytes))) {
if (_ax12.readable()) {
Status[plen] = _ax12.getc();
plen++;
timeout = 0;
}
// wait for the bit period
wait (1.0/_baud);
timeout++;
}
if (timeout == ((6+bytes)*10) ) {
return(-1);
}
// Copy the data from Status into data for return
for (int i=0; i < Status[3]-2 ; i++) {
data[i] = Status[5+i];
}
#ifdef AX12_READ_DEBUG
printf("\nStatus Packet\n");
printf(" Header : 0x%x\n",Status[0]);
printf(" Header : 0x%x\n",Status[1]);
printf(" ID : 0x%x\n",Status[2]);
printf(" Length : 0x%x\n",Status[3]);
printf(" Error Code : 0x%x\n",Status[4]);
for (int i=0; i < Status[3]-2 ; i++) {
printf(" Data : 0x%x\n",Status[5+i]);
}
printf(" Checksum : 0x%x\n",Status[5+(Status[3]-2)]);
#endif
} // if (ID!=0xFE)
return(Status[4]);
}
int AX12::write(int ID, int start, int bytes, char* data, int flag) {
// 0xff, 0xff, ID, Length, Intruction(write), Address, Param(s), Checksum
char TxBuf[16];
char sum = 0;
char Status[6];
#ifdef AX12_WRITE_DEBUG
printf("\nwrite(%d,0x%x,%d,data,%d)\n",ID,start,bytes,flag);
#endif
// Build the TxPacket first in RAM, then we'll send in one go
#ifdef AX12_WRITE_DEBUG
printf("\nInstruction Packet\n Header : 0xFF, 0xFF\n");
#endif
TxBuf[0] = 0xff;
TxBuf[1] = 0xff;
// ID
TxBuf[2] = ID;
sum += TxBuf[2];
#ifdef AX12_WRITE_DEBUG
printf(" ID : %d\n",TxBuf[2]);
#endif
// packet Length
TxBuf[3] = 3+bytes;
sum += TxBuf[3];
#ifdef AX12_WRITE_DEBUG
printf(" Length : %d\n",TxBuf[3]);
#endif
// Instruction
if (flag == 1) {
TxBuf[4]=0x04;
sum += TxBuf[4];
} else {
TxBuf[4]=0x03;
sum += TxBuf[4];
}
#ifdef AX12_WRITE_DEBUG
printf(" Instruction : 0x%x\n",TxBuf[4]);
#endif
// Start Address
TxBuf[5] = start;
sum += TxBuf[5];
#ifdef AX12_WRITE_DEBUG
printf(" Start : 0x%x\n",TxBuf[5]);
#endif
// data
for (char i=0; i<bytes ; i++) {
TxBuf[6+i] = data[i];
sum += TxBuf[6+i];
#ifdef AX12_WRITE_DEBUG
printf(" Data : 0x%x\n",TxBuf[6+i]);
#endif
}
// checksum
TxBuf[6+bytes] = 0xFF - sum;
#ifdef AX12_WRITE_DEBUG
printf(" Checksum : 0x%x\n",TxBuf[6+bytes]);
#endif
// Transmit the packet in one burst with no pausing
for (int i = 0; i < (7 + bytes) ; i++) {
_ax12.putc(TxBuf[i]);
}
// Wait for data to transmit
wait (0.00002);
// make sure we have a valid return
Status[4]=0x00;
// we'll only get a reply if it was not broadcast
if (_ID!=0xFE) {
// response packet is always 6 bytes
// 0xFF, 0xFF, ID, Length Error, Param(s) Checksum
// timeout is a little more than the time to transmit
// the packet back, i.e. 60 bit periods, round up to 100
int timeout = 0;
int plen = 0;
while ((timeout < 100) && (plen<6)) {
if (_ax12.readable()) {
Status[plen] = _ax12.getc();
plen++;
timeout = 0;
}
// wait for the bit period
wait (1.0/_baud);
timeout++;
}
// Build the TxPacket first in RAM, then we'll send in one go
#ifdef AX12_WRITE_DEBUG
printf("\nStatus Packet\n Header : 0x%X, 0x%X\n",Status[0],Status[1]);
printf(" ID : %d\n",Status[2]);
printf(" Length : %d\n",Status[3]);
printf(" Error : 0x%x\n",Status[4]);
printf(" Checksum : 0x%x\n",Status[5]);
#endif
}
return(Status[4]); // return error code
}

View file

@ -0,0 +1,190 @@
/* mbed AX-12+ Servo Library
*
* Copyright (c) 2010, cstyles (http://mbed.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MBED_AX12_H
#define MBED_AX12_H
#include "mbed.h"
#define AX12_WRITE_DEBUG 1
#define AX12_READ_DEBUG 1
#define AX12_TRIGGER_DEBUG 1
#define AX12_DEBUG 1
#define AX12_REG_ID 0x3
#define AX12_REG_BAUD 0x4
#define AX12_REG_CW_LIMIT 0x06
#define AX12_REG_CCW_LIMIT 0x08
#define AX12_REG_GOAL_POSITION 0x1E
#define AX12_REG_MOVING_SPEED 0x20
#define AX12_REG_VOLTS 0x2A
#define AX12_REG_TEMP 0x2B
#define AX12_REG_MOVING 0x2E
#define AX12_REG_POSITION 0x24
#define AX12_MODE_POSITION 0
#define AX12_MODE_ROTATION 1
#define AX12_CW 1
#define AX12_CCW 0
/** Servo control class, based on a PwmOut
*
* Example:
* @code
* #include "mbed.h"
* #include "AX12.h"
*
* int main() {
*
* AX12 myax12 (p9, p10, 1);
*
* while (1) {
* myax12.SetGoal(0); // go to 0 degrees
* wait (2.0);
* myax12.SetGoal(300); // go to 300 degrees
* wait (2.0);
* }
* }
* @endcode
*/
class AX12 {
public:
/** Create an AX12 servo object connected to the specified serial port, with the specified ID
*
* @param pin tx pin
* @param pin rx pin
* @param int ID, the Bus ID of the servo 1-255
*/
AX12(PinName tx, PinName rx, int ID, int baud=1000000);
/** Set the mode of the servo
* @param mode
* 0 = Positional, default
* 1 = Continuous rotation
*/
int SetMode(int mode);
/** Set baud rate of all attached servos
* @param mode
* 0x01 = 1,000,000 bps
* 0x03 = 500,000 bps
* 0x04 = 400,000 bps
* 0x07 = 250,000 bps
* 0x09 = 200,000 bps
* 0x10 = 115,200 bps
* 0x22 = 57,600 bps
* 0x67 = 19,200 bps
* 0xCF = 9,600 bp
*/
int SetBaud(int baud);
/** Set goal angle in integer degrees, in positional mode
*
* @param degrees 0-300
* @param flags, defaults to 0
* flags[0] = blocking, return when goal position reached
* flags[1] = register, activate with a broadcast trigger
*
*/
int SetGoal(int degrees, int flags = 0);
/** Set the speed of the servo in continuous rotation mode
*
* @param speed, -1.0 to 1.0
* -1.0 = full speed counter clock wise
* 1.0 = full speed clock wise
*/
int SetCRSpeed(float speed);
/** Set the clockwise limit of the servo
*
* @param degrees, 0-300
*/
int SetCWLimit(int degrees);
/** Set the counter-clockwise limit of the servo
*
* @param degrees, 0-300
*/
int SetCCWLimit(int degrees);
// Change the ID
/** Change the ID of a servo
*
* @param CurentID 1-255
* @param NewID 1-255
*
* If a servo ID is not know, the broadcast address of 0 can be used for CurrentID.
* In this situation, only one servo should be connected to the bus
*/
int SetID(int CurrentID, int NewID);
/** Poll to see if the servo is moving
*
* @returns true is the servo is moving
*/
int isMoving(void);
/** Send the broadcast "trigger" command, to activate any outstanding registered commands
*/
void trigger(void);
/** Read the current angle of the servo
*
* @returns float in the range 0.0-300.0
*/
float GetPosition();
/** Read the temperature of the servo
*
* @returns float temperature
*/
float GetTemp(void);
/** Read the supply voltage of the servo
*
* @returns float voltage
*/
float GetVolts(void);
int read(int ID, int start, int length, char* data);
int write(int ID, int start, int length, char* data, int flag=0);
private :
SerialHalfDuplex _ax12;
int _ID;
int _baud;
};
#endif

View file

@ -0,0 +1,193 @@
#include "MMA7660.h"
MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
{
setActive(active);
samplerate = 64;
}
//Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
bool MMA7660::testConnection( void )
{
if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
return true;
else
return false;
}
void MMA7660::setActive(bool state)
{
char modereg = read(MMA7660_MODE_R);
modereg &= ~(1<<0);
//If it somehow was in testmode, disable that
if (modereg && (1<<2)) {
modereg &= ~(1<<2);
write(MMA7660_MODE_R, modereg);
}
modereg += state;
write(MMA7660_MODE_R, modereg);
}
void MMA7660::readData(int *data)
{
if (!active) {
setActive(true);
active = true;
wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
}
char temp[3];
bool alert;
do {
alert = false;
read(MMA7660_XOUT_R, temp, 3);
for (int i = 0; i<3; i++) {
if (temp[i] > 63)
alert = true;
if (temp[i] > 31)
temp[i] += 128+64;
data[i] = (signed char)temp[i];
}
} while (alert);
if (!active)
setActive(false);
}
void MMA7660::readData(float *data)
{
int intdata[3];
readData(intdata);
for (int i = 0; i<3; i++)
data[i] = intdata[i]/MMA7660_SENSITIVITY;
}
float MMA7660::x( void )
{
return getSingle(0);
}
float MMA7660::y( void )
{
return getSingle(1);
}
float MMA7660::z( void )
{
return getSingle(2);
}
void MMA7660::setSampleRate(int samplerate)
{
setActive(false); //Not allowed to be active to change anything
int rates[] = {120, 64, 32, 16, 8, 4, 2, 1}; //Alowed samplerates (and their number in array is also number required for MMA)
int sampleLoc = 0, sampleError = 10000, temp;
for (int i = 0; i<8; i++) {
temp = abs( rates[i] - samplerate );
if (temp<sampleError) {
sampleLoc = i;
sampleError=temp;
}
}
//Update the samplerate reg
temp = read(MMA7660_SR_R);
temp &= ~0x07; //Awake sample rate are lowest 3 bit
temp |= sampleLoc;
write(MMA7660_SR_R, temp);
this->samplerate = rates[sampleLoc];
setActive(active); //Restore previous active state
}
MMA7660::Orientation MMA7660::getSide( void )
{
char tiltreg = read(MMA7660_TILT_R);
//We care about 2 LSBs
tiltreg &= 0x03;
if (tiltreg == 0x01)
return MMA7660::Front;
if (tiltreg == 0x02)
return MMA7660::Back;
return MMA7660::Unknown;
}
MMA7660::Orientation MMA7660::getOrientation( void )
{
char tiltreg = read(MMA7660_TILT_R);
//We care about bit 2, 3 and 4 (counting from zero)
tiltreg &= 0x07<<2;
tiltreg >>= 2;
if (tiltreg == 0x01)
return MMA7660::Left;
if (tiltreg == 0x02)
return MMA7660::Right;
if (tiltreg == 0x05)
return MMA7660::Down;
if (tiltreg == 0x06)
return MMA7660::Up;
return MMA7660::Unknown;
}
//////////////////////////////////////////////
///////////////PRIVATE////////////////////////
//////////////////////////////////////////////
void MMA7660::write(char address, char data)
{
char temp[2];
temp[0]=address;
temp[1]=data;
_i2c.write(MMA7660_ADDRESS, temp, 2);
}
char MMA7660::read(char address)
{
char retval;
_i2c.write(MMA7660_ADDRESS, &address, 1, true);
_i2c.read(MMA7660_ADDRESS, &retval, 1);
return retval;
}
void MMA7660::read(char address, char *data, int length)
{
_i2c.write(MMA7660_ADDRESS, &address, 1, true);
_i2c.read(MMA7660_ADDRESS, data, length);
}
float MMA7660::getSingle( int number )
{
if (!active) {
setActive(true);
wait(0.012 + 1/samplerate); //Wait until new sample is ready
}
signed char temp;
bool alert;
do {
alert = false;
temp = read(MMA7660_XOUT_R + number);
if (temp > 63)
alert = true;
if (temp > 31)
temp += 128+64;
} while (alert);
if (!active)
setActive(false);
return temp / MMA7660_SENSITIVITY;
}

View file

@ -0,0 +1,207 @@
/* Copyright (c) <year> <copyright holders>, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "mbed.h"
#ifndef MMA7660_H
#define MMA7660_H
#define MMA7660_ADDRESS 0x98
#define MMA7660_SENSITIVITY 21.33
#define MMA7660_XOUT_R 0x00
#define MMA7660_YOUT_R 0x01
#define MMA7660_ZOUT_R 0x02
#define MMA7660_TILT_R 0x03
#define MMA7660_INT_R 0x06
#define MMA7660_MODE_R 0x07
#define MMA7660_SR_R 0x08
/** An interface for the MMA7660 triple axis accelerometer
*
* @code
* //Uses the measured z-acceleration to drive leds 2 and 3 of the mbed
*
* #include "mbed.h"
* #include "MMA7660.h"
*
* MMA7660 MMA(p28, p27);
*
* DigitalOut connectionLed(LED1);
* PwmOut Zaxis_p(LED2);
* PwmOut Zaxis_n(LED3);
*
* int main() {
* if (MMA.testConnection())
* connectionLed = 1;
*
* while(1) {
* Zaxis_p = MMA.z();
* Zaxis_n = -MMA.z();
* }
*
* }
* @endcode
*/
class MMA7660
{
public:
/**
* The 6 different orientations and unknown
*
* Up & Down = X-axis
* Right & Left = Y-axis
* Back & Front = Z-axis
*
*/
enum Orientation {Up, Down,
Right, Left,
Back, Front,
Unknown
};
/**
* Creates a new MMA7660 object
*
* @param sda - I2C data pin
* @param scl - I2C clock pin
* @param active - true (default) to enable the device, false to keep it standby
*/
MMA7660(PinName sda, PinName scl, bool active = true);
/**
* Tests if communication is possible with the MMA7660
*
* Because the MMA7660 lacks a WHO_AM_I register, this function can only check
* if there is an I2C device that responds to the MMA7660 address
*
* @param return - true for successfull connection, false for no connection
*/
bool testConnection( void );
/**
* Sets the active state of the MMA7660
*
* Note: This is unrelated to awake/sleep mode
*
* @param state - true for active, false for standby
*/
void setActive( bool state);
/**
* Reads acceleration data from the sensor
*
* When the parameter is a pointer to an integer array it will be the raw data.
* When it is a pointer to a float array it will be the acceleration in g's
*
* @param data - pointer to array with length 3 where the acceleration data will be stored, X-Y-Z
*/
void readData( int *data);
void readData( float *data);
/**
* Get X-data
*
* @param return - X-acceleration in g's
*/
float x( void );
/**
* Get Y-data
*
* @param return - Y-acceleration in g's
*/
float y( void );
/**
* Get Z-data
*
* @param return - Z-acceleration in g's
*/
float z( void );
/**
* Sets the active samplerate
*
* The entered samplerate will be rounded to nearest supported samplerate.
* Supported samplerates are: 120 - 64 - 32 - 16 - 8 - 4 - 2 - 1 samples/second.
*
* @param samplerate - the samplerate that will be set
*/
void setSampleRate(int samplerate);
/**
* Returns if it is on its front, back, or unknown side
*
* This is read from MMA7760s registers, page 12 of datasheet
*
* @param return - Front, Back or Unknown orientation
*/
Orientation getSide( void );
/**
* Returns if it is on it left, right, down or up side
*
* This is read from MMA7760s registers, page 12 of datasheet
*
* @param return - Left, Right, Down, Up or Unknown orientation
*/
Orientation getOrientation ( void );
private:
/**
* Writes data to the device
*
* @param adress - register address to write to
* @param data - data to write
*/
void write( char address, char data);
/**
* Read data from the device
*
* @param adress - register address to write to
* @return - data from the register specified by RA
*/
char read( char adress);
/**
* Read multiple regigsters from the device, more efficient than using multiple normal reads.
*
* @param adress - register address to write to
* @param length - number of bytes to read
* @param data - pointer where the data needs to be written to
*/
void read( char adress, char *data, int length);
/**
* Reads single axis
*/
float getSingle(int number);
I2C _i2c;
bool active;
float samplerate;
};
#endif

View file

@ -0,0 +1,81 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "MMA8451Q.h"
#define REG_WHO_AM_I 0x0D
#define REG_CTRL_REG_1 0x2A
#define REG_OUT_X_MSB 0x01
#define REG_OUT_Y_MSB 0x03
#define REG_OUT_Z_MSB 0x05
#define UINT14_MAX 16383
MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
// activate the peripheral
uint8_t data[2] = {REG_CTRL_REG_1, 0x01};
writeRegs(data, 2);
}
MMA8451Q::~MMA8451Q() { }
uint8_t MMA8451Q::getWhoAmI() {
uint8_t who_am_i = 0;
readRegs(REG_WHO_AM_I, &who_am_i, 1);
return who_am_i;
}
int16_t MMA8451Q::getAccX() {
return getAccAxis(REG_OUT_X_MSB);
}
int16_t MMA8451Q::getAccY() {
return getAccAxis(REG_OUT_Y_MSB);
}
int16_t MMA8451Q::getAccZ() {
return getAccAxis(REG_OUT_Z_MSB);
}
void MMA8451Q::getAccAllAxis(int16_t * res) {
res[0] = getAccX();
res[1] = getAccY();
res[2] = getAccZ();
}
int16_t MMA8451Q::getAccAxis(uint8_t addr) {
int16_t acc;
uint8_t res[2];
readRegs(addr, res, 2);
acc = (res[0] << 6) | (res[1] >> 2);
if (acc > UINT14_MAX/2)
acc -= UINT14_MAX;
return acc;
}
void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
char t[1] = {addr};
m_i2c.write(m_addr, t, 1, true);
m_i2c.read(m_addr, (char *)data, len);
}
void MMA8451Q::writeRegs(uint8_t * data, int len) {
m_i2c.write(m_addr, (char *)data, len);
}

View file

@ -0,0 +1,108 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef MMA8451Q_H
#define MMA8451Q_H
#include "mbed.h"
/**
* MMA8451Q accelerometer example
* #include "mbed.h"
* #include "MMA8451Q.h"
*
* #define MMA8451_I2C_ADDRESS (0x1d<<1)
*
* int main(void) {
* DigitalOut led(LED_GREEN);
* MMA8451Q acc(P_E25, P_E24, MMA8451_I2C_ADDRESS);
* printf("WHO AM I: 0x%2X\r\n", acc.getWhoAmI());
*
* while (true) {
* printf("-----------\r\n");
* printf("acc_x: %d\r\n", acc.getAccX());
* printf("acc_y: %d\r\n", acc.getAccY());
* printf("acc_z: %d\r\n", acc.getAccZ());
*
* wait(1);
* led = !led;
* }
* }
*/
class MMA8451Q
{
public:
/**
* MMA8451Q constructor
*
* @param sda SDA pin
* @param sdl SCL pin
* @param addr addr of the I2C peripheral
*/
MMA8451Q(PinName sda, PinName scl, int addr);
/**
* MMA8451Q destructor
*/
~MMA8451Q();
/**
* Get the value of the WHO_AM_I register
*
* @returns WHO_AM_I value
*/
uint8_t getWhoAmI();
/**
* Get X axis acceleration
*
* @returns X axis acceleration
*/
int16_t getAccX();
/**
* Get Y axis acceleration
*
* @returns Y axis acceleration
*/
int16_t getAccY();
/**
* Get Z axis acceleration
*
* @returns Z axis acceleration
*/
int16_t getAccZ();
/**
* Get XYZ axis acceleration
*
* @param res array where acceleration data will be stored
*/
void getAccAllAxis(int16_t * res);
private:
I2C m_i2c;
int m_addr;
void readRegs(int addr, uint8_t * data, int len);
void writeRegs(uint8_t * data, int len);
int16_t getAccAxis(uint8_t addr);
};
#endif

View file

@ -0,0 +1,67 @@
/*
Copyright (c) 2010 Chris Styles ( chris dot styles at mbed dot org )
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "SRF08.h"
SRF08::SRF08(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
char cmd[2];
// Set up SRF08 max range and receiver sensitivity over I2C bus
cmd[0] = 0x02; // Range register
cmd[1] = 0x1C; // Set max range about 100cm
m_i2c.write(m_addr, cmd, 2);
cmd[0] = 0x01; // Receiver gain register
cmd[1] = 0x1B; // Set max receiver gain
m_i2c.write(m_addr, cmd, 2);
}
SRF08::~SRF08() {
}
float SRF08::read() {
char cmd[2];
char echo[2];
// Get range data from SRF08
// Send Tx burst command over I2C bus
cmd[0] = 0x00; // Command register
cmd[1] = 0x51; // Ranging results in cm
m_i2c.write(m_addr, cmd, 2); // Send ranging burst
wait(0.07); // Wait for return echo
// Read back range over I2C bus
cmd[0] = 0x02; // Address of first echo
m_i2c.write(m_addr, cmd, 1, 1); // Send address of first echo
m_i2c.read(m_addr, echo, 2); // Read two-byte echo result
// Generate PWM mark/space ratio from range data
float range = (echo[0]<<8)+echo[1];
return range;
}

View file

@ -0,0 +1,60 @@
/*
Copyright (c) 2010 Chris Styles (chris dot styles at mbed dot org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef SRF08_H
#define SRF08_H
#include "mbed.h"
//!Library for the SRF08 Ultrasonic Ranger
/*!
The SRF08 is an Ultrasonic range finder, with an I2C interface that allows the measurement to be read directly in centimetres
*/
class SRF08
{
public:
//!Creates an instance of the class.
/*!
Connect module at I2C address addr using I2C port pins sda and scl.
SRF08
*/
SRF08(PinName sda, PinName scl, int addr);
/*!
Destroys instance.
*/
~SRF08();
//!Reads the current temperature.
/*!
Reads the temperature register of the TMP102 and converts it to a useable value.
*/
float read();
private:
I2C m_i2c;
int m_addr;
};
#endif

View file

@ -0,0 +1,23 @@
#include "TMP102.h"
#define TEMP_REG_ADDR 0x00
TMP102::TMP102(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
m_i2c.frequency(400000);
}
TMP102::~TMP102() { }
float TMP102::read() {
const char tempRegAddr = TEMP_REG_ADDR;
m_i2c.write(m_addr, &tempRegAddr, 1);
char reg[2] = {0,0};
m_i2c.read(m_addr, reg, 2);
unsigned short res = (reg[0] << 4) | (reg[1] >> 4);
float temp = (float) ((float)res * 0.0625);
return temp;
}

View file

@ -0,0 +1,39 @@
#ifndef TMP102_H
#define TMP102_H
#include "mbed.h"
//!Library for the TI TMP102 temperature sensor.
/*!
The TMP102 is an I2C digital temperature sensor in a small SOT563 package, with a 0.0625C resolution and 0.5C accuracy.
*/
class TMP102
{
public:
//!Creates an instance of the class.
/*!
Connect module at I2C address addr using I2C port pins sda and scl.
TMP102
\param addr <table><tr><th>A0 pin connection</th><th>Address</th></tr><tr><td>GND</td><td>0x90</td></tr><tr><td>V+</td><td>0x92</td></tr><tr><td>SDA</td><td>0x94</td></tr><tr><td>SCL</td><td>0x96</td></tr></table>
*/
TMP102(PinName sda, PinName scl, int addr);
/*!
Destroys instance.
*/
~TMP102();
//!Reads the current temperature.
/*!
Reads the temperature register of the TMP102 and converts it to a useable value.
*/
float read();
I2C m_i2c;
private:
int m_addr;
};
#endif

View file

@ -0,0 +1,231 @@
/* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
*
* mbed Microcontroller Library
* (c) Copyright 2009-2012 ARM Limited.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "mbed.h"
#include "TSISensor.h"
#define NO_TOUCH 0
#define SLIDER_LENGTH 40 //LENGTH in mm
#define TOTAL_ELECTRODE 2
#define TSI0a 0
#define TSI1 1
#define TSI2 2
#define TSI3 3
#define TSI4 4
#define TSI5 5
#define TSI6 6
#define TSI7 7
#define TSI8 8
#define TSI9 9
#define TSI10 10
#define TSI11 11
#define TSI12 12
#define TSI13 13
#define TSI14 14
#define TSI15 15
/*Chose the correct TSI channel for the electrode number*/
#define ELECTRODE0 TSI9
#define ELECTRODE1 TSI10
#define ELECTRODE2 TSI0a
#define ELECTRODE3 TSI1
#define ELECTRODE4 TSI2
#define ELECTRODE5 TSI3
#define ELECTRODE6 TSI4
#define ELECTRODE7 TSI5
#define ELECTRODE8 TSI6
#define ELECTRODE9 TSI7
#define ELECTRODE10 TSI8
#define ELECTRODE11 TSI11
#define ELECTRODE12 TSI12
#define ELECTRODE13 TSI13
#define ELECTRODE14 TSI14
#define ELECTRODE15 TSI15
#define THRESHOLD0 100
#define THRESHOLD1 100
#define THRESHOLD2 100
#define THRESHOLD3 100
#define THRESHOLD4 100
#define THRESHOLD5 100
#define THRESHOLD6 100
#define THRESHOLD7 100
#define THRESHOLD8 100
#define THRESHOLD9 100
#define THRESHOLD10 100
#define THRESHOLD11 100
#define THRESHOLD12 100
#define THRESHOLD13 100
#define THRESHOLD14 100
#define THRESHOLD15 100
static uint8_t total_electrode = TOTAL_ELECTRODE;
static uint8_t elec_array[16]={ELECTRODE0,ELECTRODE1,ELECTRODE2,ELECTRODE3,ELECTRODE4,ELECTRODE5,
ELECTRODE6,ELECTRODE7,ELECTRODE8,ELECTRODE9,ELECTRODE10,ELECTRODE11,
ELECTRODE12,ELECTRODE13,ELECTRODE14,ELECTRODE15};
static uint16_t gu16TSICount[16];
static uint16_t gu16Baseline[16];
static uint16_t gu16Threshold[16]={THRESHOLD0,THRESHOLD1,THRESHOLD2,THRESHOLD3,THRESHOLD4,THRESHOLD5,
THRESHOLD6,THRESHOLD7,THRESHOLD8,THRESHOLD9,THRESHOLD10,THRESHOLD11,
THRESHOLD12,THRESHOLD13,THRESHOLD14,THRESHOLD15};
static uint16_t gu16Delta[16];
static uint8_t ongoing_elec;
static uint8_t end_flag = 1;
static uint8_t SliderPercentegePosition[2] = {NO_TOUCH,NO_TOUCH};
static uint8_t SliderDistancePosition[2] = {NO_TOUCH,NO_TOUCH};
static uint32_t AbsolutePercentegePosition = NO_TOUCH;
static uint32_t AbsoluteDistancePosition = NO_TOUCH;
static void tsi_irq();
TSISensor::TSISensor() {
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
TSI0->GENCS |= (TSI_GENCS_ESOR_MASK
| TSI_GENCS_MODE(0)
| TSI_GENCS_REFCHRG(4)
| TSI_GENCS_DVOLT(0)
| TSI_GENCS_EXTCHRG(7)
| TSI_GENCS_PS(4)
| TSI_GENCS_NSCN(11)
| TSI_GENCS_TSIIEN_MASK
| TSI_GENCS_STPE_MASK
);
TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
NVIC_EnableIRQ(TSI0_IRQn);
selfCalibration();
}
void TSISensor::selfCalibration(void)
{
unsigned char cnt;
unsigned char trigger_backup;
TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK; // Disable TSI module
if(TSI0->GENCS & TSI_GENCS_STM_MASK) // Back-up TSI Trigger mode from Application
trigger_backup = 1;
else
trigger_backup = 0;
TSI0->GENCS &= ~TSI_GENCS_STM_MASK; // Use SW trigger
TSI0->GENCS &= ~TSI_GENCS_TSIIEN_MASK; // Enable TSI interrupts
TSI0->GENCS |= TSI_GENCS_TSIEN_MASK; // Enable TSI module
for(cnt=0; cnt < total_electrode; cnt++) // Get Counts when Electrode not pressed
{
TSI0->DATA = ((elec_array[cnt] << TSI_DATA_TSICH_SHIFT) );
TSI0->DATA |= TSI_DATA_SWTS_MASK;
while(!(TSI0->GENCS & TSI_GENCS_EOSF_MASK));
TSI0->GENCS |= TSI_GENCS_EOSF_MASK;
gu16Baseline[cnt] = (TSI0->DATA & TSI_DATA_TSICNT_MASK);
}
TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK; // Disable TSI module
TSI0->GENCS |= TSI_GENCS_TSIIEN_MASK; // Enale TSI interrupt
if(trigger_backup) // Restore trigger mode
TSI0->GENCS |= TSI_GENCS_STM_MASK;
else
TSI0->GENCS &= ~TSI_GENCS_STM_MASK;
TSI0->GENCS |= TSI_GENCS_TSIEN_MASK; // Enable TSI module
TSI0->DATA = ((elec_array[0]<<TSI_DATA_TSICH_SHIFT) );
TSI0->DATA |= TSI_DATA_SWTS_MASK;
}
void TSISensor::sliderRead(void ) {
if(end_flag) {
end_flag = 0;
if((gu16Delta[0] > gu16Threshold[0])||(gu16Delta[1] > gu16Threshold[1])) {
SliderPercentegePosition[0] = (gu16Delta[0]*100)/(gu16Delta[0]+gu16Delta[1]);
SliderPercentegePosition[1] = (gu16Delta[1]*100)/(gu16Delta[0]+gu16Delta[1]);
SliderDistancePosition[0] = (SliderPercentegePosition[0]* SLIDER_LENGTH)/100;
SliderDistancePosition[1] = (SliderPercentegePosition[1]* SLIDER_LENGTH)/100;
AbsolutePercentegePosition = ((100 - SliderPercentegePosition[0]) + SliderPercentegePosition[1])/2;
AbsoluteDistancePosition = ((SLIDER_LENGTH - SliderDistancePosition[0]) + SliderDistancePosition[1])/2;
} else {
SliderPercentegePosition[0] = NO_TOUCH;
SliderPercentegePosition[1] = NO_TOUCH;
SliderDistancePosition[0] = NO_TOUCH;
SliderDistancePosition[1] = NO_TOUCH;
AbsolutePercentegePosition = NO_TOUCH;
AbsoluteDistancePosition = NO_TOUCH;
}
}
}
float TSISensor::readPercentage() {
sliderRead();
return (float)AbsolutePercentegePosition/100.0;
}
uint8_t TSISensor::readDistance() {
sliderRead();
return AbsoluteDistancePosition;
}
static void changeElectrode(void)
{
int16_t u16temp_delta;
gu16TSICount[ongoing_elec] = (TSI0->DATA & TSI_DATA_TSICNT_MASK); // Save Counts for current electrode
u16temp_delta = gu16TSICount[ongoing_elec] - gu16Baseline[ongoing_elec]; // Obtains Counts Delta from callibration reference
if(u16temp_delta < 0)
gu16Delta[ongoing_elec] = 0;
else
gu16Delta[ongoing_elec] = u16temp_delta;
//Change Electrode to Scan
if(total_electrode > 1)
{
if((total_electrode-1) > ongoing_elec)
ongoing_elec++;
else
ongoing_elec = 0;
TSI0->DATA = ((elec_array[ongoing_elec]<<TSI_DATA_TSICH_SHIFT) );
TSI0->DATA |= TSI_DATA_SWTS_MASK;
}
}
void tsi_irq(void)
{
end_flag = 1;
TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
changeElectrode();
}

View file

@ -0,0 +1,73 @@
/* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
*
* mbed Microcontroller Library
* (c) Copyright 2009-2012 ARM Limited.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TSISENSOR_H
#define TSISENSOR_H
/**
* TSISensor example
*
* @code
* #include "mbed.h"
* #include "TSISensor.h"
*
* int main(void) {
* DigitalOut led(LED_GREEN);
* TSISensor tsi;
*
* while (true) {
* printf("slider percentage: %f%\r\n", tsi.readPercentage());
* printf("slider distance: %dmm\r\n", tsi.readDistance());
* wait(1);
* led = !led;
* }
* }
* @endcode
*/
class TSISensor {
public:
/**
* Initialize the TSI Touch Sensor
*/
TSISensor();
/**
* Read Touch Sensor percentage value
*
* @returns percentage value between [0 ... 1]
*/
float readPercentage();
/**
* Read Touch Sensor distance
*
* @returns distance in mm. The value is between [0 ... 40]
*/
uint8_t readDistance();
private:
void sliderRead(void);
void selfCalibration(void);
};
#endif