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:
parent
a20ef7052c
commit
1fe4406f37
4198 changed files with 2016457 additions and 0 deletions
|
@ -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;
|
||||
|
||||
}
|
537
tool/mbed/mbed-sdk/libraries/tests/peripherals/ADXL345/ADXL345.h
Normal file
537
tool/mbed/mbed-sdk/libraries/tests/peripherals/ADXL345/ADXL345.h
Normal 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 */
|
534
tool/mbed/mbed-sdk/libraries/tests/peripherals/AX12/AX12.cpp
Normal file
534
tool/mbed/mbed-sdk/libraries/tests/peripherals/AX12/AX12.cpp
Normal 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
|
||||
}
|
190
tool/mbed/mbed-sdk/libraries/tests/peripherals/AX12/AX12.h
Normal file
190
tool/mbed/mbed-sdk/libraries/tests/peripherals/AX12/AX12.h
Normal 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
|
|
@ -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;
|
||||
}
|
207
tool/mbed/mbed-sdk/libraries/tests/peripherals/MMA7660/MMA7660.h
Normal file
207
tool/mbed/mbed-sdk/libraries/tests/peripherals/MMA7660/MMA7660.h
Normal 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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
60
tool/mbed/mbed-sdk/libraries/tests/peripherals/SRF08/SRF08.h
Normal file
60
tool/mbed/mbed-sdk/libraries/tests/peripherals/SRF08/SRF08.h
Normal 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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
231
tool/mbed/mbed-sdk/libraries/tests/peripherals/TSI/TSISensor.cpp
Normal file
231
tool/mbed/mbed-sdk/libraries/tests/peripherals/TSI/TSISensor.cpp
Normal 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();
|
||||
}
|
||||
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue