mirror of
https://github.com/KevinMidboe/Arduino.git
synced 2025-10-29 17:40:11 +00:00
Init commit with many years of arduino sketches and projects. I dont know if the esp8266 includes much, but there are also libraries. I hope they dont have crazy automatic versioning through the Arduino IDE.
This commit is contained in:
2
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/.gitignore
vendored
Executable file
2
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/.gitignore
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
release.sh
|
||||
463
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Adafruit_BLE_Firmata.cpp
Executable file
463
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Adafruit_BLE_Firmata.cpp
Executable file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
Firmata.cpp - Firmata library
|
||||
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
|
||||
|
||||
Modified for Adafruit_BLE_Uart by Limor Fried/Kevin Townsend for
|
||||
Adafruit Industries, 2014
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Includes
|
||||
//******************************************************************************
|
||||
|
||||
#include "Adafruit_BLE_Firmata.h"
|
||||
|
||||
extern "C" {
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
//* Support Functions
|
||||
//******************************************************************************
|
||||
|
||||
void Adafruit_BLE_FirmataClass::sendValueAsTwo7bitBytes(int value)
|
||||
{
|
||||
FirmataSerial.write(value & B01111111); // LSB
|
||||
FirmataSerial.write(value >> 7 & B01111111); // MSB
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::startSysex(void)
|
||||
{
|
||||
FirmataSerial.write(START_SYSEX);
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::endSysex(void)
|
||||
{
|
||||
FirmataSerial.write(END_SYSEX);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
//* Constructors
|
||||
//******************************************************************************
|
||||
|
||||
Adafruit_BLE_FirmataClass::Adafruit_BLE_FirmataClass(Adafruit_BLE_UART &s) : FirmataSerial(s)
|
||||
{
|
||||
firmwareVersionCount = 0;
|
||||
systemReset();
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
//* Public Methods
|
||||
//******************************************************************************
|
||||
|
||||
/* begin method for overriding default serial bitrate */
|
||||
void Adafruit_BLE_FirmataClass::begin(void)
|
||||
{
|
||||
blinkVersion();
|
||||
printVersion();
|
||||
printFirmwareVersion();
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::begin(Adafruit_BLE_UART &s)
|
||||
{
|
||||
FirmataSerial = s;
|
||||
systemReset();
|
||||
printVersion();
|
||||
printFirmwareVersion();
|
||||
}
|
||||
|
||||
// output the protocol version message to the serial port
|
||||
void Adafruit_BLE_FirmataClass::printVersion(void) {
|
||||
FirmataSerial.write(REPORT_VERSION);
|
||||
FirmataSerial.write(FIRMATA_MAJOR_VERSION);
|
||||
FirmataSerial.write(FIRMATA_MINOR_VERSION);
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::blinkVersion(void)
|
||||
{
|
||||
// flash the pin with the protocol version
|
||||
pinMode(VERSION_BLINK_PIN,OUTPUT);
|
||||
pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
|
||||
delay(250);
|
||||
pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
|
||||
delay(125);
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::printFirmwareVersion(void)
|
||||
{
|
||||
byte i;
|
||||
|
||||
if(firmwareVersionCount) { // make sure that the name has been set before reporting
|
||||
startSysex();
|
||||
FirmataSerial.write(REPORT_FIRMWARE);
|
||||
FirmataSerial.write(firmwareVersionVector[0]); // major version number
|
||||
FirmataSerial.write(firmwareVersionVector[1]); // minor version number
|
||||
for(i=2; i<firmwareVersionCount; ++i) {
|
||||
sendValueAsTwo7bitBytes(firmwareVersionVector[i]);
|
||||
}
|
||||
endSysex();
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::setFirmwareNameAndVersion(const char *name, byte major, byte minor)
|
||||
{
|
||||
const char *filename;
|
||||
char *extension;
|
||||
|
||||
// parse out ".cpp" and "applet/" that comes from using __FILE__
|
||||
extension = strstr(name, ".cpp");
|
||||
filename = strrchr(name, '/') + 1; //points to slash, +1 gets to start of filename
|
||||
// add two bytes for version numbers
|
||||
if(extension && filename) {
|
||||
firmwareVersionCount = extension - filename + 2;
|
||||
} else {
|
||||
firmwareVersionCount = strlen(name) + 2;
|
||||
filename = name;
|
||||
}
|
||||
firmwareVersionVector = (byte *) malloc(firmwareVersionCount);
|
||||
firmwareVersionVector[firmwareVersionCount] = 0;
|
||||
firmwareVersionVector[0] = major;
|
||||
firmwareVersionVector[1] = minor;
|
||||
strncpy((char*)firmwareVersionVector + 2, filename, firmwareVersionCount - 2);
|
||||
// alas, no snprintf on Arduino
|
||||
// snprintf(firmwareVersionVector, MAX_DATA_BYTES, "%c%c%s",
|
||||
// (char)major, (char)minor, firmwareVersionVector);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Serial Receive Handling
|
||||
|
||||
int Adafruit_BLE_FirmataClass::available(void)
|
||||
{
|
||||
return FirmataSerial.available();
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_BLE_FirmataClass::processSysexMessage(void)
|
||||
{
|
||||
switch(storedInputData[0]) { //first byte in buffer is command
|
||||
case REPORT_FIRMWARE:
|
||||
printFirmwareVersion();
|
||||
break;
|
||||
case STRING_DATA:
|
||||
if(currentStringCallback) {
|
||||
byte bufferLength = (sysexBytesRead - 1) / 2;
|
||||
char *buffer = (char*)malloc(bufferLength * sizeof(char));
|
||||
byte i = 1;
|
||||
byte j = 0;
|
||||
while(j < bufferLength) {
|
||||
buffer[j] = (char)storedInputData[i];
|
||||
i++;
|
||||
buffer[j] += (char)(storedInputData[i] << 7);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
(*currentStringCallback)(buffer);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(currentSysexCallback)
|
||||
(*currentSysexCallback)(storedInputData[0], sysexBytesRead - 1, storedInputData + 1);
|
||||
}
|
||||
}
|
||||
|
||||
int Adafruit_BLE_FirmataClass::processInput(void)
|
||||
{
|
||||
int inputData = FirmataSerial.read(); // this is 'int' to handle -1 when no data
|
||||
int command;
|
||||
|
||||
if (inputData == -1) return -1;
|
||||
|
||||
if (parsingSysex) {
|
||||
if(inputData == END_SYSEX) {
|
||||
//stop sysex byte
|
||||
parsingSysex = false;
|
||||
//fire off handler function
|
||||
processSysexMessage();
|
||||
} else {
|
||||
//normal data byte - add to buffer
|
||||
storedInputData[sysexBytesRead] = inputData;
|
||||
sysexBytesRead++;
|
||||
}
|
||||
} else if( (waitForData > 0) && (inputData < 128) ) {
|
||||
waitForData--;
|
||||
storedInputData[waitForData] = inputData;
|
||||
#ifdef BLE_DEBUG
|
||||
Serial.print(F(" 0x")); Serial.print(inputData, HEX);
|
||||
#endif
|
||||
|
||||
if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
|
||||
|
||||
#ifdef BLE_DEBUG
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
|
||||
switch(executeMultiByteCommand) {
|
||||
case ANALOG_MESSAGE:
|
||||
if(currentAnalogCallback) {
|
||||
(*currentAnalogCallback)(multiByteChannel,
|
||||
(storedInputData[0] << 7)
|
||||
+ storedInputData[1]);
|
||||
}
|
||||
break;
|
||||
case DIGITAL_MESSAGE:
|
||||
if(currentDigitalCallback) {
|
||||
(*currentDigitalCallback)(multiByteChannel,
|
||||
(storedInputData[0] << 7)
|
||||
+ storedInputData[1]);
|
||||
}
|
||||
break;
|
||||
case SET_PIN_MODE:
|
||||
if(currentPinModeCallback)
|
||||
(*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
|
||||
break;
|
||||
case REPORT_ANALOG:
|
||||
if(currentReportAnalogCallback)
|
||||
(*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
|
||||
break;
|
||||
case REPORT_DIGITAL:
|
||||
if(currentReportDigitalCallback)
|
||||
(*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
|
||||
break;
|
||||
}
|
||||
executeMultiByteCommand = 0;
|
||||
}
|
||||
} else {
|
||||
#ifdef BLE_DEBUG
|
||||
Serial.print(F("\tReceived 0x")); Serial.print(inputData, HEX);
|
||||
#endif
|
||||
// remove channel info from command byte if less than 0xF0
|
||||
if(inputData < 0xF0) {
|
||||
command = inputData & 0xF0;
|
||||
multiByteChannel = inputData & 0x0F;
|
||||
} else {
|
||||
command = inputData;
|
||||
// commands in the 0xF* range don't use channel data
|
||||
}
|
||||
switch (command) {
|
||||
case ANALOG_MESSAGE:
|
||||
case DIGITAL_MESSAGE:
|
||||
case SET_PIN_MODE:
|
||||
waitForData = 2; // two data bytes needed
|
||||
executeMultiByteCommand = command;
|
||||
break;
|
||||
case REPORT_ANALOG:
|
||||
case REPORT_DIGITAL:
|
||||
waitForData = 1; // two data bytes needed
|
||||
executeMultiByteCommand = command;
|
||||
break;
|
||||
case START_SYSEX:
|
||||
parsingSysex = true;
|
||||
sysexBytesRead = 0;
|
||||
break;
|
||||
case SYSTEM_RESET:
|
||||
systemReset();
|
||||
break;
|
||||
case REPORT_VERSION:
|
||||
printVersion();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return inputData;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Serial Send Handling
|
||||
|
||||
// send an analog message
|
||||
void Adafruit_BLE_FirmataClass::sendAnalog(byte pin, int value)
|
||||
{
|
||||
// create a three byte buffer
|
||||
uint8_t sendbuffer[3];
|
||||
|
||||
// pin can only be 0-15, so chop higher bits
|
||||
//FirmataSerial.write(ANALOG_MESSAGE | (pin & 0xF));
|
||||
sendbuffer[0] = ANALOG_MESSAGE | (pin & 0xF);
|
||||
|
||||
//sendValueAsTwo7bitBytes(value);
|
||||
sendbuffer[1] = value % 128; // Tx bits 0-6
|
||||
sendbuffer[2] = (value >> 7) &0x7F; // Tx bits 7-13
|
||||
|
||||
FirmataSerial.write(sendbuffer, 3);
|
||||
}
|
||||
|
||||
// send a single digital pin in a digital message
|
||||
void Adafruit_BLE_FirmataClass::sendDigital(byte pin, int value)
|
||||
{
|
||||
/* TODO add single pin digital messages to the protocol, this needs to
|
||||
* track the last digital data sent so that it can be sure to change just
|
||||
* one bit in the packet. This is complicated by the fact that the
|
||||
* numbering of the pins will probably differ on Arduino, Wiring, and
|
||||
* other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
|
||||
* probably easier to send 8 bit ports for any board with more than 14
|
||||
* digital pins.
|
||||
*/
|
||||
|
||||
// TODO: the digital message should not be sent on the serial port every
|
||||
// time sendDigital() is called. Instead, it should add it to an int
|
||||
// which will be sent on a schedule. If a pin changes more than once
|
||||
// before the digital message is sent on the serial port, it should send a
|
||||
// digital message for each change.
|
||||
|
||||
// if(value == 0)
|
||||
// sendDigitalPortPair();
|
||||
}
|
||||
|
||||
|
||||
// send 14-bits in a single digital message (protocol v1)
|
||||
// send an 8-bit port in a single digital message (protocol v2)
|
||||
void Adafruit_BLE_FirmataClass::sendDigitalPort(byte portNumber, int portData)
|
||||
{
|
||||
// create a three byte buffer
|
||||
uint8_t sendbuffer[3];
|
||||
|
||||
sendbuffer[0] = DIGITAL_MESSAGE | (portNumber & 0xF);
|
||||
sendbuffer[1] = (byte)portData % 128; // Tx bits 0-6
|
||||
sendbuffer[2] = portData >> 7; // Tx bits 7-13
|
||||
FirmataSerial.write(sendbuffer, 3);
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_BLE_FirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
|
||||
{
|
||||
byte i;
|
||||
startSysex();
|
||||
FirmataSerial.write(command);
|
||||
for(i=0; i<bytec; i++) {
|
||||
sendValueAsTwo7bitBytes(bytev[i]);
|
||||
}
|
||||
endSysex();
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::sendString(byte command, const char* string)
|
||||
{
|
||||
sendSysex(command, strlen(string), (byte *)string);
|
||||
}
|
||||
|
||||
|
||||
// send a string as the protocol string type
|
||||
void Adafruit_BLE_FirmataClass::sendString(const char* string)
|
||||
{
|
||||
sendString(STRING_DATA, string);
|
||||
}
|
||||
|
||||
|
||||
// Internal Actions/////////////////////////////////////////////////////////////
|
||||
|
||||
// generic callbacks
|
||||
void Adafruit_BLE_FirmataClass::attach(byte command, callbackFunction newFunction)
|
||||
{
|
||||
switch(command) {
|
||||
case ANALOG_MESSAGE: currentAnalogCallback = newFunction; break;
|
||||
case DIGITAL_MESSAGE: currentDigitalCallback = newFunction; break;
|
||||
case REPORT_ANALOG: currentReportAnalogCallback = newFunction; break;
|
||||
case REPORT_DIGITAL: currentReportDigitalCallback = newFunction; break;
|
||||
case SET_PIN_MODE: currentPinModeCallback = newFunction; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::attach(byte command, systemResetCallbackFunction newFunction)
|
||||
{
|
||||
switch(command) {
|
||||
case SYSTEM_RESET: currentSystemResetCallback = newFunction; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::attach(byte command, stringCallbackFunction newFunction)
|
||||
{
|
||||
switch(command) {
|
||||
case STRING_DATA: currentStringCallback = newFunction; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::attach(byte command, sysexCallbackFunction newFunction)
|
||||
{
|
||||
currentSysexCallback = newFunction;
|
||||
}
|
||||
|
||||
void Adafruit_BLE_FirmataClass::detach(byte command)
|
||||
{
|
||||
switch(command) {
|
||||
case SYSTEM_RESET: currentSystemResetCallback = NULL; break;
|
||||
case STRING_DATA: currentStringCallback = NULL; break;
|
||||
case START_SYSEX: currentSysexCallback = NULL; break;
|
||||
default:
|
||||
attach(command, (callbackFunction)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// sysex callbacks
|
||||
/*
|
||||
* this is too complicated for analogReceive, but maybe for Sysex?
|
||||
void Adafruit_BLE_FirmataClass::attachSysex(sysexFunction newFunction)
|
||||
{
|
||||
byte i;
|
||||
byte tmpCount = analogReceiveFunctionCount;
|
||||
analogReceiveFunction* tmpArray = analogReceiveFunctionArray;
|
||||
analogReceiveFunctionCount++;
|
||||
analogReceiveFunctionArray = (analogReceiveFunction*) calloc(analogReceiveFunctionCount, sizeof(analogReceiveFunction));
|
||||
for(i = 0; i < tmpCount; i++) {
|
||||
analogReceiveFunctionArray[i] = tmpArray[i];
|
||||
}
|
||||
analogReceiveFunctionArray[tmpCount] = newFunction;
|
||||
free(tmpArray);
|
||||
}
|
||||
*/
|
||||
|
||||
//******************************************************************************
|
||||
//* Private Methods
|
||||
//******************************************************************************/
|
||||
|
||||
|
||||
// resets the system state upon a SYSTEM_RESET message from the host software
|
||||
void Adafruit_BLE_FirmataClass::systemReset(void)
|
||||
{
|
||||
byte i;
|
||||
|
||||
waitForData = 0; // this flag says the next serial input will be data
|
||||
executeMultiByteCommand = 0; // execute this after getting multi-byte data
|
||||
multiByteChannel = 0; // channel data for multiByteCommands
|
||||
|
||||
|
||||
for(i=0; i<MAX_DATA_BYTES; i++) {
|
||||
storedInputData[i] = 0;
|
||||
}
|
||||
|
||||
parsingSysex = false;
|
||||
sysexBytesRead = 0;
|
||||
|
||||
if(currentSystemResetCallback)
|
||||
(*currentSystemResetCallback)();
|
||||
|
||||
//flush(); //TODO uncomment when Firmata is a subclass of HardwareSerial
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// used for flashing the pin for the version number
|
||||
void Adafruit_BLE_FirmataClass::pin13strobe(int count, int onInterval, int offInterval)
|
||||
{
|
||||
byte i;
|
||||
pinMode(VERSION_BLINK_PIN, OUTPUT);
|
||||
for(i=0; i<count; i++) {
|
||||
delay(offInterval);
|
||||
digitalWrite(VERSION_BLINK_PIN, HIGH);
|
||||
delay(onInterval);
|
||||
digitalWrite(VERSION_BLINK_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
182
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Adafruit_BLE_Firmata.h
Executable file
182
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Adafruit_BLE_Firmata.h
Executable file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
Firmata.h - Firmata library
|
||||
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
|
||||
|
||||
Modified for Adafruit_BLE_Uart by Limor Fried/Kevin Townsend for
|
||||
Adafruit Industries, 2014
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef Adafruit_BLE_Firmata_h
|
||||
#define Adafruit_BLE_Firmata_h
|
||||
|
||||
#include "Adafruit_BLE_UART.h"
|
||||
#include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
|
||||
|
||||
#define BLE_DEBUG
|
||||
|
||||
// move the following defines to Firmata.h?
|
||||
#define I2C_WRITE B00000000
|
||||
#define I2C_READ B00001000
|
||||
#define I2C_READ_CONTINUOUSLY B00010000
|
||||
#define I2C_STOP_READING B00011000
|
||||
#define I2C_READ_WRITE_MODE_MASK B00011000
|
||||
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
|
||||
|
||||
#define MAX_QUERIES 8
|
||||
#define MINIMUM_SAMPLING_INTERVAL 10
|
||||
|
||||
#define REGISTER_NOT_SPECIFIED -1
|
||||
|
||||
/* Version numbers for the protocol. The protocol is still changing, so these
|
||||
* version numbers are important. This number can be queried so that host
|
||||
* software can test whether it will be compatible with the currently
|
||||
* installed firmware. */
|
||||
#define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
|
||||
#define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
|
||||
#define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
|
||||
|
||||
#define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
|
||||
|
||||
// message command bytes (128-255/0x80-0xFF)
|
||||
#define DIGITAL_MESSAGE 0x90 // send data for a digital pin
|
||||
#define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
|
||||
#define REPORT_ANALOG 0xC0 // enable analog input by pin #
|
||||
#define REPORT_DIGITAL 0xD0 // enable digital input by port pair
|
||||
//
|
||||
#define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
|
||||
//
|
||||
#define REPORT_VERSION 0xF9 // report protocol version
|
||||
#define SYSTEM_RESET 0xFF // reset from MIDI
|
||||
//
|
||||
#define START_SYSEX 0xF0 // start a MIDI Sysex message
|
||||
#define END_SYSEX 0xF7 // end a MIDI Sysex message
|
||||
|
||||
// extended command set using sysex (0-127/0x00-0x7F)
|
||||
/* 0x00-0x0F reserved for user-defined commands */
|
||||
#define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
|
||||
#define STRING_DATA 0x71 // a string message with 14-bits per char
|
||||
#define SHIFT_DATA 0x75 // a bitstream to/from a shift register
|
||||
#define I2C_REQUEST 0x76 // send an I2C read/write request
|
||||
#define I2C_REPLY 0x77 // a reply to an I2C read request
|
||||
#define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
|
||||
#define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
|
||||
#define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
|
||||
#define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
|
||||
#define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
|
||||
#define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
|
||||
#define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
|
||||
#define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
|
||||
#define REPORT_FIRMWARE 0x79 // report name and version of the firmware
|
||||
#define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
|
||||
#define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
|
||||
#define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
|
||||
// these are DEPRECATED to make the naming more consistent
|
||||
#define FIRMATA_STRING 0x71 // same as STRING_DATA
|
||||
#define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
|
||||
#define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
|
||||
#define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
|
||||
|
||||
// pin modes
|
||||
//#define INPUT 0x00 // defined in wiring.h
|
||||
//#define OUTPUT 0x01 // defined in wiring.h
|
||||
#define ANALOG 0x02 // analog pin in analogInput mode
|
||||
#define PWM 0x03 // digital pin in PWM output mode
|
||||
#define SERVO 0x04 // digital pin in Servo output mode
|
||||
#define SHIFT 0x05 // shiftIn/shiftOut mode
|
||||
#define I2C 0x06 // pin included in I2C setup
|
||||
#define TOTAL_PIN_MODES 7
|
||||
|
||||
extern "C" {
|
||||
// callback function types
|
||||
typedef void (*callbackFunction)(byte, int);
|
||||
typedef void (*systemResetCallbackFunction)(void);
|
||||
typedef void (*stringCallbackFunction)(char*);
|
||||
typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
|
||||
}
|
||||
|
||||
|
||||
// TODO make it a subclass of a generic Serial/Stream base class
|
||||
class Adafruit_BLE_FirmataClass
|
||||
{
|
||||
public:
|
||||
Adafruit_BLE_FirmataClass(Adafruit_BLE_UART &s);
|
||||
/* Arduino constructors */
|
||||
void begin();
|
||||
void begin(Adafruit_BLE_UART &s);
|
||||
/* querying functions */
|
||||
void printVersion(void);
|
||||
void blinkVersion(void);
|
||||
void printFirmwareVersion(void);
|
||||
//void setFirmwareVersion(byte major, byte minor); // see macro below
|
||||
void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
|
||||
/* serial receive handling */
|
||||
int available(void);
|
||||
int processInput(void);
|
||||
/* serial send handling */
|
||||
void sendAnalog(byte pin, int value);
|
||||
void sendDigital(byte pin, int value); // TODO implement this
|
||||
void sendDigitalPort(byte portNumber, int portData);
|
||||
void sendString(const char* string);
|
||||
void sendString(byte command, const char* string);
|
||||
void sendSysex(byte command, byte bytec, byte* bytev);
|
||||
/* attach & detach callback functions to messages */
|
||||
void attach(byte command, callbackFunction newFunction);
|
||||
void attach(byte command, systemResetCallbackFunction newFunction);
|
||||
void attach(byte command, stringCallbackFunction newFunction);
|
||||
void attach(byte command, sysexCallbackFunction newFunction);
|
||||
void detach(byte command);
|
||||
|
||||
private:
|
||||
Adafruit_BLE_UART &FirmataSerial;
|
||||
/* firmware name and version */
|
||||
byte firmwareVersionCount;
|
||||
byte *firmwareVersionVector;
|
||||
/* input message handling */
|
||||
byte waitForData; // this flag says the next serial input will be data
|
||||
byte executeMultiByteCommand; // execute this after getting multi-byte data
|
||||
byte multiByteChannel; // channel data for multiByteCommands
|
||||
byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
|
||||
/* sysex */
|
||||
boolean parsingSysex;
|
||||
int sysexBytesRead;
|
||||
/* callback functions */
|
||||
callbackFunction currentAnalogCallback;
|
||||
callbackFunction currentDigitalCallback;
|
||||
callbackFunction currentReportAnalogCallback;
|
||||
callbackFunction currentReportDigitalCallback;
|
||||
callbackFunction currentPinModeCallback;
|
||||
systemResetCallbackFunction currentSystemResetCallback;
|
||||
stringCallbackFunction currentStringCallback;
|
||||
sysexCallbackFunction currentSysexCallback;
|
||||
|
||||
/* private methods ------------------------------ */
|
||||
void processSysexMessage(void);
|
||||
void systemReset(void);
|
||||
void pin13strobe(int count, int onInterval, int offInterval);
|
||||
void sendValueAsTwo7bitBytes(int value);
|
||||
void startSysex(void);
|
||||
void endSysex(void);
|
||||
};
|
||||
|
||||
extern Adafruit_BLE_FirmataClass BLE_Firmata;
|
||||
|
||||
/*==============================================================================
|
||||
* MACROS
|
||||
*============================================================================*/
|
||||
|
||||
/* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
|
||||
* firmware name. It needs to be a macro so that __FILE__ is included in the
|
||||
* firmware source file rather than the library source file.
|
||||
*/
|
||||
#define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
|
||||
|
||||
#endif /* BLE_Firmata_h */
|
||||
|
||||
250
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Boards.h
Executable file
250
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/Boards.h
Executable file
@@ -0,0 +1,250 @@
|
||||
/* Boards.h - Hardware Abstraction Layer for Firmata library */
|
||||
|
||||
#ifndef BLE_Firmata_Boards_h
|
||||
#define BLE_Firmata_Boards_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h" // for digitalRead, digitalWrite, etc
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
// Normally Servo.h must be included before Firmata.h (which then includes
|
||||
// this file). If Servo.h wasn't included, this allows the code to still
|
||||
// compile, but without support for any Servos. Hopefully that's what the
|
||||
// user intended by not including Servo.h
|
||||
#ifndef MAX_SERVOS
|
||||
#define MAX_SERVOS 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
Firmata Hardware Abstraction Layer
|
||||
|
||||
Firmata is built on top of the hardware abstraction functions of Arduino,
|
||||
specifically digitalWrite, digitalRead, analogWrite, analogRead, and
|
||||
pinMode. While these functions offer simple integer pin numbers, Firmata
|
||||
needs more information than is provided by Arduino. This file provides
|
||||
all other hardware specific details. To make Firmata support a new board,
|
||||
only this file should require editing.
|
||||
|
||||
The key concept is every "pin" implemented by Firmata may be mapped to
|
||||
any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
|
||||
best, but such mapping should not be assumed. This hardware abstraction
|
||||
layer allows Firmata to implement any number of pins which map onto the
|
||||
Arduino implemented pins in almost any arbitrary way.
|
||||
|
||||
|
||||
General Constants:
|
||||
|
||||
These constants provide basic information Firmata requires.
|
||||
|
||||
TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
|
||||
Usually this will match the number of pins the Arduino functions
|
||||
implement, including any pins pins capable of analog or digital.
|
||||
However, Firmata may implement any number of pins. For example,
|
||||
on Arduino Mini with 8 analog inputs, 6 of these may be used
|
||||
for digital functions, and 2 are analog only. On such boards,
|
||||
Firmata can implement more pins than Arduino's pinMode()
|
||||
function, in order to accommodate those special pins. The
|
||||
Firmata protocol supports a maximum of 128 pins, so this
|
||||
constant must not exceed 128.
|
||||
|
||||
TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
|
||||
The Firmata protocol allows up to 16 analog inputs, accessed
|
||||
using offsets 0 to 15. Because Firmata presents the analog
|
||||
inputs using different offsets than the actual pin numbers
|
||||
(a legacy of Arduino's analogRead function, and the way the
|
||||
analog input capable pins are physically labeled on all
|
||||
Arduino boards), the total number of analog input signals
|
||||
must be specified. 16 is the maximum.
|
||||
|
||||
VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
|
||||
number. This constant is the Arduino pin number where a
|
||||
LED is connected.
|
||||
|
||||
|
||||
Pin Mapping Macros:
|
||||
|
||||
These macros provide the mapping between pins as implemented by
|
||||
Firmata protocol and the actual pin numbers used by the Arduino
|
||||
functions. Even though such mappings are often simple, pin
|
||||
numbers received by Firmata protocol should always be used as
|
||||
input to these macros, and the result of the macro should be
|
||||
used with with any Arduino function.
|
||||
|
||||
When Firmata is extended to support a new pin mode or feature,
|
||||
a pair of macros should be added and used for all hardware
|
||||
access. For simple 1:1 mapping, these macros add no actual
|
||||
overhead, yet their consistent use allows source code which
|
||||
uses them consistently to be easily adapted to all other boards
|
||||
with different requirements.
|
||||
|
||||
IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
|
||||
if a pin as implemented by Firmata corresponds to a pin
|
||||
that actually implements the named feature.
|
||||
|
||||
PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
|
||||
implemented by Firmata to the pin numbers needed as inputs
|
||||
to the Arduino functions. The corresponding IS_PIN macro
|
||||
should always be tested before using a PIN_TO macro, so
|
||||
these macros only need to handle valid Firmata pin
|
||||
numbers for the named feature.
|
||||
|
||||
|
||||
Port Access Inline Funtions:
|
||||
|
||||
For efficiency, Firmata protocol provides access to digital
|
||||
input and output pins grouped by 8 bit ports. When these
|
||||
groups of 8 correspond to actual 8 bit ports as implemented
|
||||
by the hardware, these inline functions can provide high
|
||||
speed direct port access. Otherwise, a default implementation
|
||||
using 8 calls to digitalWrite or digitalRead is used.
|
||||
|
||||
When porting Firmata to a new board, it is recommended to
|
||||
use the default functions first and focus only on the constants
|
||||
and macros above. When those are working, if optimized port
|
||||
access is desired, these inline functions may be extended.
|
||||
The recommended approach defines a symbol indicating which
|
||||
optimization to use, and then conditional complication is
|
||||
used within these functions.
|
||||
|
||||
readPort(port, bitmask): Read an 8 bit port, returning the value.
|
||||
port: The port number, Firmata pins port*8 to port*8+7
|
||||
bitmask: The actual pins to read, indicated by 1 bits.
|
||||
|
||||
writePort(port, value, bitmask): Write an 8 bit port.
|
||||
port: The port number, Firmata pins port*8 to port*8+7
|
||||
value: The 8 bit value to write
|
||||
bitmask: The actual pins to write, indicated by 1 bits.
|
||||
*/
|
||||
|
||||
/*==============================================================================
|
||||
* Board Specific Configuration
|
||||
*============================================================================*/
|
||||
|
||||
#ifndef digitalPinHasPWM
|
||||
#define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
|
||||
#endif
|
||||
|
||||
// Arduino Duemilanove, Diecimila, and NG
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
||||
#if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
|
||||
#define TOTAL_ANALOG_PINS 6
|
||||
#define TOTAL_PINS 22 // 14 digital (not all are 'digital/available') + 6 analog
|
||||
#else
|
||||
#define TOTAL_ANALOG_PINS 8
|
||||
#define TOTAL_PINS 22 // 14 digital + 8 analog
|
||||
#endif
|
||||
|
||||
#define VERSION_BLINK_PIN 99
|
||||
// we dont use digital 2 or 9, 10, 11, 12, 13 -> BTLE link
|
||||
#define IS_PIN_DIGITAL(p) (((p) >= 3 && (p) <= 8) || ((p) >= 14 && (p) <= 19 ))
|
||||
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
|
||||
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
|
||||
#define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
|
||||
#define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
|
||||
#define PIN_TO_DIGITAL(p) (p)
|
||||
#define PIN_TO_ANALOG(p) ((p) - 14)
|
||||
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
|
||||
#define PIN_TO_SERVO(p) ((p) - 2)
|
||||
#define ARDUINO_PINOUT_OPTIMIZE 0
|
||||
|
||||
|
||||
// Arduino Mega
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TOTAL_ANALOG_PINS 16
|
||||
#define TOTAL_PINS 70 // 54 digital + 16 analog
|
||||
#define VERSION_BLINK_PIN 13
|
||||
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
|
||||
#define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
|
||||
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
|
||||
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
|
||||
#define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
|
||||
#define PIN_TO_DIGITAL(p) (p)
|
||||
#define PIN_TO_ANALOG(p) ((p) - 54)
|
||||
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
|
||||
#define PIN_TO_SERVO(p) ((p) - 2)
|
||||
|
||||
|
||||
// anything else
|
||||
#else
|
||||
#error "Please edit Boards.h with a hardware abstraction for this board"
|
||||
#endif
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* readPort() - Read an 8 bit port
|
||||
*============================================================================*/
|
||||
|
||||
static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
|
||||
static inline unsigned char readPort(byte port, byte bitmask)
|
||||
{
|
||||
unsigned char out=0, pin=port*8;
|
||||
if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
|
||||
if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
|
||||
if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
|
||||
if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
|
||||
if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
|
||||
if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
|
||||
if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
|
||||
if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* writePort() - Write an 8 bit port, only touch pins specified by a bitmask
|
||||
*============================================================================*/
|
||||
|
||||
static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
|
||||
static inline unsigned char writePort(byte port, byte value, byte bitmask)
|
||||
{
|
||||
#if defined(ARDUINO_PINOUT_OPTIMIZE)
|
||||
if (port == 0) {
|
||||
bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
|
||||
byte valD = value & bitmask;
|
||||
byte maskD = ~bitmask;
|
||||
cli();
|
||||
PORTD = (PORTD & maskD) | valD;
|
||||
sei();
|
||||
} else if (port == 1) {
|
||||
byte valB = (value & bitmask) & 0x3F;
|
||||
byte valC = (value & bitmask) >> 6;
|
||||
byte maskB = ~(bitmask & 0x3F);
|
||||
byte maskC = ~((bitmask & 0xC0) >> 6);
|
||||
cli();
|
||||
PORTB = (PORTB & maskB) | valB;
|
||||
PORTC = (PORTC & maskC) | valC;
|
||||
sei();
|
||||
} else if (port == 2) {
|
||||
bitmask = bitmask & 0x0F;
|
||||
byte valC = (value & bitmask) << 2;
|
||||
byte maskC = ~(bitmask << 2);
|
||||
cli();
|
||||
PORTC = (PORTC & maskC) | valC;
|
||||
sei();
|
||||
}
|
||||
#else
|
||||
byte pin=port*8;
|
||||
for (uint8_t i=0; i<8; i++) {
|
||||
if (bitmask & (1 << i)) {
|
||||
// dont touch non-digital pins
|
||||
if (IS_PIN_DIGITAL(pin+i))
|
||||
digitalWrite(PIN_TO_DIGITAL(pin+i), (value & (1 << i)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef TOTAL_PORTS
|
||||
#define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* BLE_Firmata_Boards_h */
|
||||
|
||||
458
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/LICENSE.txt
Executable file
458
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/LICENSE.txt
Executable file
@@ -0,0 +1,458 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
125
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/README.md
Executable file
125
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/README.md
Executable file
@@ -0,0 +1,125 @@
|
||||
#Firmata
|
||||
|
||||
Firmata is a protocol for communicating with microcontrollers from software on a host computer. The [protocol](http://firmata.org/wiki/Protocol) can be implemented in firmware on any microcontroller architecture as well as software on any host computer software package. The arduino repository described here is a Firmata library for Arduino and Arduino-compatible devices. See the [firmata wiki](http://firmata.org/wiki/Main_Page) for additional informataion. If you would like to contribute to Firmata, please see the [Contributing](#contributing) section below.
|
||||
|
||||
##Usage
|
||||
|
||||
There are two main models of usage of Firmata. In one model, the author of the Arduino sketch uses the various methods provided by the Firmata library to selectively send and receive data between the Arduino device and the software running on the host computer. For example, a user can send analog data to the host using ``` Firmata.sendAnalog(analogPin, analogRead(analogPin)) ``` or send data packed in a string using ``` Firmata.sendString(stringToSend) ```. See File -> Examples -> Firmata -> AnalogFirmata & EchoString respectively for examples.
|
||||
|
||||
The second and more common model is to load a general purpose sketch called StandardFirmata on the Arduino board and then use the host computer exclusively to interact with the Arduino board. StandardFirmata is located in the Arduino IDE in File -> Examples -> Firmata.
|
||||
|
||||
##Firmata Client Libraries
|
||||
Most of the time you will be interacting with arduino with a client library on the host computers. Several Firmata client libraries have been implemented in a variety of popular programming languages:
|
||||
|
||||
* procesing
|
||||
* [https://github.com/firmata/processing]
|
||||
* [http://funnel.cc]
|
||||
* python
|
||||
* [https://github.com/firmata/pyduino]
|
||||
* [https://github.com/lupeke/python-firmata]
|
||||
* [https://github.com/tino/pyFirmata]
|
||||
* perl
|
||||
* [https://github.com/ntruchsess/perl-firmata]
|
||||
* [https://github.com/rcaputo/rx-firmata]
|
||||
* ruby
|
||||
* [https://github.com/hardbap/firmata]
|
||||
* [https://github.com/PlasticLizard/rufinol]
|
||||
* [http://funnel.cc]
|
||||
* clojure
|
||||
* [https://github.com/nakkaya/clodiuno]
|
||||
* javascript
|
||||
* [https://github.com/jgautier/firmata]
|
||||
* [http://breakoutjs.com]
|
||||
* [https://github.com/rwldrn/johnny-five]
|
||||
* java
|
||||
* [https://github.com/4ntoine/Firmata]
|
||||
* [https://github.com/shigeodayo/Javarduino]
|
||||
* .NET
|
||||
* [http://www.imagitronics.org/projects/firmatanet/]
|
||||
* Flash/AS3
|
||||
* [http://funnel.cc]
|
||||
* [http://code.google.com/p/as3glue/]
|
||||
* PHP
|
||||
* [https://bitbucket.org/ThomasWeinert/carica-firmata]
|
||||
|
||||
Note: The above libraries may support various versions of the Firmata protocol and therefore may not support all features of the latest Firmata spec nor all arduino and arduino-compatible boards. Refer to the respective projects for details.
|
||||
|
||||
##Updating Firmata in the Arduino IDE (< Arduino 1.5)
|
||||
The version of firmata in the Arduino IDE contains an outdated version of Firmata. To update Firmata, clone the repo into the location of firmata in the arduino IDE or download the latest [tagged version](https://github.com/firmata/arduino/tags) (stable), rename the folder to "Firmata" and replace the existing Firmata folder in your Ardino application.
|
||||
|
||||
**Mac OSX**:
|
||||
|
||||
```bash
|
||||
$ rm -r /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
|
||||
$ git clone git@github.com:firmata/arduino.git /Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata
|
||||
```
|
||||
|
||||
If you are downloading the latest tagged version of Firmata, rename it to "Firmata" and copy to /Applications/Arduino.app/Contents/Resources/Java/libraries/ overwriting the existing Firmata directory. Right-click (or conrol + click) on the Arduino application and choose "Show Package Contents" and navigate to the libraries directory.
|
||||
|
||||
**Windows**:
|
||||
|
||||
Using the Git Shell application installed with [GitHub for Windows](http://windows.github.com/) (set default shell in options to Git Bash) or other command line based git tool:
|
||||
|
||||
update the path and arduino version as necessary
|
||||
```bash
|
||||
$ rm -r c:/Program\ Files/arduino-1.x/libraries/Firmata
|
||||
$ git clone git@github.com:firmata/arduino.git c:/Program\ Files/arduino-1.x/libraries/Firmata
|
||||
```
|
||||
|
||||
Note: If you use GitHub for Windows, you must clone the firmata/arduino repository using the Git Shell application as described above. You can use the Github for Windows GUI only after you have cloned the repository. Drag the Firmata file into the Github for Windows GUI to track it.
|
||||
|
||||
**Linux**:
|
||||
|
||||
update the path and arduino version as necessary
|
||||
```bash
|
||||
$ rm -r ~/arduino-1.x/libraries/Firmata
|
||||
$ git clone git@github.com:firmata/arduino.git ~/arduino-1.x/libraries/Firmata
|
||||
```
|
||||
|
||||
##Updating Firmata in the Arduino IDE (>= Arduino 1.5.2)
|
||||
As of Arduino 1.5.2 and there are separate library directories for the sam and
|
||||
avr architectures. To update Firmata in Arduino 1.5.2 or higher, follow the
|
||||
instructions above for pre Arduino 1.5 versions but update the path as follows:
|
||||
|
||||
**Mac OSX**:
|
||||
```
|
||||
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/libraries/Firmata
|
||||
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/sam/libraries/Firmata
|
||||
```
|
||||
|
||||
**Windows**:
|
||||
```
|
||||
/Program\ Files/arduino-1.5.x/hardware/arduino/avr/libraries/Firmata
|
||||
/Program\ Files/arduino-1.5.x/hardware/arduino/sam/libraries/Firmata
|
||||
```
|
||||
|
||||
**Linux**
|
||||
```
|
||||
~/arduino-1.5.x/hardware/arduino/avr/libraries/Firmata
|
||||
~/arduino-1.5.x/hardware/arduino/sam/libraries/Firmata
|
||||
```
|
||||
|
||||
<a name="contributing" />
|
||||
##Contributing
|
||||
|
||||
If you discover a bug or would like to propose a new feature, please open a new [issue](https://github.com/firmata/arduino/issues?sort=created&state=open). Due to the limited memory of standard Arduino boards we cannot add every requested feature to StandardFirmata. Requests to add new features to StandardFirmata will be evaluated by the Firmata developers. However it is still possible to add new features to other Firmata implementations (Firmata is a protocol whereas StandardFirmata is just one of many possible implementations).
|
||||
|
||||
To contribute, fork this respository and create a new topic branch for the bug, feature or other existing issue you are addressing. Submit the pull request against the *dev* branch.
|
||||
|
||||
If you would like to contribute but don't have a specific bugfix or new feature to contribute, you can take on an existing issue, see issues labeled "pull-request-encouraged". Add a comment to the issue to express your intent to begin work and/or to get any additional information about the issue.
|
||||
|
||||
You must thorougly test your contributed code. In your pull request, describe tests performed to ensure that no existing code is broken and that any changes maintain backwards compatibility with the existing api. Test on multiple Arduino board variants if possible. We hope to enable some form of automated (or at least semi-automated) testing in the future, but for now any tests will need to be executed manually by the contributor and reviewsers.
|
||||
|
||||
Maintain the existing code style:
|
||||
|
||||
- Indentation is 2 spaces
|
||||
- Use spaces instead of tabs
|
||||
- Use camel case for both private and public properties and methods
|
||||
- Document functions (specific doc style is TBD... for now just be sure to document)
|
||||
- Insert first block bracket on line following the function definition:
|
||||
|
||||
<pre>void someFunction()
|
||||
{
|
||||
// do something
|
||||
}
|
||||
</pre>
|
||||
@@ -0,0 +1,458 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
# Arduino makefile
|
||||
#
|
||||
# This makefile allows you to build sketches from the command line
|
||||
# without the Arduino environment (or Java).
|
||||
#
|
||||
# The Arduino environment does preliminary processing on a sketch before
|
||||
# compiling it. If you're using this makefile instead, you'll need to do
|
||||
# a few things differently:
|
||||
#
|
||||
# - Give your program's file a .cpp extension (e.g. foo.cpp).
|
||||
#
|
||||
# - Put this line at top of your code: #include <WProgram.h>
|
||||
#
|
||||
# - Write prototypes for all your functions (or define them before you
|
||||
# call them). A prototype declares the types of parameters a
|
||||
# function will take and what type of value it will return. This
|
||||
# means that you can have a call to a function before the definition
|
||||
# of the function. A function prototype looks like the first line of
|
||||
# the function, with a semi-colon at the end. For example:
|
||||
# int digitalRead(int pin);
|
||||
#
|
||||
# Instructions for using the makefile:
|
||||
#
|
||||
# 1. Copy this file into the folder with your sketch.
|
||||
#
|
||||
# 2. Below, modify the line containing "TARGET" to refer to the name of
|
||||
# of your program's file without an extension (e.g. TARGET = foo).
|
||||
#
|
||||
# 3. Modify the line containg "ARDUINO" to point the directory that
|
||||
# contains the Arduino core (for normal Arduino installations, this
|
||||
# is the hardware/cores/arduino sub-directory).
|
||||
#
|
||||
# 4. Modify the line containing "PORT" to refer to the filename
|
||||
# representing the USB or serial connection to your Arduino board
|
||||
# (e.g. PORT = /dev/tty.USB0). If the exact name of this file
|
||||
# changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
|
||||
#
|
||||
# 5. At the command line, change to the directory containing your
|
||||
# program's file and the makefile.
|
||||
#
|
||||
# 6. Type "make" and press enter to compile/verify your program.
|
||||
#
|
||||
# 7. Type "make upload", reset your Arduino board, and press enter to
|
||||
# upload your program to the Arduino board.
|
||||
#
|
||||
# $Id: Makefile,v 1.7 2007/04/13 05:28:23 eighthave Exp $
|
||||
|
||||
PORT = /dev/tty.usbserial-*
|
||||
TARGET := $(shell pwd | sed 's|.*/\(.*\)|\1|')
|
||||
ARDUINO = /Applications/arduino
|
||||
ARDUINO_SRC = $(ARDUINO)/hardware/cores/arduino
|
||||
ARDUINO_LIB_SRC = $(ARDUINO)/hardware/libraries
|
||||
ARDUINO_TOOLS = $(ARDUINO)/hardware/tools
|
||||
INCLUDE = -I$(ARDUINO_SRC) -I$(ARDUINO)/hardware/tools/avr/avr/include \
|
||||
-I$(ARDUINO_LIB_SRC)/EEPROM \
|
||||
-I$(ARDUINO_LIB_SRC)/Firmata \
|
||||
-I$(ARDUINO_LIB_SRC)/Matrix \
|
||||
-I$(ARDUINO_LIB_SRC)/Servo \
|
||||
-I$(ARDUINO_LIB_SRC)/Wire \
|
||||
-I$(ARDUINO_LIB_SRC)
|
||||
SRC = $(wildcard $(ARDUINO_SRC)/*.c)
|
||||
CXXSRC = applet/$(TARGET).cpp $(ARDUINO_SRC)/HardwareSerial.cpp \
|
||||
$(ARDUINO_LIB_SRC)/EEPROM/EEPROM.cpp \
|
||||
$(ARDUINO_LIB_SRC)/Firmata/Firmata.cpp \
|
||||
$(ARDUINO_LIB_SRC)/Servo/Servo.cpp \
|
||||
$(ARDUINO_SRC)/Print.cpp \
|
||||
$(ARDUINO_SRC)/WMath.cpp
|
||||
HEADERS = $(wildcard $(ARDUINO_SRC)/*.h) $(wildcard $(ARDUINO_LIB_SRC)/*/*.h)
|
||||
|
||||
MCU = atmega168
|
||||
#MCU = atmega8
|
||||
F_CPU = 16000000
|
||||
FORMAT = ihex
|
||||
UPLOAD_RATE = 19200
|
||||
|
||||
# Name of this Makefile (used for "make depend").
|
||||
MAKEFILE = Makefile
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
|
||||
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
|
||||
DEBUG = stabs
|
||||
|
||||
OPT = s
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS = -DF_CPU=$(F_CPU)
|
||||
CXXDEFS = -DF_CPU=$(F_CPU)
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 - "ANSI" C
|
||||
# gnu89 - c89 plus GCC extensions
|
||||
# c99 - ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 - c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
CDEBUG = -g$(DEBUG)
|
||||
CWARN = -Wall -Wstrict-prototypes
|
||||
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
|
||||
|
||||
CFLAGS = $(CDEBUG) $(CDEFS) $(INCLUDE) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
|
||||
CXXFLAGS = $(CDEFS) $(INCLUDE) -O$(OPT)
|
||||
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
LDFLAGS =
|
||||
|
||||
|
||||
# Programming support using avrdude. Settings and variables.
|
||||
AVRDUDE_PROGRAMMER = stk500
|
||||
AVRDUDE_PORT = $(PORT)
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
|
||||
AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
|
||||
-b $(UPLOAD_RATE) -q -V
|
||||
|
||||
# Program settings
|
||||
ARDUINO_AVR_BIN = $(ARDUINO_TOOLS)/avr/bin
|
||||
CC = $(ARDUINO_AVR_BIN)/avr-gcc
|
||||
CXX = $(ARDUINO_AVR_BIN)/avr-g++
|
||||
OBJCOPY = $(ARDUINO_AVR_BIN)/avr-objcopy
|
||||
OBJDUMP = $(ARDUINO_AVR_BIN)/avr-objdump
|
||||
SIZE = $(ARDUINO_AVR_BIN)/avr-size
|
||||
NM = $(ARDUINO_AVR_BIN)/avr-nm
|
||||
#AVRDUDE = $(ARDUINO_AVR_BIN)/avrdude
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
MV = mv -f
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
|
||||
ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
# Default target.
|
||||
all: build
|
||||
|
||||
build: applet/$(TARGET).hex
|
||||
|
||||
eep: applet/$(TARGET).eep
|
||||
lss: applet/$(TARGET).lss
|
||||
sym: applet/$(TARGET).sym
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT=$(OBJCOPY) --debugging \
|
||||
--change-section-address .data-0x800000 \
|
||||
--change-section-address .bss-0x800000 \
|
||||
--change-section-address .noinit-0x800000 \
|
||||
--change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
coff: applet/$(TARGET).elf
|
||||
$(COFFCONVERT) -O coff-avr applet/$(TARGET).elf applet/$(TARGET).cof
|
||||
|
||||
|
||||
extcoff: applet/$(TARGET).elf
|
||||
$(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf applet/$(TARGET).cof
|
||||
|
||||
|
||||
.SUFFIXES: .elf .hex .eep .lss .sym .pde
|
||||
|
||||
.elf.hex:
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
.elf.eep:
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
.elf.lss:
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
.elf.sym:
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
.cpp.o: $(HEADERS)
|
||||
$(CXX) -c $(ALL_CXXFLAGS) $< -o $@
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
.c.o: $(HEADERS)
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
.c.s:
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
.S.o:
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
applet/$(TARGET).cpp: $(TARGET).pde
|
||||
test -d applet || mkdir applet
|
||||
echo '#include "WProgram.h"' > applet/$(TARGET).cpp
|
||||
echo '#include "avr/interrupt.h"' >> applet/$(TARGET).cpp
|
||||
sed -n 's|^\(void .*)\).*|\1;|p' $(TARGET).pde | grep -v 'setup()' | \
|
||||
grep -v 'loop()' >> applet/$(TARGET).cpp
|
||||
cat $(TARGET).pde >> applet/$(TARGET).cpp
|
||||
cat $(ARDUINO_SRC)/main.cxx >> applet/$(TARGET).cpp
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
applet/$(TARGET).elf: applet/$(TARGET).cpp $(OBJ)
|
||||
$(CC) $(ALL_CFLAGS) $(OBJ) -lm --output $@ $(LDFLAGS)
|
||||
# $(CC) $(ALL_CFLAGS) $(OBJ) $(ARDUINO_TOOLS)/avr/avr/lib/avr5/crtm168.o --output $@ $(LDFLAGS)
|
||||
|
||||
pd_close_serial:
|
||||
echo 'close;' | /Applications/Pd-extended.app/Contents/Resources/bin/pdsend 34567 || true
|
||||
|
||||
# Program the device.
|
||||
upload: applet/$(TARGET).hex
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
|
||||
|
||||
|
||||
pd_test: build pd_close_serial upload
|
||||
|
||||
# Target: clean project.
|
||||
clean:
|
||||
$(REMOVE) -- applet/$(TARGET).hex applet/$(TARGET).eep \
|
||||
applet/$(TARGET).cof applet/$(TARGET).elf $(TARGET).map \
|
||||
applet/$(TARGET).sym applet/$(TARGET).lss applet/$(TARGET).cpp \
|
||||
$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
|
||||
rmdir -- applet
|
||||
|
||||
depend:
|
||||
if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
|
||||
then \
|
||||
sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
|
||||
$(MAKEFILE).$$$$ && \
|
||||
$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
|
||||
fi
|
||||
echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
|
||||
>> $(MAKEFILE); \
|
||||
$(CC) -M -mmcu=$(MCU) $(CDEFS) $(INCLUDE) $(SRC) $(ASRC) >> $(MAKEFILE)
|
||||
|
||||
.PHONY: all build eep lss sym coff extcoff clean depend pd_close_serial pd_test
|
||||
|
||||
# for emacs
|
||||
etags:
|
||||
make etags_`uname -s`
|
||||
etags *.pde \
|
||||
$(ARDUINO_SRC)/*.[ch] \
|
||||
$(ARDUINO_SRC)/*.cpp \
|
||||
$(ARDUINO_LIB_SRC)/*/*.[ch] \
|
||||
$(ARDUINO_LIB_SRC)/*/*.cpp \
|
||||
$(ARDUINO)/hardware/tools/avr/avr/include/avr/*.[ch] \
|
||||
$(ARDUINO)/hardware/tools/avr/avr/include/*.[ch]
|
||||
|
||||
etags_Darwin:
|
||||
# etags -a
|
||||
|
||||
etags_Linux:
|
||||
# etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h
|
||||
|
||||
etags_MINGW:
|
||||
# etags -a /usr/include/*.h /usr/include/sys/*.h
|
||||
|
||||
|
||||
path:
|
||||
echo $(PATH)
|
||||
echo $$PATH
|
||||
|
||||
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* Firmata is a generic protocol for communicating with microcontrollers
|
||||
* from software on a host computer. It is intended to work with
|
||||
* any host computer software package.
|
||||
*
|
||||
* This version is modified to specifically work with Adafruit's BLE
|
||||
* library. It no longer works over the standard "USB" connection!
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
|
||||
Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
|
||||
Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
|
||||
Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved.
|
||||
Copyright (C) 2014 Limor Fried/Kevin Townsend All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See file LICENSE.txt for further informations on licensing terms.
|
||||
|
||||
formatted using the GNU C formatting and indenting
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: use Program Control to load stored profiles from EEPROM
|
||||
*/
|
||||
|
||||
#include <Servo.h>
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <Adafruit_BLE_Firmata.h>
|
||||
#include "Adafruit_BLE_UART.h"
|
||||
|
||||
#define AUTO_INPUT_PULLUPS true
|
||||
|
||||
// Connect CLK/MISO/MOSI to hardware SPI
|
||||
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
|
||||
#define ADAFRUITBLE_REQ 10
|
||||
#define ADAFRUITBLE_RDY 2 // This should be an interrupt pin, on Uno thats #2 or #3
|
||||
#define ADAFRUITBLE_RST 9
|
||||
|
||||
// so we have digital 3-8 and analog 0-6
|
||||
|
||||
Adafruit_BLE_UART BLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
|
||||
|
||||
|
||||
// make one instance for the user to use
|
||||
Adafruit_BLE_FirmataClass BLE_Firmata(BLEserial);
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* GLOBAL VARIABLES
|
||||
*============================================================================*/
|
||||
|
||||
/* analog inputs */
|
||||
int analogInputsToReport = 0; // bitwise array to store pin reporting
|
||||
int lastAnalogReads[NUM_ANALOG_INPUTS];
|
||||
|
||||
/* digital input ports */
|
||||
byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
|
||||
byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
|
||||
|
||||
/* pins configuration */
|
||||
byte pinConfig[TOTAL_PINS]; // configuration of every pin
|
||||
byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
|
||||
int pinState[TOTAL_PINS]; // any value that has been written
|
||||
|
||||
/* timer variables */
|
||||
unsigned long currentMillis; // store the current value from millis()
|
||||
unsigned long previousMillis; // for comparison with currentMillis
|
||||
int samplingInterval = 200; // how often to run the main loop (in ms)
|
||||
#define MINIMUM_SAMPLE_DELAY 150
|
||||
#define ANALOG_SAMPLE_DELAY 50
|
||||
|
||||
|
||||
/* i2c data */
|
||||
struct i2c_device_info {
|
||||
byte addr;
|
||||
byte reg;
|
||||
byte bytes;
|
||||
};
|
||||
|
||||
/* for i2c read continuous more */
|
||||
i2c_device_info query[MAX_QUERIES];
|
||||
|
||||
byte i2cRxData[32];
|
||||
boolean isI2CEnabled = false;
|
||||
signed char queryIndex = -1;
|
||||
unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
|
||||
|
||||
Servo servos[MAX_SERVOS];
|
||||
/*==============================================================================
|
||||
* FUNCTIONS
|
||||
*============================================================================*/
|
||||
|
||||
void readAndReportData(byte address, int theRegister, byte numBytes) {
|
||||
// allow I2C requests that don't require a register read
|
||||
// for example, some devices using an interrupt pin to signify new data available
|
||||
// do not always require the register read so upon interrupt you call Wire.requestFrom()
|
||||
if (theRegister != REGISTER_NOT_SPECIFIED) {
|
||||
Wire.beginTransmission(address);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write((byte)theRegister);
|
||||
#else
|
||||
Wire.send((byte)theRegister);
|
||||
#endif
|
||||
Wire.endTransmission();
|
||||
delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
|
||||
} else {
|
||||
theRegister = 0; // fill the register with a dummy value
|
||||
}
|
||||
|
||||
Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
|
||||
|
||||
// check to be sure correct number of bytes were returned by slave
|
||||
if(numBytes == Wire.available()) {
|
||||
i2cRxData[0] = address;
|
||||
i2cRxData[1] = theRegister;
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
#if ARDUINO >= 100
|
||||
i2cRxData[2 + i] = Wire.read();
|
||||
#else
|
||||
i2cRxData[2 + i] = Wire.receive();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(numBytes > Wire.available()) {
|
||||
BLE_Firmata.sendString("I2C Read Error: Too many bytes received");
|
||||
} else {
|
||||
BLE_Firmata.sendString("I2C Read Error: Too few bytes received");
|
||||
}
|
||||
}
|
||||
|
||||
// send slave address, register and received bytes
|
||||
BLE_Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
|
||||
}
|
||||
|
||||
void outputPort(byte portNumber, byte portValue, byte forceSend)
|
||||
{
|
||||
// pins not configured as INPUT are cleared to zeros
|
||||
portValue = portValue & portConfigInputs[portNumber];
|
||||
// only send if the value is different than previously sent
|
||||
if(forceSend || previousPINs[portNumber] != portValue) {
|
||||
Serial.print(F("Sending update for port ")); Serial.print(portNumber); Serial.print(" = 0x"); Serial.println(portValue, HEX);
|
||||
BLE_Firmata.sendDigitalPort(portNumber, portValue);
|
||||
previousPINs[portNumber] = portValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* check all the active digital inputs for change of state, then add any events
|
||||
* to the Serial output queue using Serial.print() */
|
||||
void checkDigitalInputs(boolean forceSend = false)
|
||||
{
|
||||
/* Using non-looping code allows constants to be given to readPort().
|
||||
* The compiler will apply substantial optimizations if the inputs
|
||||
* to readPort() are compile-time constants. */
|
||||
for (uint8_t i=0; i<TOTAL_PORTS; i++) {
|
||||
if (reportPINs[i]) {
|
||||
// Serial.print("Reporting on port "); Serial.print(i); Serial.print(" mask 0x"); Serial.println(portConfigInputs[i], HEX);
|
||||
uint8_t x = readPort(i, portConfigInputs[i]);
|
||||
// Serial.print("Read 0x"); Serial.println(x, HEX);
|
||||
outputPort(i, x, forceSend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/* sets the pin mode to the correct state and sets the relevant bits in the
|
||||
* two bit-arrays that track Digital I/O and PWM status
|
||||
*/
|
||||
void setPinModeCallback(byte pin, int mode)
|
||||
{
|
||||
if ((pinConfig[pin] == I2C) && (isI2CEnabled) && (mode != I2C)) {
|
||||
// disable i2c so pins can be used for other functions
|
||||
// the following if statements should reconfigure the pins properly
|
||||
disableI2CPins();
|
||||
}
|
||||
if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
|
||||
servos[PIN_TO_SERVO(pin)].detach();
|
||||
}
|
||||
if (IS_PIN_ANALOG(pin)) {
|
||||
reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
|
||||
}
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
if (mode == INPUT) {
|
||||
portConfigInputs[pin/8] |= (1 << (pin & 7));
|
||||
} else {
|
||||
portConfigInputs[pin/8] &= ~(1 << (pin & 7));
|
||||
}
|
||||
// Serial.print(F("Setting pin #")); Serial.print(pin); Serial.print(F(" port config mask to = 0x"));
|
||||
// Serial.println(portConfigInputs[pin/8], HEX);
|
||||
}
|
||||
pinState[pin] = 0;
|
||||
switch(mode) {
|
||||
case ANALOG:
|
||||
if (IS_PIN_ANALOG(pin)) {
|
||||
Serial.print(F("Set pin #")); Serial.print(pin); Serial.println(F(" to analog"));
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
|
||||
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
|
||||
}
|
||||
pinConfig[pin] = ANALOG;
|
||||
lastAnalogReads[PIN_TO_ANALOG(pin)] = -1;
|
||||
}
|
||||
break;
|
||||
case INPUT:
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
Serial.print(F("Set pin #")); Serial.print(pin); Serial.println(F(" to input"));
|
||||
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
|
||||
if (AUTO_INPUT_PULLUPS) {
|
||||
digitalWrite(PIN_TO_DIGITAL(pin), HIGH); // enable internal pull-ups
|
||||
} else {
|
||||
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
|
||||
}
|
||||
pinConfig[pin] = INPUT;
|
||||
|
||||
// force sending state immediately
|
||||
//delay(10);
|
||||
//checkDigitalInputs(true);
|
||||
}
|
||||
break;
|
||||
case OUTPUT:
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
Serial.print(F("Set pin #")); Serial.print(pin); Serial.println(F(" to output"));
|
||||
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
|
||||
pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
|
||||
pinConfig[pin] = OUTPUT;
|
||||
}
|
||||
break;
|
||||
case PWM:
|
||||
if (IS_PIN_PWM(pin)) {
|
||||
pinMode(PIN_TO_PWM(pin), OUTPUT);
|
||||
analogWrite(PIN_TO_PWM(pin), 0);
|
||||
pinConfig[pin] = PWM;
|
||||
}
|
||||
break;
|
||||
case SERVO:
|
||||
if (IS_PIN_SERVO(pin)) {
|
||||
pinConfig[pin] = SERVO;
|
||||
if (!servos[PIN_TO_SERVO(pin)].attached()) {
|
||||
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case I2C:
|
||||
if (IS_PIN_I2C(pin)) {
|
||||
// mark the pin as i2c
|
||||
// the user must call I2C_CONFIG to enable I2C for a device
|
||||
pinConfig[pin] = I2C;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Serial.print(F("Unknown pin mode")); // TODO: put error msgs in EEPROM
|
||||
}
|
||||
// TODO: save status to EEPROM here, if changed
|
||||
}
|
||||
|
||||
void analogWriteCallback(byte pin, int value)
|
||||
{
|
||||
if (pin < TOTAL_PINS) {
|
||||
switch(pinConfig[pin]) {
|
||||
case SERVO:
|
||||
if (IS_PIN_SERVO(pin))
|
||||
servos[PIN_TO_SERVO(pin)].write(value);
|
||||
pinState[pin] = value;
|
||||
break;
|
||||
case PWM:
|
||||
if (IS_PIN_PWM(pin))
|
||||
analogWrite(PIN_TO_PWM(pin), value);
|
||||
pinState[pin] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWriteCallback(byte port, int value)
|
||||
{
|
||||
byte pin, lastPin, mask=1, pinWriteMask=0;
|
||||
|
||||
if (port < TOTAL_PORTS) {
|
||||
// create a mask of the pins on this port that are writable.
|
||||
lastPin = port*8+8;
|
||||
if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
|
||||
for (pin=port*8; pin < lastPin; pin++) {
|
||||
// do not disturb non-digital pins (eg, Rx & Tx)
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
// only write to OUTPUT and INPUT (enables pullup)
|
||||
// do not touch pins in PWM, ANALOG, SERVO or other modes
|
||||
if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
|
||||
pinWriteMask |= mask;
|
||||
pinState[pin] = ((byte)value & mask) ? 1 : 0;
|
||||
|
||||
if (AUTO_INPUT_PULLUPS && ( pinConfig[pin] == INPUT)) {
|
||||
value |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
mask = mask << 1;
|
||||
}
|
||||
Serial.print(F("Write digital port #")); Serial.print(port);
|
||||
Serial.print(F(" = 0x")); Serial.print(value, HEX);
|
||||
Serial.print(F(" mask = 0x")); Serial.println(pinWriteMask, HEX);
|
||||
writePort(port, (byte)value, pinWriteMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
|
||||
*/
|
||||
//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
|
||||
//}
|
||||
void reportAnalogCallback(byte analogPin, int value)
|
||||
{
|
||||
if (analogPin < TOTAL_ANALOG_PINS) {
|
||||
if(value == 0) {
|
||||
analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
|
||||
Serial.print(F("Stop reporting analog pin #")); Serial.println(analogPin);
|
||||
} else {
|
||||
analogInputsToReport |= (1 << analogPin);
|
||||
Serial.print(F("Will report analog pin #")); Serial.println(analogPin);
|
||||
}
|
||||
}
|
||||
// TODO: save status to EEPROM here, if changed
|
||||
}
|
||||
|
||||
void reportDigitalCallback(byte port, int value)
|
||||
{
|
||||
if (port < TOTAL_PORTS) {
|
||||
Serial.print(F("Will report 0x")); Serial.print(value, HEX); Serial.print(F(" digital mask on port ")); Serial.println(port);
|
||||
reportPINs[port] = (byte)value;
|
||||
}
|
||||
// do not disable analog reporting on these 8 pins, to allow some
|
||||
// pins used for digital, others analog. Instead, allow both types
|
||||
// of reporting to be enabled, but check if the pin is configured
|
||||
// as analog when sampling the analog inputs. Likewise, while
|
||||
// scanning digital pins, portConfigInputs will mask off values from any
|
||||
// pins configured as analog
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* SYSEX-BASED commands
|
||||
*============================================================================*/
|
||||
|
||||
void sysexCallback(byte command, byte argc, byte *argv)
|
||||
{
|
||||
byte mode;
|
||||
byte slaveAddress;
|
||||
byte slaveRegister;
|
||||
byte data;
|
||||
unsigned int delayTime;
|
||||
|
||||
switch(command) {
|
||||
case I2C_REQUEST:
|
||||
mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
|
||||
if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
|
||||
//BLE_Firmata.sendString("10-bit addressing mode is not yet supported");
|
||||
Serial.println(F("10-bit addressing mode is not yet supported"));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
slaveAddress = argv[0];
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case I2C_WRITE:
|
||||
Wire.beginTransmission(slaveAddress);
|
||||
for (byte i = 2; i < argc; i += 2) {
|
||||
data = argv[i] + (argv[i + 1] << 7);
|
||||
#if ARDUINO >= 100
|
||||
Wire.write(data);
|
||||
#else
|
||||
Wire.send(data);
|
||||
#endif
|
||||
}
|
||||
Wire.endTransmission();
|
||||
delayMicroseconds(70);
|
||||
break;
|
||||
case I2C_READ:
|
||||
if (argc == 6) {
|
||||
// a slave register is specified
|
||||
slaveRegister = argv[2] + (argv[3] << 7);
|
||||
data = argv[4] + (argv[5] << 7); // bytes to read
|
||||
readAndReportData(slaveAddress, (int)slaveRegister, data);
|
||||
}
|
||||
else {
|
||||
// a slave register is NOT specified
|
||||
data = argv[2] + (argv[3] << 7); // bytes to read
|
||||
readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
|
||||
}
|
||||
break;
|
||||
case I2C_READ_CONTINUOUSLY:
|
||||
if ((queryIndex + 1) >= MAX_QUERIES) {
|
||||
// too many queries, just ignore
|
||||
BLE_Firmata.sendString("too many queries");
|
||||
break;
|
||||
}
|
||||
queryIndex++;
|
||||
query[queryIndex].addr = slaveAddress;
|
||||
query[queryIndex].reg = argv[2] + (argv[3] << 7);
|
||||
query[queryIndex].bytes = argv[4] + (argv[5] << 7);
|
||||
break;
|
||||
case I2C_STOP_READING:
|
||||
byte queryIndexToSkip;
|
||||
// if read continuous mode is enabled for only 1 i2c device, disable
|
||||
// read continuous reporting for that device
|
||||
if (queryIndex <= 0) {
|
||||
queryIndex = -1;
|
||||
} else {
|
||||
// if read continuous mode is enabled for multiple devices,
|
||||
// determine which device to stop reading and remove it's data from
|
||||
// the array, shifiting other array data to fill the space
|
||||
for (byte i = 0; i < queryIndex + 1; i++) {
|
||||
if (query[i].addr = slaveAddress) {
|
||||
queryIndexToSkip = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = queryIndexToSkip; i<queryIndex + 1; i++) {
|
||||
if (i < MAX_QUERIES) {
|
||||
query[i].addr = query[i+1].addr;
|
||||
query[i].reg = query[i+1].addr;
|
||||
query[i].bytes = query[i+1].bytes;
|
||||
}
|
||||
}
|
||||
queryIndex--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case I2C_CONFIG:
|
||||
delayTime = (argv[0] + (argv[1] << 7));
|
||||
|
||||
if(delayTime > 0) {
|
||||
i2cReadDelayTime = delayTime;
|
||||
}
|
||||
|
||||
if (!isI2CEnabled) {
|
||||
enableI2CPins();
|
||||
}
|
||||
|
||||
break;
|
||||
case SERVO_CONFIG:
|
||||
if(argc > 4) {
|
||||
// these vars are here for clarity, they'll optimized away by the compiler
|
||||
byte pin = argv[0];
|
||||
int minPulse = argv[1] + (argv[2] << 7);
|
||||
int maxPulse = argv[3] + (argv[4] << 7);
|
||||
|
||||
if (IS_PIN_SERVO(pin)) {
|
||||
if (servos[PIN_TO_SERVO(pin)].attached())
|
||||
servos[PIN_TO_SERVO(pin)].detach();
|
||||
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
|
||||
setPinModeCallback(pin, SERVO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SAMPLING_INTERVAL:
|
||||
if (argc > 1) {
|
||||
samplingInterval = argv[0] + (argv[1] << 7);
|
||||
if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
|
||||
samplingInterval = MINIMUM_SAMPLING_INTERVAL;
|
||||
}
|
||||
} else {
|
||||
//BLE_Firmata.sendString("Not enough data");
|
||||
}
|
||||
break;
|
||||
case EXTENDED_ANALOG:
|
||||
if (argc > 1) {
|
||||
int val = argv[1];
|
||||
if (argc > 2) val |= (argv[2] << 7);
|
||||
if (argc > 3) val |= (argv[3] << 14);
|
||||
analogWriteCallback(argv[0], val);
|
||||
}
|
||||
break;
|
||||
case CAPABILITY_QUERY:
|
||||
Serial.write(START_SYSEX);
|
||||
Serial.write(CAPABILITY_RESPONSE);
|
||||
for (byte pin=0; pin < TOTAL_PINS; pin++) {
|
||||
if (IS_PIN_DIGITAL(pin)) {
|
||||
Serial.write((byte)INPUT);
|
||||
Serial.write(1);
|
||||
Serial.write((byte)OUTPUT);
|
||||
Serial.write(1);
|
||||
}
|
||||
if (IS_PIN_ANALOG(pin)) {
|
||||
Serial.write(ANALOG);
|
||||
Serial.write(10);
|
||||
}
|
||||
if (IS_PIN_PWM(pin)) {
|
||||
Serial.write(PWM);
|
||||
Serial.write(8);
|
||||
}
|
||||
if (IS_PIN_SERVO(pin)) {
|
||||
Serial.write(SERVO);
|
||||
Serial.write(14);
|
||||
}
|
||||
if (IS_PIN_I2C(pin)) {
|
||||
Serial.write(I2C);
|
||||
Serial.write(1); // to do: determine appropriate value
|
||||
}
|
||||
Serial.write(127);
|
||||
}
|
||||
Serial.write(END_SYSEX);
|
||||
break;
|
||||
case PIN_STATE_QUERY:
|
||||
if (argc > 0) {
|
||||
byte pin=argv[0];
|
||||
Serial.write(START_SYSEX);
|
||||
Serial.write(PIN_STATE_RESPONSE);
|
||||
Serial.write(pin);
|
||||
if (pin < TOTAL_PINS) {
|
||||
Serial.write((byte)pinConfig[pin]);
|
||||
Serial.write((byte)pinState[pin] & 0x7F);
|
||||
if (pinState[pin] & 0xFF80) Serial.write((byte)(pinState[pin] >> 7) & 0x7F);
|
||||
if (pinState[pin] & 0xC000) Serial.write((byte)(pinState[pin] >> 14) & 0x7F);
|
||||
}
|
||||
Serial.write(END_SYSEX);
|
||||
}
|
||||
break;
|
||||
case ANALOG_MAPPING_QUERY:
|
||||
Serial.write(START_SYSEX);
|
||||
Serial.write(ANALOG_MAPPING_RESPONSE);
|
||||
for (byte pin=0; pin < TOTAL_PINS; pin++) {
|
||||
Serial.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
|
||||
}
|
||||
Serial.write(END_SYSEX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void enableI2CPins()
|
||||
{
|
||||
byte i;
|
||||
// is there a faster way to do this? would probaby require importing
|
||||
// Arduino.h to get SCL and SDA pins
|
||||
for (i=0; i < TOTAL_PINS; i++) {
|
||||
if(IS_PIN_I2C(i)) {
|
||||
// mark pins as i2c so they are ignore in non i2c data requests
|
||||
setPinModeCallback(i, I2C);
|
||||
}
|
||||
}
|
||||
|
||||
isI2CEnabled = true;
|
||||
|
||||
// is there enough time before the first I2C request to call this here?
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
/* disable the i2c pins so they can be used for other functions */
|
||||
void disableI2CPins() {
|
||||
isI2CEnabled = false;
|
||||
// disable read continuous mode for all devices
|
||||
queryIndex = -1;
|
||||
// uncomment the following if or when the end() method is added to Wire library
|
||||
// Wire.end();
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* SETUP()
|
||||
*============================================================================*/
|
||||
|
||||
void systemResetCallback()
|
||||
{
|
||||
// initialize a defalt state
|
||||
Serial.println(F("***RESET***"));
|
||||
// TODO: option to load config from EEPROM instead of default
|
||||
if (isI2CEnabled) {
|
||||
disableI2CPins();
|
||||
}
|
||||
for (byte i=0; i < TOTAL_PORTS; i++) {
|
||||
reportPINs[i] = false; // by default, reporting off
|
||||
portConfigInputs[i] = 0; // until activated
|
||||
previousPINs[i] = 0;
|
||||
}
|
||||
// pins with analog capability default to analog input
|
||||
// otherwise, pins default to digital output
|
||||
for (byte i=0; i < TOTAL_PINS; i++) {
|
||||
if (IS_PIN_ANALOG(i)) {
|
||||
// turns off pullup, configures everything
|
||||
setPinModeCallback(i, ANALOG);
|
||||
} else {
|
||||
// sets the output to 0, configures portConfigInputs
|
||||
setPinModeCallback(i, INPUT);
|
||||
}
|
||||
}
|
||||
// by default, do not report any analog inputs
|
||||
analogInputsToReport = 0;
|
||||
|
||||
/* send digital inputs to set the initial state on the host computer,
|
||||
* since once in the loop(), this firmware will only send on change */
|
||||
/*
|
||||
TODO: this can never execute, since no pins default to digital input
|
||||
but it will be needed when/if we support EEPROM stored config
|
||||
for (byte i=0; i < TOTAL_PORTS; i++) {
|
||||
outputPort(i, readPort(i, portConfigInputs[i]), true);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
aci_evt_opcode_t lastBTLEstatus, BTLEstatus;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
Serial.println(F("Adafruit BTLE Firmata test"));
|
||||
|
||||
BLEserial.begin();
|
||||
|
||||
BTLEstatus = lastBTLEstatus = ACI_EVT_DISCONNECTED;
|
||||
}
|
||||
|
||||
void firmataInit() {
|
||||
Serial.println(F("Init firmata"));
|
||||
//BLE_Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
|
||||
//Serial.println(F("firmata analog"));
|
||||
BLE_Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
|
||||
//Serial.println(F("firmata digital"));
|
||||
BLE_Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
|
||||
//Serial.println(F("firmata analog report"));
|
||||
BLE_Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
|
||||
//Serial.println(F("firmata digital report"));
|
||||
BLE_Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
|
||||
//Serial.println(F("firmata pinmode"));
|
||||
BLE_Firmata.attach(SET_PIN_MODE, setPinModeCallback);
|
||||
//Serial.println(F("firmata sysex"));
|
||||
BLE_Firmata.attach(START_SYSEX, sysexCallback);
|
||||
//Serial.println(F("firmata reset"));
|
||||
BLE_Firmata.attach(SYSTEM_RESET, systemResetCallback);
|
||||
|
||||
Serial.println(F("Begin firmata"));
|
||||
BLE_Firmata.begin();
|
||||
systemResetCallback(); // reset to default config
|
||||
}
|
||||
/*==============================================================================
|
||||
* LOOP()
|
||||
*============================================================================*/
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Check the BTLE link, how're we doing?
|
||||
BLEserial.pollACI();
|
||||
// Link status check
|
||||
BTLEstatus = BLEserial.getState();
|
||||
|
||||
// Check if something has changed
|
||||
if (BTLEstatus != lastBTLEstatus) {
|
||||
// print it out!
|
||||
if (BTLEstatus == ACI_EVT_DEVICE_STARTED) {
|
||||
Serial.println(F("* Advertising started"));
|
||||
}
|
||||
if (BTLEstatus == ACI_EVT_CONNECTED) {
|
||||
Serial.println(F("* Connected!"));
|
||||
// initialize Firmata cleanly
|
||||
firmataInit();
|
||||
}
|
||||
if (BTLEstatus == ACI_EVT_DISCONNECTED) {
|
||||
Serial.println(F("* Disconnected or advertising timed out"));
|
||||
}
|
||||
// OK set the last status change to this one
|
||||
lastBTLEstatus = BTLEstatus;
|
||||
}
|
||||
|
||||
// if not connected... bail
|
||||
if (BTLEstatus != ACI_EVT_CONNECTED) {
|
||||
delay(100);
|
||||
return;
|
||||
}
|
||||
|
||||
// For debugging, see if there's data on the serial console, we would forwad it to BTLE
|
||||
if (Serial.available()) {
|
||||
BLEserial.write(Serial.read());
|
||||
}
|
||||
|
||||
// Onto the Firmata main loop
|
||||
|
||||
byte pin, analogPin;
|
||||
|
||||
/* DIGITALREAD - as fast as possible, check for changes and output them to the
|
||||
* BTLE buffer using Serial.print() */
|
||||
checkDigitalInputs();
|
||||
|
||||
/* SERIALREAD - processing incoming messagse as soon as possible, while still
|
||||
* checking digital inputs. */
|
||||
while(BLE_Firmata.available()) {
|
||||
//Serial.println(F("*data available*"));
|
||||
BLE_Firmata.processInput();
|
||||
}
|
||||
/* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
|
||||
* 60 bytes. use a timer to sending an event character every 4 ms to
|
||||
* trigger the buffer to dump. */
|
||||
|
||||
// make the sampling interval longer if we have more analog inputs!
|
||||
uint8_t analogreportnums = 0;
|
||||
for(uint8_t a=0; a<8; a++) {
|
||||
if (analogInputsToReport & (1 << a)) {
|
||||
analogreportnums++;
|
||||
}
|
||||
}
|
||||
|
||||
samplingInterval = (uint16_t)MINIMUM_SAMPLE_DELAY + (uint16_t)ANALOG_SAMPLE_DELAY * (1+analogreportnums);
|
||||
|
||||
currentMillis = millis();
|
||||
if (currentMillis - previousMillis > samplingInterval) {
|
||||
previousMillis += samplingInterval;
|
||||
/* ANALOGREAD - do all analogReads() at the configured sampling interval */
|
||||
for(pin=0; pin<TOTAL_PINS; pin++) {
|
||||
if (IS_PIN_ANALOG(pin) && (pinConfig[pin] == ANALOG)) {
|
||||
analogPin = PIN_TO_ANALOG(pin);
|
||||
|
||||
if (analogInputsToReport & (1 << analogPin)) {
|
||||
int currentRead = analogRead(analogPin);
|
||||
|
||||
if ((lastAnalogReads[analogPin] == -1) || (lastAnalogReads[analogPin] != currentRead)) {
|
||||
Serial.print(F("Analog")); Serial.print(analogPin); Serial.print(F(" = ")); Serial.println(currentRead);
|
||||
BLE_Firmata.sendAnalog(analogPin, currentRead);
|
||||
lastAnalogReads[analogPin] = currentRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// report i2c data for all device with read continuous mode enabled
|
||||
if (queryIndex > -1) {
|
||||
for (byte i = 0; i < queryIndex + 1; i++) {
|
||||
readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/keywords.txt
Executable file
62
Projects/libraries/Installed_libs/Adafruit_BLEFirmata/keywords.txt
Executable file
@@ -0,0 +1,62 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Firmata
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
Firmata KEYWORD1
|
||||
callbackFunction KEYWORD1
|
||||
systemResetCallbackFunction KEYWORD1
|
||||
stringCallbackFunction KEYWORD1
|
||||
sysexCallbackFunction KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
begin KEYWORD2
|
||||
printVersion KEYWORD2
|
||||
blinkVersion KEYWORD2
|
||||
printFirmwareVersion KEYWORD2
|
||||
setFirmwareVersion KEYWORD2
|
||||
setFirmwareNameAndVersion KEYWORD2
|
||||
available KEYWORD2
|
||||
processInput KEYWORD2
|
||||
sendAnalog KEYWORD2
|
||||
sendDigital KEYWORD2
|
||||
sendDigitalPortPair KEYWORD2
|
||||
sendDigitalPort KEYWORD2
|
||||
sendString KEYWORD2
|
||||
sendString KEYWORD2
|
||||
sendSysex KEYWORD2
|
||||
attach KEYWORD2
|
||||
detach KEYWORD2
|
||||
flush KEYWORD2
|
||||
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
MAX_DATA_BYTES LITERAL1
|
||||
|
||||
DIGITAL_MESSAGE LITERAL1
|
||||
ANALOG_MESSAGE LITERAL1
|
||||
REPORT_ANALOG LITERAL1
|
||||
REPORT_DIGITAL LITERAL1
|
||||
REPORT_VERSION LITERAL1
|
||||
SET_PIN_MODE LITERAL1
|
||||
SYSTEM_RESET LITERAL1
|
||||
|
||||
START_SYSEX LITERAL1
|
||||
END_SYSEX LITERAL1
|
||||
|
||||
PWM LITERAL1
|
||||
|
||||
TOTAL_ANALOG_PINS LITERAL1
|
||||
TOTAL_DIGITAL_PINS LITERAL1
|
||||
TOTAL_PORTS LITERAL1
|
||||
ANALOG_PORT LITERAL1
|
||||
483
Projects/libraries/Installed_libs/Adafruit_BLE_UART/Adafruit_BLE_UART.cpp
Executable file
483
Projects/libraries/Installed_libs/Adafruit_BLE_UART/Adafruit_BLE_UART.cpp
Executable file
@@ -0,0 +1,483 @@
|
||||
/*********************************************************************
|
||||
This is a library for our nRF8001 Bluetooth Low Energy Breakout
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/products/1697
|
||||
|
||||
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||
interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Kevin Townsend/KTOWN for Adafruit Industries.
|
||||
MIT license, check LICENSE for more information
|
||||
All text above, and the splash screen below must be included in any redistribution
|
||||
*********************************************************************/
|
||||
#include <SPI.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdlib.h>
|
||||
#include <ble_system.h>
|
||||
#include <lib_aci.h>
|
||||
#include <aci_setup.h>
|
||||
#include "uart/services.h"
|
||||
|
||||
#include "Adafruit_BLE_UART.h"
|
||||
|
||||
/* Get the service pipe data created in nRFGo Studio */
|
||||
#ifdef SERVICES_PIPE_TYPE_MAPPING_CONTENT
|
||||
static services_pipe_type_mapping_t
|
||||
services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
|
||||
#else
|
||||
#define NUMBER_OF_PIPES 0
|
||||
static services_pipe_type_mapping_t * services_pipe_type_mapping = NULL;
|
||||
#endif
|
||||
|
||||
/* Length of the buffer used to store flash strings temporarily when printing. */
|
||||
#define PRINT_BUFFER_SIZE 20
|
||||
|
||||
/* Store the setup for the nRF8001 in the flash of the AVR to save on RAM */
|
||||
static const hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] PROGMEM = SETUP_MESSAGES_CONTENT;
|
||||
|
||||
static struct aci_state_t aci_state; /* ACI state data */
|
||||
static hal_aci_evt_t aci_data; /* Command buffer */
|
||||
static bool timing_change_done = false;
|
||||
|
||||
// This is the Uart RX buffer, which we manage internally when data is available!
|
||||
#define ADAFRUIT_BLE_UART_RXBUFFER_SIZE 64
|
||||
uint8_t adafruit_ble_rx_buffer[ADAFRUIT_BLE_UART_RXBUFFER_SIZE];
|
||||
volatile uint16_t adafruit_ble_rx_head;
|
||||
volatile uint16_t adafruit_ble_rx_tail;
|
||||
|
||||
|
||||
int8_t HAL_IO_RADIO_RESET, HAL_IO_RADIO_REQN, HAL_IO_RADIO_RDY, HAL_IO_RADIO_IRQ;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Constructor for the UART service
|
||||
*/
|
||||
/**************************************************************************/
|
||||
// default RX callback!
|
||||
|
||||
void Adafruit_BLE_UART::defaultRX(uint8_t *buffer, uint8_t len)
|
||||
{
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
uint16_t new_head = (uint16_t)(adafruit_ble_rx_head + 1) % ADAFRUIT_BLE_UART_RXBUFFER_SIZE;
|
||||
|
||||
// if we should be storing the received character into the location
|
||||
// just before the tail (meaning that the head would advance to the
|
||||
// current location of the tail), we're about to overflow the buffer
|
||||
// and so we don't write the character or advance the head.
|
||||
if (new_head != adafruit_ble_rx_tail) {
|
||||
adafruit_ble_rx_buffer[adafruit_ble_rx_head] = buffer[i];
|
||||
|
||||
// debug echo print
|
||||
// Serial.print((char)buffer[i]);
|
||||
|
||||
adafruit_ble_rx_head = new_head;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Serial.print("Buffer: ");
|
||||
for(int i=0; i<adafruit_ble_rx_head; i++)
|
||||
{
|
||||
Serial.print(" 0x"); Serial.print((char)adafruit_ble_rx_buffer[i], HEX);
|
||||
}
|
||||
Serial.println();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* Stream stuff */
|
||||
|
||||
int Adafruit_BLE_UART::available(void)
|
||||
{
|
||||
return (uint16_t)(ADAFRUIT_BLE_UART_RXBUFFER_SIZE + adafruit_ble_rx_head - adafruit_ble_rx_tail)
|
||||
% ADAFRUIT_BLE_UART_RXBUFFER_SIZE;
|
||||
}
|
||||
|
||||
int Adafruit_BLE_UART::read(void)
|
||||
{
|
||||
// if the head isn't ahead of the tail, we don't have any characters
|
||||
if (adafruit_ble_rx_head == adafruit_ble_rx_tail) {
|
||||
return -1;
|
||||
} else {
|
||||
unsigned char c = adafruit_ble_rx_buffer[adafruit_ble_rx_tail];
|
||||
adafruit_ble_rx_tail ++;
|
||||
adafruit_ble_rx_tail %= ADAFRUIT_BLE_UART_RXBUFFER_SIZE;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int Adafruit_BLE_UART::peek(void)
|
||||
{
|
||||
if (adafruit_ble_rx_head == adafruit_ble_rx_tail) {
|
||||
return -1;
|
||||
} else {
|
||||
return adafruit_ble_rx_buffer[adafruit_ble_rx_tail];
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_BLE_UART::flush(void)
|
||||
{
|
||||
// MEME: KTOWN what do we do here?
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// more callbacks
|
||||
|
||||
void Adafruit_BLE_UART::defaultACICallback(aci_evt_opcode_t event)
|
||||
{
|
||||
currentStatus = event;
|
||||
}
|
||||
|
||||
aci_evt_opcode_t Adafruit_BLE_UART::getState(void) {
|
||||
return currentStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Constructor for the UART service
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_BLE_UART::Adafruit_BLE_UART(int8_t req, int8_t rdy, int8_t rst)
|
||||
{
|
||||
debugMode = true;
|
||||
|
||||
HAL_IO_RADIO_REQN = req;
|
||||
HAL_IO_RADIO_RDY = rdy;
|
||||
HAL_IO_RADIO_RESET = rst;
|
||||
|
||||
rx_event = NULL;
|
||||
aci_event = NULL;
|
||||
|
||||
memset(device_name, 0x00, 8);
|
||||
|
||||
adafruit_ble_rx_head = adafruit_ble_rx_tail = 0;
|
||||
|
||||
currentStatus = ACI_EVT_DISCONNECTED;
|
||||
}
|
||||
|
||||
void Adafruit_BLE_UART::setACIcallback(aci_callback aciEvent) {
|
||||
aci_event = aciEvent;
|
||||
}
|
||||
|
||||
void Adafruit_BLE_UART::setRXcallback(rx_callback rxEvent) {
|
||||
rx_event = rxEvent;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Transmits data out via the TX characteristic (when available)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
size_t Adafruit_BLE_UART::println(const char * thestr)
|
||||
{
|
||||
uint8_t len = strlen(thestr),
|
||||
written = len ? write((uint8_t *)thestr, len) : 0;
|
||||
if(written == len) written += write((uint8_t *)"\r\n", 2);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::print(const char * thestr)
|
||||
{
|
||||
return write((uint8_t *)thestr, strlen(thestr));
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::print(String thestr)
|
||||
{
|
||||
return write((uint8_t *)thestr.c_str(), thestr.length());
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::print(int theint)
|
||||
{
|
||||
char message[4*sizeof(int)+1] = {0};
|
||||
itoa(theint, message, 10);
|
||||
return write((uint8_t *)message, strlen(message));
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
// Copy bytes from flash string into RAM, then send them a buffer at a time.
|
||||
char buffer[PRINT_BUFFER_SIZE] = {0};
|
||||
const char PROGMEM *p = (const char PROGMEM *)ifsh;
|
||||
size_t written = 0;
|
||||
int i = 0;
|
||||
unsigned char c = pgm_read_byte(p++);
|
||||
// Read data from flash until a null terminator is found.
|
||||
while (c != 0) {
|
||||
// Copy data to RAM and increase buffer index.
|
||||
buffer[i] = c;
|
||||
i++;
|
||||
if (i >= PRINT_BUFFER_SIZE) {
|
||||
// Send buffer when it's full and reset buffer index.
|
||||
written += write((uint8_t *)buffer, PRINT_BUFFER_SIZE);
|
||||
i = 0;
|
||||
}
|
||||
// Grab a new byte from flash.
|
||||
c = pgm_read_byte(p++);
|
||||
}
|
||||
if (i > 0) {
|
||||
// Send any remaining data in the buffer.
|
||||
written += write((uint8_t *)buffer, i);
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::write(uint8_t * buffer, uint8_t len)
|
||||
{
|
||||
uint8_t bytesThisPass, sent = 0;
|
||||
|
||||
#ifdef BLE_RW_DEBUG
|
||||
Serial.print(F("\tWriting out to BTLE:"));
|
||||
for (uint8_t i=0; i<len; i++) {
|
||||
Serial.print(F(" 0x")); Serial.print(buffer[i], HEX);
|
||||
}
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
while(len) { // Parcelize into chunks
|
||||
bytesThisPass = len;
|
||||
if(bytesThisPass > ACI_PIPE_TX_DATA_MAX_LEN)
|
||||
bytesThisPass = ACI_PIPE_TX_DATA_MAX_LEN;
|
||||
|
||||
if(!lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX))
|
||||
{
|
||||
pollACI();
|
||||
continue;
|
||||
}
|
||||
|
||||
lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer[sent],
|
||||
bytesThisPass);
|
||||
aci_state.data_credit_available--;
|
||||
|
||||
delay(35); // required delay between sends
|
||||
|
||||
if(!(len -= bytesThisPass)) break;
|
||||
sent += bytesThisPass;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
size_t Adafruit_BLE_UART::write(uint8_t buffer)
|
||||
{
|
||||
#ifdef BLE_RW_DEBUG
|
||||
Serial.print(F("\tWriting one byte 0x")); Serial.println(buffer, HEX);
|
||||
#endif
|
||||
if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX))
|
||||
{
|
||||
lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer, 1);
|
||||
aci_state.data_credit_available--;
|
||||
|
||||
delay(35); // required delay between sends
|
||||
return 1;
|
||||
}
|
||||
|
||||
pollACI();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Update the device name (7 characters or less!)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_BLE_UART::setDeviceName(const char * deviceName)
|
||||
{
|
||||
if (strlen(deviceName) > 7)
|
||||
{
|
||||
/* String too long! */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(device_name, deviceName, strlen(deviceName));
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Handles low level ACI events, and passes them up to an application
|
||||
level callback when appropriate
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_BLE_UART::pollACI()
|
||||
{
|
||||
// We enter the if statement only when there is a ACI event available to be processed
|
||||
if (lib_aci_event_get(&aci_state, &aci_data))
|
||||
{
|
||||
aci_evt_t * aci_evt;
|
||||
|
||||
aci_evt = &aci_data.evt;
|
||||
switch(aci_evt->evt_opcode)
|
||||
{
|
||||
/* As soon as you reset the nRF8001 you will get an ACI Device Started Event */
|
||||
case ACI_EVT_DEVICE_STARTED:
|
||||
{
|
||||
aci_state.data_credit_total = aci_evt->params.device_started.credit_available;
|
||||
switch(aci_evt->params.device_started.device_mode)
|
||||
{
|
||||
case ACI_DEVICE_SETUP:
|
||||
/* Device is in setup mode! */
|
||||
if (ACI_STATUS_TRANSACTION_COMPLETE != do_aci_setup(&aci_state))
|
||||
{
|
||||
if (debugMode) {
|
||||
Serial.println(F("Error in ACI Setup"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_DEVICE_STANDBY:
|
||||
/* Start advertising ... first value is advertising time in seconds, the */
|
||||
/* second value is the advertising interval in 0.625ms units */
|
||||
if (device_name[0] != 0x00)
|
||||
{
|
||||
/* Update the device name */
|
||||
lib_aci_set_local_data(&aci_state, PIPE_GAP_DEVICE_NAME_SET , (uint8_t *)&device_name, strlen(device_name));
|
||||
}
|
||||
lib_aci_connect(adv_timeout, adv_interval);
|
||||
defaultACICallback(ACI_EVT_DEVICE_STARTED);
|
||||
if (aci_event)
|
||||
aci_event(ACI_EVT_DEVICE_STARTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_EVT_CMD_RSP:
|
||||
/* If an ACI command response event comes with an error -> stop */
|
||||
if (ACI_STATUS_SUCCESS != aci_evt->params.cmd_rsp.cmd_status)
|
||||
{
|
||||
// ACI ReadDynamicData and ACI WriteDynamicData will have status codes of
|
||||
// TRANSACTION_CONTINUE and TRANSACTION_COMPLETE
|
||||
// all other ACI commands will have status code of ACI_STATUS_SUCCESS for a successful command
|
||||
if (debugMode) {
|
||||
Serial.print(F("ACI Command "));
|
||||
Serial.println(aci_evt->params.cmd_rsp.cmd_opcode, HEX);
|
||||
Serial.println(F("Evt Cmd respone: Error. Arduino is in an while(1); loop"));
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
if (ACI_CMD_GET_DEVICE_VERSION == aci_evt->params.cmd_rsp.cmd_opcode)
|
||||
{
|
||||
// Store the version and configuration information of the nRF8001 in the Hardware Revision String Characteristic
|
||||
lib_aci_set_local_data(&aci_state, PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET,
|
||||
(uint8_t *)&(aci_evt->params.cmd_rsp.params.get_device_version), sizeof(aci_evt_cmd_rsp_params_get_device_version_t));
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_EVT_CONNECTED:
|
||||
aci_state.data_credit_available = aci_state.data_credit_total;
|
||||
/* Get the device version of the nRF8001 and store it in the Hardware Revision String */
|
||||
lib_aci_device_version();
|
||||
|
||||
defaultACICallback(ACI_EVT_CONNECTED);
|
||||
if (aci_event)
|
||||
aci_event(ACI_EVT_CONNECTED);
|
||||
|
||||
case ACI_EVT_PIPE_STATUS:
|
||||
if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX) && (false == timing_change_done))
|
||||
{
|
||||
lib_aci_change_timing_GAP_PPCP(); // change the timing on the link as specified in the nRFgo studio -> nRF8001 conf. -> GAP.
|
||||
// Used to increase or decrease bandwidth
|
||||
timing_change_done = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_EVT_TIMING:
|
||||
/* Link connection interval changed */
|
||||
break;
|
||||
|
||||
case ACI_EVT_DISCONNECTED:
|
||||
/* Restart advertising ... first value is advertising time in seconds, the */
|
||||
/* second value is the advertising interval in 0.625ms units */
|
||||
|
||||
defaultACICallback(ACI_EVT_DISCONNECTED);
|
||||
if (aci_event)
|
||||
aci_event(ACI_EVT_DISCONNECTED);
|
||||
|
||||
lib_aci_connect(adv_timeout, adv_interval);
|
||||
|
||||
defaultACICallback(ACI_EVT_DEVICE_STARTED);
|
||||
if (aci_event)
|
||||
aci_event(ACI_EVT_DEVICE_STARTED);
|
||||
break;
|
||||
|
||||
case ACI_EVT_DATA_RECEIVED:
|
||||
defaultRX(aci_evt->params.data_received.rx_data.aci_data, aci_evt->len - 2);
|
||||
if (rx_event)
|
||||
rx_event(aci_evt->params.data_received.rx_data.aci_data, aci_evt->len - 2);
|
||||
break;
|
||||
|
||||
case ACI_EVT_DATA_CREDIT:
|
||||
aci_state.data_credit_available = aci_state.data_credit_available + aci_evt->params.data_credit.credit;
|
||||
break;
|
||||
|
||||
case ACI_EVT_PIPE_ERROR:
|
||||
/* See the appendix in the nRF8001 Product Specication for details on the error codes */
|
||||
if (debugMode) {
|
||||
Serial.print(F("ACI Evt Pipe Error: Pipe #:"));
|
||||
Serial.print(aci_evt->params.pipe_error.pipe_number, DEC);
|
||||
Serial.print(F(" Pipe Error Code: 0x"));
|
||||
Serial.println(aci_evt->params.pipe_error.error_code, HEX);
|
||||
}
|
||||
|
||||
/* Increment the credit available as the data packet was not sent */
|
||||
aci_state.data_credit_available++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Serial.println(F("No ACI Events available"));
|
||||
// No event in the ACI Event queue and if there is no event in the ACI command queue the arduino can go to sleep
|
||||
// Arduino can go to sleep now
|
||||
// Wakeup from sleep from the RDYN line
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Configures the nRF8001 and starts advertising the UART Service
|
||||
|
||||
@param[in] advTimeout
|
||||
The advertising timeout in seconds (0 = infinite advertising)
|
||||
@param[in] advInterval
|
||||
The delay between advertising packets in 0.625ms units
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_BLE_UART::begin(uint16_t advTimeout, uint16_t advInterval)
|
||||
{
|
||||
/* Store the advertising timeout and interval */
|
||||
adv_timeout = advTimeout; /* ToDo: Check range! */
|
||||
adv_interval = advInterval; /* ToDo: Check range! */
|
||||
|
||||
/* Setup the service data from nRFGo Studio (services.h) */
|
||||
if (NULL != services_pipe_type_mapping)
|
||||
{
|
||||
aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
aci_state.aci_setup_info.services_pipe_type_mapping = NULL;
|
||||
}
|
||||
aci_state.aci_setup_info.number_of_pipes = NUMBER_OF_PIPES;
|
||||
aci_state.aci_setup_info.setup_msgs = (hal_aci_data_t*)setup_msgs;
|
||||
aci_state.aci_setup_info.num_setup_msgs = NB_SETUP_MESSAGES;
|
||||
|
||||
/* Pass the service data into the appropriate struct in the ACI */
|
||||
lib_aci_init(&aci_state);
|
||||
|
||||
/* ToDo: Check for chip ID to make sure we're connected! */
|
||||
|
||||
return true;
|
||||
}
|
||||
86
Projects/libraries/Installed_libs/Adafruit_BLE_UART/Adafruit_BLE_UART.h
Executable file
86
Projects/libraries/Installed_libs/Adafruit_BLE_UART/Adafruit_BLE_UART.h
Executable file
@@ -0,0 +1,86 @@
|
||||
/*********************************************************************
|
||||
This is a library for our nRF8001 Bluetooth Low Energy Breakout
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/products/1697
|
||||
|
||||
These displays use SPI to communicate, 4 or 5 pins are required to
|
||||
interface
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Kevin Townsend/KTOWN for Adafruit Industries.
|
||||
MIT license, check LICENSE for more information
|
||||
All text above, and the splash screen below must be included in any redistribution
|
||||
*********************************************************************/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ADAFRUIT_BLE_UART_H_
|
||||
#define _ADAFRUIT_BLE_UART_H_
|
||||
|
||||
#include "utility/aci_evts.h"
|
||||
|
||||
#define BLE_RW_DEBUG
|
||||
|
||||
extern "C"
|
||||
{
|
||||
/* Callback prototypes */
|
||||
typedef void (*aci_callback)(aci_evt_opcode_t event);
|
||||
typedef void (*rx_callback) (uint8_t *buffer, uint8_t len);
|
||||
}
|
||||
|
||||
class Adafruit_BLE_UART : public Stream
|
||||
{
|
||||
public:
|
||||
Adafruit_BLE_UART (int8_t req, int8_t rdy, int8_t rst);
|
||||
|
||||
bool begin ( uint16_t advTimeout = 0, uint16_t advInterval = 80 );
|
||||
void pollACI ( void );
|
||||
size_t write ( uint8_t * buffer, uint8_t len );
|
||||
size_t write ( uint8_t buffer);
|
||||
|
||||
size_t println(const char * thestr);
|
||||
size_t print(const char * thestr);
|
||||
size_t print(String thestr);
|
||||
size_t print(int theint);
|
||||
size_t print(const __FlashStringHelper *ifsh);
|
||||
|
||||
void setACIcallback(aci_callback aciEvent = NULL);
|
||||
void setRXcallback(rx_callback rxEvent = NULL);
|
||||
void setDeviceName(const char * deviceName);
|
||||
|
||||
// Stream compatibility
|
||||
int available(void);
|
||||
int read(void);
|
||||
int peek(void);
|
||||
void flush(void);
|
||||
|
||||
aci_evt_opcode_t getState(void);
|
||||
|
||||
private:
|
||||
void defaultACICallback(aci_evt_opcode_t event);
|
||||
void defaultRX(uint8_t *buffer, uint8_t len);
|
||||
|
||||
// callbacks you can set with setCallback function for user extension
|
||||
aci_callback aci_event;
|
||||
rx_callback rx_event;
|
||||
|
||||
bool debugMode;
|
||||
uint16_t adv_timeout;
|
||||
uint16_t adv_interval;
|
||||
char device_name[8];
|
||||
|
||||
aci_evt_opcode_t currentStatus;
|
||||
|
||||
// pins usd
|
||||
int8_t _REQ, _RDY, _RST;
|
||||
};
|
||||
|
||||
#endif
|
||||
48
Projects/libraries/Installed_libs/Adafruit_BLE_UART/README.md
Executable file
48
Projects/libraries/Installed_libs/Adafruit_BLE_UART/README.md
Executable file
@@ -0,0 +1,48 @@
|
||||
# Adafruit_nRF8001 #
|
||||
|
||||
Driver and example code for Adafruit's nRF8001 Bluetooth Low Energy Breakout.
|
||||
|
||||
## PINOUT ##
|
||||
|
||||
The pin locations are defined in **ble_system.h**, the supported systems are defined in **hal_aci_tl.cpp**. The following pinout is used by default for the Arduino Uno:
|
||||
|
||||
* SCK -> Pin 13
|
||||
* MISO -> Pin 12
|
||||
* MOSI -> Pin 11
|
||||
* REQ -> Pin 10
|
||||
* RDY -> Pin 2 (HW interrupt)
|
||||
* ACT -> Not connected
|
||||
* RST -> Pin 9
|
||||
* 3V0 - > Not connected
|
||||
* GND -> GND
|
||||
* VIN -> 5V
|
||||
|
||||
RDY must be on pin 2 since this pin requires a HW interrupt.
|
||||
|
||||
3V0 is an optional pin that exposes the output of the on-board 3.3V regulator. You can use this to supply 3.3V to other peripherals, but normally it will be left unconnected.
|
||||
|
||||
ACT is not currently used in any of the existing examples, and can be left unconnected if necessary.
|
||||
|
||||
# Examples #
|
||||
|
||||
The following examples are included for the Adafruit nRF8001 Breakout
|
||||
|
||||
## UART ##
|
||||
|
||||
This example creates a UART-style bridge between the Arduino and any BLE capable device.
|
||||
|
||||
You can send and receive up to 20 bytes at a time between your BLE-enabled phone or tablet and the Arduino.
|
||||
|
||||
Any data sent to the Arduino will be displayed in the Serial Monitor output, and echo'ed back to the phone or tablet on the mobile device's RX channel.
|
||||
|
||||
This demo creates a custom UART service, with one characteristic for TX and one for RX using the following UUIDs:
|
||||
|
||||
* 6E400001-B5A3-F393-E0A9-E50E24DCCA9E for the Service
|
||||
* 6E400002-B5A3-F393-E0A9-E50E24DCCA9E for the TX Characteristic (Property = Notify)
|
||||
* 6E400003-B5A3-F393-E0A9-E50E24DCCA9E for the RX Characteristic (Property = Write without response)
|
||||
|
||||
You can test the UART service with the free nRF UART apps from Nordic Semiconductors, available for both iOS and Android:
|
||||
|
||||
* Compatible iOS devices: https://itunes.apple.com/us/app/nrf-uart/id614594903?mt=8
|
||||
* Compatible Android 4.3 and higher devices: https://play.google.com/store/apps/details?id=com.nordicsemi.nrfUARTv2
|
||||
* Compatible pre Android 4.3 Samsung devices (uses a proprietary Samsung BLE stack): https://play.google.com/store/apps/details?id=com.nordicsemi.nrfUART
|
||||
@@ -0,0 +1,100 @@
|
||||
/*********************************************************************
|
||||
This is an example for our nRF8001 Bluetooth Low Energy Breakout
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/products/1697
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Kevin Townsend/KTOWN for Adafruit Industries.
|
||||
MIT license, check LICENSE for more information
|
||||
All text above, and the splash screen below must be included in any redistribution
|
||||
*********************************************************************/
|
||||
|
||||
// This version uses call-backs on the event and RX so there's no data handling in the main loop!
|
||||
|
||||
#include <SPI.h>
|
||||
#include "Adafruit_BLE_UART.h"
|
||||
|
||||
#define ADAFRUITBLE_REQ 10
|
||||
#define ADAFRUITBLE_RDY 2
|
||||
#define ADAFRUITBLE_RST 9
|
||||
|
||||
Adafruit_BLE_UART uart = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
This function is called whenever select ACI events happen
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void aciCallback(aci_evt_opcode_t event)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case ACI_EVT_DEVICE_STARTED:
|
||||
Serial.println(F("Advertising started"));
|
||||
break;
|
||||
case ACI_EVT_CONNECTED:
|
||||
Serial.println(F("Connected!"));
|
||||
break;
|
||||
case ACI_EVT_DISCONNECTED:
|
||||
Serial.println(F("Disconnected or advertising timed out"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
This function is called whenever data arrives on the RX channel
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void rxCallback(uint8_t *buffer, uint8_t len)
|
||||
{
|
||||
Serial.print(F("Received "));
|
||||
Serial.print(len);
|
||||
Serial.print(F(" bytes: "));
|
||||
for(int i=0; i<len; i++)
|
||||
Serial.print((char)buffer[i]);
|
||||
|
||||
Serial.print(F(" ["));
|
||||
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
Serial.print(" 0x"); Serial.print((char)buffer[i], HEX);
|
||||
}
|
||||
Serial.println(F(" ]"));
|
||||
|
||||
/* Echo the same data back! */
|
||||
uart.write(buffer, len);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Configure the Arduino and start advertising with the radio
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
while(!Serial); // Leonardo/Micro should wait for serial init
|
||||
Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Callback Echo demo"));
|
||||
|
||||
uart.setRXcallback(rxCallback);
|
||||
uart.setACIcallback(aciCallback);
|
||||
// uart.setDeviceName("NEWNAME"); /* 7 characters max! */
|
||||
uart.begin();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Constantly checks for new events on the nRF8001
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void loop()
|
||||
{
|
||||
uart.pollACI();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*********************************************************************
|
||||
This is an example for our nRF8001 Bluetooth Low Energy Breakout
|
||||
|
||||
Pick one up today in the adafruit shop!
|
||||
------> http://www.adafruit.com/products/1697
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Kevin Townsend/KTOWN for Adafruit Industries.
|
||||
MIT license, check LICENSE for more information
|
||||
All text above, and the splash screen below must be included in any redistribution
|
||||
*********************************************************************/
|
||||
|
||||
// This version uses the internal data queing so you can treat it like Serial (kinda)!
|
||||
|
||||
#include <SPI.h>
|
||||
#include "Adafruit_BLE_UART.h"
|
||||
|
||||
// Connect CLK/MISO/MOSI to hardware SPI
|
||||
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
|
||||
#define ADAFRUITBLE_REQ 10
|
||||
#define ADAFRUITBLE_RDY 2 // This should be an interrupt pin, on Uno thats #2 or #3
|
||||
#define ADAFRUITBLE_RST 9
|
||||
|
||||
Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Configure the Arduino and start advertising with the radio
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(9600);
|
||||
while(!Serial); // Leonardo/Micro should wait for serial init
|
||||
Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));
|
||||
|
||||
// BTLEserial.setDeviceName("NEWNAME"); /* 7 characters max! */
|
||||
|
||||
BTLEserial.begin();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
Constantly checks for new events on the nRF8001
|
||||
*/
|
||||
/**************************************************************************/
|
||||
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Tell the nRF8001 to do whatever it should be working on.
|
||||
BTLEserial.pollACI();
|
||||
|
||||
// Ask what is our current status
|
||||
aci_evt_opcode_t status = BTLEserial.getState();
|
||||
// If the status changed....
|
||||
if (status != laststatus) {
|
||||
// print it out!
|
||||
if (status == ACI_EVT_DEVICE_STARTED) {
|
||||
Serial.println(F("* Advertising started"));
|
||||
}
|
||||
if (status == ACI_EVT_CONNECTED) {
|
||||
Serial.println(F("* Connected!"));
|
||||
}
|
||||
if (status == ACI_EVT_DISCONNECTED) {
|
||||
Serial.println(F("* Disconnected or advertising timed out"));
|
||||
}
|
||||
// OK set the last status change to this one
|
||||
laststatus = status;
|
||||
}
|
||||
|
||||
if (status == ACI_EVT_CONNECTED) {
|
||||
// Lets see if there's any data for us!
|
||||
if (BTLEserial.available()) {
|
||||
Serial.print("* "); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
|
||||
}
|
||||
// OK while we still have something to read, get a character and print it out
|
||||
while (BTLEserial.available()) {
|
||||
char c = BTLEserial.read();
|
||||
Serial.print(c);
|
||||
}
|
||||
|
||||
// Next up, see if we have any data to get from the Serial console
|
||||
|
||||
if (Serial.available()) {
|
||||
// Read a line from Serial
|
||||
Serial.setTimeout(100); // 100 millisecond timeout
|
||||
String s = Serial.readString();
|
||||
|
||||
// We need to convert the line to bytes, no more than 20 at this time
|
||||
uint8_t sendbuffer[20];
|
||||
s.getBytes(sendbuffer, 20);
|
||||
char sendbuffersize = min(20, s.length());
|
||||
|
||||
Serial.print(F("\n* Sending -> \"")); Serial.print((char *)sendbuffer); Serial.println("\"");
|
||||
|
||||
// write the data
|
||||
BTLEserial.write(sendbuffer, sendbuffersize);
|
||||
}
|
||||
}
|
||||
}
|
||||
608
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci.h
Executable file
608
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci.h
Executable file
@@ -0,0 +1,608 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @defgroup aci aci
|
||||
* @{
|
||||
* @ingroup lib
|
||||
*
|
||||
* @brief Definitions for the ACI (Application Control Interface)
|
||||
* @remarks
|
||||
*
|
||||
* Flow control from application mcu to nRF8001
|
||||
*
|
||||
* Data flow control:
|
||||
* The flow control is credit based and the credit is initally given using the "device started" event.
|
||||
* A credit of more than 1 is given to the application mcu.
|
||||
* These credits are used only after the "ACI Connected Event" is sent to the application mcu.
|
||||
*
|
||||
* every send_data that is used decrements the credit available by 1. This is to be tracked by the application mcu.
|
||||
* When the credit available reaches 0, the application mcu shall not send any more send_data.
|
||||
* Credit is returned using the "credit event", this returned credit can then be used to send more send_data.
|
||||
* This flow control is not necessary and not available for Broadcast.
|
||||
* The entire credit available with the external mcu expires when a "disconnected" event arrives.
|
||||
*
|
||||
* Command flow control:
|
||||
* When a command is sent over the ACI, the next command shall not be sent until after a response
|
||||
* for the command sent has arrived.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ACI_H__
|
||||
#define ACI_H__
|
||||
|
||||
/**
|
||||
* @def ACI_VERSION
|
||||
* @brief Current ACI protocol version. 0 means a device that is not yet released.
|
||||
* A numer greater than 0 refers to a specific ACI version documented and released.
|
||||
* The ACI consists of the ACI commands, ACI events and error codes.
|
||||
*/
|
||||
#define ACI_VERSION (0x02)
|
||||
/**
|
||||
* @def BTLE_DEVICE_ADDRESS_SIZE
|
||||
* @brief Size in bytes of a Bluetooth Address
|
||||
*/
|
||||
#define BTLE_DEVICE_ADDRESS_SIZE (6)
|
||||
/**
|
||||
* @def ACI_PACKET_MAX_LEN
|
||||
* @brief Maximum length in bytes of a full ACI packet, including length prefix, opcode and payload
|
||||
*/
|
||||
#define ACI_PACKET_MAX_LEN (32)
|
||||
/**
|
||||
* @def ACI_ECHO_DATA_MAX_LEN
|
||||
* @brief Maximum length in bytes of the echo data portion
|
||||
*/
|
||||
#define ACI_ECHO_DATA_MAX_LEN (ACI_PACKET_MAX_LEN - 3)
|
||||
/**
|
||||
* @def ACI_DEVICE_MAX_PIPES
|
||||
* @brief Maximum number of ACI pipes
|
||||
*/
|
||||
#define ACI_DEVICE_MAX_PIPES (62)
|
||||
/**
|
||||
* @def ACI_PIPE_TX_DATA_MAX_LEN
|
||||
* @brief Maximum length in bytes of a transmission data pipe packet
|
||||
*/
|
||||
#define ACI_PIPE_TX_DATA_MAX_LEN (20)
|
||||
/**
|
||||
* @def ACI_PIPE_RX_DATA_MAX_LEN
|
||||
* @brief Maximum length in bytes of a reception data pipe packet
|
||||
*/
|
||||
#define ACI_PIPE_RX_DATA_MAX_LEN (22)
|
||||
/**
|
||||
* @def ACI_GAP_DEVNAME_MAX_LEN
|
||||
* @brief Maximum length in bytes of the GAP device name
|
||||
*/
|
||||
#define ACI_GAP_DEVNAME_MAX_LEN (20)
|
||||
/**
|
||||
* @def ACI_AD_PACKET_MAX_LEN
|
||||
* @brief Maximum length in bytes of an AD packet
|
||||
*/
|
||||
#define ACI_AD_PACKET_MAX_LEN (31)
|
||||
/**
|
||||
* @def ACI_AD_PACKET_MAX_USER_LEN
|
||||
* @brief Maximum usable length in bytes of an AD packet
|
||||
*/
|
||||
#define ACI_AD_PACKET_MAX_USER_LEN (31 - 3)
|
||||
/**
|
||||
* @def ACI_PIPE_INVALID
|
||||
* @brief Invalid pipe number
|
||||
*/
|
||||
#define ACI_PIPE_INVALID (0xFF)
|
||||
|
||||
/**
|
||||
* @enum aci_pipe_store_t
|
||||
* @brief Storage type identifiers: local and remote
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_STORE_INVALID = 0x0,
|
||||
ACI_STORE_LOCAL= 0x01,
|
||||
ACI_STORE_REMOTE= 0x02
|
||||
} aci_pipe_store_t;
|
||||
|
||||
/**
|
||||
* @enum aci_pipe_type_t
|
||||
* @brief Pipe types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_TX_BROADCAST = 0x0001,
|
||||
ACI_TX = 0x0002,
|
||||
ACI_TX_ACK = 0x0004,
|
||||
ACI_RX = 0x0008,
|
||||
ACI_RX_ACK = 0x0010,
|
||||
ACI_TX_REQ = 0x0020,
|
||||
ACI_RX_REQ = 0x0040,
|
||||
ACI_SET = 0x0080,
|
||||
ACI_TX_SIGN = 0x0100,
|
||||
ACI_RX_SIGN = 0x0200,
|
||||
ACI_RX_ACK_AUTO = 0x0400
|
||||
} aci_pipe_type_t;
|
||||
|
||||
/**
|
||||
* @enum aci_bd_addr_type_t
|
||||
* @brief Bluetooth Address types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_BD_ADDR_TYPE_INVALID = 0x00,
|
||||
ACI_BD_ADDR_TYPE_PUBLIC = 0x01,
|
||||
ACI_BD_ADDR_TYPE_RANDOM_STATIC = 0x02,
|
||||
ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 0x03,
|
||||
ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_UNRESOLVABLE = 0x04
|
||||
} aci_bd_addr_type_t;
|
||||
|
||||
/**
|
||||
* @enum aci_device_output_power_t
|
||||
* @brief Radio output power levels
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_DEVICE_OUTPUT_POWER_MINUS_18DBM = 0x00, /**< Output power set to -18dBm */
|
||||
ACI_DEVICE_OUTPUT_POWER_MINUS_12DBM = 0x01, /**< Output power set to -12dBm */
|
||||
ACI_DEVICE_OUTPUT_POWER_MINUS_6DBM = 0x02, /**< Output power set to -6dBm */
|
||||
ACI_DEVICE_OUTPUT_POWER_0DBM = 0x03 /**< Output power set to 0dBm - DEFAULT*/
|
||||
} aci_device_output_power_t;
|
||||
|
||||
/**
|
||||
* @enum aci_device_operation_mode_t
|
||||
* @brief Device operation modes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_DEVICE_INVALID =0x00,
|
||||
ACI_DEVICE_TEST =0x01,
|
||||
ACI_DEVICE_SETUP =0x02,
|
||||
ACI_DEVICE_STANDBY =0x03,
|
||||
ACI_DEVICE_SLEEP =0x04
|
||||
} aci_device_operation_mode_t;
|
||||
|
||||
/**
|
||||
* @enum aci_disconnect_reason_t
|
||||
* @brief Reason enumeration for ACI_CMD_DISCONNECT
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_REASON_TERMINATE =0x01, /**< Use this to disconnect (does a terminate request), you need to wait for the "disconnected" event */
|
||||
ACI_REASON_BAD_TIMING =0x02 /*<Use this to disconnect and inform the peer, that the timing on the link is not acceptable for the device, you need to wait for the "disconnected" event */
|
||||
} aci_disconnect_reason_t;
|
||||
|
||||
/**
|
||||
* @enum aci_test_mode_change_t
|
||||
* @brief Device test mode control
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_TEST_MODE_DTM_UART = 0x01,
|
||||
ACI_TEST_MODE_DTM_ACI = 0x02,
|
||||
ACI_TEST_MODE_EXIT = 0xFF
|
||||
|
||||
} aci_test_mode_change_t;
|
||||
|
||||
/**
|
||||
* @enum aci_permissions_t
|
||||
* @brief Data store permissions
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_PERMISSIONS_NONE =0x00,
|
||||
ACI_PERMISSIONS_LINK_AUTHENTICATED =0x01
|
||||
} aci_permissions_t;
|
||||
|
||||
/**
|
||||
* @def ACI_VS_UUID_128_MAX_COUNT
|
||||
* @brief Maximum number of 128-bit Vendor Specific
|
||||
* UUIDs that can be set
|
||||
*/
|
||||
#define ACI_VS_UUID_128_MAX_COUNT 64 /** #0 reserved for invalid, #1 reservered for BT SIG and a maximum of 1024 bytes (16*64) */
|
||||
|
||||
/**
|
||||
* @struct aci_ll_conn_params_t
|
||||
* @brief Link Layer Connection Parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t min_conn_interval; /**< Minimum connection interval requested from peer */
|
||||
#define ACI_PPCP_MIN_CONN_INTVL_NONE 0xFFFF
|
||||
#define ACI_PPCP_MIN_CONN_INTVL_MIN 0x0006
|
||||
#define ACI_PPCP_MIN_CONN_INTVL_MAX 0x0C80
|
||||
uint16_t max_conn_interval; /**< Maximum connection interval requested from peer */
|
||||
#define ACI_PPCP_MAX_CONN_INTVL_NONE 0xFFFF
|
||||
#define ACI_PPCP_MAX_CONN_INTVL_MIN 0x0006
|
||||
#define ACI_PPCP_MAX_CONN_INTVL_MAX 0x0C80
|
||||
uint16_t slave_latency; /**< Connection interval latency requested from peer */
|
||||
#define ACI_PPCP_SLAVE_LATENCY_MAX 0x03E8
|
||||
uint16_t timeout_mult; /**< Link supervisor timeout multiplier requested from peer */
|
||||
#define ACI_PPCP_TIMEOUT_MULT_NONE 0xFFFF
|
||||
#define ACI_PPCP_TIMEOUT_MULT_MIN 0x000A
|
||||
#define ACI_PPCP_TIMEOUT_MULT_MAX 0x0C80
|
||||
} aci_ll_conn_params_t;
|
||||
|
||||
/**
|
||||
* @def aci_gap_ppcp_t
|
||||
* @brief GAP Peripheral Preferred Connection Parameters
|
||||
*/
|
||||
#define aci_gap_ppcp_t aci_ll_conn_params_t
|
||||
|
||||
/**
|
||||
* @def ACI_AD_LOC_SVCUUID_16_MAX_COUNT
|
||||
* @brief Maximum number of 16-bit UUIDs that can
|
||||
* be inserted in the Services tag of AD
|
||||
*/
|
||||
#define ACI_AD_LOC_SVCUUID_16_MAX_COUNT 5
|
||||
|
||||
/**
|
||||
* @def ACI_AD_LOC_SVCUUID_128_MAX_COUNT
|
||||
* @brief Maximum number of 128-bit UUIDs that can
|
||||
* be inserted in the Services tag of AD
|
||||
*/
|
||||
#define ACI_AD_LOC_SVCUUID_128_MAX_COUNT 1
|
||||
|
||||
/**
|
||||
* @def ACI_AD_SOL_SVCUUID_16_MAX_COUNT
|
||||
* @brief Maximum number of UUIDs that can
|
||||
* be inserted in the Solicited Services tag of AD
|
||||
*/
|
||||
#define ACI_AD_SOL_SVCUUID_16_MAX_COUNT 5
|
||||
|
||||
/**
|
||||
* @def ACI_AD_SOL_SVCUUID_128_MAX_COUNT
|
||||
* @brief Maximum number of UUIDs that can
|
||||
* be inserted in the Solicited Services tag of AD
|
||||
*/
|
||||
#define ACI_AD_SOL_SVCUUID_128_MAX_COUNT 1
|
||||
|
||||
/**
|
||||
* @def ACI_SEC_ENCKEY_SIZE_MIN
|
||||
* @brief Minimum encryption key size
|
||||
*/
|
||||
#define ACI_SEC_ENCKEY_SIZE_MIN 7
|
||||
/**
|
||||
* @def ACI_SEC_ENCKEY_SIZE_MAX
|
||||
* @brief Maximum encryption key size
|
||||
*/
|
||||
#define ACI_SEC_ENCKEY_SIZE_MAX 16
|
||||
/**
|
||||
* @def ACI_CUSTOM_AD_TYPE_MAX_COUNT
|
||||
* @brief Maximum number of custom ad types
|
||||
*/
|
||||
#define ACI_CUSTOM_AD_TYPE_MAX_COUNT 8
|
||||
/**
|
||||
* @def ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH
|
||||
* @brief Maximum custom ad type data size
|
||||
*/
|
||||
#define ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH 20
|
||||
|
||||
/**
|
||||
* @struct aci_tx_data_t
|
||||
* @brief Generic ACI transmit data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
uint8_t aci_data[ACI_PIPE_TX_DATA_MAX_LEN];
|
||||
} aci_tx_data_t;
|
||||
|
||||
/**
|
||||
* @struct aci_rx_data_t
|
||||
* @brief Generic ACI receive data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
uint8_t aci_data[ACI_PIPE_RX_DATA_MAX_LEN];
|
||||
} aci_rx_data_t;
|
||||
|
||||
/**
|
||||
* @enum aci_hw_error_t
|
||||
* @brief Hardware Error codes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_HW_ERROR_NONE = 0x00,
|
||||
ACI_HW_ERROR_FATAL = 0x01
|
||||
} aci_hw_error_t;
|
||||
|
||||
/**
|
||||
* @enum aci_clock_accuracy_t
|
||||
* @brief Bluetooth Low Energy Clock Accuracy
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_CLOCK_ACCURACY_500_PPM = 0x00,
|
||||
ACI_CLOCK_ACCURACY_250_PPM = 0x01,
|
||||
ACI_CLOCK_ACCURACY_150_PPM = 0x02,
|
||||
ACI_CLOCK_ACCURACY_100_PPM = 0x03,
|
||||
ACI_CLOCK_ACCURACY_75_PPM = 0x04,
|
||||
ACI_CLOCK_ACCURACY_50_PPM = 0x05,
|
||||
ACI_CLOCK_ACCURACY_30_PPM = 0x06,
|
||||
ACI_CLOCK_ACCURACY_20_PPM = 0x07
|
||||
} aci_clock_accuracy_t;
|
||||
|
||||
/**
|
||||
* @enum aci_app_latency_mode_t
|
||||
* @brief Application latency modes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_APP_LATENCY_DISABLE = 0,
|
||||
ACI_APP_LATENCY_ENABLE = 1
|
||||
} aci_app_latency_mode_t;
|
||||
|
||||
/**
|
||||
* @enum gatt_format_t
|
||||
* @brief GATT format definitions
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_GATT_FORMAT_NONE = 0x00, /**< No characteristic format available */
|
||||
ACI_GATT_FORMAT_BOOLEAN = 0x01, /**< Not Supported */
|
||||
ACI_GATT_FORMAT_2BIT = 0x02, /**< Not Supported */
|
||||
ACI_GATT_FORMAT_NIBBLE = 0x03, /**< Not Supported */
|
||||
ACI_GATT_FORMAT_UINT8 = 0x04,
|
||||
ACI_GATT_FORMAT_UINT12 = 0x05,
|
||||
ACI_GATT_FORMAT_UINT16 = 0x06,
|
||||
ACI_GATT_FORMAT_UINT24 = 0x07,
|
||||
ACI_GATT_FORMAT_UINT32 = 0x08,
|
||||
ACI_GATT_FORMAT_UINT48 = 0x09,
|
||||
ACI_GATT_FORMAT_UINT64 = 0x0A,
|
||||
ACI_GATT_FORMAT_UINT128 = 0x0B,
|
||||
ACI_GATT_FORMAT_SINT8 = 0x0C,
|
||||
ACI_GATT_FORMAT_SINT12 = 0x0D,
|
||||
ACI_GATT_FORMAT_SINT16 = 0x0E,
|
||||
ACI_GATT_FORMAT_SINT24 = 0x0F,
|
||||
ACI_GATT_FORMAT_SINT32 = 0x10,
|
||||
ACI_GATT_FORMAT_SINT48 = 0x11,
|
||||
ACI_GATT_FORMAT_SINT64 = 0x12,
|
||||
ACI_GATT_FORMAT_SINT128 = 0x13,
|
||||
ACI_GATT_FORMAT_FLOAT32 = 0x14,
|
||||
ACI_GATT_FORMAT_FLOAT64 = 0x15,
|
||||
ACI_GATT_FORMAT_SFLOAT = 0x16,
|
||||
ACI_GATT_FORMAT_FLOAT = 0x17,
|
||||
ACI_GATT_FORMAT_DUINT16 = 0x18,
|
||||
ACI_GATT_FORMAT_UTF8S = 0x19,
|
||||
ACI_GATT_FORMAT_UTF16S = 0x1A,
|
||||
ACI_GATT_FORMAT_STRUCT = 0x1B
|
||||
} aci_gatt_format_t;
|
||||
|
||||
/**
|
||||
* @brief GATT Bluetooth namespace
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_GATT_NAMESPACE_INVALID = 0x00,
|
||||
ACI_GATT_NAMESPACE_BTSIG = 0x01 /**< Bluetooth SIG */
|
||||
} aci_gatt_namespace_t;
|
||||
|
||||
/**
|
||||
* @brief Security key types
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_KEY_TYPE_INVALID = 0x00,
|
||||
ACI_KEY_TYPE_PASSKEY = 0x01
|
||||
} aci_key_type_t;
|
||||
|
||||
/**
|
||||
* @enum aci_bond_status_code_t
|
||||
* @brief Bond status code
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* Bonding succeeded
|
||||
*/
|
||||
ACI_BOND_STATUS_SUCCESS = 0x00,
|
||||
/**
|
||||
* Bonding failed
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED = 0x01,
|
||||
/**
|
||||
* Bonding error: Timeout can occur when link termination is unexpected or did not get connected OR SMP timer expired
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_TIMED_OUT = 0x02,
|
||||
/**
|
||||
* Bonding error: Passkey entry failed
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_PASSKEY_ENTRY_FAILED = 0x81,
|
||||
/**
|
||||
* Bonding error: OOB unavailable
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_OOB_UNAVAILABLE = 0x82,
|
||||
/**
|
||||
* Bonding error: Authentication request failed
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_AUTHENTICATION_REQ = 0x83,
|
||||
/**
|
||||
* Bonding error: Confirm value failed
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_CONFIRM_VALUE = 0x84,
|
||||
/**
|
||||
* Bonding error: Pairing unsupported
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_PAIRING_UNSUPPORTED = 0x85,
|
||||
/**
|
||||
* Bonding error: Invalid encryption key size
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_ENCRYPTION_KEY_SIZE = 0x86,
|
||||
/**
|
||||
* Bonding error: Unsupported SMP command
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_SMP_CMD_UNSUPPORTED = 0x87,
|
||||
/**
|
||||
* Bonding error: Unspecified reason
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_UNSPECIFIED_REASON = 0x88,
|
||||
/**
|
||||
* Bonding error: Too many attempts
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_REPEATED_ATTEMPTS = 0x89,
|
||||
/**
|
||||
* Bonding error: Invalid parameters
|
||||
*/
|
||||
ACI_BOND_STATUS_FAILED_INVALID_PARAMETERS = 0x8A
|
||||
|
||||
} aci_bond_status_code_t;
|
||||
|
||||
/**
|
||||
* @enum aci_bond_status_source_t
|
||||
* @brief Source of a bond status code
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ACI_BOND_STATUS_SOURCE_INVALID = 0x00,
|
||||
ACI_BOND_STATUS_SOURCE_LOCAL = 0x01,
|
||||
ACI_BOND_STATUS_SOURCE_REMOTE = 0x02
|
||||
|
||||
} aci_bond_status_source_t;
|
||||
|
||||
/**
|
||||
* @enum aci_status_code_t
|
||||
* @brief ACI status codes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* Success
|
||||
*/
|
||||
ACI_STATUS_SUCCESS = 0x00,
|
||||
/**
|
||||
* Transaction continuation status
|
||||
*/
|
||||
ACI_STATUS_TRANSACTION_CONTINUE = 0x01,
|
||||
/**
|
||||
* Transaction completed
|
||||
*/
|
||||
ACI_STATUS_TRANSACTION_COMPLETE = 0x02,
|
||||
/**
|
||||
* Extended status, further checks needed
|
||||
*/
|
||||
ACI_STATUS_EXTENDED = 0x03,
|
||||
/**
|
||||
* Unknown error.
|
||||
*/
|
||||
ACI_STATUS_ERROR_UNKNOWN = 0x80,
|
||||
/**
|
||||
* Internal error.
|
||||
*/
|
||||
ACI_STATUS_ERROR_INTERNAL = 0x81,
|
||||
/**
|
||||
* Unknown command
|
||||
*/
|
||||
ACI_STATUS_ERROR_CMD_UNKNOWN = 0x82,
|
||||
/**
|
||||
* Command invalid in the current device state
|
||||
*/
|
||||
ACI_STATUS_ERROR_DEVICE_STATE_INVALID = 0x83,
|
||||
/**
|
||||
* Invalid length
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_LENGTH = 0x84,
|
||||
/**
|
||||
* Invalid input parameters
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_PARAMETER = 0x85,
|
||||
/**
|
||||
* Busy
|
||||
*/
|
||||
ACI_STATUS_ERROR_BUSY = 0x86,
|
||||
/**
|
||||
* Invalid data format or contents
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_DATA = 0x87,
|
||||
/**
|
||||
* CRC mismatch
|
||||
*/
|
||||
ACI_STATUS_ERROR_CRC_MISMATCH = 0x88,
|
||||
/**
|
||||
* Unsupported setup format
|
||||
*/
|
||||
ACI_STATUS_ERROR_UNSUPPORTED_SETUP_FORMAT = 0x89,
|
||||
/**
|
||||
* Invalid sequence number during a write dynamic data sequence
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_SEQ_NO = 0x8A,
|
||||
/**
|
||||
* Setup data is locked and cannot be modified
|
||||
*/
|
||||
ACI_STATUS_ERROR_SETUP_LOCKED = 0x8B,
|
||||
/**
|
||||
* Setup error due to lock verification failure
|
||||
*/
|
||||
ACI_STATUS_ERROR_LOCK_FAILED = 0x8C,
|
||||
/**
|
||||
* Bond required: Local Pipes need bonded/trusted peer
|
||||
*/
|
||||
ACI_STATUS_ERROR_BOND_REQUIRED = 0x8D,
|
||||
/**
|
||||
* Command rejected as a transaction is still pending
|
||||
*/
|
||||
ACI_STATUS_ERROR_REJECTED = 0x8E,
|
||||
/**
|
||||
* Pipe Error Event : Data size exceeds size specified for pipe : Transmit failed
|
||||
*/
|
||||
ACI_STATUS_ERROR_DATA_SIZE = 0x8F,
|
||||
/**
|
||||
* Pipe Error Event : Invalid pipe
|
||||
*/
|
||||
ACI_STATUS_ERROR_PIPE_INVALID = 0x90,
|
||||
/**
|
||||
* Pipe Error Event : Credit not available
|
||||
*/
|
||||
ACI_STATUS_ERROR_CREDIT_NOT_AVAILABLE = 0x91,
|
||||
/**
|
||||
* Pipe Error Event : Peer device has sent an error on an pipe operation on the remote characteristic
|
||||
*/
|
||||
ACI_STATUS_ERROR_PEER_ATT_ERROR = 0x92,
|
||||
/**
|
||||
* Connection was not established before the BTLE advertising was stopped
|
||||
*/
|
||||
ACI_STATUS_ERROR_ADVT_TIMEOUT = 0x93,
|
||||
/**
|
||||
* Peer has triggered a Security Manager Protocol Error
|
||||
*/
|
||||
ACI_STATUS_ERROR_PEER_SMP_ERROR = 0x94,
|
||||
/**
|
||||
* Pipe Error Event : Pipe type invalid for the selected operation
|
||||
*/
|
||||
ACI_STATUS_ERROR_PIPE_TYPE_INVALID = 0x95,
|
||||
/**
|
||||
* Pipe Error Event : Pipe state invalid for the selected operation
|
||||
*/
|
||||
ACI_STATUS_ERROR_PIPE_STATE_INVALID = 0x96,
|
||||
/**
|
||||
* Invalid key size provided
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_KEY_SIZE = 0x97,
|
||||
/**
|
||||
* Invalid key data provided
|
||||
*/
|
||||
ACI_STATUS_ERROR_INVALID_KEY_DATA = 0x98,
|
||||
/**
|
||||
* Reserved range start
|
||||
*/
|
||||
ACI_STATUS_RESERVED_START = 0xF0,
|
||||
/**
|
||||
* Reserved range end
|
||||
*/
|
||||
ACI_STATUS_RESERVED_END = 0xFF
|
||||
|
||||
} aci_status_code_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif // ACI_H__
|
||||
404
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_cmds.h
Executable file
404
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_cmds.h
Executable file
@@ -0,0 +1,404 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup aci
|
||||
*
|
||||
* @brief Definitions for the ACI (Application Control Interface) commands
|
||||
* @remarks
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ACI_CMDS_H__
|
||||
#define ACI_CMDS_H__
|
||||
|
||||
/**
|
||||
* @enum aci_cmd_opcode_t
|
||||
* @brief ACI command opcodes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* Enter test mode
|
||||
*/
|
||||
ACI_CMD_TEST = 0x01,
|
||||
/**
|
||||
* Echo (loopback) test command
|
||||
*/
|
||||
ACI_CMD_ECHO = 0x02,
|
||||
/**
|
||||
* Send a BTLE DTM command to the radio
|
||||
*/
|
||||
ACI_CMD_DTM_CMD = 0x03,
|
||||
/**
|
||||
* Put the device to sleep
|
||||
*/
|
||||
ACI_CMD_SLEEP = 0x04,
|
||||
/**
|
||||
* Wakeup the device from deep sleep
|
||||
*/
|
||||
ACI_CMD_WAKEUP = 0x05,
|
||||
/**
|
||||
* Replace the contents of the internal database with
|
||||
* user provided data
|
||||
*/
|
||||
ACI_CMD_SETUP = 0x06,
|
||||
/**
|
||||
* Read the portions of memory required to be restored after a power cycle
|
||||
*/
|
||||
ACI_CMD_READ_DYNAMIC_DATA = 0x07,
|
||||
/**
|
||||
* Write back the data retrieved using ACI_CMD_READ_DYNAMIC_DATA
|
||||
*/
|
||||
ACI_CMD_WRITE_DYNAMIC_DATA = 0x08,
|
||||
/**
|
||||
* Retrieve the device's version information
|
||||
*/
|
||||
ACI_CMD_GET_DEVICE_VERSION = 0x09,
|
||||
/**
|
||||
* Request the Bluetooth address and its type
|
||||
*/
|
||||
ACI_CMD_GET_DEVICE_ADDRESS = 0x0A,
|
||||
/**
|
||||
* Request the battery level measured by nRF8001
|
||||
*/
|
||||
ACI_CMD_GET_BATTERY_LEVEL = 0x0B,
|
||||
/**
|
||||
* Request the temperature value measured by nRF8001
|
||||
*/
|
||||
ACI_CMD_GET_TEMPERATURE = 0x0C,
|
||||
/**
|
||||
* Write to the local Attribute Database
|
||||
*/
|
||||
ACI_CMD_SET_LOCAL_DATA = 0x0D,
|
||||
/**
|
||||
* Reset the baseband and radio and go back to idle
|
||||
*/
|
||||
ACI_CMD_RADIO_RESET = 0x0E,
|
||||
/**
|
||||
* Start advertising and wait for a master connection
|
||||
*/
|
||||
ACI_CMD_CONNECT = 0x0F,
|
||||
/**
|
||||
* Start advertising and wait for a master connection
|
||||
*/
|
||||
ACI_CMD_BOND = 0x10,
|
||||
/**
|
||||
* Start advertising and wait for a master connection
|
||||
*/
|
||||
ACI_CMD_DISCONNECT = 0x11,
|
||||
/**
|
||||
* Throttles the Radio transmit power
|
||||
*/
|
||||
ACI_CMD_SET_TX_POWER = 0x12,
|
||||
/**
|
||||
* Trigger a connection parameter update
|
||||
*/
|
||||
ACI_CMD_CHANGE_TIMING = 0x13,
|
||||
/**
|
||||
* Open a remote pipe for data reception
|
||||
*/
|
||||
ACI_CMD_OPEN_REMOTE_PIPE = 0x14,
|
||||
/**
|
||||
* Transmit data over an open pipe
|
||||
*/
|
||||
ACI_CMD_SEND_DATA = 0x15,
|
||||
/**
|
||||
* Send an acknowledgment of received data
|
||||
*/
|
||||
ACI_CMD_SEND_DATA_ACK = 0x16,
|
||||
/**
|
||||
* Request data over an open pipe
|
||||
*/
|
||||
ACI_CMD_REQUEST_DATA = 0x17,
|
||||
/**
|
||||
* NACK a data reception
|
||||
*/
|
||||
ACI_CMD_SEND_DATA_NACK = 0x18,
|
||||
/**
|
||||
* Set application latency
|
||||
*/
|
||||
ACI_CMD_SET_APP_LATENCY = 0x19,
|
||||
/**
|
||||
* Set a security key
|
||||
*/
|
||||
ACI_CMD_SET_KEY = 0x1A,
|
||||
/**
|
||||
* Open Advertising Pipes
|
||||
*/
|
||||
ACI_CMD_OPEN_ADV_PIPE = 0x1B,
|
||||
/**
|
||||
* Start non-connectable advertising
|
||||
*/
|
||||
ACI_CMD_BROADCAST = 0x1C,
|
||||
/**
|
||||
* Start a security request in bonding mode
|
||||
*/
|
||||
ACI_CMD_BOND_SECURITY_REQUEST = 0x1D,
|
||||
/**
|
||||
* Start Directed advertising towards a Bonded Peer
|
||||
*/
|
||||
ACI_CMD_CONNECT_DIRECT = 0x1E,
|
||||
/**
|
||||
* Close a previously opened remote pipe
|
||||
*/
|
||||
ACI_CMD_CLOSE_REMOTE_PIPE = 0x1F,
|
||||
/**
|
||||
* Invalid ACI command opcode
|
||||
*/
|
||||
ACI_CMD_INVALID = 0xFF
|
||||
|
||||
} aci_cmd_opcode_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_test_t
|
||||
* @brief Structure for the ACI_CMD_TEST ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t test_mode_change; /**< enum aci_test_mode_change_t */
|
||||
} aci_cmd_params_test_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_echo_t
|
||||
* @brief Structure for the ACI_CMD_ECHO ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
|
||||
} aci_cmd_params_echo_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_dtm_cmd_t
|
||||
* @brief Structure for the ACI_CMD_DTM_CMD ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cmd_msb;
|
||||
uint8_t cmd_lsb;
|
||||
} aci_cmd_params_dtm_cmd_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_setup_t
|
||||
* @brief Structure for the ACI_CMD_SETUP ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t setup_data[1];
|
||||
} aci_cmd_params_setup_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_write_dynamic_data_t
|
||||
* @brief Structure for the ACI_CMD_WRITE_DYNAMIC_DATA ACI command parameters
|
||||
* @note Dynamic data chunk size in this command is defined to go up to ACI_PACKET_MAX_LEN - 3
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t seq_no;
|
||||
uint8_t dynamic_data[1];
|
||||
} aci_cmd_params_write_dynamic_data_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_set_local_data_t
|
||||
* @brief Structure for the ACI_CMD_SET_LOCAL_DATA ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_tx_data_t tx_data;
|
||||
} aci_cmd_params_set_local_data_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_connect_t
|
||||
* @brief Structure for the ACI_CMD_CONNECT ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t timeout; /**< 0x0000 (no timeout) to 0x3FFF */
|
||||
uint16_t adv_interval; /**< 16 bits of advertising interval for general discovery */
|
||||
} aci_cmd_params_connect_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_bond_t
|
||||
* @brief Structure for the ACI_CMD_BOND ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t timeout; /**< 0x0000 (no timeout) to 0x3FFF */
|
||||
uint16_t adv_interval; /**< 16 bits of advertising interval for general discovery */
|
||||
} aci_cmd_params_bond_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_disconnect_t
|
||||
* @brief Structure for the ACI_CMD_DISCONNECT ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t reason; /**< enum aci_disconnect_reason_t */
|
||||
} aci_cmd_params_disconnect_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_set_tx_power_t
|
||||
* @brief Structure for the ACI_CMD_SET_TX_POWER ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t device_power; /**< enum aci_device_output_power_t */
|
||||
} aci_cmd_params_set_tx_power_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_change_timing_t
|
||||
* @brief Structure for the ACI_CMD_CHANGE_TIMING ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_ll_conn_params_t conn_params;
|
||||
} aci_cmd_params_change_timing_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_open_remote_pipe_t
|
||||
* @brief Structure for the ACI_CMD_OPEN_REMOTE_PIPE ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
} aci_cmd_params_open_remote_pipe_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_send_data_t
|
||||
* @brief Structure for the ACI_CMD_SEND_DATA ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_tx_data_t tx_data;
|
||||
} aci_cmd_params_send_data_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_send_data_ack_t
|
||||
* @brief Structure for the ACI_CMD_SEND_DATA_ACK ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
} aci_cmd_params_send_data_ack_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_send_data_t
|
||||
* @brief Structure for the ACI_CMD_SEND_DATA ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
} aci_cmd_params_request_data_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_send_data_nack_t
|
||||
* @brief Structure for the ACI_CMD_SEND_DATA_NACK ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
uint8_t error_code;
|
||||
} aci_cmd_params_send_data_nack_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_set_app_latency_t
|
||||
* @brief Structure for the ACI_CMD_SET_APP_LATENCY ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_app_latency_mode_t mode;
|
||||
uint16_t latency;
|
||||
} aci_cmd_params_set_app_latency_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_set_key_t
|
||||
* @brief Structure for the ACI_CMD_SET_KEY ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_key_type_t key_type;
|
||||
union
|
||||
{
|
||||
uint8_t passkey[6];
|
||||
uint8_t oob_key[16];
|
||||
} key;
|
||||
} aci_cmd_params_set_key_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_open_adv_pipe_t
|
||||
* @brief Structure for the ACI_CMD_OPEN_ADV_PIPE ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipes[8];
|
||||
} aci_cmd_params_open_adv_pipe_t;
|
||||
|
||||
/**
|
||||
* @define aci_cmd_params_broadcast_t
|
||||
* @brief Structure for the ACI_CMD_BROADCAST ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t timeout; /**< 0x0000 (no timeout) to 0x3FFF */
|
||||
uint16_t adv_interval; /**< 16 bits of advertising interval for general discovery */
|
||||
} aci_cmd_params_broadcast_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_params_close_remote_pipe_t
|
||||
* @brief Structure for the ACI_CMD_CLOSE_REMOTE_PIPE ACI command parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
} aci_cmd_params_close_remote_pipe_t;
|
||||
|
||||
/**
|
||||
* @struct aci_cmd_t
|
||||
* @brief Encapsulates a generic ACI command
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len; /**< Length of the ACI command */
|
||||
uint8_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Opcode of the ACI command */
|
||||
union
|
||||
{
|
||||
aci_cmd_params_test_t test;
|
||||
aci_cmd_params_echo_t echo;
|
||||
aci_cmd_params_dtm_cmd_t dtm_cmd;
|
||||
aci_cmd_params_setup_t setup;
|
||||
aci_cmd_params_write_dynamic_data_t write_dynamic_data;
|
||||
aci_cmd_params_set_local_data_t set_local_data;
|
||||
aci_cmd_params_connect_t connect;
|
||||
aci_cmd_params_bond_t bond;
|
||||
aci_cmd_params_disconnect_t disconnect;
|
||||
aci_cmd_params_set_tx_power_t set_tx_power;
|
||||
aci_cmd_params_change_timing_t change_timing;
|
||||
aci_cmd_params_open_remote_pipe_t open_remote_pipe;
|
||||
aci_cmd_params_send_data_t send_data;
|
||||
aci_cmd_params_send_data_ack_t send_data_ack;
|
||||
aci_cmd_params_request_data_t request_data;
|
||||
aci_cmd_params_send_data_nack_t send_data_nack;
|
||||
aci_cmd_params_set_app_latency_t set_app_latency;
|
||||
aci_cmd_params_set_key_t set_key;
|
||||
aci_cmd_params_open_adv_pipe_t open_adv_pipe;
|
||||
aci_cmd_params_broadcast_t broadcast;
|
||||
aci_cmd_params_close_remote_pipe_t close_remote_pipe;
|
||||
|
||||
} params;
|
||||
} aci_cmd_t;
|
||||
|
||||
#endif // ACI_CMDS_H__
|
||||
|
||||
|
||||
364
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_evts.h
Executable file
364
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_evts.h
Executable file
@@ -0,0 +1,364 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup aci
|
||||
*
|
||||
* @brief Definitions for the ACI (Application Control Interface) events
|
||||
*/
|
||||
|
||||
#ifndef ACI_EVTS_H__
|
||||
#define ACI_EVTS_H__
|
||||
|
||||
#include "aci.h"
|
||||
/**
|
||||
* @enum aci_evt_opcode_t
|
||||
* @brief ACI event opcodes
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* Invalid event code
|
||||
*/
|
||||
ACI_EVT_INVALID = 0x00,
|
||||
/**
|
||||
* Sent every time the device starts
|
||||
*/
|
||||
ACI_EVT_DEVICE_STARTED = 0x81,
|
||||
/**
|
||||
* Mirrors the ACI_CMD_ECHO
|
||||
*/
|
||||
ACI_EVT_ECHO = 0x82,
|
||||
/**
|
||||
* Asynchronous hardware error event
|
||||
*/
|
||||
ACI_EVT_HW_ERROR = 0x83,
|
||||
/**
|
||||
* Event opcode used as a event response for all commands
|
||||
*/
|
||||
ACI_EVT_CMD_RSP = 0x84,
|
||||
/**
|
||||
* Link connected
|
||||
*/
|
||||
ACI_EVT_CONNECTED = 0x85,
|
||||
/**
|
||||
* Link disconnected
|
||||
*/
|
||||
ACI_EVT_DISCONNECTED = 0x86,
|
||||
/**
|
||||
* Bond completion result
|
||||
*/
|
||||
ACI_EVT_BOND_STATUS = 0x87,
|
||||
/**
|
||||
* Pipe bitmap for available pipes
|
||||
*/
|
||||
ACI_EVT_PIPE_STATUS = 0x88,
|
||||
/**
|
||||
* Sent to the application when the radio enters a connected state
|
||||
* or when the timing of the radio connection changes
|
||||
*/
|
||||
ACI_EVT_TIMING = 0x89,
|
||||
/**
|
||||
* Notification to the application that transmit credits are
|
||||
* available
|
||||
*/
|
||||
ACI_EVT_DATA_CREDIT = 0x8A,
|
||||
/**
|
||||
* Data acknowledgement event
|
||||
*/
|
||||
ACI_EVT_DATA_ACK = 0x8B,
|
||||
/**
|
||||
* Data received notification event
|
||||
*/
|
||||
ACI_EVT_DATA_RECEIVED = 0x8C,
|
||||
/**
|
||||
* Error notification event
|
||||
*/
|
||||
ACI_EVT_PIPE_ERROR = 0x8D,
|
||||
/**
|
||||
* Display Passkey Event
|
||||
*/
|
||||
ACI_EVT_DISPLAY_PASSKEY = 0x8E,
|
||||
/**
|
||||
* Security Key request
|
||||
*/
|
||||
ACI_EVT_KEY_REQUEST = 0x8F
|
||||
|
||||
} aci_evt_opcode_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_device_started_t
|
||||
* @brief Structure for the ACI_EVT_DEVICE_STARTED event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t device_mode; /**< enum aci_device_operation_mode_t -> Mode in which the device is being started */
|
||||
uint8_t hw_error; /**< enum aci_hw_error_t -> Hardware Error if available for the start */
|
||||
uint8_t credit_available; /**< Flow control credit available for this specific FW build */
|
||||
} aci_evt_params_device_started_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_hw_error_t
|
||||
* @brief Structure for the ACI_EVT_HW_ERROR event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t line_num;
|
||||
uint8_t file_name[20];
|
||||
} aci_evt_params_hw_error_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_params_dtm_cmd_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_DTM_CMD event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t evt_msb;
|
||||
uint8_t evt_lsb;
|
||||
} aci_evt_cmd_rsp_params_dtm_cmd_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_read_dynamic_data_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_READ_DYNAMIC_DATA event return parameters
|
||||
* @note Dynamic data chunk size in this event is defined to go up to ACI_PACKET_MAX_LEN - 5
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t seq_no;
|
||||
uint8_t dynamic_data[1];
|
||||
} aci_evt_cmd_rsp_read_dynamic_data_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_params_get_device_version_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_VERSION event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t configuration_id;
|
||||
uint8_t aci_version;
|
||||
uint8_t setup_format;
|
||||
uint32_t setup_id;
|
||||
uint8_t setup_status;
|
||||
} aci_evt_cmd_rsp_params_get_device_version_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_params_get_device_address_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_ADDRESS event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bd_addr_own[BTLE_DEVICE_ADDRESS_SIZE];
|
||||
uint8_t bd_addr_type; /**< enum aci_bd_addr_type_t */
|
||||
} aci_evt_cmd_rsp_params_get_device_address_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_params_get_battery_level_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_BATTERY_LEVEL event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t battery_level;
|
||||
} aci_evt_cmd_rsp_params_get_battery_level_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_cmd_rsp_params_get_temperature_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_TEMPERATURE event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int16_t temperature_value;
|
||||
} aci_evt_cmd_rsp_params_get_temperature_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_cmd_rsp_t
|
||||
* @brief Structure for the ACI_EVT_CMD_RSP event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Command opcode for which the event response is being sent */
|
||||
uint8_t cmd_status; /**< enum aci_status_code_t -> Status of the command that was sent. Used in the context of the command. */
|
||||
union
|
||||
{
|
||||
aci_evt_cmd_rsp_params_dtm_cmd_t dtm_cmd;
|
||||
aci_evt_cmd_rsp_read_dynamic_data_t read_dynamic_data;
|
||||
aci_evt_cmd_rsp_params_get_device_version_t get_device_version;
|
||||
aci_evt_cmd_rsp_params_get_device_address_t get_device_address;
|
||||
aci_evt_cmd_rsp_params_get_battery_level_t get_battery_level;
|
||||
aci_evt_cmd_rsp_params_get_temperature_t get_temperature;
|
||||
uint8_t padding[29];
|
||||
} params;
|
||||
} aci_evt_params_cmd_rsp_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_connected_t
|
||||
* @brief Structure for the ACI_EVT_CONNECTED event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_bd_addr_type_t dev_addr_type;
|
||||
uint8_t dev_addr[BTLE_DEVICE_ADDRESS_SIZE];
|
||||
uint16_t conn_rf_interval; /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
|
||||
uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
|
||||
uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
|
||||
uint8_t master_clock_accuracy; /**< enum aci_clock_accuracy_t -> Clock accuracy of Bluetooth master: Enumerated list of values from 500 ppm to 20 ppm */
|
||||
} aci_evt_params_connected_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_disconnected_t
|
||||
* @brief Structure for the ACI_EVT_DISCONNECTED event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t aci_status; /**< enum aci_status_code_t */
|
||||
uint8_t btle_status;
|
||||
} aci_evt_params_disconnected_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_bond_status_t
|
||||
* @brief Structure for the ACI_EVT_BOND_STATUS event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t status_code;
|
||||
uint8_t status_source; /**< enum aci_bond_status_source_t */
|
||||
uint8_t secmode1_bitmap;
|
||||
uint8_t secmode2_bitmap;
|
||||
uint8_t keys_exchanged_slave;
|
||||
uint8_t keys_exchanged_master;
|
||||
} aci_evt_params_bond_status_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_pipe_status_t
|
||||
* @brief Structure for the ACI_EVT_PIPE_STATUS event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipes_open_bitmap[8];
|
||||
uint8_t pipes_closed_bitmap[8];
|
||||
} aci_evt_params_pipe_status_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_timing_t
|
||||
* @brief Structure for the ACI_EVT_TIMING event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_rf_interval; /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
|
||||
uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
|
||||
uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
|
||||
} aci_evt_params_timing_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_data_credit_t
|
||||
* @brief Structure for the ACI_EVT_DATA_CREDIT event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t credit;
|
||||
} aci_evt_params_data_credit_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_data_ack_t
|
||||
* @brief Structure for the ACI_EVT_DATA_ACK event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
} aci_evt_params_data_ack_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_data_received_t
|
||||
* @brief Structure for the ACI_EVT_DATA_RECEIVED event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
aci_rx_data_t rx_data;
|
||||
} aci_evt_params_data_received_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t content[1];
|
||||
} error_data_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_pipe_error_t
|
||||
* @brief Structure for the ACI_EVT_PIPE_ERROR event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_number;
|
||||
uint8_t error_code;
|
||||
union
|
||||
{
|
||||
error_data_t error_data;
|
||||
} params;
|
||||
} aci_evt_params_pipe_error_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_display_passkey_t
|
||||
* @brief Structure for the ACI_EVT_DISPLAY_PASSKEY event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t passkey[6];
|
||||
} aci_evt_params_display_passkey_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_params_key_request_t
|
||||
* @brief Structure for the ACI_EVT_KEY_REQUEST event return parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t key_type; /**< enum aci_key_type_t */
|
||||
} aci_evt_params_key_request_t;
|
||||
|
||||
/**
|
||||
* @struct aci_event_params_echo_t
|
||||
* @brief Structure for the ACI_EVT_ECHO ACI event parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
|
||||
} aci_evt_params_echo_t;
|
||||
|
||||
/**
|
||||
* @struct aci_evt_t
|
||||
* @brief Encapsulates a generic ACI event
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t evt_opcode; /** enum aci_evt_opcode_t */
|
||||
union
|
||||
{
|
||||
aci_evt_params_device_started_t device_started;
|
||||
aci_evt_params_echo_t echo;
|
||||
aci_evt_params_hw_error_t hw_error;
|
||||
aci_evt_params_cmd_rsp_t cmd_rsp;
|
||||
aci_evt_params_connected_t connected;
|
||||
aci_evt_params_disconnected_t disconnected;
|
||||
aci_evt_params_bond_status_t bond_status;
|
||||
aci_evt_params_pipe_status_t pipe_status;
|
||||
aci_evt_params_timing_t timing;
|
||||
aci_evt_params_data_credit_t data_credit;
|
||||
aci_evt_params_data_ack_t data_ack;
|
||||
aci_evt_params_data_received_t data_received;
|
||||
aci_evt_params_pipe_error_t pipe_error;
|
||||
aci_evt_params_display_passkey_t display_passkey;
|
||||
aci_evt_params_key_request_t key_request;
|
||||
} params;
|
||||
} aci_evt_t;
|
||||
|
||||
#endif // ACI_EVTS_H__
|
||||
@@ -0,0 +1,178 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. *
|
||||
* *
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.*
|
||||
* Terms and conditions of usage are described in detail in NORDIC *
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. *
|
||||
* *
|
||||
* Licensees are granted free, non-transferable use of the information. NO *
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from *
|
||||
* the file. *
|
||||
* */
|
||||
|
||||
/* *
|
||||
* This file contents defines for the position of all the fields of ACI *
|
||||
* command or event messages *
|
||||
* */
|
||||
|
||||
#ifndef ACI_OFFSET_H__
|
||||
#define ACI_OFFSET_H__
|
||||
|
||||
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB 0
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB 1
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB 2
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB 3
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB 4
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB 5
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB 6
|
||||
#define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB 7
|
||||
#define OFFSET_ACI_TX_DATA_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_TX_DATA_T_ACI_DATA 1
|
||||
#define OFFSET_ACI_RX_DATA_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_RX_DATA_T_ACI_DATA 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_MSB 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_LSB 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_SETUP_T_SETUP_DATA 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_LOCAL_DATA_T_TX_DATA 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB 2
|
||||
#define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB 3
|
||||
#define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB 2
|
||||
#define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB 3
|
||||
#define OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_OOB_KEY 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB 0
|
||||
#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB 1
|
||||
#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB 2
|
||||
#define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB 3
|
||||
#define OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_CMD_T_LEN 0
|
||||
#define OFFSET_ACI_CMD_T_CMD_OPCODE 1
|
||||
#define OFFSET_ACI_CMD_T_TEST 2
|
||||
#define OFFSET_ACI_CMD_T_ECHO 2
|
||||
#define OFFSET_ACI_CMD_T_DTM_CMD 2
|
||||
#define OFFSET_ACI_CMD_T_SETUP 2
|
||||
#define OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA 2
|
||||
#define OFFSET_ACI_CMD_T_SET_LOCAL_DATA 2
|
||||
#define OFFSET_ACI_CMD_T_CONNECT 2
|
||||
#define OFFSET_ACI_CMD_T_BOND 2
|
||||
#define OFFSET_ACI_CMD_T_DISCONNECT 2
|
||||
#define OFFSET_ACI_CMD_T_SET_TX_POWER 2
|
||||
#define OFFSET_ACI_CMD_T_CHANGE_TIMING 2
|
||||
#define OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE 2
|
||||
#define OFFSET_ACI_CMD_T_SEND_DATA 2
|
||||
#define OFFSET_ACI_CMD_T_SEND_DATA_ACK 2
|
||||
#define OFFSET_ACI_CMD_T_REQUEST_DATA 2
|
||||
#define OFFSET_ACI_CMD_T_SEND_DATA_NACK 2
|
||||
#define OFFSET_ACI_CMD_T_SET_APP_LATENCY 2
|
||||
#define OFFSET_ACI_CMD_T_SET_KEY 2
|
||||
#define OFFSET_ACI_CMD_T_OPEN_ADV_PIPE 2
|
||||
#define OFFSET_ACI_CMD_T_BROADCAST 2
|
||||
#define OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME 2
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB 1
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_DYNAMIC_DATA 1
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB 1
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION 2
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT 3
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0 4
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1 5
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0 6
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1 7
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS 8
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE 6
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB 1
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB 0
|
||||
#define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB 7
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB 8
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB 9
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB 10
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB 11
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB 12
|
||||
#define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY 13
|
||||
#define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP 3
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE 4
|
||||
#define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER 5
|
||||
#define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP 8
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB 3
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB 4
|
||||
#define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB 5
|
||||
#define OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_DATA_RECEIVED_T_RX_DATA 0
|
||||
#define OFFSET_ERROR_DATA_T_CONTENT 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE 1
|
||||
#define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA 2
|
||||
#define OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY 0
|
||||
#define OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE 0
|
||||
#define OFFSET_ACI_EVT_T_LEN 0
|
||||
#define OFFSET_ACI_EVT_T_EVT_OPCODE 1
|
||||
#define OFFSET_ACI_EVT_T_DEVICE_STARTED 2
|
||||
#define OFFSET_ACI_EVT_T_HW_ERROR 2
|
||||
#define OFFSET_ACI_EVT_T_CMD_RSP 2
|
||||
#define OFFSET_ACI_EVT_T_CONNECTED 2
|
||||
#define OFFSET_ACI_EVT_T_DISCONNECTED 2
|
||||
#define OFFSET_ACI_EVT_T_BOND_STATUS 2
|
||||
#define OFFSET_ACI_EVT_T_PIPE_STATUS 2
|
||||
#define OFFSET_ACI_EVT_T_TIMING 2
|
||||
#define OFFSET_ACI_EVT_T_DATA_CREDIT 2
|
||||
#define OFFSET_ACI_EVT_T_DATA_ACK 2
|
||||
#define OFFSET_ACI_EVT_T_DATA_RECEIVED 2
|
||||
#define OFFSET_ACI_EVT_T_PIPE_ERROR 2
|
||||
#define OFFSET_ACI_EVT_T_DISPLAY_PASSKEY 2
|
||||
#define OFFSET_ACI_EVT_T_KEY_REQUEST 2
|
||||
|
||||
#endif //ACI_OFFSET_H__
|
||||
|
||||
131
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_setup.cpp
Executable file
131
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_setup.cpp
Executable file
@@ -0,0 +1,131 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* My project template
|
||||
*/
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <ble_system.h>
|
||||
#include <lib_aci.h>
|
||||
#include "aci_setup.h"
|
||||
|
||||
|
||||
// aci_struct that will contain
|
||||
// total initial credits
|
||||
// current credit
|
||||
// current state of the aci (setup/standby/active/sleep)
|
||||
// open remote pipe pending
|
||||
// close remote pipe pending
|
||||
// Current pipe available bitmap
|
||||
// Current pipe closed bitmap
|
||||
// Current connection interval, slave latency and link supervision timeout
|
||||
// Current State of the the GATT client (Service Discovery status)
|
||||
|
||||
static hal_aci_evt_t aci_data;
|
||||
static hal_aci_data_t aci_cmd;
|
||||
|
||||
aci_status_code_t aci_setup(aci_state_t *aci_stat, uint8_t num_cmds, uint8_t num_cmd_offset)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t evt_count = 0;
|
||||
aci_evt_t * aci_evt = NULL;
|
||||
|
||||
while (i < num_cmds)
|
||||
{
|
||||
//Copy the setup ACI message from Flash to RAM
|
||||
//Add 2 bytes to the length byte for status byte, length for the total number of bytes
|
||||
memcpy_P(&aci_cmd, &(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i]),
|
||||
pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i].buffer[0]))+2);
|
||||
|
||||
//Put the Setup ACI message in the command queue
|
||||
if (!hal_aci_tl_send(&aci_cmd))
|
||||
{
|
||||
Serial.println(F("Cmd Queue Full"));
|
||||
return ACI_STATUS_ERROR_INTERNAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug messages:
|
||||
//Serial.print(F("Setup msg"));
|
||||
//Serial.println(i, DEC);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
//We will sit here if we do not get the same number of command response evts as the commands sent to the ACI
|
||||
//
|
||||
//@check The setup wil fail in the while(1) below when the 32KHz source for the nRF8001 is in-correct in the setup generated in the nRFgo studio
|
||||
if (true == lib_aci_event_get(aci_stat, &aci_data))
|
||||
{
|
||||
aci_evt = &aci_data.evt;
|
||||
|
||||
evt_count++;
|
||||
|
||||
if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode )
|
||||
{
|
||||
//Got something other than a command response evt -> Error
|
||||
return ACI_STATUS_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (!((ACI_STATUS_TRANSACTION_CONTINUE == aci_evt->params.cmd_rsp.cmd_status) ||
|
||||
(ACI_STATUS_TRANSACTION_COMPLETE == aci_evt->params.cmd_rsp.cmd_status)))
|
||||
{
|
||||
return (aci_status_code_t )aci_evt->params.cmd_rsp.cmd_status;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Serial.print(F("Cmd Response Evt "));
|
||||
//Serial.println(evt_count);
|
||||
}
|
||||
|
||||
if (num_cmds == evt_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ((aci_status_code_t)aci_evt->params.cmd_rsp.cmd_status);
|
||||
}
|
||||
|
||||
|
||||
aci_status_code_t do_aci_setup(aci_state_t *aci_stat)
|
||||
{
|
||||
aci_status_code_t status = ACI_STATUS_ERROR_CRC_MISMATCH;
|
||||
uint8_t i=0;
|
||||
|
||||
if(ACI_QUEUE_SIZE >= aci_stat->aci_setup_info.num_setup_msgs)
|
||||
{
|
||||
status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<(aci_stat->aci_setup_info.num_setup_msgs/ACI_QUEUE_SIZE); i++)
|
||||
{
|
||||
//Serial.print(ACI_QUEUE_SIZE, DEC);
|
||||
//Serial.print(F(" "));
|
||||
//Serial.println(0+(ACI_QUEUE_SIZE*i), DEC);
|
||||
status = aci_setup(aci_stat, ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
|
||||
}
|
||||
if ((aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE) != 0)
|
||||
{
|
||||
status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
12
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_setup.h
Executable file
12
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/aci_setup.h
Executable file
@@ -0,0 +1,12 @@
|
||||
#ifndef H_ACI_SETUP
|
||||
#define H_ACI_SETUP
|
||||
|
||||
#define ACI_CMD_Q_SIZE 16
|
||||
|
||||
/**
|
||||
Do the ACI setup by sending the setup messages generated by the nRFgo studio to the nRF8001.
|
||||
After all the setup messages are sent. The nRF8001 will send a Device Started Event (Mode = STANDBY)
|
||||
*/
|
||||
aci_status_code_t do_aci_setup(aci_state_t *aci_stat);
|
||||
|
||||
#endif
|
||||
602
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib.cpp
Executable file
602
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib.cpp
Executable file
@@ -0,0 +1,602 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Implementation of the acilib module.
|
||||
*/
|
||||
|
||||
|
||||
#include "hal_platform.h"
|
||||
#include "aci.h"
|
||||
#include "aci_cmds.h"
|
||||
#include "aci_evts.h"
|
||||
#include "acilib.h"
|
||||
#include "aci_protocol_defines.h"
|
||||
#include "acilib_defs.h"
|
||||
#include "acilib_if.h"
|
||||
#include "acilib_types.h"
|
||||
|
||||
|
||||
void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 2;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_TEST;
|
||||
*(buffer + OFFSET_ACI_CMD_T_TEST + OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE) = p_aci_cmd_params_test->test_mode_change;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_sleep(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SLEEP;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_get_device_version(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_VERSION;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_LOCAL_DATA_BASE_LEN + data_size;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_LOCAL_DATA;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_set_local_data->tx_data.pipe_number;
|
||||
memcpy(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA, &(p_aci_cmd_params_set_local_data->tx_data.aci_data[0]), data_size);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CONNECT_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_connect->timeout >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_connect->timeout);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BOND_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND;
|
||||
*(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_bond->timeout >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_bond->timeout);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DISCONNECT_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DISCONNECT;
|
||||
*(buffer + OFFSET_ACI_CMD_T_DISCONNECT + OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON) = (uint8_t)(p_aci_cmd_params_disconnect->reason);
|
||||
}
|
||||
|
||||
void acil_encode_baseband_reset(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BASEBAND_RESET_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_RADIO_RESET;
|
||||
}
|
||||
|
||||
void acil_encode_direct_connect(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DIRECT_CONNECT_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT_DIRECT;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_wakeup(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WAKEUP_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WAKEUP;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_RADIO_TX_POWER_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_TX_POWER;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_TX_POWER + OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER) = (uint8_t)p_aci_cmd_params_set_tx_power->device_power;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_get_address(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_GET_DEVICE_ADDR_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_ADDRESS;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SEND_DATA_BASE_LEN + data_size;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_send_data_t->tx_data.pipe_number;
|
||||
memcpy((buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA), &(p_aci_cmd_params_send_data_t->tx_data.aci_data[0]), data_size);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DATA_REQUEST_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_REQUEST_DATA;
|
||||
*(buffer + OFFSET_ACI_CMD_T_REQUEST_DATA + OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_request_data->pipe_number;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_REMOTE_PIPE_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_REMOTE_PIPE;
|
||||
*(buffer + OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_open_remote_pipe->pipe_number;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CLOSE_REMOTE_PIPE_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CLOSE_REMOTE_PIPE;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_close_remote_pipe->pipe_number;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ECHO_MSG_CMD_BASE_LEN + msg_size;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_ECHO;
|
||||
memcpy((buffer + OFFSET_ACI_CMD_T_ECHO + OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA), &(p_cmd_params_echo->echo_data[0]), msg_size);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_battery_level(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_BATTERY_LEVEL;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_temparature(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_TEMPERATURE;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_read_dynamic_data(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_READ_DYNAMIC_DATA;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WRITE_DYNAMIC_DATA_BASE_LEN + dynamic_data_size;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WRITE_DYNAMIC_DATA;
|
||||
*(buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO) = seq_no;
|
||||
memcpy((buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), dynamic_data, dynamic_data_size);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_APP_LATENCY_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_APP_LATENCY;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE) = (uint8_t)( p_aci_cmd_params_set_app_latency->mode);
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency>>8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN_GAP_PPCP;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
|
||||
}
|
||||
|
||||
|
||||
void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = setup_data_size + MSG_SETUP_CMD_BASE_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SETUP;
|
||||
memcpy((buffer + OFFSET_ACI_CMD_T_SETUP), &(p_aci_cmd_params_setup->setup_data[0]), setup_data_size);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DTM_CMD;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DTM_CMD;
|
||||
*(buffer + OFFSET_ACI_CMD_T_DTM_CMD) = p_aci_cmd_params_dtm_cmd->cmd_msb;
|
||||
*(buffer + OFFSET_ACI_CMD_T_DTM_CMD + 1) = p_aci_cmd_params_dtm_cmd->cmd_lsb;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number )
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ACK_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_ACK;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SEND_DATA_ACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER) = pipe_number;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number, const uint8_t err_code )
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_NACK_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_NACK;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER) = pipe_number;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE) = err_code;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_bond_security_request(uint8_t *buffer)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND_SECURITY_REQUEST;
|
||||
}
|
||||
|
||||
void acil_encode_cmd_broadcast(uint8_t *buffer, aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BROADCAST_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BROADCAST;
|
||||
*(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB) = (p_aci_cmd_params_broadcast->timeout & 0xff);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->timeout >> 8);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB) = (p_aci_cmd_params_broadcast->adv_interval & 0xff);
|
||||
*(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->adv_interval >> 8);
|
||||
}
|
||||
|
||||
void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_open_adv_pipe)
|
||||
{
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_ADV_PIPES_LEN;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_ADV_PIPE;
|
||||
memcpy(buffer + OFFSET_ACI_CMD_T_OPEN_ADV_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES, p_aci_cmd_params_open_adv_pipe->pipes, 8);
|
||||
}
|
||||
|
||||
|
||||
void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key)
|
||||
{
|
||||
/*
|
||||
The length of the key is computed based on the type of key transaction.
|
||||
- Key Reject
|
||||
- Key type is passkey
|
||||
*/
|
||||
uint8_t len;
|
||||
|
||||
switch (p_aci_cmd_params_set_key->key_type)
|
||||
{
|
||||
case ACI_KEY_TYPE_INVALID:
|
||||
len = MSG_SET_KEY_REJECT_LEN;
|
||||
break;
|
||||
case ACI_KEY_TYPE_PASSKEY:
|
||||
len = MSG_SET_KEY_PASSKEY_LEN;
|
||||
break;
|
||||
default:
|
||||
len=0;
|
||||
break;
|
||||
}
|
||||
*(buffer + OFFSET_ACI_CMD_T_LEN) = len;
|
||||
*(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_KEY;
|
||||
*(buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE) = p_aci_cmd_params_set_key->key_type;
|
||||
memcpy((buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY), (uint8_t * )&(p_aci_cmd_params_set_key->key), len-2);//Reducing 2 for the opcode byte and type
|
||||
}
|
||||
|
||||
bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd)
|
||||
{
|
||||
bool ret_val = false;
|
||||
|
||||
switch(p_aci_cmd->cmd_opcode)
|
||||
{
|
||||
case ACI_CMD_TEST:
|
||||
acil_encode_cmd_set_test_mode(buffer, &(p_aci_cmd->params.test));
|
||||
break;
|
||||
case ACI_CMD_SLEEP:
|
||||
acil_encode_cmd_sleep(buffer);
|
||||
break;
|
||||
case ACI_CMD_GET_DEVICE_VERSION:
|
||||
acil_encode_cmd_get_device_version(buffer);
|
||||
break;
|
||||
case ACI_CMD_WAKEUP:
|
||||
acil_encode_cmd_wakeup(buffer);
|
||||
break;
|
||||
case ACI_CMD_ECHO:
|
||||
acil_encode_cmd_echo_msg(buffer, &(p_aci_cmd->params.echo), (p_aci_cmd->len - MSG_ECHO_MSG_CMD_BASE_LEN));
|
||||
break;
|
||||
case ACI_CMD_GET_BATTERY_LEVEL:
|
||||
acil_encode_cmd_battery_level(buffer);
|
||||
break;
|
||||
case ACI_CMD_GET_TEMPERATURE:
|
||||
acil_encode_cmd_temparature(buffer);
|
||||
break;
|
||||
case ACI_CMD_GET_DEVICE_ADDRESS:
|
||||
acil_encode_cmd_get_address(buffer);
|
||||
break;
|
||||
case ACI_CMD_SET_TX_POWER:
|
||||
acil_encode_cmd_set_radio_tx_power(buffer, &(p_aci_cmd->params.set_tx_power));
|
||||
break;
|
||||
case ACI_CMD_CONNECT:
|
||||
acil_encode_cmd_connect(buffer, &(p_aci_cmd->params.connect));
|
||||
break;
|
||||
case ACI_CMD_BOND:
|
||||
acil_encode_cmd_bond(buffer, &(p_aci_cmd->params.bond));
|
||||
break;
|
||||
case ACI_CMD_DISCONNECT:
|
||||
acil_encode_cmd_disconnect(buffer, &(p_aci_cmd->params.disconnect));
|
||||
break;
|
||||
case ACI_CMD_RADIO_RESET:
|
||||
acil_encode_baseband_reset(buffer);
|
||||
break;
|
||||
case ACI_CMD_CHANGE_TIMING:
|
||||
acil_encode_cmd_change_timing_req(buffer, &(p_aci_cmd->params.change_timing));
|
||||
break;
|
||||
case ACI_CMD_SETUP:
|
||||
acil_encode_cmd_setup(buffer, &(p_aci_cmd->params.setup), (p_aci_cmd->len - MSG_SETUP_CMD_BASE_LEN));
|
||||
break;
|
||||
case ACI_CMD_DTM_CMD:
|
||||
acil_encode_cmd_dtm_cmd(buffer, &(p_aci_cmd->params.dtm_cmd));
|
||||
break;
|
||||
case ACI_CMD_READ_DYNAMIC_DATA:
|
||||
acil_encode_cmd_read_dynamic_data(buffer);
|
||||
break;
|
||||
case ACI_CMD_WRITE_DYNAMIC_DATA:
|
||||
acil_encode_cmd_write_dynamic_data(buffer, p_aci_cmd->params.write_dynamic_data.seq_no, &(p_aci_cmd->params.write_dynamic_data.dynamic_data[0]), (p_aci_cmd->len - MSG_WRITE_DYNAMIC_DATA_BASE_LEN));
|
||||
break;
|
||||
case ACI_CMD_OPEN_REMOTE_PIPE:
|
||||
acil_encode_cmd_open_remote_pipe(buffer, &(p_aci_cmd->params.open_remote_pipe));
|
||||
break;
|
||||
case ACI_CMD_SEND_DATA:
|
||||
acil_encode_cmd_send_data(buffer, &(p_aci_cmd->params.send_data), (p_aci_cmd->len - MSG_SEND_DATA_BASE_LEN));
|
||||
break;
|
||||
case ACI_CMD_SEND_DATA_ACK:
|
||||
acil_encode_cmd_send_data_ack(buffer, p_aci_cmd->params.send_data_ack.pipe_number );
|
||||
break;
|
||||
case ACI_CMD_REQUEST_DATA:
|
||||
acil_encode_cmd_request_data(buffer, &(p_aci_cmd->params.request_data));
|
||||
break;
|
||||
case ACI_CMD_SET_LOCAL_DATA:
|
||||
acil_encode_cmd_set_local_data(buffer, (aci_cmd_params_set_local_data_t *)(&(p_aci_cmd->params.send_data)), (p_aci_cmd->len - MSG_SET_LOCAL_DATA_BASE_LEN));
|
||||
break;
|
||||
case ACI_CMD_BOND_SECURITY_REQUEST:
|
||||
acil_encode_cmd_bond_security_request(buffer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp)
|
||||
{
|
||||
aci_evt_cmd_rsp_params_get_device_version_t *p_device_version;
|
||||
aci_evt_cmd_rsp_params_get_device_address_t *p_device_address;
|
||||
aci_evt_cmd_rsp_params_get_temperature_t *p_temperature;
|
||||
aci_evt_cmd_rsp_params_get_battery_level_t *p_batt_lvl;
|
||||
aci_evt_cmd_rsp_read_dynamic_data_t *p_read_dyn_data;
|
||||
aci_evt_cmd_rsp_params_dtm_cmd_t *p_dtm_evt;
|
||||
|
||||
p_evt_params_cmd_rsp->cmd_opcode = (aci_cmd_opcode_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE);
|
||||
p_evt_params_cmd_rsp->cmd_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS);
|
||||
|
||||
switch (p_evt_params_cmd_rsp->cmd_opcode)
|
||||
{
|
||||
case ACI_CMD_GET_DEVICE_VERSION:
|
||||
p_device_version = &(p_evt_params_cmd_rsp->params.get_device_version);
|
||||
p_device_version->configuration_id = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB);
|
||||
p_device_version->configuration_id |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB) << 8;
|
||||
p_device_version->aci_version = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION);
|
||||
p_device_version->setup_format = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT);
|
||||
p_device_version->setup_id = (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0);
|
||||
p_device_version->setup_id |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1) << 8;
|
||||
p_device_version->setup_id |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0) << 16;
|
||||
p_device_version->setup_id |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1) << 24;
|
||||
p_device_version->setup_status = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS);
|
||||
break;
|
||||
|
||||
case ACI_CMD_GET_DEVICE_ADDRESS:
|
||||
p_device_address = &(p_evt_params_cmd_rsp->params.get_device_address);
|
||||
memcpy((uint8_t *)(p_device_address->bd_addr_own), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN), BTLE_DEVICE_ADDRESS_SIZE);
|
||||
p_device_address->bd_addr_type = (aci_bd_addr_type_t) *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE);
|
||||
break;
|
||||
|
||||
case ACI_CMD_GET_TEMPERATURE:
|
||||
p_temperature = &(p_evt_params_cmd_rsp->params.get_temperature);
|
||||
p_temperature->temperature_value = (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB);
|
||||
p_temperature->temperature_value |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB) << 8;
|
||||
break;
|
||||
|
||||
case ACI_CMD_GET_BATTERY_LEVEL:
|
||||
p_batt_lvl = &(p_evt_params_cmd_rsp->params.get_battery_level);
|
||||
p_batt_lvl->battery_level = (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB);
|
||||
p_batt_lvl->battery_level |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB) << 8;
|
||||
break;
|
||||
|
||||
case ACI_CMD_READ_DYNAMIC_DATA:
|
||||
p_read_dyn_data = &(p_evt_params_cmd_rsp->params.read_dynamic_data);
|
||||
p_read_dyn_data->seq_no = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO);
|
||||
memcpy((uint8_t *)(p_read_dyn_data->dynamic_data), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), ACIL_DECODE_EVT_GET_LENGTH(buffer_in) - 3); // 3 bytes subtracted account for EventCode, CommandOpCode and Status bytes.
|
||||
// Now that the p_read_dyn_data->dynamic_data will be pointing to memory location with enough space to accommodate upto 27 bytes of dynamic data received. This is because of the padding element in aci_evt_params_cmd_rsp_t
|
||||
break;
|
||||
|
||||
case ACI_CMD_DTM_CMD:
|
||||
p_dtm_evt = &(p_evt_params_cmd_rsp->params.dtm_cmd);
|
||||
p_dtm_evt->evt_msb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB);
|
||||
p_dtm_evt->evt_lsb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started)
|
||||
{
|
||||
p_evt_params_device_started->device_mode = (aci_device_operation_mode_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE);
|
||||
p_evt_params_device_started->hw_error = (aci_hw_error_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR);
|
||||
p_evt_params_device_started->credit_available = *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE);
|
||||
}
|
||||
|
||||
void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status)
|
||||
{
|
||||
memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_open_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP), 8);
|
||||
memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_closed_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP), 8);
|
||||
}
|
||||
|
||||
void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected)
|
||||
{
|
||||
p_aci_evt_params_disconnected->aci_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS);
|
||||
p_aci_evt_params_disconnected->btle_status = *(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS);
|
||||
}
|
||||
|
||||
void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status)
|
||||
{
|
||||
p_aci_evt_params_bond_status->status_code = (aci_bond_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE);
|
||||
p_aci_evt_params_bond_status->status_source = (aci_bond_status_source_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE);
|
||||
p_aci_evt_params_bond_status->secmode1_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP);
|
||||
p_aci_evt_params_bond_status->secmode2_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP);
|
||||
p_aci_evt_params_bond_status->keys_exchanged_slave = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE);
|
||||
p_aci_evt_params_bond_status->keys_exchanged_master = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER);
|
||||
}
|
||||
|
||||
uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received)
|
||||
{
|
||||
uint8_t size = *( buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA) + 1 ;
|
||||
p_evt_params_data_received->rx_data.pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_PIPE_NUMBER);
|
||||
memcpy((uint8_t *)p_evt_params_data_received->rx_data.aci_data, (buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack)
|
||||
{
|
||||
p_evt_params_data_ack->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_ACK + OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER);
|
||||
}
|
||||
|
||||
uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error)
|
||||
{
|
||||
uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME) + 1;
|
||||
p_aci_evt_params_hw_error->line_num = (uint16_t)(*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB)) << 8;
|
||||
p_aci_evt_params_hw_error->line_num |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB);
|
||||
memcpy((uint8_t *)p_aci_evt_params_hw_error->file_name, (buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit)
|
||||
{
|
||||
p_evt_params_data_credit->credit = *(buffer_in + OFFSET_ACI_EVT_T_DATA_CREDIT + OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT);
|
||||
}
|
||||
|
||||
void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected)
|
||||
{
|
||||
p_aci_evt_params_connected->dev_addr_type = (aci_bd_addr_type_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE);
|
||||
memcpy(&(p_aci_evt_params_connected->dev_addr[0]), (buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR), BTLE_DEVICE_ADDRESS_SIZE);
|
||||
p_aci_evt_params_connected->conn_rf_interval = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB) << 8;
|
||||
p_aci_evt_params_connected->conn_rf_interval |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB);
|
||||
p_aci_evt_params_connected->conn_slave_rf_latency = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;
|
||||
p_aci_evt_params_connected->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB);
|
||||
p_aci_evt_params_connected->conn_rf_timeout = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB) << 8;
|
||||
p_aci_evt_params_connected->conn_rf_timeout |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB);
|
||||
p_aci_evt_params_connected->master_clock_accuracy = (aci_clock_accuracy_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY);
|
||||
|
||||
}
|
||||
|
||||
void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing)
|
||||
{
|
||||
p_evt_params_timing->conn_rf_interval = *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB) << 8;
|
||||
p_evt_params_timing->conn_rf_interval |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB);
|
||||
p_evt_params_timing->conn_slave_rf_latency = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;
|
||||
p_evt_params_timing->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB);
|
||||
p_evt_params_timing->conn_rf_timeout = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB) << 8;
|
||||
p_evt_params_timing->conn_rf_timeout |= *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB);
|
||||
}
|
||||
|
||||
void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error)
|
||||
{
|
||||
//volatile uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA) + 1;
|
||||
p_evt_params_pipe_error->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER);
|
||||
p_evt_params_pipe_error->error_code = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE);
|
||||
p_evt_params_pipe_error->params.error_data.content[0] = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA + OFFSET_ERROR_DATA_T_CONTENT);
|
||||
}
|
||||
|
||||
void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request)
|
||||
{
|
||||
p_evt_params_key_request->key_type = (aci_key_type_t)*(buffer_in + OFFSET_ACI_EVT_T_KEY_REQUEST + OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE);
|
||||
}
|
||||
|
||||
uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *aci_evt_params_echo)
|
||||
{
|
||||
uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - 1;
|
||||
memcpy(&aci_evt_params_echo->echo_data[0], (buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE + 1), size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey)
|
||||
{
|
||||
p_aci_evt_params_display_passkey->passkey[0] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 0);
|
||||
p_aci_evt_params_display_passkey->passkey[1] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 1);
|
||||
p_aci_evt_params_display_passkey->passkey[2] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 2);
|
||||
p_aci_evt_params_display_passkey->passkey[3] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 3);
|
||||
p_aci_evt_params_display_passkey->passkey[4] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 4);
|
||||
p_aci_evt_params_display_passkey->passkey[5] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY + OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 5);
|
||||
}
|
||||
|
||||
bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt)
|
||||
{
|
||||
bool ret_val = true;
|
||||
|
||||
p_aci_evt->len = ACIL_DECODE_EVT_GET_LENGTH(buffer_in);
|
||||
p_aci_evt->evt_opcode = (aci_evt_opcode_t)ACIL_DECODE_EVT_GET_OPCODE(buffer_in);
|
||||
|
||||
switch(p_aci_evt->evt_opcode)
|
||||
{
|
||||
case ACI_EVT_DEVICE_STARTED:
|
||||
acil_decode_evt_device_started(buffer_in, &(p_aci_evt->params.device_started));
|
||||
break;
|
||||
case ACI_EVT_HW_ERROR:
|
||||
acil_decode_evt_hw_error(buffer_in, &(p_aci_evt->params.hw_error));
|
||||
break;
|
||||
case ACI_EVT_CMD_RSP:
|
||||
acil_decode_evt_command_response(buffer_in, &(p_aci_evt->params.cmd_rsp));
|
||||
break;
|
||||
case ACI_EVT_DATA_CREDIT:
|
||||
acil_decode_evt_credit(buffer_in, &(p_aci_evt->params.data_credit));
|
||||
break;
|
||||
case ACI_EVT_CONNECTED:
|
||||
acil_decode_evt_connected(buffer_in, &(p_aci_evt->params.connected));
|
||||
break;
|
||||
case ACI_EVT_PIPE_STATUS:
|
||||
acil_decode_evt_pipe_status(buffer_in, &(p_aci_evt->params.pipe_status));
|
||||
break;
|
||||
case ACI_EVT_DISCONNECTED:
|
||||
acil_decode_evt_disconnected(buffer_in, &(p_aci_evt->params.disconnected));
|
||||
break;
|
||||
case ACI_EVT_BOND_STATUS:
|
||||
acil_decode_evt_bond_status(buffer_in, &(p_aci_evt->params.bond_status));
|
||||
break;
|
||||
case ACI_EVT_TIMING:
|
||||
acil_decode_evt_timing(buffer_in, &(p_aci_evt->params.timing));
|
||||
break;
|
||||
case ACI_EVT_DATA_ACK:
|
||||
acil_decode_evt_data_ack(buffer_in, &(p_aci_evt->params.data_ack));
|
||||
break;
|
||||
case ACI_EVT_DATA_RECEIVED:
|
||||
acil_decode_evt_data_received(buffer_in, &(p_aci_evt->params.data_received));
|
||||
break;
|
||||
case ACI_EVT_PIPE_ERROR:
|
||||
acil_decode_evt_pipe_error(buffer_in, &(p_aci_evt->params.pipe_error));
|
||||
break;
|
||||
case ACI_EVT_KEY_REQUEST:
|
||||
acil_decode_evt_key_request(buffer_in, &(p_aci_evt->params.key_request));
|
||||
break;
|
||||
case ACI_EVT_DISPLAY_PASSKEY:
|
||||
acil_decode_evt_display_passkey(buffer_in, &(p_aci_evt->params.display_passkey));
|
||||
break;
|
||||
default:
|
||||
ret_val = false;
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
53
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib.h
Executable file
53
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib.h
Executable file
@@ -0,0 +1,53 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Internal prototype for acilib module.
|
||||
*/
|
||||
|
||||
#ifndef _acilib_H_
|
||||
#define _acilib_H_
|
||||
|
||||
#define MSG_SET_LOCAL_DATA_BASE_LEN 2
|
||||
#define MSG_CONNECT_LEN 5
|
||||
#define MSG_BOND_LEN 5
|
||||
#define MSG_DISCONNECT_LEN 2
|
||||
#define MSG_BASEBAND_RESET_LEN 1
|
||||
#define MSG_WAKEUP_LEN 1
|
||||
#define MSG_SET_RADIO_TX_POWER_LEN 2
|
||||
#define MSG_GET_DEVICE_ADDR_LEN 1
|
||||
#define MSG_SEND_DATA_BASE_LEN 2
|
||||
#define MSG_DATA_REQUEST_LEN 2
|
||||
#define MSG_OPEN_REMOTE_PIPE_LEN 2
|
||||
#define MSG_CLOSE_REMOTE_PIPE_LEN 2
|
||||
#define MSG_DTM_CMD 3
|
||||
#define MSG_WRITE_DYNAMIC_DATA_BASE_LEN 2
|
||||
#define MSG_SETUP_CMD_BASE_LEN 1
|
||||
#define MSG_ECHO_MSG_CMD_BASE_LEN 1
|
||||
#define MSG_CHANGE_TIMING_LEN 9
|
||||
#define MSG_SET_APP_LATENCY_LEN 4
|
||||
#define MSG_CHANGE_TIMING_LEN_GAP_PPCP 1
|
||||
#define MSG_DIRECT_CONNECT_LEN 1
|
||||
#define MSG_SET_KEY_REJECT_LEN 2
|
||||
#define MSG_SET_KEY_PASSKEY_LEN 8
|
||||
#define MSG_SET_KEY_OOB_LEN 18
|
||||
#define MSG_ACK_LEN 2
|
||||
#define MSG_NACK_LEN 3
|
||||
#define MSG_BROADCAST_LEN 5
|
||||
#define MSG_OPEN_ADV_PIPES_LEN 9
|
||||
|
||||
#endif /* _acilib_H_ */
|
||||
29
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_defs.h
Executable file
29
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_defs.h
Executable file
@@ -0,0 +1,29 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Definitions for the acilib interfaces
|
||||
*/
|
||||
|
||||
#ifndef _acilib_DEFS_H_
|
||||
#define _acilib_DEFS_H_
|
||||
|
||||
#define ACIL_DECODE_EVT_GET_LENGTH(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_LEN))
|
||||
|
||||
#define ACIL_DECODE_EVT_GET_OPCODE(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE))
|
||||
|
||||
#endif /* _acilib_DEFS_H_ */
|
||||
463
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_if.h
Executable file
463
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_if.h
Executable file
@@ -0,0 +1,463 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Prototypes for the acilib interfaces.
|
||||
*/
|
||||
|
||||
#ifndef _acilib_IF_H_
|
||||
#define _acilib_IF_H_
|
||||
|
||||
/** @brief Encode the ACI message for set test mode command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] test_mode Pointer to the test mode in ::aci_cmd_params_test_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test);
|
||||
|
||||
/** @brief Encode the ACI message for sleep command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_sleep(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message for get device version
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_get_device_version(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message for set local data
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_set_local_data Pointer to the local data parameters in ::aci_cmd_params_set_local_data_t
|
||||
* @param[in] data_size Size of data message
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size);
|
||||
|
||||
/** @brief Encode the ACI message to connect
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_connect Pointer to the run parameters in ::aci_cmd_params_connect_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect);
|
||||
|
||||
/** @brief Encode the ACI message to bond
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_bond Pointer to the run parameters in ::aci_cmd_params_bond_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond);
|
||||
|
||||
/** @brief Encode the ACI message to disconnect
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_disconnect Pointer to the run parameters in ::aci_cmd_params_disconnect_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect);
|
||||
|
||||
/** @brief Encode the ACI message to baseband reset
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_baseband_reset(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message for Directed Advertising
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_direct_connect(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message to wakeup
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_wakeup(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message for set radio Tx power
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_set_tx_power Pointer to the set Tx power parameters in ::aci_cmd_params_set_tx_power_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power);
|
||||
|
||||
/** @brief Encode the ACI message for get device address
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_get_address(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message for send data
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_send_data_t Pointer to the data parameters in ::aci_cmd_params_send_data_t
|
||||
* @param[in] data_size Size of data message
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size);
|
||||
|
||||
/** @brief Encode the ACI message for request data
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_request_data Pointer to the request data parameters in ::aci_cmd_params_request_data_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data);
|
||||
|
||||
/** @brief Encode the ACI message for open remote pipe
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_open_remote_pipe Pointer to the dynamic data parameters in ::aci_cmd_params_open_remote_pipe_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe);
|
||||
|
||||
/** @brief Encode the ACI message for close remote pipe
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_close_remote_pipe Pointer to the dynamic data parameters in ::aci_cmd_params_close_remote_pipe_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe);
|
||||
|
||||
/** @brief Encode the ACI message for echo message
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_cmd_params_echo Pointer to the dynamic data parameters in ::aci_cmd_params_echo_t
|
||||
* @param[in] msg_size Size of the message
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size);
|
||||
|
||||
/** @brief Encode the ACI message to battery level
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_battery_level(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message to temparature
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_temparature(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message to read dynamic data
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_read_dynamic_data(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message to change timing request
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_change_timing Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing);
|
||||
|
||||
/** @brief Encode the ACI message to change timing request using the timing parameters from GAP PPCP
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_change_timing Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer);
|
||||
|
||||
|
||||
/** @brief Encode the ACI message for write dynamic data
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] seq_no Sequence number of the dynamic data (as received in the response to @c Read Dynamic Data)
|
||||
* @param[in] dynamic_data Pointer to the dynamic data
|
||||
* @param[in] dynamic_data_size Size of dynamic data
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size);
|
||||
|
||||
/** @brief Encode the ACI message to send data acknowledgement
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] pipe_number Pipe number for which the ack is to be sent
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number);
|
||||
|
||||
/** @brief Encode the ACI message to send negative acknowledgement
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] pipe_number Pipe number for which the nack is to be sent
|
||||
* @param[in] error_code Error code that has to be sent in the NACK
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number,const uint8_t error_code);
|
||||
|
||||
/** @brief Encode the ACI message to set the application latency
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd_params_set_app_latency Pointer to the set_application_latency command parameters in ::aci_cmd_params_dtm_cmd_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency);
|
||||
|
||||
/** @brief Encode the ACI message for setup
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_cmd_params_set_run_behaviour Pointer to the setup data in ::aci_cmd_params_setup_t
|
||||
* @param[in] setup_data_size Size of setup message
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size);
|
||||
|
||||
/** @brief Encode the ACI message for DTM command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_cmd_params_set_run_behaviour Pointer to the DTM command parameters in ::aci_cmd_params_dtm_cmd_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd);
|
||||
|
||||
/** @brief Encode the ACI message for Set Key Request command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key);
|
||||
|
||||
/** @brief Encode the ACI message for Bond Security Request command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_bond_security_request(uint8_t *buffer);
|
||||
|
||||
/** @brief Encode the ACI message
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd Pointer to ACI command data in ::aci_cmd_t
|
||||
* @param[in] bool
|
||||
*
|
||||
* @return bool true, if succesful, else returns false
|
||||
*/
|
||||
bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd);
|
||||
|
||||
/** @brief Encode the ACI message for Broadcast command
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd Pointer to ACI command data in ::aci_cmd_params_broadcast_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_broadcast(uint8_t *buffer, aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast);
|
||||
|
||||
/** @brief Encode the ACI message for Open Adv Pipes
|
||||
*
|
||||
* @param[in,out] buffer Pointer to ACI message buffer
|
||||
* @param[in] p_aci_cmd Pointer to ACI command data in ::aci_cmd_params_open_adv_pipe_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_set_adv_svc_data);
|
||||
|
||||
/** @brief Decode the ACI event command response
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] buffer Pointer to the decoded message in ::aci_evt_params_cmd_rsp_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp);
|
||||
|
||||
/** @brief Decode the ACI event device started
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt Pointer to the decoded message in ::aci_evt_params_device_started_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started);
|
||||
|
||||
/** @brief Decode the ACI event pipe status
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt_params_pipe_status Pointer to the decoded message in ::aci_evt_params_pipe_status_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status);
|
||||
|
||||
/** @brief Decode the ACI event for disconnected
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt_params_disconnected Pointer to the decoded message in ::aci_evt_params_disconnected_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected);
|
||||
|
||||
/** @brief Decode the ACI event for bond status
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt_params_bond_status Pointer to the decoded message in ::aci_evt_params_bond_status_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status);
|
||||
|
||||
/** @brief Decode the ACI event for data received
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_data_received Pointer to the decoded message in ::aci_evt_params_data_received_t
|
||||
*
|
||||
* @return size Received data size
|
||||
*/
|
||||
uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received);
|
||||
|
||||
/** @brief Decode the ACI event data acknowledgement
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_data_ack Pointer to the decoded message in ::aci_evt_params_data_ack_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack);
|
||||
|
||||
/** @brief Decode the ACI event for hardware error
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt_params_hw_error Pointer to the decoded message in ::aci_evt_params_hw_error_t
|
||||
*
|
||||
* @return size Size of debug information
|
||||
*/
|
||||
uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error);
|
||||
|
||||
/** @brief Decode the ACI event data credit
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_data_credit Pointer to the decoded message in ::aci_evt_params_data_credit_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit);
|
||||
|
||||
/** @brief Decode the ACI event for connected
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt_params_connected Pointer to the decoded message in ::aci_evt_params_connected_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected);
|
||||
|
||||
/** @brief Decode the ACI event for timing
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_timing Pointer to the decoded message in ::aci_evt_params_timing_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing);
|
||||
|
||||
/** @brief Decode the ACI event for pipe error
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_pipe_error Pointer to the decoded message in ::aci_evt_params_pipe_error_t
|
||||
*
|
||||
*/
|
||||
void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error);
|
||||
|
||||
/** @brief Decode the ACI event for key request
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_evt_params_key_type Pointer to the decoded message in ::aci_evt_params_key_type_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request);
|
||||
|
||||
/** @brief Decode the ACI event for echo
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] buffer_out Pointer to the echo message (max size of buffer ::ACI_ECHO_DATA_MAX_LEN)
|
||||
*
|
||||
* @return size Received echo message size
|
||||
*/
|
||||
uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *buffer_out);
|
||||
|
||||
/** @brief Decode the ACI event
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt Pointer to the decoded message in ::aci_evt_t
|
||||
*
|
||||
* @return bool true, if succesful, else returns false
|
||||
*/
|
||||
bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt);
|
||||
|
||||
/** @brief Decode the Display Key Event
|
||||
*
|
||||
* @param[in] buffer_in Pointer to message received
|
||||
* @param[in,out] p_aci_evt Pointer to the decoded message in ::aci_evt_params_display_passkey_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey);
|
||||
|
||||
#endif /* _acilib_IF_H_ */
|
||||
25
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_types.h
Executable file
25
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/acilib_types.h
Executable file
@@ -0,0 +1,25 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Type used in the acilib interfaces
|
||||
*/
|
||||
|
||||
#ifndef _acilib_TYPES_H_
|
||||
#define _acilib_TYPES_H_
|
||||
|
||||
#endif /* _acilib_TYPES_H_ */
|
||||
22
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/ble_system.h
Executable file
22
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/ble_system.h
Executable file
@@ -0,0 +1,22 @@
|
||||
#ifndef BLE_SYSTEM_H_
|
||||
#define BLE_SYSTEM_H
|
||||
|
||||
/*
|
||||
#define HAL_IO_RADIO_CSN SS
|
||||
#define HAL_IO_RADIO_REQN SS
|
||||
#define HAL_IO_RADIO_RDY 3
|
||||
#define HAL_IO_RADIO_SCK SCK
|
||||
#define HAL_IO_RADIO_MOSI MOSI
|
||||
#define HAL_IO_RADIO_MISO MISO
|
||||
#define HAL_IO_RADIO_RESET 9
|
||||
#define HAL_IO_RADIO_ACTIVE 8
|
||||
|
||||
//#define HAL_IO_LED0 2
|
||||
//#define HAL_IO_LED1 6
|
||||
*/
|
||||
|
||||
#define ENABLE_INTERRUPTS() sei()
|
||||
#define DISABLE_INTERRUPTS() cli()
|
||||
#define ARE_INTERRUPTS_ENABLED() ((SREG & 0x80) == 0x80)
|
||||
|
||||
#endif
|
||||
55
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/dtm.h
Executable file
55
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/dtm.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup group_acilib
|
||||
*
|
||||
* @brief Internal prototype for acilib module.
|
||||
*/
|
||||
|
||||
#ifndef DTM_H__
|
||||
#define DTM_H__
|
||||
|
||||
/** @brief DTM command codes (upper two bits in the DTM command), use a bitwise OR with the frequency N = 0x00 <20> 0x27: N = (F-2402)/2 Frequency Range 2402 MHz
|
||||
to 2480 MHz*/
|
||||
#define DTM_LE_CMD_RESET 0x00
|
||||
#define DTM_LE_CMD_RECEIVER_TEST 0x40
|
||||
#define DTM_LE_CMD_TRANSMITTER_TEST 0x80
|
||||
#define DTM_LE_CMD_TEST_END 0xC0
|
||||
|
||||
|
||||
/** @brief Defined packet types for DTM */
|
||||
#define DTM_LE_PKT_PRBS9 0x00 /**< Bit pattern PRBS9. */
|
||||
#define DTM_LE_PKT_0X0F 0x01 /**< Bit pattern 11110000 (LSB is the leftmost bit). */
|
||||
#define DTM_LE_PKT_0X55 0x02 /**< Bit pattern 10101010 (LSB is the leftmost bit). */
|
||||
#define DTM_LE_PKT_VENDOR 0x03 /**< Vendor specific. Nordic: continous carrier test */
|
||||
|
||||
/** @brief Defined bit fields for DTM responses. */
|
||||
#define LE_PACKET_REPORTING_EVENT_MSB_BIT 0x80
|
||||
#define LE_TEST_STATUS_EVENT_LSB_BIT 0x01
|
||||
|
||||
/** @brief DTM response types. */
|
||||
#define LE_TEST_STATUS_EVENT 0x00
|
||||
#define LE_TEST_PACKET_REPORT_EVENT 0x80
|
||||
|
||||
/** @brief DTM return values. */
|
||||
#define LE_TEST_STATUS_SUCCESS 0x00
|
||||
#define LE_TEST_STATUS_FAILURE 0x01
|
||||
|
||||
|
||||
|
||||
#endif //DTM_H__
|
||||
|
||||
/** @} */
|
||||
108
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal/hal_aci_tl.h
Executable file
108
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal/hal_aci_tl.h
Executable file
@@ -0,0 +1,108 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Interface for hal_aci_tl.
|
||||
*/
|
||||
|
||||
/** @defgroup hal_aci_tl hal_aci_tl
|
||||
@{
|
||||
@ingroup hal
|
||||
|
||||
@brief Module for the ACI Transport Layer interface
|
||||
@details This module is responsible for sending and receiving messages over the ACI interface of the nRF8001 chip.
|
||||
The hal_aci_tl_send_cmd() can be called directly to send ACI commands.
|
||||
|
||||
|
||||
The RDYN line is hooked to an interrupt on the MCU when the level is low.
|
||||
The SPI master clocks in the interrupt context.
|
||||
The ACI Command is taken from the head of the command queue is sent over the SPI
|
||||
and the received ACI event is placed in the tail of the event queue.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HAL_ACI_TL_H__
|
||||
#define HAL_ACI_TL_H__
|
||||
|
||||
#include "hal_platform.h"
|
||||
|
||||
#ifndef HAL_ACI_MAX_LENGTH
|
||||
#define HAL_ACI_MAX_LENGTH 31
|
||||
#endif //HAL_ACI_MAX_LENGTH
|
||||
|
||||
#define ACI_QUEUE_SIZE 8
|
||||
|
||||
/** Data type for ACI commands and events */
|
||||
typedef struct hal_aci_data_t{
|
||||
uint8_t status_byte;
|
||||
uint8_t buffer[HAL_ACI_MAX_LENGTH+1];
|
||||
} hal_aci_data_t;
|
||||
|
||||
|
||||
/** @brief Message received hook function.
|
||||
* @details A hook function that must be implemented by the client of this module.
|
||||
* The function will be called by this module when a new message has been received from the nRF8001.
|
||||
* @param received_msg Pointer to a structure containing a pointer to the received data.
|
||||
*/
|
||||
extern void hal_aci_tl_msg_rcv_hook(hal_aci_data_t *received_msg);
|
||||
|
||||
/** ACI Transport Layer configures inputs/outputs.
|
||||
*/
|
||||
void hal_aci_tl_io_config(void);
|
||||
|
||||
|
||||
/** ACI Transport Layer initialization.
|
||||
*/
|
||||
void hal_aci_tl_init(void);
|
||||
|
||||
/**@brief Sends an ACI command to the radio.
|
||||
* @details
|
||||
* This function sends an ACI command to the radio. This will memorize the pointer of the message to send and
|
||||
* lower the request line. When the device lowers the ready line, @ref hal_aci_tl_poll_rdy_line() will send the data.
|
||||
* @param aci_buffer Pointer to the message to send.
|
||||
* @return True if the send is started successfully, false if a transaction is already running.
|
||||
*/
|
||||
bool hal_aci_tl_send(hal_aci_data_t *aci_buffer);
|
||||
|
||||
|
||||
/** @brief Check for pending transaction.
|
||||
* @details
|
||||
* Call this function from the main context at regular intervals to check if the nRF8001 RDYN line indicates a pending transaction.
|
||||
* If a transaction is pending, this function will treat it and call the receive hook.
|
||||
*/
|
||||
void hal_aci_tl_poll_rdy_line(void);
|
||||
|
||||
hal_aci_data_t * hal_aci_tl_poll_get(void);
|
||||
|
||||
bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);
|
||||
|
||||
/** @brief Flush the ACI command Queue and the ACI Event Queue
|
||||
* @details
|
||||
* Call this function in the main thread
|
||||
*/
|
||||
void m_aci_q_flush(void);
|
||||
|
||||
/** @brief Enable debug printing of all ACI commands sent and ACI events received
|
||||
* @details
|
||||
* when the enable parameter is true. The debug printing is enabled on the Serial.
|
||||
* When the enable parameter is false. The debug printing is disabled on the Serial.
|
||||
* By default the debug printing is disabled.
|
||||
*/
|
||||
void hal_aci_debug_print(bool enable);
|
||||
|
||||
#endif // HAL_ACI_TL_H__
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
71
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal/hal_io.h
Executable file
71
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal/hal_io.h
Executable file
@@ -0,0 +1,71 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*/
|
||||
|
||||
/** @defgroup hal_io hal_io
|
||||
* @{
|
||||
* @ingroup hal
|
||||
* @brief Macros input/output management
|
||||
*/
|
||||
|
||||
#include "hal_platform.h"
|
||||
|
||||
#ifndef HAL_IO_H__
|
||||
#define HAL_IO_H__
|
||||
|
||||
#define HAL_IO_P00 PIN0
|
||||
#define HAL_IO_P01 PIN1
|
||||
#define HAL_IO_P02 PIN2
|
||||
#define HAL_IO_P03 PIN3
|
||||
#define HAL_IO_P04 PIN4
|
||||
#define HAL_IO_P05 PIN5
|
||||
#define HAL_IO_P06 PIN6
|
||||
#define HAL_IO_P07 PIN7
|
||||
#define HAL_IO_P08 PIN8
|
||||
#define HAL_IO_P09 PIN9
|
||||
|
||||
#define HAL_IO_OUTPUT OUTPUT
|
||||
#define HAL_IO_INPUT INPUT
|
||||
|
||||
/**@brief Macro to configure an I/O.
|
||||
* @details
|
||||
* This macro configures a given I/O to input or output with pullup/buffer configuration.
|
||||
* @param io_name I/O to configure.
|
||||
* @param is_input Indicate if the I/O is to be set as an input.
|
||||
* @param io_mode Pull resistor and buffer configuration (must be HAL_IO_OUTPUT_NORMAL_STRENGTH, HAL_IO_OUTPUT_HIGH_STRENGTH, HAL_IO_INPUT_BUF_ON_NO_PULL,
|
||||
* HAL_IO_INPUT_BUF_ON_PULL_DOWN, HAL_IO_INPUT_BUF_ON_PULL_UP, or HAL_IO_INPUT_BUF_OFF).
|
||||
*/
|
||||
#define HAL_IO_CONFIG(io_name, is_input, io_mode) pinMode(io_name, is_input)
|
||||
|
||||
/**@brief Macro to set an output.
|
||||
* @details
|
||||
* This macro sets the given output to the given level (1 -> high, 0 -> low).
|
||||
* @param io_name Output to change.
|
||||
* @param io_state Level to set.
|
||||
*/
|
||||
#define HAL_IO_SET_STATE(io_name, io_state) digitalWrite(io_name, io_state)
|
||||
|
||||
/**@brief Macro that reads the current state of an input.
|
||||
* @details
|
||||
* This macro reads the current state of a logical input.
|
||||
* @param io_name Input to read.
|
||||
* @return Input state level (1 if high, 0 if low).
|
||||
*/
|
||||
#define HAL_IO_READ(io_name) digitalRead(io_name)
|
||||
|
||||
|
||||
#endif //HAL_IO_H__
|
||||
|
||||
/** @} */
|
||||
425
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal_aci_tl.cpp
Executable file
425
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal_aci_tl.cpp
Executable file
@@ -0,0 +1,425 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision: 4808 $
|
||||
*/
|
||||
|
||||
/** @file
|
||||
@brief Implementation of the ACI transport layer module
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "hal_platform.h"
|
||||
#include "hal/hal_aci_tl.h"
|
||||
#include "hal/hal_io.h"
|
||||
#include "ble_system.h"
|
||||
#include <avr/sleep.h>
|
||||
|
||||
extern int8_t HAL_IO_RADIO_RESET, HAL_IO_RADIO_REQN, HAL_IO_RADIO_RDY, HAL_IO_RADIO_IRQ;
|
||||
|
||||
static const uint8_t dreqinttable[] = {
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
|
||||
2, 0,
|
||||
3, 1,
|
||||
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||
2, 0,
|
||||
3, 1,
|
||||
21, 2,
|
||||
20, 3,
|
||||
19, 4,
|
||||
18, 5,
|
||||
#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
|
||||
5, 0,
|
||||
6, 1,
|
||||
7, 2,
|
||||
8, 3,
|
||||
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
|
||||
0, 0,
|
||||
1, 1,
|
||||
2, 2,
|
||||
3, 3,
|
||||
36, 4,
|
||||
37, 5,
|
||||
18, 6,
|
||||
19, 7,
|
||||
#elif defined(__arm__) && defined(CORE_TEENSY)
|
||||
0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||||
5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
|
||||
10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
||||
15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
|
||||
20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
|
||||
25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
|
||||
30, 30, 31, 31, 32, 32, 33, 33,
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
7, 4,
|
||||
3, 0,
|
||||
2, 1,
|
||||
0, 2,
|
||||
1, 3,
|
||||
#elif defined(__AVR_ATmega256RFR2__)
|
||||
4, 0,
|
||||
5, 1,
|
||||
15, 2,
|
||||
16, 3,
|
||||
13, 4,
|
||||
14, 5,
|
||||
7, 6,
|
||||
18, 7,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static void m_print_aci_data(hal_aci_data_t *p_data);
|
||||
|
||||
typedef struct {
|
||||
hal_aci_data_t aci_data[ACI_QUEUE_SIZE];
|
||||
uint8_t head;
|
||||
uint8_t tail;
|
||||
} aci_queue_t;
|
||||
|
||||
static hal_aci_data_t received_data;
|
||||
static uint8_t spi_readwrite(uint8_t aci_byte);
|
||||
static bool aci_debug_print;
|
||||
|
||||
|
||||
|
||||
|
||||
static aci_queue_t aci_tx_q;
|
||||
static aci_queue_t aci_rx_q;
|
||||
|
||||
static void m_aci_q_init(aci_queue_t *aci_q)
|
||||
{
|
||||
uint8_t loop;
|
||||
|
||||
aci_debug_print = false;
|
||||
aci_q->head = 0;
|
||||
aci_q->tail = 0;
|
||||
for(loop=0; loop<ACI_QUEUE_SIZE; loop++)
|
||||
{
|
||||
aci_tx_q.aci_data[loop].buffer[0] = 0x00;
|
||||
aci_tx_q.aci_data[loop].buffer[1] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void hal_aci_debug_print(bool enable)
|
||||
{
|
||||
aci_debug_print = enable;
|
||||
}
|
||||
|
||||
static bool m_aci_q_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
|
||||
{
|
||||
const uint8_t next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
|
||||
const uint8_t length = p_data->buffer[0];
|
||||
|
||||
if (next == aci_q->head)
|
||||
{
|
||||
/* full queue */
|
||||
return false;
|
||||
}
|
||||
aci_q->aci_data[aci_q->tail].status_byte = 0;
|
||||
|
||||
memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);
|
||||
aci_q->tail = next;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//@comment after a port have test for the queue states, esp. the full and the empty states
|
||||
static bool m_aci_q_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
|
||||
{
|
||||
if (aci_q->head == aci_q->tail)
|
||||
{
|
||||
/* empty queue */
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
|
||||
aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool m_aci_q_is_empty(aci_queue_t *aci_q)
|
||||
{
|
||||
return (aci_q->head == aci_q->tail);
|
||||
}
|
||||
|
||||
static bool m_aci_q_is_full(aci_queue_t *aci_q)
|
||||
{
|
||||
uint8_t next;
|
||||
bool state;
|
||||
|
||||
//This should be done in a critical section
|
||||
noInterrupts();
|
||||
next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
|
||||
|
||||
if (next == aci_q->head)
|
||||
{
|
||||
state = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = false;
|
||||
}
|
||||
|
||||
interrupts();
|
||||
//end
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void m_print_aci_data(hal_aci_data_t *p_data)
|
||||
{
|
||||
const uint8_t length = p_data->buffer[0];
|
||||
uint8_t i;
|
||||
Serial.print(length, DEC);
|
||||
Serial.print(" :");
|
||||
for (i=0; i<=length; i++)
|
||||
{
|
||||
Serial.print(p_data->buffer[i], HEX);
|
||||
Serial.print(F(", "));
|
||||
}
|
||||
Serial.println(F(""));
|
||||
}
|
||||
|
||||
void toggle_eimsk(bool state)
|
||||
{
|
||||
/* ToDo: This will currently only work with the UNO/ATMega48/88/128/328 */
|
||||
/* due to EIMSK. Abstract this away to something MCU nuetral! */
|
||||
uint8_t eimsk_bit = 0xFF;
|
||||
for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) {
|
||||
if (HAL_IO_RADIO_RDY == dreqinttable[i]) {
|
||||
eimsk_bit = dreqinttable[i+1];
|
||||
}
|
||||
}
|
||||
if (eimsk_bit != 0xFF)
|
||||
{
|
||||
if (state)
|
||||
EIMSK |= (1 << eimsk_bit);
|
||||
else
|
||||
EIMSK &= ~(1 << eimsk_bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RDY isn't a valid HW INT pin! */
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
void m_rdy_line_handle(void)
|
||||
{
|
||||
hal_aci_data_t *p_aci_data;
|
||||
|
||||
sleep_disable();
|
||||
detachInterrupt(HAL_IO_RADIO_IRQ);
|
||||
|
||||
// Receive or transmit data
|
||||
p_aci_data = hal_aci_tl_poll_get();
|
||||
|
||||
// Check if we received data
|
||||
if (p_aci_data->buffer[0] > 0)
|
||||
{
|
||||
if (!m_aci_q_enqueue(&aci_rx_q, p_aci_data))
|
||||
{
|
||||
/* Receive Buffer full.
|
||||
Should never happen.
|
||||
Spin in a while loop.
|
||||
*/
|
||||
while(1);
|
||||
}
|
||||
if (m_aci_q_is_full(&aci_rx_q))
|
||||
{
|
||||
/* Disable RDY line interrupt.
|
||||
Will latch any pending RDY lines, so when enabled it again this
|
||||
routine should be taken again */
|
||||
toggle_eimsk(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)
|
||||
{
|
||||
bool was_full = m_aci_q_is_full(&aci_rx_q);
|
||||
|
||||
if (m_aci_q_dequeue(&aci_rx_q, p_aci_data))
|
||||
{
|
||||
if (true == aci_debug_print)
|
||||
{
|
||||
Serial.print(" E");
|
||||
m_print_aci_data(p_aci_data);
|
||||
}
|
||||
|
||||
if (was_full)
|
||||
{
|
||||
toggle_eimsk(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void hal_aci_tl_init()
|
||||
{
|
||||
received_data.buffer[0] = 0;
|
||||
|
||||
SPI.begin();
|
||||
SPI.setBitOrder(LSBFIRST);
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV8);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
|
||||
|
||||
|
||||
/* initialize aci cmd queue */
|
||||
m_aci_q_init(&aci_tx_q);
|
||||
m_aci_q_init(&aci_rx_q);
|
||||
|
||||
//Configure the IO lines
|
||||
pinMode(HAL_IO_RADIO_RESET, OUTPUT);
|
||||
pinMode(HAL_IO_RADIO_RDY, INPUT_PULLUP);
|
||||
pinMode(HAL_IO_RADIO_REQN, OUTPUT);
|
||||
|
||||
digitalWrite(HAL_IO_RADIO_RESET, 1);
|
||||
delay(100);
|
||||
digitalWrite(HAL_IO_RADIO_RESET, 0);
|
||||
digitalWrite(HAL_IO_RADIO_RESET, 1);
|
||||
|
||||
digitalWrite(SCK, 0);
|
||||
digitalWrite(MOSI, 0);
|
||||
digitalWrite(HAL_IO_RADIO_REQN, 1);
|
||||
digitalWrite(SCK, 0);
|
||||
|
||||
HAL_IO_RADIO_IRQ = 0xFF;
|
||||
for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) {
|
||||
if (HAL_IO_RADIO_RDY == dreqinttable[i]) {
|
||||
HAL_IO_RADIO_IRQ = dreqinttable[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
delay(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset
|
||||
if (HAL_IO_RADIO_IRQ != 0xFF)
|
||||
attachInterrupt(HAL_IO_RADIO_IRQ, m_rdy_line_handle, LOW);
|
||||
// We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW
|
||||
}
|
||||
|
||||
bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd)
|
||||
{
|
||||
const uint8_t length = p_aci_cmd->buffer[0];
|
||||
bool ret_val = false;
|
||||
|
||||
if (length > HAL_ACI_MAX_LENGTH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_aci_q_enqueue(&aci_tx_q, p_aci_cmd))
|
||||
{
|
||||
ret_val = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (true == aci_debug_print)
|
||||
{
|
||||
Serial.print("C");
|
||||
m_print_aci_data(p_aci_cmd);
|
||||
}
|
||||
|
||||
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
hal_aci_data_t * hal_aci_tl_poll_get(void)
|
||||
{
|
||||
uint8_t byte_cnt;
|
||||
uint8_t byte_sent_cnt;
|
||||
uint8_t max_bytes;
|
||||
hal_aci_data_t data_to_send;
|
||||
|
||||
|
||||
//SPI.begin();
|
||||
|
||||
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
|
||||
|
||||
// Receive from queue
|
||||
if (m_aci_q_dequeue(&aci_tx_q, &data_to_send) == false)
|
||||
{
|
||||
/* queue was empty, nothing to send */
|
||||
data_to_send.status_byte = 0;
|
||||
data_to_send.buffer[0] = 0;
|
||||
}
|
||||
|
||||
//Change this if your mcu has DMA for the master SPI
|
||||
|
||||
// Send length, receive header
|
||||
byte_sent_cnt = 0;
|
||||
received_data.status_byte = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
|
||||
// Send first byte, receive length from slave
|
||||
received_data.buffer[0] = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
|
||||
if (0 == data_to_send.buffer[0])
|
||||
{
|
||||
max_bytes = received_data.buffer[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the maximum to the biggest size. One command byte is already sent
|
||||
max_bytes = (received_data.buffer[0] > (data_to_send.buffer[0] - 1))
|
||||
? received_data.buffer[0] : (data_to_send.buffer[0] - 1);
|
||||
}
|
||||
|
||||
if (max_bytes > HAL_ACI_MAX_LENGTH)
|
||||
{
|
||||
max_bytes = HAL_ACI_MAX_LENGTH;
|
||||
}
|
||||
|
||||
// Transmit/receive the rest of the packet
|
||||
for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
|
||||
{
|
||||
received_data.buffer[byte_cnt+1] = spi_readwrite(data_to_send.buffer[byte_sent_cnt++]);
|
||||
}
|
||||
|
||||
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 1);
|
||||
//SPI.end()
|
||||
//RDYN should follow the REQN line in approx 100ns
|
||||
|
||||
sleep_enable();
|
||||
attachInterrupt(HAL_IO_RADIO_IRQ, m_rdy_line_handle, LOW);
|
||||
|
||||
|
||||
|
||||
if (false == m_aci_q_is_empty(&aci_tx_q))
|
||||
{
|
||||
//Lower the REQN line to start a new ACI transaction
|
||||
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
|
||||
}
|
||||
|
||||
/* valid Rx available or transmit finished*/
|
||||
return (&received_data);
|
||||
}
|
||||
|
||||
static uint8_t spi_readwrite(const uint8_t aci_byte)
|
||||
{
|
||||
return SPI.transfer(aci_byte);
|
||||
}
|
||||
|
||||
void m_aci_q_flush(void)
|
||||
{
|
||||
noInterrupts();
|
||||
/* re-initialize aci cmd queue and aci event queue to flush them*/
|
||||
m_aci_q_init(&aci_tx_q);
|
||||
m_aci_q_init(&aci_rx_q);
|
||||
interrupts();
|
||||
}
|
||||
69
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal_platform.h
Executable file
69
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/hal_platform.h
Executable file
@@ -0,0 +1,69 @@
|
||||
/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_H__
|
||||
#define PLATFORM_H__
|
||||
|
||||
/** @file
|
||||
* @brief
|
||||
*/
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define hal_pltf_clear_spi_master_config() do { SPCR = 0; } while(0)
|
||||
|
||||
//SPI2X=1 SPS0=1 SPR0=1 -> 250KHz
|
||||
//DORD=1 LSBit first
|
||||
//SPE=1 Enable the SPI
|
||||
//MSTR=1 Enable master mode
|
||||
//CPOL=0 See Section 7 in the nRF8001 PS (Clock Polarity)
|
||||
//CPHA=0 See Section 7 in the nRF8001 PS (Clock Phase)
|
||||
/*
|
||||
Atmega328
|
||||
Table 18-5. Relationship Between SCK and the Oscillator Frequency
|
||||
SPI2X SPR1 SPR0 SCK Frequency
|
||||
0 0 0 fosc/4
|
||||
0 0 1 fosc/16
|
||||
0 1 0 fosc/64
|
||||
0 1 1 fosc/128
|
||||
1 0 0 fosc/2
|
||||
1 0 1 fosc/8
|
||||
1 1 0 fosc/32
|
||||
1 1 1 fosc/64
|
||||
*/
|
||||
/*
|
||||
#define hal_pltf_spi_master_config() do { \
|
||||
pinMode(SCK, OUTPUT);\
|
||||
pinMode(MOSI, OUTPUT);\
|
||||
pinMode(SS, OUTPUT);\
|
||||
pinMode(MISO, INPUT);\
|
||||
digitalWrite(SCK, LOW);\
|
||||
digitalWrite(MOSI, LOW);\
|
||||
digitalWrite(SS, HIGH);\
|
||||
SPCR = 0; \
|
||||
SPSR = 0; \
|
||||
SPSR = (1<<SPI2X);\
|
||||
SPCR = ((1<<SPE)|(1<<MSTR)|(0<<SPR1) | (1<<SPR0) | (1<<DORD) | (0<<CPOL) | (0<<CPHA));}\
|
||||
while(0)
|
||||
*/
|
||||
|
||||
#define hal_pltf_enable_spi() do { SPCR |= _BV(SPE); } while(0)
|
||||
#define hal_pltf_disable_spi() do { SPCR &= ~_BV(SPE); } while(0)
|
||||
|
||||
|
||||
|
||||
#define hal_pltf_configure_spi_for_aci() do{\
|
||||
hal_pltf_spi_master_config();\
|
||||
}while(0)
|
||||
|
||||
#endif /* PLATFORM_H__ */
|
||||
645
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/lib_aci.cpp
Executable file
645
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/lib_aci.cpp
Executable file
@@ -0,0 +1,645 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision: 4808 $
|
||||
*/
|
||||
/* Attention!
|
||||
* To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile
|
||||
* qualification listings, this section of source code must not be modified.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
@brief Implementation of the ACI library.
|
||||
*/
|
||||
|
||||
#include "hal_platform.h"
|
||||
#include "aci.h"
|
||||
#include "aci_cmds.h"
|
||||
#include "aci_evts.h"
|
||||
#include "aci_protocol_defines.h"
|
||||
#include "acilib_defs.h"
|
||||
#include "acilib_if.h"
|
||||
#include "hal/hal_aci_tl.h"
|
||||
#include "lib_aci.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define LIB_ACI_DEFAULT_CREDIT_NUMBER 1
|
||||
|
||||
|
||||
static services_pipe_type_mapping_t * p_services_pipe_type_map;
|
||||
static uint8_t pipe_count;
|
||||
static hal_aci_data_t * p_setup_msgs;
|
||||
static uint8_t setup_msgs_count;
|
||||
|
||||
|
||||
|
||||
static hal_aci_data_t msg_to_send;
|
||||
|
||||
static hal_aci_data_t *p_rcvd_evt;
|
||||
|
||||
static uint8_t cur_transaction_cmd;
|
||||
static uint8_t memorized_rcvd_cmd_opcode;
|
||||
static uint8_t memorized_transaction_cmd_opcode;
|
||||
|
||||
static bool is_cmd_response_expected;
|
||||
|
||||
static uint16_t cx_rf_interval; // rf_interval = cx_rf_interval * 1.25 ms Range:0x0006 to 0x0C80
|
||||
static uint16_t current_slave_latency;
|
||||
|
||||
|
||||
static bool is_request_operation_pending;
|
||||
static bool is_indicate_operation_pending;
|
||||
static bool is_open_remote_pipe_pending;
|
||||
static bool is_close_remote_pipe_pending;
|
||||
|
||||
static uint8_t request_operation_pipe = 0;
|
||||
static uint8_t indicate_operation_pipe = 0;
|
||||
|
||||
|
||||
// The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command
|
||||
// including the pipes to be opened.
|
||||
static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe;
|
||||
|
||||
static uint8_t cur_error_code;
|
||||
|
||||
bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe)
|
||||
{
|
||||
uint8_t byte_idx;
|
||||
|
||||
byte_idx = pipe / 8;
|
||||
if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8)))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe)
|
||||
{
|
||||
uint8_t byte_idx;
|
||||
|
||||
byte_idx = pipe / 8;
|
||||
if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8)))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_is_discovery_finished(aci_state_t *aci_stat)
|
||||
{
|
||||
return(aci_stat->pipes_open_bitmap[0]&0x01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void lib_aci_init(aci_state_t *aci_stat)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < PIPES_ARRAY_SIZE; i++)
|
||||
{
|
||||
aci_stat->pipes_open_bitmap[i] = 0;
|
||||
aci_stat->pipes_closed_bitmap[i] = 0;
|
||||
aci_cmd_params_open_adv_pipe.pipes[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
is_request_operation_pending = false;
|
||||
is_indicate_operation_pending = false;
|
||||
is_open_remote_pipe_pending = false;
|
||||
is_close_remote_pipe_pending = false;
|
||||
cur_transaction_cmd = ACI_CMD_INVALID;
|
||||
memorized_rcvd_cmd_opcode = ACI_CMD_INVALID;
|
||||
memorized_transaction_cmd_opcode = ACI_CMD_INVALID;
|
||||
cx_rf_interval = 0;
|
||||
current_slave_latency = 0;
|
||||
request_operation_pipe = 0;
|
||||
indicate_operation_pipe = 0;
|
||||
cur_error_code = 0;
|
||||
p_rcvd_evt = NULL;
|
||||
|
||||
p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;
|
||||
pipe_count = aci_stat->aci_setup_info.number_of_pipes;
|
||||
p_setup_msgs = aci_stat->aci_setup_info.setup_msgs;
|
||||
setup_msgs_count = aci_stat->aci_setup_info.num_setup_msgs;
|
||||
|
||||
hal_aci_tl_init();
|
||||
}
|
||||
|
||||
|
||||
uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat)
|
||||
{
|
||||
return aci_stat->data_credit_available;
|
||||
}
|
||||
|
||||
uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat)
|
||||
{
|
||||
uint32_t cx_rf_interval_ms_32bits;
|
||||
uint16_t cx_rf_interval_ms;
|
||||
|
||||
cx_rf_interval_ms_32bits = aci_stat->connection_interval;
|
||||
cx_rf_interval_ms_32bits *= 125; // the connection interval is given in multiple of 0.125 milliseconds
|
||||
cx_rf_interval_ms = cx_rf_interval_ms_32bits / 100;
|
||||
|
||||
return cx_rf_interval_ms;
|
||||
}
|
||||
|
||||
|
||||
uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat)
|
||||
{
|
||||
return aci_stat->connection_interval;
|
||||
}
|
||||
|
||||
|
||||
uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat)
|
||||
{
|
||||
return aci_stat->slave_latency;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode)
|
||||
{
|
||||
aci_cmd_params_set_app_latency_t aci_set_app_latency;
|
||||
|
||||
aci_set_app_latency.mode = latency_mode;
|
||||
aci_set_app_latency.latency = latency;
|
||||
acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency);
|
||||
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode)
|
||||
{
|
||||
aci_cmd_params_test_t aci_cmd_params_test;
|
||||
aci_cmd_params_test.test_mode_change = enter_exit_test_mode;
|
||||
acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_sleep()
|
||||
{
|
||||
acil_encode_cmd_sleep(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_radio_reset()
|
||||
{
|
||||
acil_encode_baseband_reset(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_direct_connect()
|
||||
{
|
||||
acil_encode_direct_connect(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_device_version()
|
||||
{
|
||||
acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size)
|
||||
{
|
||||
aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data;
|
||||
|
||||
if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL)
|
||||
||
|
||||
(size > ACI_PIPE_TX_DATA_MAX_LEN))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
aci_cmd_params_set_local_data.tx_data.pipe_number = pipe;
|
||||
memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size);
|
||||
acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval)
|
||||
{
|
||||
aci_cmd_params_connect_t aci_cmd_params_connect;
|
||||
aci_cmd_params_connect.timeout = run_timeout;
|
||||
aci_cmd_params_connect.adv_interval = adv_interval;
|
||||
acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason)
|
||||
{
|
||||
bool ret_val;
|
||||
uint8_t i;
|
||||
aci_cmd_params_disconnect_t aci_cmd_params_disconnect;
|
||||
aci_cmd_params_disconnect.reason = reason;
|
||||
acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect);
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
// If we have actually sent the disconnect
|
||||
if (ret_val)
|
||||
{
|
||||
// Update pipes immediately so that while the disconnect is happening,
|
||||
// the application can't attempt sending another message
|
||||
// If the application sends another message before we updated this
|
||||
// a ACI Pipe Error Event will be received from nRF8001
|
||||
for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
||||
{
|
||||
aci_stat->pipes_open_bitmap[i] = 0;
|
||||
aci_stat->pipes_closed_bitmap[i] = 0;
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval)
|
||||
{
|
||||
aci_cmd_params_bond_t aci_cmd_params_bond;
|
||||
aci_cmd_params_bond.timeout = run_timeout;
|
||||
aci_cmd_params_bond.adv_interval = adv_interval;
|
||||
acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_wakeup()
|
||||
{
|
||||
acil_encode_cmd_wakeup(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_set_tx_power(aci_device_output_power_t tx_power)
|
||||
{
|
||||
aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power;
|
||||
aci_cmd_params_set_tx_power.device_power = tx_power;
|
||||
acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_get_address()
|
||||
{
|
||||
acil_encode_cmd_get_address(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_get_temperature()
|
||||
{
|
||||
acil_encode_cmd_temparature(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_get_battery_level()
|
||||
{
|
||||
acil_encode_cmd_battery_level(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size)
|
||||
{
|
||||
bool ret_val = false;
|
||||
aci_cmd_params_send_data_t aci_cmd_params_send_data;
|
||||
|
||||
|
||||
if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) ||
|
||||
(p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size > ACI_PIPE_TX_DATA_MAX_LEN)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
{
|
||||
aci_cmd_params_send_data.tx_data.pipe_number = pipe;
|
||||
memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size);
|
||||
acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size);
|
||||
is_cmd_response_expected = false;
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe)
|
||||
{
|
||||
bool ret_val = false;
|
||||
aci_cmd_params_request_data_t aci_cmd_params_request_data;
|
||||
|
||||
if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
aci_cmd_params_request_data.pipe_number = pipe;
|
||||
acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data);
|
||||
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout)
|
||||
{
|
||||
aci_cmd_params_change_timing_t aci_cmd_params_change_timing;
|
||||
aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval;
|
||||
aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval;
|
||||
aci_cmd_params_change_timing.conn_params.slave_latency = slave_latency;
|
||||
aci_cmd_params_change_timing.conn_params.timeout_mult = timeout;
|
||||
acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_change_timing_GAP_PPCP()
|
||||
{
|
||||
acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
|
||||
{
|
||||
bool ret_val = false;
|
||||
aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe;
|
||||
|
||||
if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
|
||||
((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
|
||||
(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
|
||||
(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
is_request_operation_pending = true;
|
||||
is_open_remote_pipe_pending = true;
|
||||
request_operation_pipe = pipe;
|
||||
aci_cmd_params_open_remote_pipe.pipe_number = pipe;
|
||||
acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe);
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
|
||||
{
|
||||
bool ret_val = false;
|
||||
aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe;
|
||||
|
||||
if((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
|
||||
((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
|
||||
(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
|
||||
(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
|
||||
is_request_operation_pending = true;
|
||||
is_close_remote_pipe_pending = true;
|
||||
request_operation_pipe = pipe;
|
||||
aci_cmd_params_close_remote_pipe.pipe_number = pipe;
|
||||
acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe);
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len)
|
||||
{
|
||||
aci_cmd_params_set_key_t aci_cmd_params_set_key;
|
||||
aci_cmd_params_set_key.key_type = key_rsp_type;
|
||||
memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len);
|
||||
acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data)
|
||||
{
|
||||
aci_cmd_params_echo_t aci_cmd_params_echo;
|
||||
if(msg_size > (ACI_ECHO_DATA_MAX_LEN))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (msg_size > (ACI_ECHO_DATA_MAX_LEN))
|
||||
{
|
||||
msg_size = ACI_ECHO_DATA_MAX_LEN;
|
||||
}
|
||||
|
||||
memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size);
|
||||
acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size);
|
||||
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_bond_request()
|
||||
{
|
||||
acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)
|
||||
{
|
||||
bool status;
|
||||
status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);
|
||||
|
||||
/**
|
||||
Update the state of the ACI witn the
|
||||
ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error
|
||||
*/
|
||||
{
|
||||
aci_evt_t * aci_evt;
|
||||
|
||||
aci_evt = &p_aci_evt_data->evt;
|
||||
|
||||
switch(aci_evt->evt_opcode)
|
||||
{
|
||||
case ACI_EVT_PIPE_STATUS:
|
||||
{
|
||||
uint8_t i=0;
|
||||
|
||||
for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
||||
{
|
||||
aci_stat->pipes_open_bitmap[i] = aci_evt->params.pipe_status.pipes_open_bitmap[i];
|
||||
aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_EVT_DISCONNECTED:
|
||||
{
|
||||
uint8_t i=0;
|
||||
|
||||
for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
||||
{
|
||||
aci_stat->pipes_open_bitmap[i] = 0;
|
||||
aci_stat->pipes_closed_bitmap[i] = 0;
|
||||
}
|
||||
aci_stat->confirmation_pending = false;
|
||||
aci_stat->data_credit_available = aci_stat->data_credit_total;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ACI_EVT_TIMING:
|
||||
aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval;
|
||||
aci_stat->slave_latency = aci_evt->params.timing.conn_slave_rf_latency;
|
||||
aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe)
|
||||
{
|
||||
bool ret_val = false;
|
||||
{
|
||||
acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe);
|
||||
is_cmd_response_expected = false;
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code)
|
||||
{
|
||||
bool ret_val = false;
|
||||
|
||||
{
|
||||
is_cmd_response_expected = false;
|
||||
acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code);
|
||||
ret_val = hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval)
|
||||
{
|
||||
aci_cmd_params_broadcast_t aci_cmd_params_broadcast;
|
||||
if (timeout > 16383)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The adv_interval should be between 160 and 16384 (which translates to the advertisement
|
||||
// interval values 100 ms and 10.24 s.
|
||||
if ((160 > adv_interval) || (adv_interval > 16384))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
aci_cmd_params_broadcast.timeout = timeout;
|
||||
aci_cmd_params_broadcast.adv_interval = adv_interval;
|
||||
acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < PIPES_ARRAY_SIZE; i++)
|
||||
{
|
||||
aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i];
|
||||
}
|
||||
|
||||
acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
bool lib_aci_open_adv_pipe(const uint8_t pipe)
|
||||
{
|
||||
uint8_t byte_idx = pipe / 8;
|
||||
|
||||
aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8));
|
||||
acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_read_dynamic_data()
|
||||
{
|
||||
acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0]));
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
|
||||
bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length)
|
||||
{
|
||||
acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte)
|
||||
{
|
||||
aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd;
|
||||
aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte;
|
||||
aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte;
|
||||
acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd);
|
||||
return hal_aci_tl_send(&msg_to_send);
|
||||
}
|
||||
|
||||
void lib_aci_flush(void)
|
||||
{
|
||||
m_aci_q_flush();
|
||||
}
|
||||
|
||||
void lib_aci_debug_print(bool enable)
|
||||
{
|
||||
hal_aci_debug_print(enable);
|
||||
}
|
||||
|
||||
507
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/lib_aci.h
Executable file
507
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/lib_aci.h
Executable file
@@ -0,0 +1,507 @@
|
||||
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
* $LastChangedRevision$
|
||||
*/
|
||||
/* Attention!
|
||||
* To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile
|
||||
* qualification listings, this section of source code must not be modified.
|
||||
*/
|
||||
|
||||
#ifndef LIB_ACI_H__
|
||||
#define LIB_ACI_H__
|
||||
|
||||
/** @file
|
||||
* @brief ACI library
|
||||
*/
|
||||
|
||||
/** @addtogroup lib_aci
|
||||
@{
|
||||
@brief Library for the logical part of the Application Controller Interface (ACI)
|
||||
*/
|
||||
|
||||
|
||||
#include "hal_platform.h"
|
||||
#include "hal/hal_aci_tl.h"
|
||||
#include "aci.h"
|
||||
#include "aci_cmds.h"
|
||||
#include "aci_evts.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define EVT_CMD_RESPONSE_MIN_LENGTH 3
|
||||
|
||||
#define PIPES_ARRAY_SIZE ((ACI_DEVICE_MAX_PIPES + 7)/8)
|
||||
|
||||
/* Same size as a hal_aci_data_t */
|
||||
typedef struct hal_aci_evt_t{
|
||||
uint8_t debug_byte;
|
||||
aci_evt_t evt;
|
||||
} hal_aci_evt_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t location; /**< enum aci_pipe_store_t */
|
||||
aci_pipe_type_t pipe_type;
|
||||
} services_pipe_type_mapping_t;
|
||||
|
||||
typedef struct aci_setup_info_t
|
||||
{
|
||||
services_pipe_type_mapping_t *services_pipe_type_mapping;
|
||||
uint8_t number_of_pipes;
|
||||
hal_aci_data_t *setup_msgs;
|
||||
uint8_t num_setup_msgs;
|
||||
} aci_setup_info_t;
|
||||
|
||||
// aci_struct that will contain
|
||||
// total initial credits
|
||||
// current credit
|
||||
// current state of the aci (setup/standby/active/sleep)
|
||||
// open remote pipe pending
|
||||
// close remote pipe pending
|
||||
// Current pipe available bitmap
|
||||
// Current pipe closed bitmap
|
||||
// Current connection interval, slave latency and link supervision timeout
|
||||
// Current State of the the GATT client (Service Discovery status)
|
||||
// Relationship of bond to peer address
|
||||
typedef struct aci_state_t
|
||||
{
|
||||
aci_setup_info_t aci_setup_info; /* Data structures that are created from nRFgo Studio */
|
||||
uint8_t bonded; /* ( aci_bond_status_code_t ) Is the nRF8001 bonded to a peer device */
|
||||
uint8_t data_credit_total; /* Total data credit available for the specific version of the nRF8001, total equals available when a link is established */
|
||||
aci_device_operation_mode_t device_state; /* Operating mode of the nRF8001 */
|
||||
|
||||
/* Start : Variables that are valid only when in a connection */
|
||||
uint8_t data_credit_available; /* Available data credits at a specific point of time, ACI_EVT_DATA_CREDIT updates the available credits */
|
||||
|
||||
uint16_t connection_interval; /* Multiply by 1.25 to get the connection interval in milliseconds*/
|
||||
uint16_t slave_latency; /* Number of consecutive connection intervals that the nRF8001 is not required to transmit. Use this to save power */
|
||||
uint16_t supervision_timeout; /* Multiply by 10 to get the supervision timeout in milliseconds */
|
||||
|
||||
uint8_t pipes_open_bitmap[PIPES_ARRAY_SIZE]; /* Bitmap -> pipes are open and can be used for sending data over the air */
|
||||
uint8_t pipes_closed_bitmap[PIPES_ARRAY_SIZE]; /* Bitmap -> pipes are closed and cannot be used for sending data over the air */
|
||||
bool confirmation_pending; /* Attribute protocol Handle Value confirmation is pending for a Handle Value Indication
|
||||
(ACK is pending for a TX_ACK pipe) on local GATT Server*/
|
||||
/* End : Variables that are valid only when in a connection */
|
||||
|
||||
} aci_state_t;
|
||||
|
||||
|
||||
|
||||
#define DISCONNECT_REASON_CX_TIMEOUT 0x08
|
||||
#define DISCONNECT_REASON_CX_CLOSED_BY_PEER_DEVICE 0x13
|
||||
#define DISCONNECT_REASON_POWER_LOSS 0x14
|
||||
#define DISCONNECT_REASON_CX_CLOSED_BY_LOCAL_DEVICE 0x16
|
||||
#define DISCONNECT_REASON_ADVERTISER_TIMEOUT 0x50
|
||||
|
||||
|
||||
/** @name Functions for library management */
|
||||
//@{
|
||||
|
||||
/** @brief Function to enable printing of all ACI commands sent and ACI events received
|
||||
* @details This function shall be used to enable or disable the debug printing.
|
||||
Debug printing is disabled by default.
|
||||
*/
|
||||
void lib_aci_debug_print(bool enable);
|
||||
|
||||
/** @brief Initialization function.
|
||||
* @details This function shall be used to initialize/reset ACI Library and also Resets the nRF8001 by togging the reset pin of the nRF8001. This function will reset
|
||||
* all the variables locally used by ACI library to their respective default values.
|
||||
*/
|
||||
void lib_aci_init(aci_state_t *aci_stat);
|
||||
|
||||
|
||||
/** @brief Gets the number of currently available ACI credits.
|
||||
* @return Number of ACI credits.
|
||||
*/
|
||||
uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat);
|
||||
|
||||
/** @brief Gets the connection interval in milliseconds.
|
||||
* @return Connection interval in milliseconds.
|
||||
*/
|
||||
uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat);
|
||||
|
||||
/** @brief Gets the connection interval in multiple of 1.25 ms.
|
||||
* @return Connection interval in multiple of 1.25 ms.
|
||||
*/
|
||||
uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat);
|
||||
|
||||
/** @brief Gets the current slave latency.
|
||||
* @return Current slave latency.
|
||||
*/
|
||||
uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat);
|
||||
|
||||
/** @brief Checks if a given pipe is available.
|
||||
* @param pipe Pipe to check.
|
||||
* @return True if the pipe is available, otherwise false.
|
||||
*/
|
||||
bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe);
|
||||
|
||||
/** @brief Checks if a given pipe is closed.
|
||||
* @param pipe Pipe to check.
|
||||
* @return True if the pipe is closed, otherwise false.
|
||||
*/
|
||||
bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe);
|
||||
|
||||
/** @brief Checks if the discovery operation is finished.
|
||||
* @return True if the discovery is finished.
|
||||
*/
|
||||
bool lib_aci_is_discovery_finished(aci_state_t *aci_stat);
|
||||
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
/** @name ACI Commands available in all modes */
|
||||
//@{
|
||||
|
||||
/** @brief Sets the radio in sleep mode.
|
||||
* @details The function sends a @c sleep command to the radio.
|
||||
* If the radio is advertising or connected, it sends back an error, then use lib_aci_radio_reset
|
||||
* if advertising or disconnect if in a connection.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_sleep(void);
|
||||
|
||||
/** @brief Resets the radio.
|
||||
* @details The function sends a @c BasebandReset command to the radio.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_radio_reset(void);
|
||||
|
||||
/** @brief Radio starts directed advertising to bonded device.
|
||||
* @details The function sends a @c DirectedConnect command to the radio.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_direct_connect(void);
|
||||
|
||||
/** @brief Gets the radio's version.
|
||||
* @details This function sends a @c GetDeviceVersion command.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_device_version(void);
|
||||
|
||||
/** @brief Gets the device address.
|
||||
* @details This function sends a @c GetDeviceAddress command.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_get_address(void);
|
||||
|
||||
/** @brief Gets the temperature.
|
||||
* @details This function sends a @c GetTemperature command. lib_aci
|
||||
* calls the @ref lib_aci_transaction_finished_hook() function when the temperature is received.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_get_temperature(void);
|
||||
|
||||
/** @brief Gets the battery level.
|
||||
* @details This function sends a @c GetBatteryLevel command.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_get_battery_level(void);
|
||||
|
||||
//@}
|
||||
|
||||
/** @name ACI commands available in Sleep mode */
|
||||
//@{
|
||||
|
||||
/** @brief Wakes up the radio.
|
||||
* @details This function sends a @c Wakeup command to wake up the radio from
|
||||
* sleep mode. When woken up the radio sends a @c DeviceStartedEvent and
|
||||
* a @c CommandResponseEvent.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_wakeup(void);
|
||||
|
||||
//@}
|
||||
|
||||
/** @name ACI commands available in Active mode */
|
||||
//@{
|
||||
|
||||
/** @brief Sets the radio in test mode.
|
||||
* @details This function sends a @c Test command to the radio. There are two
|
||||
* Test modes available:
|
||||
* - UART: DTM commands are received over UART.
|
||||
* - ACI: DTM commands are received over ACI.
|
||||
* The same command is used to exit the test mode When receiving
|
||||
* a @c DeviceStartedEvent the radio has entered the new mode.
|
||||
* @param enter_exit_test_mode Enter a Test mode, or exit Test mode.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode);
|
||||
|
||||
/** @brief Sets the radio's TX power.
|
||||
* @details This function sends a @c SetTxPower command.
|
||||
* @param tx_power TX power to be used by the radio.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_set_tx_power(aci_device_output_power_t tx_power);
|
||||
|
||||
/** @brief Tries to connect to a peer device.
|
||||
* @details This function sends a @c Connect command to the radio.
|
||||
* @param run_timeout Maximum advertising time in seconds (0 means infinite).
|
||||
* @param adv_interval Advertising interval (in multiple of 0.625 ms).
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval);
|
||||
|
||||
/** @brief Tries to bond with a peer device.
|
||||
* @details This function sends a @c Bond command to the radio.
|
||||
* @param run_timeout Maximum advertising time in seconds (0 means infinite).
|
||||
* @param adv_interval Advertising interval (in multiple of 0.625 ms).
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval);
|
||||
|
||||
/** @brief Disconnects from peer device.
|
||||
* @details This function sends a @c Disconnect command to the radio.
|
||||
* @param reason Reason for disconnecting.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason);
|
||||
|
||||
/**@brief Sets Local Data.
|
||||
* @details
|
||||
* This command updates the value of the characteristic value or the characteristic descriptor stored locally on the device.
|
||||
* Can be called for all types of pipes as long as the data is stored locally.
|
||||
* @param ACI state structure
|
||||
* @param pipe Pipe number on which the data should be set.
|
||||
* @param value Pointer to the data to set.
|
||||
* @param size Size of the data to set.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *value, uint8_t size);
|
||||
|
||||
/** @brief Sends Broadcast message to the radio.
|
||||
* @details The Broadcast message starts advertisement procedure
|
||||
* using the given interval with the intention of broadcasting data to a peer device.
|
||||
* @param timeout Time, in seconds, to advertise before exiting to standby mode (0 means infinite).
|
||||
* Valid values: 0 to 16383.
|
||||
* @param adv_interval Advertising interval (in multiple of 0.625 ms).
|
||||
* Valid values: 160 to 16384 (which corresponds to an interval from 100 ms to 10.24 s).
|
||||
* @return True if the broadcast message is sent successfully to the radio.
|
||||
*/
|
||||
bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval);
|
||||
|
||||
/** @name Open Advertising Pipes. */
|
||||
|
||||
/** @brief Sends a command to the radio to set the input pipe to be placed in Advertisement Service Data.
|
||||
* @details This function sends a command to the radio that places the pipe in
|
||||
* advertisement service data. To start advertising service data, call this function before
|
||||
* Connecting, Broadcasting or Bonding to peer. The data that should be sent in the advertisement packets
|
||||
* must be set using the @c lib_aci_set_local_data function. This function can be called during
|
||||
* advertising to enable/disable broadcast pipes.
|
||||
* @param pipe The pipe that has to be placed in advertising service data.
|
||||
* @return True if the Open Adv Pipe message is sent successfully to the radio.
|
||||
*/
|
||||
bool lib_aci_open_adv_pipe(const uint8_t pipe);
|
||||
|
||||
|
||||
/** @name Open Advertising Pipes */
|
||||
|
||||
/** @brief Sends a command to the radio to set the pipes to be placed in Advertisement Service Data.
|
||||
* @details This function will send a command to the radio that will set the pipes to be placed in
|
||||
* advertisement Service Data. To start advertising service data, this function should be called before
|
||||
* Connecting, Broadcasting or Bonding to peer. This function can be called during
|
||||
* advertising to enable/disable broadcast pipes. Use this as an alternative to @ref lib_aci_open_adv_pipe
|
||||
* to avoid multiple function calls for placing multiple pipes in the adv data.
|
||||
* @param adv_service_data_pipes Pipe bitmap, where '1' indicates that the corresponding
|
||||
* Valid Values: 0000000000000000 to FEFFFFFFFFFFFF7F (See the ACI Pipe Status Evt bitmap in the nRF8001 datasheet
|
||||
* TX_BROADCAST pipe data is to be placed in Advertising Service Data fields
|
||||
* @return true if the Open Adv Pipe message was sent successfully to the radio.
|
||||
*/
|
||||
bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes);
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
/** @name ACI commands available in Connected mode */
|
||||
//@{
|
||||
|
||||
|
||||
/** @brief Sets a given application latency.
|
||||
* @details This function sends a @c setApplicationLatency command.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode);
|
||||
|
||||
/** @brief Opens a remote pipe.
|
||||
* @details This function sends an @c OpenRemotePipe command.
|
||||
* @param pipe Number of the pipe to open.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
|
||||
|
||||
/** @brief Closes a remote pipe.
|
||||
* @details This function sends an @c CloseRemotePipe command.
|
||||
* @param pipe Pipe number to close.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
|
||||
|
||||
/** @brief Sends data on a given pipe.
|
||||
* @details This function sends a @c SendData command with application data to
|
||||
* the radio. This function memorizes credit use, and checks that
|
||||
* enough credits are available.
|
||||
* @param pipe Pipe number on which the data should be sent.
|
||||
* @param value Pointer to the data to send.
|
||||
* @param size Size of the data to send.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_send_data(uint8_t pipe, uint8_t *value, uint8_t size);
|
||||
|
||||
/** @brief Requests data from a given pipe.
|
||||
* @details This function sends a @c RequestData command to the radio. This
|
||||
* function memorizes credit uses, and check that enough credits are available.
|
||||
* After this command, the radio sends back either a @c DataReceivedEvent
|
||||
* or a @c PipeErrorEvent.
|
||||
* @param pipe Pipe number on which the data is requested.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe);
|
||||
|
||||
/** @brief Sends a L2CAP change connection parameters request.
|
||||
* @details This function sends a @c ChangeTiming command to the radio. This command triggers a "L2CAP change connection parameters" request
|
||||
* to the master. If the master rejects or accepts but doesn't change the connection parameters within
|
||||
* 30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
|
||||
* If the request is accepted and the master changes connection parameters, a timing event with
|
||||
* the new connection parameters is sent by the radio.
|
||||
* If the master doesn't reply to the request within 60 seconds, the radio disconnects.
|
||||
* @param minimun_cx_interval Minimum connection interval requested, in multiple of 1.25 ms.
|
||||
* @param maximum_cx_interval Maximum connection interval requested, in multiple of 1.25 ms.
|
||||
* @param slave_latency requested slave latency.
|
||||
* @param timeout requested slave timeout, in multiple of 10 ms.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout);
|
||||
|
||||
/** @brief Sends a L2CAP change connection parameters request with the connection predefined preffered connection parameters.
|
||||
* @details This function sends a @c ChangeTiming command to the radio. This command triggers a "L2CAP change connection parameters" request
|
||||
* to the master. If the master rejects or accepts but doesn't change the connection parameters within
|
||||
* 30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
|
||||
* If the request is accepted and the master changes connection parameters, a timing event with
|
||||
* the new connection parameters is sent by the radio.
|
||||
* If the master doesn't reply to the request within 60 seconds, the radio disconnects.
|
||||
* The timing parameters used are the Timing parameters in the GAP settings in the nRFgo Studio.
|
||||
* The Timing parameters as stored as the GAP Preferred Peripheral Connection Parameters.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_change_timing_GAP_PPCP(void);
|
||||
|
||||
/** @brief Sends acknowledgement message to peer.
|
||||
* @details This function sends @c SendDataAck command to radio. The radio is expected
|
||||
* to send either Handle Value Confirmation or Write response depending
|
||||
* on whether the data is stored remotely or locally.
|
||||
* @param pipe Pipe number for which the acknowledgement is to be sent.
|
||||
* @return True if the ack was sent successfully. False otherwise.
|
||||
*/
|
||||
bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe);
|
||||
|
||||
/** @brief Sends negative acknowledgement message to peer.
|
||||
* @details This function sends @c SendDataNack command to radio. The radio is expected
|
||||
* to send Error Response to the peer.
|
||||
* @param pipe Pipe number for which the nack is to be sent.
|
||||
* @param error_code Error code to be sent in the NACk.
|
||||
* @return True if the nack was sent successfully. False otherwise.
|
||||
*/
|
||||
bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code);
|
||||
|
||||
/** @brief Sends ReadDynamicData command to the host.
|
||||
* @details This function sends @c ReadDynamicData command to host. The host is expected
|
||||
* to send @c CommandResponse back with the dynamic data. The application is expected to
|
||||
* call this function in a loop until all the dynamic data is read out from the host.
|
||||
* As long as there is dynamic data to be read from the host, the command response
|
||||
* for this message has its status field set to ACI_STATUS_TRANSACTION_CONTINUE (0x01).
|
||||
* The application may chose to store this read out data in a non-volatile memory location
|
||||
* and later chose to write it back using the function lib_aci_write_dynamic_data.
|
||||
* @return True if the command was sent successfully through the ACI. False otherwise.
|
||||
*/
|
||||
bool lib_aci_read_dynamic_data(void);
|
||||
|
||||
/** @brief Sends WriteDynamicData command to the host.
|
||||
* @details This function sends @c WriteDynamicData command to host. The host is expected
|
||||
* to send @c CommandResponse with the status of this operation. As long as the status field
|
||||
* in the @c CommandResponse is ACI_STATUS_TRANSACTION_CONTINUE (0x01), the hosts expects
|
||||
* more dynamic data to be written. This function should ideally be called in a cycle,
|
||||
* until all the stored dynamic data is sent to the host. This function should be
|
||||
* called with the dynamic data obtained from the response to a @c ReadDynamicData
|
||||
* (see @c lib_aci_read_dynamic_data) command.
|
||||
* @param sequence_number Sequence number of the dynamic data to be sent.
|
||||
* @param dynamic_data Pointer to the dynamic data.
|
||||
* @param length Length of the dynamic data.
|
||||
* @return True if the command was sent successfully through the ACI. False otherwise.
|
||||
*/
|
||||
bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length);
|
||||
//@}
|
||||
|
||||
/** @name ACI commands available while connected in Bond mode */
|
||||
//@{
|
||||
|
||||
/** @brief Sends a SMP Security Request.
|
||||
* @details This function send a @c BondRequest command to the radio.
|
||||
* This command triggers a SMP Security Request to the master. If the
|
||||
* master rejects with a pairing failed or if the bond timer expires the connection is closed.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_bond_request(void);
|
||||
|
||||
/** @brief Set the key requested by the 8001.
|
||||
* @details This function sends an @c SetKey command to the radio.
|
||||
* @param key_rsp_type Type of key.
|
||||
* @param key Pointer to the key to set.
|
||||
* @param len Length of the key.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len);
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/** @name ACI commands available in Test mode */
|
||||
//@{
|
||||
|
||||
/** @brief Sends an echo message
|
||||
* @details This function sends an @c Echo command to the radio. lib_aci
|
||||
* places the Echp ACI command in the ACI command queue
|
||||
* @param message_size Length of the data to send.
|
||||
* @param message_data Pointer to the data to send.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_echo_msg(uint8_t message_size, uint8_t *message_data);
|
||||
|
||||
/** @brief Sends an DTM command
|
||||
* @details This function sends an @c DTM command to the radio.
|
||||
* @param dtm_command_msbyte Most significant byte of the DTM command.
|
||||
* @param dtm_command_lsbyte Least significant byte of the DTM command.
|
||||
* @return True if the transaction is successfully initiated.
|
||||
*/
|
||||
bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte);
|
||||
|
||||
/** @brief Gets an ACI event from the ACI Event Queue
|
||||
* @details This function gets an ACI event from the ACI event queue.
|
||||
* The queue is updated by the SPI driver for the ACI running in the interrupt context
|
||||
* @param aci_stat pointer to the state of the ACI.
|
||||
* @param p_aci_data pointer to the ACI Event. The ACI Event received will be copied into this pointer.
|
||||
* @return True if an ACI Event was copied to the pointer.
|
||||
*/
|
||||
bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t * aci_evt);
|
||||
|
||||
/** @brief Flushes the events in the ACI command queues and ACI Event queue
|
||||
*
|
||||
*/
|
||||
void lib_aci_flush(void);
|
||||
|
||||
//@}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* LIB_ACI_H__ */
|
||||
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE AttributeServer>
|
||||
<Profile Version="1.3">
|
||||
<SetupId>0</SetupId>
|
||||
<Device>nRF8001_Dx</Device>
|
||||
<Service Type="local" PrimaryService="true">
|
||||
<Name>UART over BTLE</Name>
|
||||
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0001</Uuid>
|
||||
<Characteristic>
|
||||
<Name>UART RX</Name>
|
||||
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0002</Uuid>
|
||||
<DefaultValue></DefaultValue>
|
||||
<UsePresentationFormat>0</UsePresentationFormat>
|
||||
<UserDescription></UserDescription>
|
||||
<MaxDataLength>20</MaxDataLength>
|
||||
<AttributeLenType>2</AttributeLenType>
|
||||
<ForceOpen>false</ForceOpen>
|
||||
<Properties>
|
||||
<WriteWithoutResponse>true</WriteWithoutResponse>
|
||||
<Write>false</Write>
|
||||
<Notify>false</Notify>
|
||||
<Indicate>false</Indicate>
|
||||
<Broadcast>false</Broadcast>
|
||||
</Properties>
|
||||
<SetPipe>false</SetPipe>
|
||||
<AckIsAuto>false</AckIsAuto>
|
||||
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
|
||||
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
|
||||
<PeriodForProperties/>
|
||||
</Characteristic>
|
||||
<Characteristic>
|
||||
<Name>UART TX</Name>
|
||||
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0003</Uuid>
|
||||
<DefaultValue></DefaultValue>
|
||||
<UsePresentationFormat>0</UsePresentationFormat>
|
||||
<UserDescription></UserDescription>
|
||||
<MaxDataLength>20</MaxDataLength>
|
||||
<AttributeLenType>2</AttributeLenType>
|
||||
<ForceOpen>false</ForceOpen>
|
||||
<Properties>
|
||||
<WriteWithoutResponse>false</WriteWithoutResponse>
|
||||
<Write>false</Write>
|
||||
<Notify>true</Notify>
|
||||
<Indicate>false</Indicate>
|
||||
<Broadcast>false</Broadcast>
|
||||
</Properties>
|
||||
<SetPipe>false</SetPipe>
|
||||
<AckIsAuto>false</AckIsAuto>
|
||||
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
|
||||
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
|
||||
<PeriodForProperties/>
|
||||
</Characteristic>
|
||||
</Service>
|
||||
<Service Type="local" PrimaryService="true">
|
||||
<Name>Device Information</Name>
|
||||
<Uuid>180a</Uuid>
|
||||
<Characteristic>
|
||||
<Name>Hardware Revision String</Name>
|
||||
<Uuid>2a27</Uuid>
|
||||
<DefaultValue>0A</DefaultValue>
|
||||
<UsePresentationFormat>0</UsePresentationFormat>
|
||||
<UserDescription></UserDescription>
|
||||
<MaxDataLength>9</MaxDataLength>
|
||||
<AttributeLenType>2</AttributeLenType>
|
||||
<ForceOpen>false</ForceOpen>
|
||||
<Properties>
|
||||
<WriteWithoutResponse>false</WriteWithoutResponse>
|
||||
<Write>false</Write>
|
||||
<Notify>false</Notify>
|
||||
<Indicate>false</Indicate>
|
||||
<Broadcast>false</Broadcast>
|
||||
</Properties>
|
||||
<SetPipe>true</SetPipe>
|
||||
<AckIsAuto>false</AckIsAuto>
|
||||
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="25" NameSpace="01" Unit="0000"/>
|
||||
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
|
||||
<PeriodForProperties/>
|
||||
</Characteristic>
|
||||
</Service>
|
||||
<Gapsettings>
|
||||
<Name>UART</Name>
|
||||
<DeviceNameWriteLength>7</DeviceNameWriteLength>
|
||||
<LocalPipeOnDeviceName>true</LocalPipeOnDeviceName>
|
||||
<DeviceNameShortLength>0</DeviceNameShortLength>
|
||||
<Apperance>0000</Apperance>
|
||||
<SecurityLevel>0</SecurityLevel>
|
||||
<AuthenticationReq>0</AuthenticationReq>
|
||||
<IoCapabilities>0</IoCapabilities>
|
||||
<BondTimeout>600</BondTimeout>
|
||||
<SecurityRequestDelay>0</SecurityRequestDelay>
|
||||
<MinimumKeySize>7</MinimumKeySize>
|
||||
<MaximumKeySize>16</MaximumKeySize>
|
||||
<AdvertisingDataBondedBitmap>1a</AdvertisingDataBondedBitmap>
|
||||
<AdvertisingDataGeneralBitmap>1a</AdvertisingDataGeneralBitmap>
|
||||
<AdvertisingDataBrodcastBitmap>10</AdvertisingDataBrodcastBitmap>
|
||||
<AdvertisingDataBondedScanResponseBitmap>0</AdvertisingDataBondedScanResponseBitmap>
|
||||
<AdvertisingDataGeneralScanResponseBitmap>0</AdvertisingDataGeneralScanResponseBitmap>
|
||||
<AdvertisingDataBrodcastScanResponseBitmap>0</AdvertisingDataBrodcastScanResponseBitmap>
|
||||
<AdvertisingDataBondedBitmapCustom>0</AdvertisingDataBondedBitmapCustom>
|
||||
<AdvertisingDataGeneralBitmapCustom>0</AdvertisingDataGeneralBitmapCustom>
|
||||
<AdvertisingDataBrodcastBitmapCustom>0</AdvertisingDataBrodcastBitmapCustom>
|
||||
<AdvertisingDataBondedScanResponseBitmapCustom>0</AdvertisingDataBondedScanResponseBitmapCustom>
|
||||
<AdvertisingDataGeneralScanResponseBitmapCustom>0</AdvertisingDataGeneralScanResponseBitmapCustom>
|
||||
<AdvertisingDataBrodcastScanResponseBitmapCustom>0</AdvertisingDataBrodcastScanResponseBitmapCustom>
|
||||
<TxPowerLevelOffset>0</TxPowerLevelOffset>
|
||||
<MinimumConnectionInterval>6</MinimumConnectionInterval>
|
||||
<MaximumConnectionInterval>18</MaximumConnectionInterval>
|
||||
<SlaveLatency>0</SlaveLatency>
|
||||
<TimeoutMultipler>10</TimeoutMultipler>
|
||||
<ServiceToAdvertise>
|
||||
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0001</Uuid>
|
||||
</ServiceToAdvertise>
|
||||
<CustomAdTypes>
|
||||
<AdType index="1">
|
||||
<Type>19</Type>
|
||||
<Value>0000</Value>
|
||||
</AdType>
|
||||
<AdType index="2">
|
||||
<Type>18</Type>
|
||||
<Value></Value>
|
||||
</AdType>
|
||||
</CustomAdTypes>
|
||||
</Gapsettings>
|
||||
<Hardwaresettings>
|
||||
<Clocksource>1</Clocksource>
|
||||
<ClockAccuracy>1</ClockAccuracy>
|
||||
<InitialTxPower>3</InitialTxPower>
|
||||
<HfClkSource>0</HfClkSource>
|
||||
<DcDcConverter>0</DcDcConverter>
|
||||
<ActiveSignalModeIndex>0</ActiveSignalModeIndex>
|
||||
<ActiveSignalToTickDistance>0</ActiveSignalToTickDistance>
|
||||
<DynamicWindowLimitingEnabled>false</DynamicWindowLimitingEnabled>
|
||||
</Hardwaresettings>
|
||||
<CurrentInput>
|
||||
<BatteryCharge>220</BatteryCharge>
|
||||
<Master32KhzClockAccuracy>10</Master32KhzClockAccuracy>
|
||||
<ConnectionInterval>1000</ConnectionInterval>
|
||||
<PercentOfTimeSleeping>10</PercentOfTimeSleeping>
|
||||
<PercentOfTimeAdvertising>10</PercentOfTimeAdvertising>
|
||||
<AdvertisingInterval>1280</AdvertisingInterval>
|
||||
</CurrentInput>
|
||||
</Profile>
|
||||
164
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/uart/services.h
Executable file
164
Projects/libraries/Installed_libs/Adafruit_BLE_UART/utility/uart/services.h
Executable file
@@ -0,0 +1,164 @@
|
||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file is autogenerated by nRFgo Studio 1.14.1.2369
|
||||
*/
|
||||
|
||||
#ifndef SETUP_MESSAGES_H__
|
||||
#define SETUP_MESSAGES_H__
|
||||
|
||||
#include "hal_platform.h"
|
||||
#include "aci.h"
|
||||
#define PIPE_GAP_DEVICE_NAME_SET 1
|
||||
#define PIPE_UART_OVER_BTLE_UART_RX_RX 2
|
||||
#define PIPE_UART_OVER_BTLE_UART_TX_TX 3
|
||||
#define PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET 4
|
||||
|
||||
#define NUMBER_OF_PIPES 4
|
||||
|
||||
#define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
|
||||
{ACI_STORE_LOCAL, ACI_SET}, \
|
||||
{ACI_STORE_LOCAL, ACI_RX}, \
|
||||
{ACI_STORE_LOCAL, ACI_TX}, \
|
||||
{ACI_STORE_LOCAL, ACI_SET}, \
|
||||
}
|
||||
|
||||
#define GAP_PPCP_MAX_CONN_INT 0x12 /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
|
||||
#define GAP_PPCP_MIN_CONN_INT 0x6 /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific maximum*/
|
||||
#define GAP_PPCP_SLAVE_LATENCY 0
|
||||
#define GAP_PPCP_CONN_TIMEOUT 0xa /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
|
||||
|
||||
#define NB_SETUP_MESSAGES 21
|
||||
#define SETUP_MESSAGES_CONTENT {\
|
||||
{0x00,\
|
||||
{\
|
||||
0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xd7,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x01,0x01,0x00,0x00,0x06,0x00,0x00,\
|
||||
0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x10,0x1c,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x14,0x03,0x90,0x01,0x64,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x10,0x38,0x02,0xff,0x02,0x58,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x05,0x06,0x10,0x54,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
|
||||
0x02,0x28,0x03,0x01,0x0e,0x03,0x00,0x00,0x2a,0x04,0x14,0x07,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x1c,0x04,0x00,0x03,0x2a,0x00,0x01,0x55,0x41,0x52,0x54,0x69,0x63,0x73,0x04,0x04,0x05,\
|
||||
0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x38,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,0x06,\
|
||||
0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x54,0x00,0x07,0x2a,0x04,0x01,0x06,0x00,0x12,0x00,0x00,0x00,0x0a,0x00,0x04,0x04,0x02,\
|
||||
0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x70,0x00,0x09,0x28,0x00,0x01,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,\
|
||||
0xb5,0x01,0x00,0x40,0x6e,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0x8c,0x03,0x01,0x04,0x0b,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,\
|
||||
0xb5,0x02,0x00,0x40,0x6e,0x44,0x10,0x14,0x00,0x00,0x0b,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0xa8,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x13,0x13,0x00,0x0c,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0xc4,0x28,0x03,0x01,0x10,0x0d,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,\
|
||||
0xa3,0xb5,0x03,0x00,0x40,0x6e,0x14,0x00,0x14,0x00,0x00,0x0d,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0xe0,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x20,0xfc,0x0e,0x29,0x02,0x01,0x00,0x00,0x04,0x04,0x02,0x02,0x00,0x0f,0x28,0x00,0x01,0x0a,\
|
||||
0x18,0x04,0x04,0x05,0x05,0x00,0x10,0x28,0x03,0x01,0x02,0x11,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x19,0x06,0x21,0x18,0x00,0x27,0x2a,0x04,0x04,0x09,0x01,0x00,0x11,0x2a,0x27,0x01,0x0a,0x00,0x00,0x00,\
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x00,0x02,0x02,0x00,0x08,0x04,\
|
||||
0x00,0x0b,0x00,0x00,0x00,0x03,0x02,0x00,0x02,0x04,0x00,0x0d,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x0f,0x06,0x40,0x1c,0x00,0x0e,0x2a,0x27,0x01,0x00,0x80,0x04,0x00,0x11,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x13,0x06,0x50,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,0xb5,0x00,0x00,0x40,0x6e,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x0f,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
|
||||
},\
|
||||
},\
|
||||
{0x00,\
|
||||
{\
|
||||
0x06,0x06,0xf0,0x00,0x03,0xd3,0x88,\
|
||||
},\
|
||||
},\
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,117 @@
|
||||
------------------------------------------------------------------------------
|
||||
uBlue Setup generation report
|
||||
Generated with uBlue setup DLL version: 1.0.0.16855
|
||||
Generated: Sat Jan 12 11:40:44 2013 (UTC)
|
||||
This file is automatically generated, do not modify
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
[Counts]
|
||||
|
||||
Setup data size = 547 bytes
|
||||
Local database size = 302 bytes
|
||||
Local attribute count = 4
|
||||
Remote attribute count = 0
|
||||
Total pipe count = 4
|
||||
Dynamic data size = 181 bytes (worst case)
|
||||
|
||||
[Setup Area Layout]
|
||||
|
||||
Setup area, total = 1595 bytes
|
||||
Setup area, used = 370 bytes ( 23% of total )
|
||||
Local services = 302 bytes ( 81% of used )
|
||||
Remote services = 0 bytes ( 0% of used )
|
||||
Pipes = 40 bytes ( 10% of used )
|
||||
VS UUID area = 16 bytes ( 4% of used )
|
||||
Extended Attr area = 12 bytes ( 3% of used )
|
||||
|
||||
[Device Settings]
|
||||
|
||||
Setup ID = 0x00000000
|
||||
Setup Format = 0x03
|
||||
Security = OPEN (0)
|
||||
Bond Timeout = 600
|
||||
Security Request Delay = 0
|
||||
Change Timing Delay = 5
|
||||
Whitelist = Enabled
|
||||
|
||||
[Advertisement Data]
|
||||
|
||||
Bond Advertise = 0x00000014 [SERVICES_128_COMPLETE | LOCAL_NAME_COMPLETE]
|
||||
Bond Scan Resp = 0x00000000 []
|
||||
General Advertise = 0x00000014 [SERVICES_128_COMPLETE | LOCAL_NAME_COMPLETE]
|
||||
General Scan Resp = 0x00000000 []
|
||||
Broadcast Advertise = 0x00000010 [LOCAL_NAME_COMPLETE]
|
||||
Broadcast Scan Resp = 0x00000000 []
|
||||
|
||||
Custom Bond Advertise = 0x00 []
|
||||
Custom Bond Scan Resp = 0x00 []
|
||||
Custom General Advertise = 0x00 []
|
||||
Custom General Scan Resp = 0x00 []
|
||||
Custom Broadcast Advertise = 0x00 []
|
||||
Custom Broadcast Scan Resp = 0x00 []
|
||||
|
||||
No custom AD types
|
||||
|
||||
[Vendor Specific UUIDs]
|
||||
|
||||
VS UUID #0 (type=0x02): 0x9E 0xCA 0xDC 0x24 0x0E 0xE5 0xA9 0xE0 0x93 0xF3 0xA3 0xB5 0x00 0x00 0x40 0x6E
|
||||
|
||||
[Local Database]
|
||||
|
||||
Handle Pipes Structure
|
||||
------ ----- ---------
|
||||
0x0001 +----- Service (Primary): "GAP" (01:0x1800)
|
||||
0x0002 |----- |Characteristic: "Device Name" (01:0x2A00) [rd|wwr|wr] [rd:allow|wr:none]
|
||||
0x0003 x |Value: {0x55 0x41 0x52 0x54} [rd:allow|wr:allow]
|
||||
0x0004 |----- |Characteristic: "Appearance" (01:0x2A01) [rd] [rd:allow|wr:none]
|
||||
0x0005 |Value: {0x00 0x00} [rd:allow|wr:none]
|
||||
0x0006 |----- |Characteristic: "PPCP" (01:0x2A04) [rd] [rd:allow|wr:none]
|
||||
0x0007 |Value: {0x06 0x00 0x12 0x00 0x00 0x00 0x0A 0x00} [rd:allow|wr:none]
|
||||
0x0008 +----- Service (Primary): "GATT" (01:0x1801)
|
||||
0x0009 +----- Service (Primary): "?" (02:0x0001)
|
||||
0x000A |----- |Characteristic: "?" (02:0x0002) [wwr] [rd:allow|wr:none]
|
||||
0x000B < |Value: {} [rd:none|wr:allow]
|
||||
0x000C |----- |Characteristic: "?" (02:0x0003) [not] [rd:allow|wr:none]
|
||||
0x000D > |Value: {} [rd:none|wr:none]
|
||||
0x000E |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow]
|
||||
0x000F +----- Service (Primary): "Device Info" (01:0x180A)
|
||||
0x0010 |----- |Characteristic: "HW Rev" (01:0x2A27) [rd] [rd:allow|wr:none]
|
||||
0x0011 x |Value: {0x0A} [rd:allow|wr:none]
|
||||
|
||||
[Remote Database]
|
||||
|
||||
Handle Pipes Structure
|
||||
------ ----- ---------
|
||||
|
||||
[Pipe Map]
|
||||
|
||||
Pipe Store Type Service Char. CPF Desc.
|
||||
---- ------ ------ ---------- --------- ----------- ---------
|
||||
01 Local SET 01:0x1800 01:0x2A00 -- --
|
||||
02 Local RX 02:0x0001 02:0x0002 -- --
|
||||
03 Local TX 02:0x0001 02:0x0003 -- --
|
||||
04 Local SET 01:0x180A 01:0x2A27 -- --
|
||||
|
||||
[Setup Data]
|
||||
|
||||
07-06-00-00-03-02-41-D7
|
||||
1F-06-10-00-00-00-00-00-00-00-04-00-04-01-01-00-00-06-00-00-90-00-00-00-00-00-00-00-00-00-00-00
|
||||
1F-06-10-1C-01-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-14-00-00-00-14-03-90-01-64
|
||||
1F-06-10-38-02-FF-02-58-00-05-00-00-00-00-00-00-00-00-00-00-00-10-00-00-00-00-00-00-00-00-00-00
|
||||
05-06-10-54-00-00
|
||||
1F-06-20-00-04-04-02-02-00-01-28-00-01-00-18-04-04-05-05-00-02-28-03-01-0E-03-00-00-2A-04-14-07
|
||||
1F-06-20-1C-04-00-03-2A-00-01-55-41-52-54-69-63-73-04-04-05-05-00-04-28-03-01-02-05-00-01-2A-06
|
||||
1F-06-20-38-04-03-02-00-05-2A-01-01-00-00-04-04-05-05-00-06-28-03-01-02-07-00-04-2A-06-04-09-08
|
||||
1F-06-20-54-00-07-2A-04-01-06-00-12-00-00-00-0A-00-04-04-02-02-00-08-28-00-01-01-18-04-04-10-10
|
||||
1F-06-20-70-00-09-28-00-01-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-01-00-40-6E-04-04-13-13-00-0A-28
|
||||
1F-06-20-8C-03-01-04-0B-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-02-00-40-6E-44-10-14-00-00-0B-00
|
||||
1F-06-20-A8-02-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-04-04-13-13-00-0C
|
||||
1F-06-20-C4-28-03-01-10-0D-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-03-00-40-6E-14-00-14-00-00-0D
|
||||
1F-06-20-E0-00-03-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-46-14-03-02-00
|
||||
1F-06-20-FC-0E-29-02-01-00-00-04-04-02-02-00-0F-28-00-01-0A-18-04-04-05-05-00-10-28-03-01-02-11
|
||||
19-06-21-18-00-27-2A-04-04-09-01-00-11-2A-27-01-0A-00-00-00-00-00-00-00-00-00
|
||||
1F-06-40-00-2A-00-01-00-80-04-00-03-00-00-00-02-02-00-08-04-00-0B-00-00-00-03-02-00-02-04-00-0D
|
||||
0F-06-40-1C-00-0E-2A-27-01-00-80-04-00-11-00-00
|
||||
13-06-50-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-00-00-40-6E
|
||||
0F-06-60-00-00-00-00-00-00-00-00-00-00-00-00-00
|
||||
06-06-F0-00-83-42-00
|
||||
7
Projects/libraries/Installed_libs/Ethernet/README-ETHERNET.txt
Executable file
7
Projects/libraries/Installed_libs/Ethernet/README-ETHERNET.txt
Executable file
@@ -0,0 +1,7 @@
|
||||
These files augment the Ethernet library as distributed with Arduino0012, which in turn appears to include
|
||||
application sample code from WIZnet. Eventually, we'll have to modify the underlying socket code of that library to fix buffer overflow risks and to better conserve precious Arduino RAM.
|
||||
|
||||
For more information, look at:
|
||||
http://code.rancidbacon.com/LearningAboutArduinoWIZ810MJ
|
||||
http://trac.mlalonde.net/cral/browser/branches/follower/wiz810mj
|
||||
12/31/08
|
||||
156
Projects/libraries/Installed_libs/Ethernet/UdpBytewise.cpp
Executable file
156
Projects/libraries/Installed_libs/Ethernet/UdpBytewise.cpp
Executable file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* UdpBytewise.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* Drop UdpBytewise.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||||
* TODO: should protect buffer access with critical sections
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "types.h"
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
}
|
||||
|
||||
#include "Ethernet.h"
|
||||
#include "UdpBytewise.h"
|
||||
|
||||
/* Start UDP socket, listening at local port PORT */
|
||||
void UdpBytewiseClass::begin(uint16_t port) {
|
||||
_port = port;
|
||||
_sock = 0; //TODO: should not be hardcoded
|
||||
_txIndex =0;
|
||||
_rxIndex =0;
|
||||
_rxSize = 0;
|
||||
_txOverflowStrategy = UDP_TX_OVERFLOW_SPLIT;
|
||||
socket(_sock,Sn_MR_UDP,_port,0);
|
||||
}
|
||||
|
||||
|
||||
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes. */
|
||||
int UdpBytewiseClass::available() {
|
||||
if(_rxSize==0 || _rxSize-_rxIndex==0) {
|
||||
//if local buffer is empty or depleted
|
||||
//check wiz5100 buffer for new packet
|
||||
_rxSize = getSn_RX_RSR(_sock); //note: return value is inflated by 8 byte header
|
||||
if(_rxSize){
|
||||
//if we have a new packet there
|
||||
//reset buffer index
|
||||
_rxIndex=0;
|
||||
//copy packet into our local buffer
|
||||
_rxSize = recvfrom(_sock,_rxBuffer,_rxSize-8,_rxIp,&_rxPort);
|
||||
} else {
|
||||
//else do nothing and rxsize is still 0
|
||||
;
|
||||
}
|
||||
return _rxSize; //return the new number of bytes in our buffer
|
||||
} else{
|
||||
//if buffer is not empty, return remaining # of bytes
|
||||
return (_rxSize-_rxIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Start a new packet with given target ip and port
|
||||
* returns 1 on success, 0 if we already started a packet */
|
||||
int UdpBytewiseClass::beginPacket(uint8_t *ip, unsigned int port) {
|
||||
if(_txIndex==0) {
|
||||
//ok to start new packet - copy ip and port
|
||||
_txIp[0]=ip[0];
|
||||
_txIp[1]=ip[1];
|
||||
_txIp[2]=ip[2];
|
||||
_txIp[3]=ip[3];
|
||||
_txPort = port;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
//we already started a packet and have data in it
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a byte to the currently assembled packet if there is space
|
||||
* if there isn't space, either truncate (ignore) or split the packet.
|
||||
*/
|
||||
void UdpBytewiseClass::write(uint8_t b) {
|
||||
if(_txIndex>= UDP_TX_PACKET_MAX_SIZE) {
|
||||
//buffer is full - we can either truncate the packet or split in two
|
||||
switch (_txOverflowStrategy) {
|
||||
case UDP_TX_OVERFLOW_SPLIT:
|
||||
endPacket();
|
||||
beginPacket(_txIp,_txPort);
|
||||
//fall through to normal add of byte to buffer below
|
||||
break;
|
||||
case UDP_TX_OVERFLOW_TRUNCATE:
|
||||
default:
|
||||
//don't add - just ignore bytes past buffer size
|
||||
return;
|
||||
}
|
||||
}
|
||||
_txBuffer[_txIndex++] = b;
|
||||
}
|
||||
|
||||
/* send an assembled packet out
|
||||
* returns # of bytes sent on success, 0 if there's nothing to send */
|
||||
int UdpBytewiseClass::endPacket() {
|
||||
// send the packet
|
||||
uint16_t result = sendto(_sock,(const uint8_t *)_txBuffer,_txIndex,_txIp,_txPort);
|
||||
// reset buffer index
|
||||
_txIndex=0;
|
||||
// return sent bytes
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/* read the next byte of the last rececived packet */
|
||||
int UdpBytewiseClass::read() {
|
||||
if(_rxIndex < _rxSize) {
|
||||
// if there is something to be read, return the next byte
|
||||
return _rxBuffer[_rxIndex++];
|
||||
} else {
|
||||
//we already sent the last byte - nothing to do
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void UdpBytewiseClass::getSenderIp(uint8_t*ip) {
|
||||
ip[0]=_rxIp[0];
|
||||
ip[1]=_rxIp[1];
|
||||
ip[2]=_rxIp[2];
|
||||
ip[3]=_rxIp[3];
|
||||
}
|
||||
|
||||
unsigned int UdpBytewiseClass::getSenderPort() {
|
||||
return _rxPort;
|
||||
}
|
||||
|
||||
/* what should we do when we try to add to a full outgoing packet?
|
||||
* UDP_TX_OVERFLOW_TRUNCATE - throw overflow bytes away
|
||||
* UDP_TX_OVERFLOW_SPLIT - split into multiple packets
|
||||
*/
|
||||
void UdpBytewiseClass::setOverflowStrategy(uint8_t strategy) {
|
||||
_txOverflowStrategy = strategy;
|
||||
}
|
||||
|
||||
/* Create one global object */
|
||||
UdpBytewiseClass UdpBytewise;
|
||||
81
Projects/libraries/Installed_libs/Ethernet/UdpBytewise.h
Executable file
81
Projects/libraries/Installed_libs/Ethernet/UdpBytewise.h
Executable file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* UdpBytewise.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* Drop UdpBytewise.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#ifndef UdpBytewise_h
|
||||
#define UdpBytewise_h
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
#define UDP_TX_PACKET_MAX_SIZE 32
|
||||
#define UDP_RX_PACKET_MAX_SIZE 32
|
||||
|
||||
#define UDP_TX_OVERFLOW_TRUNCATE 0
|
||||
#define UDP_TX_OVERFLOW_SPLIT 1
|
||||
|
||||
class UdpBytewiseClass: public Print {
|
||||
private:
|
||||
uint8_t _sock; // socket ID for Wiz5100
|
||||
uint16_t _port; // local port to listen on
|
||||
|
||||
uint8_t _txBuffer[UDP_TX_PACKET_MAX_SIZE];
|
||||
uint8_t _txIndex;
|
||||
uint8_t _txIp[4];
|
||||
uint16_t _txPort;
|
||||
uint8_t _txOverflowStrategy;
|
||||
|
||||
uint8_t _rxBuffer[UDP_RX_PACKET_MAX_SIZE];
|
||||
uint8_t _rxIndex;
|
||||
int _rxSize;
|
||||
uint8_t _rxIp[4];
|
||||
uint16_t _rxPort;
|
||||
|
||||
public:
|
||||
void begin(uint16_t); // initialize, start listening on specified port
|
||||
int available(); // has data been received?
|
||||
|
||||
// Single byte-oriented functions:
|
||||
int beginPacket(uint8_t *ip, unsigned int port); // returns 1 on success, 0 if we already started a packet
|
||||
virtual void write(uint8_t); // add a byte to the currently assembled packet (if there's space)
|
||||
int endPacket(); // returns # of bytes sent on success, 0 if there's nothing to send
|
||||
|
||||
int read(); //read a byte if available - returns -1 if no data available
|
||||
|
||||
void getSenderIp(uint8_t * ip); //get remote IP of the packet we're currently reading from
|
||||
unsigned int getSenderPort(); //get remote port# of the packet we're currently reading from
|
||||
void setOverflowStrategy(uint8_t); // what to do when our packet is full and we try to add more?
|
||||
};
|
||||
|
||||
extern UdpBytewiseClass UdpBytewise;
|
||||
#endif
|
||||
133
Projects/libraries/Installed_libs/Ethernet/UdpRaw.cpp
Executable file
133
Projects/libraries/Installed_libs/Ethernet/UdpRaw.cpp
Executable file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* UdpRaw.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* This version only offers minimal wrapping of socket.c/socket.h
|
||||
* Drop UdpRaw.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "types.h"
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
}
|
||||
|
||||
#include "Ethernet.h"
|
||||
#include "UdpRaw.h"
|
||||
|
||||
/* Start UDP socket, listening at local port PORT */
|
||||
void UdpRawClass::begin(uint16_t port) {
|
||||
_port = port;
|
||||
_sock = 0; //TODO: should not be hardcoded
|
||||
socket(_sock,Sn_MR_UDP,_port,0);
|
||||
}
|
||||
|
||||
/* Send packet contained in buf of length len to peer at specified ip, and port */
|
||||
/* Use this function to transmit binary data that might contain 0x00 bytes*/
|
||||
/* This function returns sent data size for success else -1. */
|
||||
uint16_t UdpRawClass::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
|
||||
return sendto(_sock,(const uint8_t *)buf,len,ip,port);
|
||||
}
|
||||
|
||||
/* Send zero-terminated string str as packet to peer at specified ip, and port */
|
||||
/* This function returns sent data size for success else -1. */
|
||||
uint16_t UdpRawClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
|
||||
// compute strlen
|
||||
const char *s;
|
||||
for(s = str; *s; ++s);
|
||||
uint16_t len = (s-str);
|
||||
// send packet
|
||||
return sendto(_sock,(const uint8_t *)str,len,ip,port);
|
||||
}
|
||||
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
|
||||
* returned value includes 8 byte UDP header!*/
|
||||
int UdpRawClass::available() {
|
||||
return getSn_RX_RSR(_sock);
|
||||
}
|
||||
|
||||
|
||||
/* Read a received packet into buffer buf (which is of maximum length len); */
|
||||
/* store calling ip and port as well. Call available() to make sure data is ready first. */
|
||||
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
|
||||
/* so it's easy to overflow buffer. so we check and truncate. */
|
||||
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
|
||||
int UdpRawClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
|
||||
int packetLen = available()-8; //skip UDP header;
|
||||
if(packetLen < 0 ) return 0; // no real data here
|
||||
if(packetLen > (int)bufLen) {
|
||||
//packet is too large - truncate
|
||||
//HACK - hand-parse the UDP packet using TCP recv method
|
||||
uint8_t tmpBuf[8];
|
||||
int i;
|
||||
//read 8 header bytes and get IP and port from it
|
||||
recv(_sock,tmpBuf,8);
|
||||
ip[0] = tmpBuf[0];
|
||||
ip[1] = tmpBuf[1];
|
||||
ip[2] = tmpBuf[2];
|
||||
ip[3] = tmpBuf[3];
|
||||
*port = tmpBuf[4];
|
||||
*port = (*port << 8) + tmpBuf[5];
|
||||
|
||||
//now copy first (bufLen) bytes into buf
|
||||
for(i=0;i<(int)bufLen;i++) {
|
||||
recv(_sock,tmpBuf,1);
|
||||
buf[i]=tmpBuf[0];
|
||||
}
|
||||
|
||||
//and just read the rest byte by byte and throw it away
|
||||
while(available()) {
|
||||
recv(_sock,tmpBuf,1);
|
||||
}
|
||||
|
||||
return (-1*packetLen);
|
||||
|
||||
//ALTERNATIVE: requires stdlib - takes a bunch of space
|
||||
/*//create new buffer and read everything into it
|
||||
uint8_t * tmpBuf = (uint8_t *)malloc(packetLen);
|
||||
recvfrom(_sock,tmpBuf,packetLen,ip,port);
|
||||
if(!tmpBuf) return 0; //couldn't allocate
|
||||
// copy first bufLen bytes
|
||||
for(unsigned int i=0; i<bufLen; i++) {
|
||||
buf[i]=tmpBuf[i];
|
||||
}
|
||||
//free temp buffer
|
||||
free(tmpBuf);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
return recvfrom(_sock,buf,bufLen,ip,port);
|
||||
}
|
||||
|
||||
/* Read a received packet, throw away peer's ip and port. See note above. */
|
||||
int UdpRawClass::readPacket(uint8_t * buf, uint16_t len) {
|
||||
uint8_t ip[4];
|
||||
uint16_t port[1];
|
||||
return recvfrom(_sock,buf,len,ip,port);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Create one global object */
|
||||
UdpRawClass UdpRaw;
|
||||
60
Projects/libraries/Installed_libs/Ethernet/UdpRaw.h
Executable file
60
Projects/libraries/Installed_libs/Ethernet/UdpRaw.h
Executable file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* UdpRaw.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
|
||||
* This version only offers minimal wrapping of socket.c/socket.h
|
||||
* Drop UdpRaw.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#ifndef UdpRaw_h
|
||||
#define UdpRaw_h
|
||||
|
||||
#define UDP_TX_PACKET_MAX_SIZE 24
|
||||
|
||||
class UdpRawClass {
|
||||
private:
|
||||
uint8_t _sock; // socket ID for Wiz5100
|
||||
uint16_t _port; // local port to listen on
|
||||
|
||||
public:
|
||||
void begin(uint16_t); // initialize, start listening on specified port
|
||||
int available(); // has data been received?
|
||||
|
||||
// C-style buffer-oriented functions
|
||||
uint16_t sendPacket(uint8_t *, uint16_t, uint8_t *, uint16_t); //send a packet to specified peer
|
||||
uint16_t sendPacket(const char[], uint8_t *, uint16_t); //send a string as a packet to specified peer
|
||||
int readPacket(uint8_t *, uint16_t); // read a received packet
|
||||
int readPacket(uint8_t *, uint16_t, uint8_t *, uint16_t *); // read a received packet, also return sender's ip and port
|
||||
};
|
||||
|
||||
extern UdpRawClass UdpRaw;
|
||||
|
||||
#endif
|
||||
83
Projects/libraries/Installed_libs/Ethernet/UdpString.cpp
Executable file
83
Projects/libraries/Installed_libs/Ethernet/UdpString.cpp
Executable file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* UdpString.cpp: Library to send/receive UDP packets with the Arduino ethernet shield
|
||||
* using Tom Igoe/Hernando Barragan's WString library.
|
||||
* Drop UdpString.h/.cpp from this distribution into the Ethernet library directory at
|
||||
* hardware/libraries/Ethernet/
|
||||
* Then copy directory /libraries/String from this distribution to /hardware/libraries/String in
|
||||
* your Arduino installation.
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "types.h"
|
||||
#include "w5100.h"
|
||||
#include "socket.h"
|
||||
}
|
||||
|
||||
#include "Ethernet.h"
|
||||
#include "UdpString.h"
|
||||
|
||||
/* Start UDP socket, listening at local port PORT */
|
||||
void UdpStringClass::begin(uint16_t port) {
|
||||
_port = port;
|
||||
_sock = 0; //TODO: should not be hardcoded
|
||||
socket(_sock,Sn_MR_UDP,_port,0);
|
||||
}
|
||||
|
||||
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes. */
|
||||
int UdpStringClass::available() {
|
||||
return getSn_RX_RSR(_sock);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
//Wstring functions
|
||||
int UdpStringClass::sendPacket(String str, byte * ip, unsigned int port) {
|
||||
return (int)sendto(_sock,(const uint8_t *)str.cstr(),str.length(),ip,port);
|
||||
}
|
||||
|
||||
int UdpStringClass::sendPacket(String str, int length, byte * ip, unsigned int port) {
|
||||
return (int)sendto(_sock,(const uint8_t *)str.cstr(),length,ip,port);
|
||||
}
|
||||
|
||||
int UdpStringClass::readPacket(String &str) {
|
||||
uint8_t ip[4];
|
||||
uint16_t port[1];
|
||||
return readPacket(str,ip,port);
|
||||
}
|
||||
|
||||
/* read packet into String str - if str is too short, expand its capacity */
|
||||
int UdpStringClass::readPacket(String &str, byte * ip, unsigned int *port) {
|
||||
int len = available() -8; //skip UDP header
|
||||
if(len <= 0) return 0;
|
||||
if(len > str.capacity()) {
|
||||
//packet is longer than string capacity -
|
||||
//resize string - this is very implementation dependent on WString
|
||||
str = String(len);
|
||||
//fall through to read which should be ok now
|
||||
}
|
||||
return (int)recvfrom(_sock,(byte *)(str.cstr()),(uint16_t)str.capacity(),ip,port);
|
||||
}
|
||||
|
||||
/* Create one global object */
|
||||
UdpStringClass UdpString;
|
||||
70
Projects/libraries/Installed_libs/Ethernet/UdpString.h
Executable file
70
Projects/libraries/Installed_libs/Ethernet/UdpString.h
Executable file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* UdpString.h: Library to send/receive UDP packets with the Arduino ethernet shield
|
||||
* using Tom Igoe/Hernando Barragan's WString library.
|
||||
* Drop UdpString.h/.cpp from this distribution into the Ethernet library directory at
|
||||
* hardware/libraries/Ethernet/
|
||||
* Then copy directory /libraries/String from this distribution to /hardware/libraries/String in
|
||||
* your Arduino installation.
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#ifndef UdpString_h
|
||||
#define UdpString_h
|
||||
|
||||
#include "WString.h"
|
||||
|
||||
|
||||
|
||||
class UdpStringClass {
|
||||
private:
|
||||
uint8_t _sock; // socket ID for Wiz5100
|
||||
uint16_t _port; // local port to listen on
|
||||
public:
|
||||
void begin(uint16_t); // initialize, start listening on specified port
|
||||
int available(); // has data been received?
|
||||
|
||||
// C-style buffer-oriented functions
|
||||
uint16_t sendPacket(uint8_t *, uint16_t, uint8_t *, uint16_t); //send a packet to specified peer
|
||||
uint16_t sendPacket(const char[], uint8_t *, uint16_t); //send a string as a packet to specified peer
|
||||
uint16_t readPacket(uint8_t *, uint16_t); // read a received packet
|
||||
uint16_t readPacket(uint8_t *, uint16_t, uint8_t *, uint16_t *); // read a received packet, also return sender's ip and port
|
||||
|
||||
// WString functions
|
||||
int sendPacket(String str, byte * ip, unsigned int port);
|
||||
int sendPacket(String str, int length, byte * ip, unsigned int port);
|
||||
int readPacket(String &str);
|
||||
int readPacket(String &str, byte * ip, unsigned int * port);
|
||||
};
|
||||
|
||||
extern UdpStringClass UdpString;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpBytewise.h>
|
||||
|
||||
/* UdpReceiveBytewise.pde: Example how to receive packets over UDP using UdpBytewise library
|
||||
* prints received packet to serial port
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
/* ETHERNET SHIELD CONFIGURATION
|
||||
* set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets
|
||||
*/
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
unsigned int localPort = 8888; // local port to listen on
|
||||
|
||||
#define MAX_SIZE 32 // maximum packet size
|
||||
byte packetBuffer[MAX_SIZE]; //buffer to hold incoming packet
|
||||
int packetSize; // holds received packet size
|
||||
byte remoteIp[4]; // holds recieved packet's originating IP
|
||||
unsigned int remotePort; // holds received packet's originating port
|
||||
|
||||
int i;
|
||||
|
||||
/* SETUP: init Ethernet shield, start UDP listening, open serial port */
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpBytewise.begin(localPort);
|
||||
Serial.begin(38400);
|
||||
}
|
||||
/* LOOP: wait for incoming packets and print each packet to the serial port */
|
||||
void loop() {
|
||||
// if there's data available, read a packet
|
||||
if(packetSize = UdpBytewise.available()) {
|
||||
Serial.print("Received packet of size ");
|
||||
Serial.println(packetSize);
|
||||
|
||||
UdpBytewise.getSenderIp(remoteIp);
|
||||
Serial.print("From IP ");
|
||||
for(i=0; i<4; i++) {
|
||||
Serial.print(remoteIp[i],DEC);
|
||||
if(i<3) Serial.print(".");
|
||||
}
|
||||
|
||||
remotePort = UdpBytewise.getSenderPort();
|
||||
Serial.print(" Port ");
|
||||
Serial.println(remotePort);
|
||||
|
||||
Serial.println("Contents:");
|
||||
while(UdpBytewise.available()) {
|
||||
Serial.print(UdpBytewise.read(),BYTE);
|
||||
}
|
||||
}
|
||||
//wait a bit
|
||||
delay(10);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpRaw.h>
|
||||
|
||||
/* UdpReceiveRaw.pde: Example how to receive packets over UDP using UdpRaw library
|
||||
* prints received packet to serial port
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
/* ETHERNET SHIELD CONFIGURATION
|
||||
* set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets
|
||||
*/
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
int localPort = 8888; // local port to listen on
|
||||
|
||||
#define MAX_SIZE 32 // maximum packet size
|
||||
byte packetBuffer[MAX_SIZE]; //buffer to hold incoming packet
|
||||
int packetSize; // holds received packet size
|
||||
byte remoteIp[4]; // holds recvieved packet's originating IP
|
||||
unsigned int remotePort; // holds received packet's originating port
|
||||
|
||||
int i;
|
||||
|
||||
/* SETUP: init Ethernet shield, start UDP listening, open serial port */
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpRaw.begin(localPort);
|
||||
Serial.begin(38400);
|
||||
}
|
||||
/* LOOP: wait for incoming packets and print each packet to the serial port */
|
||||
void loop() {
|
||||
|
||||
// if there's data available, read a packet
|
||||
if(UdpRaw.available()) {
|
||||
packetSize = UdpRaw.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort);
|
||||
|
||||
Serial.print("Received packet of size ");
|
||||
Serial.println(abs(packetSize));
|
||||
|
||||
Serial.print("From IP ");
|
||||
for(i=0; i<3; i++) {
|
||||
Serial.print(remoteIp[i],DEC);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.print(remoteIp[3],DEC);
|
||||
|
||||
Serial.print(" Port ");
|
||||
Serial.println(remotePort);
|
||||
|
||||
if(packetSize < 0) {
|
||||
// if return value <0 the packet was truncated to fit into our buffer
|
||||
Serial.print("ERROR: Packet was truncated from ");
|
||||
Serial.print(packetSize*-1);
|
||||
Serial.print(" to ");
|
||||
Serial.print(MAX_SIZE);
|
||||
Serial.println(" bytes.");
|
||||
}
|
||||
|
||||
Serial.println("Contents:");
|
||||
for(i=0; i<min(MAX_SIZE,abs(packetSize)); i++) {
|
||||
Serial.print(packetBuffer[i],BYTE);
|
||||
}
|
||||
Serial.println("");
|
||||
|
||||
}
|
||||
//wait a bit
|
||||
delay(10);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpString.h>
|
||||
#include <WString.h>
|
||||
/* UdpReceiveString.pde: Example how to receive packets over UDP using the UdpString library
|
||||
* prints received packet to serial port
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
/* ETHERNET SHIELD CONFIGURATION
|
||||
* set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets
|
||||
*/
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
int localPort = 8888; // local port to listen on
|
||||
|
||||
String packet(32); //packet can be max 32 bytes long
|
||||
byte remoteIp[4]; // holds recvieved packet's originating IP
|
||||
unsigned int remotePort[1]; // holds received packet's originating port
|
||||
|
||||
int i;
|
||||
|
||||
/* SETUP: init Ethernet shield, start UDP listening, open serial port */
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpString.begin(localPort);
|
||||
Serial.begin(38400);
|
||||
}
|
||||
|
||||
/* LOOP: wait for incoming packets and print each packet to the serial port */
|
||||
void loop() {
|
||||
|
||||
// if there's data available, read a packet
|
||||
if(UdpString.available()) {
|
||||
int packetSize = UdpString.readPacket(packet,remoteIp,remotePort);
|
||||
|
||||
Serial.print("Received packet of size ");
|
||||
Serial.println(packetSize);
|
||||
|
||||
Serial.print("From IP ");
|
||||
for(i=0; i<3; i++) {
|
||||
Serial.print(remoteIp[i],DEC);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.print(remoteIp[3],DEC);
|
||||
|
||||
Serial.print(" Port ");
|
||||
Serial.println(remotePort[0]);
|
||||
|
||||
Serial.println("Contents:");
|
||||
Serial.println(packet);
|
||||
|
||||
|
||||
}
|
||||
//wait a bit
|
||||
delay(10);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpBytewise.h>
|
||||
/* UdpSendBytewise.pde: Example how to send packets over UDP using the UdpBytewise library
|
||||
* by assembling packets byte-by-byte
|
||||
* to check for received packets on Unix-ish setup, execute:
|
||||
* sudo tcpdump -A -ien0 "udp port 8000"
|
||||
* bjoern@cs.stanford.edu 12/29/2008 */
|
||||
|
||||
/* ETHERNET CONFIGURATION
|
||||
* ARDUINO: set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets */
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
int localPort = 8888; //local port to listen on
|
||||
|
||||
/* TARGET: set this to IP/Port of computer that will receive
|
||||
* UDP messages from Arduino */
|
||||
byte targetIp[] = { 192, 168, 11, 15};
|
||||
int targetPort = 8000;
|
||||
|
||||
int i=0;
|
||||
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpBytewise.begin(localPort);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// this version of sendPacket sends a zero-terminated string.
|
||||
UdpBytewise.beginPacket(targetIp,targetPort);
|
||||
UdpBytewise.print("Hello, World! ");
|
||||
UdpBytewise.print(i++);
|
||||
UdpBytewise.endPacket();
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpRaw.h>
|
||||
/* UdpSendRaw.pde: Example how to send packets over UDP using the UdpRaw library
|
||||
* to check for received packets on Unix-ish setup, execute:
|
||||
* sudo tcpdump -ien0 "udp port 8000"
|
||||
* bjoern@cs.stanford.edu 12/30/2008 */
|
||||
|
||||
/* ETHERNET CONFIGURATION
|
||||
* ARDUINO: set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets */
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
int localPort = 8888; //local port to listen on
|
||||
|
||||
/* TARGET: set this to IP/Port of computer that will receive
|
||||
* UDP messages from Arduino */
|
||||
byte targetIp[] = { 192, 168, 11, 15};
|
||||
int targetPort = 8000;
|
||||
|
||||
/* A binary packet we'll send to our target - can contain 0x00 */
|
||||
byte packet[] = { 'h','e','l','l','o','\0','w','o','r','l','d','\0' };
|
||||
int packetLen = 12;
|
||||
|
||||
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpRaw.begin(localPort);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// this version of sendPacket sends a zero-terminated string.
|
||||
UdpRaw.sendPacket("hello, world.",targetIp,targetPort);
|
||||
delay(1000);
|
||||
|
||||
// this version sends an arbitrary buffer with specified length;
|
||||
// buffer can contain '\0'
|
||||
UdpRaw.sendPacket(packet,packetLen,targetIp,targetPort);
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <Ethernet.h>
|
||||
#include <UdpString.h>
|
||||
#include <WString.h>
|
||||
|
||||
/* UdpSendString.pde: Example how to send packets over UDP using the String library
|
||||
* to check for received packets on Unix-ish setup, execute:
|
||||
* sudo tcpdump -A -ien0 "udp port 8000"
|
||||
* bjoern@cs.stanford.edu 12/30/2008 */
|
||||
|
||||
/* ETHERNET CONFIGURATION
|
||||
* ARDUINO: set MAC, IP address of Ethernet shield, its gateway,
|
||||
* and local port to listen on for incoming packets */
|
||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC address to use
|
||||
byte ip[] = { 192, 168, 11, 200 }; // Arduino's IP address
|
||||
byte gw[] = { 192, 168, 11, 1 }; // Gateway IP address
|
||||
int localPort = 8888; //local port to listen on
|
||||
|
||||
/* TARGET: set this to IP/Port of computer that will receive
|
||||
* UDP messages from Arduino */
|
||||
byte targetIp[] = { 192, 168, 11, 15};
|
||||
int targetPort = 8000;
|
||||
|
||||
/* Strings hold the packets we want to send */
|
||||
String asciiString;
|
||||
String binaryString(4); // if we want to send non-ASCII, we have to provide a capacity for the String
|
||||
|
||||
void setup() {
|
||||
Ethernet.begin(mac,ip,gw);
|
||||
UdpString.begin(localPort);
|
||||
|
||||
asciiString = "Hello, World";
|
||||
|
||||
binaryString.getBytes()[0]=0x00;
|
||||
binaryString.getBytes()[1]=0x01;
|
||||
binaryString.getBytes()[2]=0x02;
|
||||
binaryString.getBytes()[3]=0x03;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send a normal, zero-terminated string.
|
||||
UdpString.sendPacket(asciiString,targetIp,targetPort);
|
||||
delay(1000);
|
||||
|
||||
// sends a binary string that can contain 0x00 in the middle
|
||||
// you have to specify the length;
|
||||
UdpString.sendPacket(binaryString,binaryString.capacity(),targetIp,targetPort);
|
||||
delay(1000);
|
||||
}
|
||||
1030
Projects/libraries/Installed_libs/IRRemote/IRremote.cpp
Executable file
1030
Projects/libraries/Installed_libs/IRRemote/IRremote.cpp
Executable file
File diff suppressed because it is too large
Load Diff
118
Projects/libraries/Installed_libs/IRRemote/IRremote.h
Executable file
118
Projects/libraries/Installed_libs/IRRemote/IRremote.h
Executable file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com
|
||||
* Edited by Mitra to add new controller SANYO
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#ifndef IRremote_h
|
||||
#define IRremote_h
|
||||
|
||||
// The following are compile-time library options.
|
||||
// If you change them, recompile the library.
|
||||
// If DEBUG is defined, a lot of debugging output will be printed during decoding.
|
||||
// TEST must be defined for the IRtest unittests to work. It will make some
|
||||
// methods virtual, which will be slightly slower, which is why it is optional.
|
||||
// #define DEBUG
|
||||
// #define TEST
|
||||
|
||||
// Results returned from the decoder
|
||||
class decode_results {
|
||||
public:
|
||||
int decode_type; // NEC, SONY, RC5, UNKNOWN
|
||||
unsigned int panasonicAddress; // This is only used for decoding Panasonic data
|
||||
unsigned long value; // Decoded value
|
||||
int bits; // Number of bits in decoded value
|
||||
volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks
|
||||
int rawlen; // Number of records in rawbuf.
|
||||
};
|
||||
|
||||
// Values for decode_type
|
||||
#define NEC 1
|
||||
#define SONY 2
|
||||
#define RC5 3
|
||||
#define RC6 4
|
||||
#define DISH 5
|
||||
#define SHARP 6
|
||||
#define PANASONIC 7
|
||||
#define JVC 8
|
||||
#define SANYO 9
|
||||
#define MITSUBISHI 10
|
||||
#define UNKNOWN -1
|
||||
|
||||
// Decoded value for NEC when a repeat code is received
|
||||
#define REPEAT 0xffffffff
|
||||
|
||||
// main class for receiving IR
|
||||
class IRrecv
|
||||
{
|
||||
public:
|
||||
IRrecv(int recvpin);
|
||||
void blink13(int blinkflag);
|
||||
int decode(decode_results *results);
|
||||
void enableIRIn();
|
||||
void resume();
|
||||
private:
|
||||
// These are called by decode
|
||||
int getRClevel(decode_results *results, int *offset, int *used, int t1);
|
||||
long decodeNEC(decode_results *results);
|
||||
long decodeSony(decode_results *results);
|
||||
long decodeSanyo(decode_results *results);
|
||||
long decodeMitsubishi(decode_results *results);
|
||||
long decodeRC5(decode_results *results);
|
||||
long decodeRC6(decode_results *results);
|
||||
long decodePanasonic(decode_results *results);
|
||||
long decodeJVC(decode_results *results);
|
||||
long decodeHash(decode_results *results);
|
||||
int compare(unsigned int oldval, unsigned int newval);
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
// Only used for testing; can remove virtual for shorter code
|
||||
#ifdef TEST
|
||||
#define VIRTUAL virtual
|
||||
#else
|
||||
#define VIRTUAL
|
||||
#endif
|
||||
|
||||
class IRsend
|
||||
{
|
||||
public:
|
||||
IRsend() {}
|
||||
void sendNEC(unsigned long data, int nbits);
|
||||
void sendSony(unsigned long data, int nbits);
|
||||
// Neither Sanyo nor Mitsubishi send is implemented yet
|
||||
// void sendSanyo(unsigned long data, int nbits);
|
||||
// void sendMitsubishi(unsigned long data, int nbits);
|
||||
void sendRaw(unsigned int buf[], int len, int hz);
|
||||
void sendRC5(unsigned long data, int nbits);
|
||||
void sendRC6(unsigned long data, int nbits);
|
||||
void sendDISH(unsigned long data, int nbits);
|
||||
void sendSharp(unsigned long data, int nbits);
|
||||
void sendPanasonic(unsigned int address, unsigned long data);
|
||||
void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.
|
||||
// private:
|
||||
void enableIROut(int khz);
|
||||
VIRTUAL void mark(int usec);
|
||||
VIRTUAL void space(int usec);
|
||||
}
|
||||
;
|
||||
|
||||
// Some useful constants
|
||||
|
||||
#define USECPERTICK 50 // microseconds per clock interrupt tick
|
||||
#define RAWBUF 100 // Length of raw duration buffer
|
||||
|
||||
// Marks tend to be 100us too long, and spaces 100us too short
|
||||
// when received due to sensor lag.
|
||||
#define MARK_EXCESS 100
|
||||
|
||||
#endif
|
||||
457
Projects/libraries/Installed_libs/IRRemote/IRremoteInt.h
Executable file
457
Projects/libraries/Installed_libs/IRRemote/IRremoteInt.h
Executable file
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
* IRremote
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
*
|
||||
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
|
||||
*
|
||||
* Interrupt code based on NECIRrcv by Joe Knapp
|
||||
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
|
||||
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
|
||||
*
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#ifndef IRremoteint_h
|
||||
#define IRremoteint_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
// define which timer to use
|
||||
//
|
||||
// Uncomment the timer you wish to use on your board. If you
|
||||
// are using another library which uses timer2, you have options
|
||||
// to switch IRremote to use a different timer.
|
||||
|
||||
// Arduino Mega
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 11
|
||||
#define IR_USE_TIMER2 // tx = pin 9
|
||||
//#define IR_USE_TIMER3 // tx = pin 5
|
||||
//#define IR_USE_TIMER4 // tx = pin 6
|
||||
//#define IR_USE_TIMER5 // tx = pin 46
|
||||
|
||||
// Teensy 1.0
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define IR_USE_TIMER1 // tx = pin 17
|
||||
|
||||
// Teensy 2.0
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 14
|
||||
//#define IR_USE_TIMER3 // tx = pin 9
|
||||
#define IR_USE_TIMER4_HS // tx = pin 10
|
||||
|
||||
// Teensy++ 1.0 & 2.0
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 25
|
||||
#define IR_USE_TIMER2 // tx = pin 1
|
||||
//#define IR_USE_TIMER3 // tx = pin 16
|
||||
|
||||
// Sanguino
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
//#define IR_USE_TIMER1 // tx = pin 13
|
||||
#define IR_USE_TIMER2 // tx = pin 14
|
||||
|
||||
// Atmega8
|
||||
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define IR_USE_TIMER1 // tx = pin 9
|
||||
|
||||
#elif defined( __AVR_ATtinyX4__ )
|
||||
#define IR_USE_TIMER1 // tx = pin 6
|
||||
|
||||
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
|
||||
#else
|
||||
//#define IR_USE_TIMER1 // tx = pin 9
|
||||
#define IR_USE_TIMER2 // tx = pin 3
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef F_CPU
|
||||
#define SYSCLOCK F_CPU // main Arduino clock
|
||||
#else
|
||||
#define SYSCLOCK 16000000 // main Arduino clock
|
||||
#endif
|
||||
|
||||
#define ERR 0
|
||||
#define DECODED 1
|
||||
|
||||
|
||||
// defines for setting and clearing register bits
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
// Pulse parms are *50-100 for the Mark and *50+100 for the space
|
||||
// First MARK is the one after the long gap
|
||||
// pulse parameters in usec
|
||||
#define NEC_HDR_MARK 9000
|
||||
#define NEC_HDR_SPACE 4500
|
||||
#define NEC_BIT_MARK 560
|
||||
#define NEC_ONE_SPACE 1600
|
||||
#define NEC_ZERO_SPACE 560
|
||||
#define NEC_RPT_SPACE 2250
|
||||
|
||||
#define SONY_HDR_MARK 2400
|
||||
#define SONY_HDR_SPACE 600
|
||||
#define SONY_ONE_MARK 1200
|
||||
#define SONY_ZERO_MARK 600
|
||||
#define SONY_RPT_LENGTH 45000
|
||||
#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
|
||||
|
||||
// SA 8650B
|
||||
#define SANYO_HDR_MARK 3500 // seen range 3500
|
||||
#define SANYO_HDR_SPACE 950 // seen 950
|
||||
#define SANYO_ONE_MARK 2400 // seen 2400
|
||||
#define SANYO_ZERO_MARK 700 // seen 700
|
||||
#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
#define SANYO_RPT_LENGTH 45000
|
||||
|
||||
// Mitsubishi RM 75501
|
||||
// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
|
||||
|
||||
// #define MITSUBISHI_HDR_MARK 250 // seen range 3500
|
||||
#define MITSUBISHI_HDR_SPACE 350 // 7*50+100
|
||||
#define MITSUBISHI_ONE_MARK 1950 // 41*50-100
|
||||
#define MITSUBISHI_ZERO_MARK 750 // 17*50-100
|
||||
// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
|
||||
// #define MITSUBISHI_RPT_LENGTH 45000
|
||||
|
||||
|
||||
#define RC5_T1 889
|
||||
#define RC5_RPT_LENGTH 46000
|
||||
|
||||
#define RC6_HDR_MARK 2666
|
||||
#define RC6_HDR_SPACE 889
|
||||
#define RC6_T1 444
|
||||
#define RC6_RPT_LENGTH 46000
|
||||
|
||||
#define SHARP_BIT_MARK 245
|
||||
#define SHARP_ONE_SPACE 1805
|
||||
#define SHARP_ZERO_SPACE 795
|
||||
#define SHARP_GAP 600000
|
||||
#define SHARP_TOGGLE_MASK 0x3FF
|
||||
#define SHARP_RPT_SPACE 3000
|
||||
|
||||
#define DISH_HDR_MARK 400
|
||||
#define DISH_HDR_SPACE 6100
|
||||
#define DISH_BIT_MARK 400
|
||||
#define DISH_ONE_SPACE 1700
|
||||
#define DISH_ZERO_SPACE 2800
|
||||
#define DISH_RPT_SPACE 6200
|
||||
#define DISH_TOP_BIT 0x8000
|
||||
|
||||
#define PANASONIC_HDR_MARK 3502
|
||||
#define PANASONIC_HDR_SPACE 1750
|
||||
#define PANASONIC_BIT_MARK 502
|
||||
#define PANASONIC_ONE_SPACE 1244
|
||||
#define PANASONIC_ZERO_SPACE 400
|
||||
|
||||
#define JVC_HDR_MARK 8000
|
||||
#define JVC_HDR_SPACE 4000
|
||||
#define JVC_BIT_MARK 600
|
||||
#define JVC_ONE_SPACE 1600
|
||||
#define JVC_ZERO_SPACE 550
|
||||
#define JVC_RPT_LENGTH 60000
|
||||
|
||||
#define SHARP_BITS 15
|
||||
#define DISH_BITS 16
|
||||
|
||||
#define TOLERANCE 25 // percent tolerance in measurements
|
||||
#define LTOL (1.0 - TOLERANCE/100.)
|
||||
#define UTOL (1.0 + TOLERANCE/100.)
|
||||
|
||||
#define _GAP 5000 // Minimum map between transmissions
|
||||
#define GAP_TICKS (_GAP/USECPERTICK)
|
||||
|
||||
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
|
||||
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
|
||||
|
||||
// receiver states
|
||||
#define STATE_IDLE 2
|
||||
#define STATE_MARK 3
|
||||
#define STATE_SPACE 4
|
||||
#define STATE_STOP 5
|
||||
|
||||
// information for the interrupt handler
|
||||
typedef struct {
|
||||
uint8_t recvpin; // pin for IR data from detector
|
||||
uint8_t rcvstate; // state machine
|
||||
uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing
|
||||
unsigned int timer; // state timer, counts 50uS ticks.
|
||||
unsigned int rawbuf[RAWBUF]; // raw data
|
||||
uint8_t rawlen; // counter of entries in rawbuf
|
||||
}
|
||||
irparams_t;
|
||||
|
||||
// Defined in IRremote.cpp
|
||||
extern volatile irparams_t irparams;
|
||||
|
||||
// IR detector output is active low
|
||||
#define MARK 0
|
||||
#define SPACE 1
|
||||
|
||||
#define TOPBIT 0x80000000
|
||||
|
||||
#define NEC_BITS 32
|
||||
#define SONY_BITS 12
|
||||
#define SANYO_BITS 12
|
||||
#define MITSUBISHI_BITS 16
|
||||
#define MIN_RC5_SAMPLES 11
|
||||
#define MIN_RC6_SAMPLES 1
|
||||
#define PANASONIC_BITS 48
|
||||
#define JVC_BITS 16
|
||||
|
||||
|
||||
|
||||
|
||||
// defines for timer2 (8 bits)
|
||||
#if defined(IR_USE_TIMER2)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
|
||||
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
|
||||
#define TIMER_INTR_NAME TIMER2_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR2A = _BV(WGM20); \
|
||||
TCCR2B = _BV(WGM22) | _BV(CS20); \
|
||||
OCR2A = pwmval; \
|
||||
OCR2B = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
|
||||
#if (TIMER_COUNT_TOP < 256)
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS20); \
|
||||
OCR2A = TIMER_COUNT_TOP; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#else
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR2A = _BV(WGM21); \
|
||||
TCCR2B = _BV(CS21); \
|
||||
OCR2A = TIMER_COUNT_TOP / 8; \
|
||||
TCNT2 = 0; \
|
||||
})
|
||||
#endif
|
||||
#if defined(CORE_OC2B_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 14 /* Sanguino */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer1 (16 bits)
|
||||
#elif defined(IR_USE_TIMER1)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
|
||||
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
|
||||
#define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK = 0)
|
||||
#else
|
||||
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK1 = 0)
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_ATtinyX4__)
|
||||
#define TIMER_INTR_NAME TIM1_COMPA_vect
|
||||
#else
|
||||
#define TIMER_INTR_NAME TIMER1_COMPA_vect
|
||||
#endif
|
||||
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR1A = _BV(WGM11); \
|
||||
TCCR1B = _BV(WGM13) | _BV(CS10); \
|
||||
ICR1 = pwmval; \
|
||||
OCR1A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR1A = 0; \
|
||||
TCCR1B = _BV(WGM12) | _BV(CS10); \
|
||||
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT1 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC1A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 11 /* Arduino Mega */
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define TIMER_PWM_PIN 13 /* Sanguino */
|
||||
#elif defined(__AVR_ATtinyX4__)
|
||||
#define TIMER_PWM_PIN 6 /* ATTiny84 */
|
||||
#else
|
||||
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer3 (16 bits)
|
||||
#elif defined(IR_USE_TIMER3)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK3 = 0)
|
||||
#define TIMER_INTR_NAME TIMER3_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR3A = _BV(WGM31); \
|
||||
TCCR3B = _BV(WGM33) | _BV(CS30); \
|
||||
ICR3 = pwmval; \
|
||||
OCR3A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR3A = 0; \
|
||||
TCCR3B = _BV(WGM32) | _BV(CS30); \
|
||||
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT3 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC3A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 5 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC3A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (10 bits, high speed option)
|
||||
#elif defined(IR_USE_TIMER4_HS)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_OVF_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = (1<<PWM4A); \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = (1<<WGM40); \
|
||||
TCCR4E = 0; \
|
||||
TC4H = pwmval >> 8; \
|
||||
OCR4C = pwmval; \
|
||||
TC4H = (pwmval / 3) >> 8; \
|
||||
OCR4A = (pwmval / 3) & 255; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(CS40); \
|
||||
TCCR4C = 0; \
|
||||
TCCR4D = 0; \
|
||||
TCCR4E = 0; \
|
||||
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
|
||||
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
|
||||
TC4H = 0; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define TIMER_PWM_PIN 13 /* Leonardo */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer4 (16 bits)
|
||||
#elif defined(IR_USE_TIMER4)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK4 = 0)
|
||||
#define TIMER_INTR_NAME TIMER4_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR4A = _BV(WGM41); \
|
||||
TCCR4B = _BV(WGM43) | _BV(CS40); \
|
||||
ICR4 = pwmval; \
|
||||
OCR4A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR4A = 0; \
|
||||
TCCR4B = _BV(WGM42) | _BV(CS40); \
|
||||
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT4 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC4A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC4A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 6 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC4A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for timer5 (16 bits)
|
||||
#elif defined(IR_USE_TIMER5)
|
||||
#define TIMER_RESET
|
||||
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
|
||||
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
|
||||
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
|
||||
#define TIMER_DISABLE_INTR (TIMSK5 = 0)
|
||||
#define TIMER_INTR_NAME TIMER5_COMPA_vect
|
||||
#define TIMER_CONFIG_KHZ(val) ({ \
|
||||
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
|
||||
TCCR5A = _BV(WGM51); \
|
||||
TCCR5B = _BV(WGM53) | _BV(CS50); \
|
||||
ICR5 = pwmval; \
|
||||
OCR5A = pwmval / 3; \
|
||||
})
|
||||
#define TIMER_CONFIG_NORMAL() ({ \
|
||||
TCCR5A = 0; \
|
||||
TCCR5B = _BV(WGM52) | _BV(CS50); \
|
||||
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
|
||||
TCNT5 = 0; \
|
||||
})
|
||||
#if defined(CORE_OC5A_PIN)
|
||||
#define TIMER_PWM_PIN CORE_OC5A_PIN
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define TIMER_PWM_PIN 46 /* Arduino Mega */
|
||||
#else
|
||||
#error "Please add OC5A pin number here\n"
|
||||
#endif
|
||||
|
||||
|
||||
#else // unknown timer
|
||||
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
|
||||
#endif
|
||||
|
||||
|
||||
// defines for blinking the LED
|
||||
#if defined(CORE_LED0_PIN)
|
||||
#define BLINKLED CORE_LED0_PIN
|
||||
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
|
||||
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B10000000)
|
||||
#define BLINKLED_OFF() (PORTB &= B01111111)
|
||||
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
|
||||
#define BLINKLED 0
|
||||
#define BLINKLED_ON() (PORTD |= B00000001)
|
||||
#define BLINKLED_OFF() (PORTD &= B11111110)
|
||||
#else
|
||||
#define BLINKLED 13
|
||||
#define BLINKLED_ON() (PORTB |= B00100000)
|
||||
#define BLINKLED_OFF() (PORTB &= B11011111)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
458
Projects/libraries/Installed_libs/IRRemote/LICENSE.txt
Executable file
458
Projects/libraries/Installed_libs/IRRemote/LICENSE.txt
Executable file
@@ -0,0 +1,458 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
167
Projects/libraries/Installed_libs/IRRemote/examples/IRrecord/IRrecord.ino
Executable file
167
Projects/libraries/Installed_libs/IRRemote/examples/IRrecord/IRrecord.ino
Executable file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* IRrecord: record and play back IR signals as a minimal
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* An IR LED must be connected to the output PWM pin 3.
|
||||
* A button must be connected to the input BUTTON_PIN; this is the
|
||||
* send button.
|
||||
* A visible LED can be connected to STATUS_PIN to provide status.
|
||||
*
|
||||
* The logic is:
|
||||
* If the button is pressed, send the IR code.
|
||||
* If an IR code is received, record it.
|
||||
*
|
||||
* Version 0.11 September, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int BUTTON_PIN = 12;
|
||||
int STATUS_PIN = 13;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
pinMode(STATUS_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
// Storage for the recorded code
|
||||
int codeType = -1; // The type of code
|
||||
unsigned long codeValue; // The code value if not raw
|
||||
unsigned int rawCodes[RAWBUF]; // The durations if raw
|
||||
int codeLen; // The length of the code
|
||||
int toggle = 0; // The RC5/6 toggle state
|
||||
|
||||
// Stores the code for later playback
|
||||
// Most of this code is just logging
|
||||
void storeCode(decode_results *results) {
|
||||
codeType = results->decode_type;
|
||||
int count = results->rawlen;
|
||||
if (codeType == UNKNOWN) {
|
||||
Serial.println("Received unknown code, saving as raw");
|
||||
codeLen = results->rawlen - 1;
|
||||
// To store raw codes:
|
||||
// Drop first value (gap)
|
||||
// Convert from ticks to microseconds
|
||||
// Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
|
||||
for (int i = 1; i <= codeLen; i++) {
|
||||
if (i % 2) {
|
||||
// Mark
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
|
||||
Serial.print(" m");
|
||||
}
|
||||
else {
|
||||
// Space
|
||||
rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
|
||||
Serial.print(" s");
|
||||
}
|
||||
Serial.print(rawCodes[i - 1], DEC);
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
else {
|
||||
if (codeType == NEC) {
|
||||
Serial.print("Received NEC: ");
|
||||
if (results->value == REPEAT) {
|
||||
// Don't record a NEC repeat value as that's useless.
|
||||
Serial.println("repeat; ignoring.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
Serial.print("Received SONY: ");
|
||||
}
|
||||
else if (codeType == RC5) {
|
||||
Serial.print("Received RC5: ");
|
||||
}
|
||||
else if (codeType == RC6) {
|
||||
Serial.print("Received RC6: ");
|
||||
}
|
||||
else {
|
||||
Serial.print("Unexpected codeType ");
|
||||
Serial.print(codeType, DEC);
|
||||
Serial.println("");
|
||||
}
|
||||
Serial.println(results->value, HEX);
|
||||
codeValue = results->value;
|
||||
codeLen = results->bits;
|
||||
}
|
||||
}
|
||||
|
||||
void sendCode(int repeat) {
|
||||
if (codeType == NEC) {
|
||||
if (repeat) {
|
||||
irsend.sendNEC(REPEAT, codeLen);
|
||||
Serial.println("Sent NEC repeat");
|
||||
}
|
||||
else {
|
||||
irsend.sendNEC(codeValue, codeLen);
|
||||
Serial.print("Sent NEC ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == SONY) {
|
||||
irsend.sendSony(codeValue, codeLen);
|
||||
Serial.print("Sent Sony ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
else if (codeType == RC5 || codeType == RC6) {
|
||||
if (!repeat) {
|
||||
// Flip the toggle bit for a new button press
|
||||
toggle = 1 - toggle;
|
||||
}
|
||||
// Put the toggle bit into the code to send
|
||||
codeValue = codeValue & ~(1 << (codeLen - 1));
|
||||
codeValue = codeValue | (toggle << (codeLen - 1));
|
||||
if (codeType == RC5) {
|
||||
Serial.print("Sent RC5 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
irsend.sendRC5(codeValue, codeLen);
|
||||
}
|
||||
else {
|
||||
irsend.sendRC6(codeValue, codeLen);
|
||||
Serial.print("Sent RC6 ");
|
||||
Serial.println(codeValue, HEX);
|
||||
}
|
||||
}
|
||||
else if (codeType == UNKNOWN /* i.e. raw */) {
|
||||
// Assume 38 KHz
|
||||
irsend.sendRaw(rawCodes, codeLen, 38);
|
||||
Serial.println("Sent raw");
|
||||
}
|
||||
}
|
||||
|
||||
int lastButtonState;
|
||||
|
||||
void loop() {
|
||||
// If button pressed, send the code.
|
||||
int buttonState = digitalRead(BUTTON_PIN);
|
||||
if (lastButtonState == HIGH && buttonState == LOW) {
|
||||
Serial.println("Released");
|
||||
irrecv.enableIRIn(); // Re-enable receiver
|
||||
}
|
||||
|
||||
if (buttonState) {
|
||||
Serial.println("Pressed, sending");
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
sendCode(lastButtonState == buttonState);
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
delay(50); // Wait a bit between retransmissions
|
||||
}
|
||||
else if (irrecv.decode(&results)) {
|
||||
digitalWrite(STATUS_PIN, HIGH);
|
||||
storeCode(&results);
|
||||
irrecv.resume(); // resume receiver
|
||||
digitalWrite(STATUS_PIN, LOW);
|
||||
}
|
||||
lastButtonState = buttonState;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* IRremote: IRrecvDump - dump details of IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
|
||||
decode_results results;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.print("Unknown encoding: ");
|
||||
}
|
||||
else if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
else if (results->decode_type == PANASONIC) {
|
||||
Serial.print("Decoded PANASONIC - Address: ");
|
||||
Serial.print(results->panasonicAddress,HEX);
|
||||
Serial.print(" Value: ");
|
||||
}
|
||||
else if (results->decode_type == JVC) {
|
||||
Serial.print("Decoded JVC: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
Serial.println(results.value, HEX);
|
||||
dump(&results);
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
85
Projects/libraries/Installed_libs/IRRemote/examples/IRrelay/IRrelay.ino
Executable file
85
Projects/libraries/Installed_libs/IRRemote/examples/IRrelay/IRrelay.ino
Executable file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
|
||||
* An IR detector/demodulator must be connected to the input RECV_PIN.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int RELAY_PIN = 4;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
decode_results results;
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
Serial.begin(9600);
|
||||
irrecv.enableIRIn(); // Start the receiver
|
||||
}
|
||||
|
||||
int on = 0;
|
||||
unsigned long last = millis();
|
||||
|
||||
void loop() {
|
||||
if (irrecv.decode(&results)) {
|
||||
// If it's been at least 1/4 second since the last
|
||||
// IR received, toggle the relay
|
||||
if (millis() - last > 250) {
|
||||
on = !on;
|
||||
digitalWrite(RELAY_PIN, on ? HIGH : LOW);
|
||||
digitalWrite(13, on ? HIGH : LOW);
|
||||
dump(&results);
|
||||
}
|
||||
last = millis();
|
||||
irrecv.resume(); // Receive the next value
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.read() != -1) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
irsend.sendSony(0xa90, 12); // Sony TV power code
|
||||
delay(40);
|
||||
}
|
||||
}
|
||||
}
|
||||
190
Projects/libraries/Installed_libs/IRRemote/examples/IRtest/IRtest.ino
Executable file
190
Projects/libraries/Installed_libs/IRRemote/examples/IRtest/IRtest.ino
Executable file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* IRremote: IRtest unittest
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*
|
||||
* Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST"
|
||||
* You must then recompile the library by removing IRremote.o and restarting
|
||||
* the arduino IDE.
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
#include <IRremoteInt.h>
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
//void dump(void *v) {
|
||||
// decode_results *results = (decode_results *)v
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
IRrecv irrecv(0);
|
||||
decode_results results;
|
||||
|
||||
class IRsendDummy :
|
||||
public IRsend
|
||||
{
|
||||
public:
|
||||
// For testing, just log the marks/spaces
|
||||
#define SENDLOG_LEN 128
|
||||
int sendlog[SENDLOG_LEN];
|
||||
int sendlogcnt;
|
||||
IRsendDummy() :
|
||||
IRsend() {
|
||||
}
|
||||
void reset() {
|
||||
sendlogcnt = 0;
|
||||
}
|
||||
void mark(int time) {
|
||||
sendlog[sendlogcnt] = time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
void space(int time) {
|
||||
sendlog[sendlogcnt] = -time;
|
||||
if (sendlogcnt < SENDLOG_LEN) sendlogcnt++;
|
||||
}
|
||||
// Copies the dummy buf into the interrupt buf
|
||||
void useDummyBuf() {
|
||||
int last = SPACE;
|
||||
irparams.rcvstate = STATE_STOP;
|
||||
irparams.rawlen = 1; // Skip the gap
|
||||
for (int i = 0 ; i < sendlogcnt; i++) {
|
||||
if (sendlog[i] < 0) {
|
||||
if (last == MARK) {
|
||||
// New space
|
||||
irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK;
|
||||
last = SPACE;
|
||||
}
|
||||
else {
|
||||
// More space
|
||||
irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
else if (sendlog[i] > 0) {
|
||||
if (last == SPACE) {
|
||||
// New mark
|
||||
irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK;
|
||||
last = MARK;
|
||||
}
|
||||
else {
|
||||
// More mark
|
||||
irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (irparams.rawlen % 2) {
|
||||
irparams.rawlen--; // Remove trailing space
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IRsendDummy irsenddummy;
|
||||
|
||||
void verify(unsigned long val, int bits, int type) {
|
||||
irsenddummy.useDummyBuf();
|
||||
irrecv.decode(&results);
|
||||
Serial.print("Testing ");
|
||||
Serial.print(val, HEX);
|
||||
if (results.value == val && results.bits == bits && results.decode_type == type) {
|
||||
Serial.println(": OK");
|
||||
}
|
||||
else {
|
||||
Serial.println(": Error");
|
||||
dump(&results);
|
||||
}
|
||||
}
|
||||
|
||||
void testNEC(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendNEC(val, bits);
|
||||
verify(val, bits, NEC);
|
||||
}
|
||||
void testSony(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendSony(val, bits);
|
||||
verify(val, bits, SONY);
|
||||
}
|
||||
void testRC5(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC5(val, bits);
|
||||
verify(val, bits, RC5);
|
||||
}
|
||||
void testRC6(unsigned long val, int bits) {
|
||||
irsenddummy.reset();
|
||||
irsenddummy.sendRC6(val, bits);
|
||||
verify(val, bits, RC6);
|
||||
}
|
||||
|
||||
void test() {
|
||||
Serial.println("NEC tests");
|
||||
testNEC(0x00000000, 32);
|
||||
testNEC(0xffffffff, 32);
|
||||
testNEC(0xaaaaaaaa, 32);
|
||||
testNEC(0x55555555, 32);
|
||||
testNEC(0x12345678, 32);
|
||||
Serial.println("Sony tests");
|
||||
testSony(0xfff, 12);
|
||||
testSony(0x000, 12);
|
||||
testSony(0xaaa, 12);
|
||||
testSony(0x555, 12);
|
||||
testSony(0x123, 12);
|
||||
Serial.println("RC5 tests");
|
||||
testRC5(0xfff, 12);
|
||||
testRC5(0x000, 12);
|
||||
testRC5(0xaaa, 12);
|
||||
testRC5(0x555, 12);
|
||||
testRC5(0x123, 12);
|
||||
Serial.println("RC6 tests");
|
||||
testRC6(0xfffff, 20);
|
||||
testRC6(0x00000, 20);
|
||||
testRC6(0xaaaaa, 20);
|
||||
testRC6(0x55555, 20);
|
||||
testRC6(0x12345, 20);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
test();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
290
Projects/libraries/Installed_libs/IRRemote/examples/IRtest2/IRtest2.ino
Executable file
290
Projects/libraries/Installed_libs/IRRemote/examples/IRtest2/IRtest2.ino
Executable file
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Test send/receive functions of IRremote, using a pair of Arduinos.
|
||||
*
|
||||
* Arduino #1 should have an IR LED connected to the send pin (3).
|
||||
* Arduino #2 should have an IR detector/demodulator connected to the
|
||||
* receive pin (11) and a visible LED connected to pin 3.
|
||||
*
|
||||
* The cycle:
|
||||
* Arduino #1 will wait 2 seconds, then run through the tests.
|
||||
* It repeats this forever.
|
||||
* Arduino #2 will wait for at least one second of no signal
|
||||
* (to synchronize with #1). It will then wait for the same test
|
||||
* signals. It will log all the status to the serial port. It will
|
||||
* also indicate status through the LED, which will flash each time a test
|
||||
* is completed. If there is an error, it will light up for 5 seconds.
|
||||
*
|
||||
* The test passes if the LED flashes 19 times, pauses, and then repeats.
|
||||
* The test fails if the LED lights for 5 seconds.
|
||||
*
|
||||
* The test software automatically decides which board is the sender and which is
|
||||
* the receiver by looking for an input on the send pin, which will indicate
|
||||
* the sender. You should hook the serial port to the receiver for debugging.
|
||||
*
|
||||
* Copyright 2010 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
*/
|
||||
|
||||
#include <IRremote.h>
|
||||
|
||||
int RECV_PIN = 11;
|
||||
int LED_PIN = 3;
|
||||
|
||||
IRrecv irrecv(RECV_PIN);
|
||||
IRsend irsend;
|
||||
|
||||
decode_results results;
|
||||
|
||||
#define RECEIVER 1
|
||||
#define SENDER 2
|
||||
#define ERROR 3
|
||||
|
||||
int mode;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
// Check RECV_PIN to decide if we're RECEIVER or SENDER
|
||||
if (digitalRead(RECV_PIN) == HIGH) {
|
||||
mode = RECEIVER;
|
||||
irrecv.enableIRIn();
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
Serial.println("Receiver mode");
|
||||
}
|
||||
else {
|
||||
mode = SENDER;
|
||||
Serial.println("Sender mode");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the gap between tests, to synchronize with
|
||||
// the sender.
|
||||
// Specifically, wait for a signal followed by a gap of at last gap ms.
|
||||
void waitForGap(int gap) {
|
||||
Serial.println("Waiting for gap");
|
||||
while (1) {
|
||||
while (digitalRead(RECV_PIN) == LOW) {
|
||||
}
|
||||
unsigned long time = millis();
|
||||
while (digitalRead(RECV_PIN) == HIGH) {
|
||||
if (millis() - time > gap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
void dump(decode_results *results) {
|
||||
int count = results->rawlen;
|
||||
if (results->decode_type == UNKNOWN) {
|
||||
Serial.println("Could not decode message");
|
||||
}
|
||||
else {
|
||||
if (results->decode_type == NEC) {
|
||||
Serial.print("Decoded NEC: ");
|
||||
}
|
||||
else if (results->decode_type == SONY) {
|
||||
Serial.print("Decoded SONY: ");
|
||||
}
|
||||
else if (results->decode_type == RC5) {
|
||||
Serial.print("Decoded RC5: ");
|
||||
}
|
||||
else if (results->decode_type == RC6) {
|
||||
Serial.print("Decoded RC6: ");
|
||||
}
|
||||
Serial.print(results->value, HEX);
|
||||
Serial.print(" (");
|
||||
Serial.print(results->bits, DEC);
|
||||
Serial.println(" bits)");
|
||||
}
|
||||
Serial.print("Raw (");
|
||||
Serial.print(count, DEC);
|
||||
Serial.print("): ");
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if ((i % 2) == 1) {
|
||||
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
else {
|
||||
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
|
||||
}
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
|
||||
// Test send or receive.
|
||||
// If mode is SENDER, send a code of the specified type, value, and bits
|
||||
// If mode is RECEIVER, receive a code and verify that it is of the
|
||||
// specified type, value, and bits. For success, the LED is flashed;
|
||||
// for failure, the mode is set to ERROR.
|
||||
// The motivation behind this method is that the sender and the receiver
|
||||
// can do the same test calls, and the mode variable indicates whether
|
||||
// to send or receive.
|
||||
void test(char *label, int type, unsigned long value, int bits) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
if (type == NEC) {
|
||||
irsend.sendNEC(value, bits);
|
||||
}
|
||||
else if (type == SONY) {
|
||||
irsend.sendSony(value, bits);
|
||||
}
|
||||
else if (type == RC5) {
|
||||
irsend.sendRC5(value, bits);
|
||||
}
|
||||
else if (type == RC6) {
|
||||
irsend.sendRC6(value, bits);
|
||||
}
|
||||
else {
|
||||
Serial.print(label);
|
||||
Serial.println("Bad type!");
|
||||
}
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type == results.decode_type && value == results.value && bits == results.bits) {
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
else {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test raw send or receive. This is similar to the test method,
|
||||
// except it send/receives raw data.
|
||||
void testRaw(char *label, unsigned int *rawbuf, int rawlen) {
|
||||
if (mode == SENDER) {
|
||||
Serial.println(label);
|
||||
irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */);
|
||||
delay(200);
|
||||
}
|
||||
else if (mode == RECEIVER ) {
|
||||
irrecv.resume(); // Receive the next value
|
||||
unsigned long max_time = millis() + 30000;
|
||||
Serial.print(label);
|
||||
|
||||
// Wait for decode or timeout
|
||||
while (!irrecv.decode(&results)) {
|
||||
if (millis() > max_time) {
|
||||
Serial.println("Timeout receiving data");
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Received length has extra first element for gap
|
||||
if (rawlen != results.rawlen - 1) {
|
||||
Serial.print("Bad raw length ");
|
||||
Serial.println(results.rawlen, DEC);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < rawlen; i++) {
|
||||
long got = results.rawbuf[i+1] * USECPERTICK;
|
||||
// Adjust for extra duration of marks
|
||||
if (i % 2 == 0) {
|
||||
got -= MARK_EXCESS;
|
||||
}
|
||||
else {
|
||||
got += MARK_EXCESS;
|
||||
}
|
||||
// See if close enough, within 25%
|
||||
if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) {
|
||||
Serial.println(": BAD");
|
||||
dump(&results);
|
||||
mode = ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
Serial.println (": OK");
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(20);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the raw data corresponding to NEC 0x12345678
|
||||
unsigned int sendbuf[] = { /* NEC format */
|
||||
9000, 4500,
|
||||
560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */
|
||||
560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */
|
||||
560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */
|
||||
560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */
|
||||
560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */
|
||||
560};
|
||||
|
||||
void loop() {
|
||||
if (mode == SENDER) {
|
||||
delay(2000); // Delay for more than gap to give receiver a better chance to sync.
|
||||
}
|
||||
else if (mode == RECEIVER) {
|
||||
waitForGap(1000);
|
||||
}
|
||||
else if (mode == ERROR) {
|
||||
// Light up for 5 seconds for error
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(5000);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
mode = RECEIVER; // Try again
|
||||
return;
|
||||
}
|
||||
|
||||
// The test suite.
|
||||
test("SONY1", SONY, 0x123, 12);
|
||||
test("SONY2", SONY, 0x000, 12);
|
||||
test("SONY3", SONY, 0xfff, 12);
|
||||
test("SONY4", SONY, 0x12345, 20);
|
||||
test("SONY5", SONY, 0x00000, 20);
|
||||
test("SONY6", SONY, 0xfffff, 20);
|
||||
test("NEC1", NEC, 0x12345678, 32);
|
||||
test("NEC2", NEC, 0x00000000, 32);
|
||||
test("NEC3", NEC, 0xffffffff, 32);
|
||||
test("NEC4", NEC, REPEAT, 32);
|
||||
test("RC51", RC5, 0x12345678, 32);
|
||||
test("RC52", RC5, 0x0, 32);
|
||||
test("RC53", RC5, 0xffffffff, 32);
|
||||
test("RC61", RC6, 0x12345678, 32);
|
||||
test("RC62", RC6, 0x0, 32);
|
||||
test("RC63", RC6, 0xffffffff, 32);
|
||||
|
||||
// Tests of raw sending and receiving.
|
||||
// First test sending raw and receiving raw.
|
||||
// Then test sending raw and receiving decoded NEC
|
||||
// Then test sending NEC and receiving raw
|
||||
testRaw("RAW1", sendbuf, 67);
|
||||
if (mode == SENDER) {
|
||||
testRaw("RAW2", sendbuf, 67);
|
||||
test("RAW3", NEC, 0x12345678, 32);
|
||||
}
|
||||
else {
|
||||
test("RAW2", NEC, 0x12345678, 32);
|
||||
testRaw("RAW3", sendbuf, 67);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
|
||||
* An IR LED must be connected to Arduino PWM pin 3.
|
||||
* Version 0.1 July, 2009
|
||||
* Copyright 2009 Ken Shirriff
|
||||
* http://arcfn.com
|
||||
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
|
||||
*/
|
||||
#include <IRremote.h>
|
||||
|
||||
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
|
||||
#define PanasonicPower 0x100BCBD // Panasonic Power button
|
||||
|
||||
#define JVCPower 0xC5E8
|
||||
|
||||
IRsend irsend;
|
||||
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void loop() {
|
||||
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
|
||||
|
||||
irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat
|
||||
delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information
|
||||
irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat
|
||||
delayMicroseconds(50);
|
||||
}
|
||||
50
Projects/libraries/Installed_libs/IRRemote/keywords.txt
Executable file
50
Projects/libraries/Installed_libs/IRRemote/keywords.txt
Executable file
@@ -0,0 +1,50 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For IRremote
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
decode_results KEYWORD1
|
||||
IRrecv KEYWORD1
|
||||
IRsend KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
blink13 KEYWORD2
|
||||
decode KEYWORD2
|
||||
enableIRIn KEYWORD2
|
||||
resume KEYWORD2
|
||||
enableIROut KEYWORD2
|
||||
sendNEC KEYWORD2
|
||||
sendSony KEYWORD2
|
||||
sendSanyo KEYWORD2
|
||||
sendMitsubishi KEYWORD2
|
||||
sendRaw KEYWORD2
|
||||
sendRC5 KEYWORD2
|
||||
sendRC6 KEYWORD2
|
||||
sendDISH KEYWORD2
|
||||
sendSharp KEYWORD2
|
||||
sendPanasonic KEYWORD2
|
||||
sendJVC KEYWORD2
|
||||
|
||||
#
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
NEC LITERAL1
|
||||
SONY LITERAL1
|
||||
SANYO LITERAL1
|
||||
MITSUBISHI LITERAL1
|
||||
RC5 LITERAL1
|
||||
RC6 LITERAL1
|
||||
DISH LITERAL1
|
||||
SHARP LITERAL1
|
||||
PANASONIC LITERAL1
|
||||
JVC LITERAL1
|
||||
UNKNOWN LITERAL1
|
||||
REPEAT LITERAL1
|
||||
14
Projects/libraries/Installed_libs/IRRemote/readme
Executable file
14
Projects/libraries/Installed_libs/IRRemote/readme
Executable file
@@ -0,0 +1,14 @@
|
||||
This is the IRremote library for the Arduino.
|
||||
|
||||
To download from github (http://github.com/shirriff/Arduino-IRremote), click on the "Downloads" link in the upper right, click "Download as zip", and get a zip file. Unzip it and rename the directory shirriff-Arduino-IRremote-nnn to IRremote
|
||||
|
||||
To install, move the downloaded IRremote directory to:
|
||||
arduino-1.x/libraries/IRremote
|
||||
where arduino-1.x is your Arduino installation directory
|
||||
|
||||
After installation you should have files such as:
|
||||
arduino-1.x/libraries/IRremote/IRremote.cpp
|
||||
|
||||
For details on the library see the Wiki on github or the blog post http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
|
||||
|
||||
Copyright 2009-2012 Ken Shirriff
|
||||
1
Projects/libraries/Installed_libs/JoystickController/.gitignore
vendored
Executable file
1
Projects/libraries/Installed_libs/JoystickController/.gitignore
vendored
Executable file
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "JoystickController.h"
|
||||
|
||||
JoystickController controller;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
controller.update();
|
||||
|
||||
if (controller.selectButtonPressed()){
|
||||
Serial.println("S");
|
||||
}
|
||||
|
||||
if (controller.upButtonPressed()){
|
||||
Serial.println("U");
|
||||
}
|
||||
|
||||
if (controller.downButtonPressed()){
|
||||
Serial.println("D");
|
||||
}
|
||||
|
||||
if (controller.leftButtonPressed()){
|
||||
Serial.println("L");
|
||||
}
|
||||
|
||||
if (controller.rightButtonPressed()){
|
||||
Serial.println("R");
|
||||
}
|
||||
|
||||
int direct = controller.getDirection();
|
||||
|
||||
switch (direct){
|
||||
case JoystickController::DIRECTION_UP:
|
||||
Serial.println("UP");
|
||||
break;
|
||||
case JoystickController::DIRECTION_UP_RIGHT:
|
||||
Serial.println("UP-RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_RIGHT:
|
||||
Serial.println("RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN_RIGHT:
|
||||
Serial.println("DOWN-RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN:
|
||||
Serial.println("DOWN");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN_LEFT:
|
||||
Serial.println("DOWN-LEFT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_LEFT:
|
||||
Serial.println("LEFT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_UP_LEFT:
|
||||
Serial.println("UP-LEFT");
|
||||
break;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
184
Projects/libraries/Installed_libs/JoystickController/JoystickController.cpp
Executable file
184
Projects/libraries/Installed_libs/JoystickController/JoystickController.cpp
Executable file
@@ -0,0 +1,184 @@
|
||||
#include "Arduino.h"
|
||||
#include "JoystickController.h"
|
||||
|
||||
enum PINS{
|
||||
PIN_ANALOG_X = 0,
|
||||
PIN_ANALOG_Y = 1,
|
||||
PIN_BUTTON_SELECT = 2,
|
||||
PIN_BUTTON_UP = 4,
|
||||
PIN_BUTTON_DOWN = 5,
|
||||
PIN_BUTTON_LEFT = 6,
|
||||
PIN_BUTTON_RIGHT = 3
|
||||
};
|
||||
|
||||
JoystickController::JoystickController(int low, int high){
|
||||
_threshouldLow = low;
|
||||
_threshouldHigh = high;
|
||||
this->_setup();
|
||||
}
|
||||
|
||||
void JoystickController::update(){
|
||||
this->_reset();
|
||||
this->_updateDirection();
|
||||
this->_updateButtons();
|
||||
}
|
||||
|
||||
int JoystickController::getDirection(){
|
||||
return _direction;
|
||||
}
|
||||
|
||||
bool JoystickController::selectButtonPressed(){
|
||||
return _selectButtonPressed;
|
||||
}
|
||||
|
||||
bool JoystickController::upButtonPressed(){
|
||||
return _upButtonPressed;
|
||||
}
|
||||
|
||||
bool JoystickController::downButtonPressed(){
|
||||
return _downButtonPressed;
|
||||
}
|
||||
|
||||
bool JoystickController::leftButtonPressed(){
|
||||
return _leftButtonPressed;
|
||||
}
|
||||
|
||||
bool JoystickController::rightButtonPressed(){
|
||||
return _rightButtonPressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected.
|
||||
*/
|
||||
void JoystickController::_reset(){
|
||||
_direction = DIRECTION_NONE;
|
||||
_selectButtonPressed = false;
|
||||
_upButtonPressed = false;
|
||||
_downButtonPressed = false;
|
||||
_leftButtonPressed = false;
|
||||
_rightButtonPressed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected.
|
||||
*/
|
||||
void JoystickController::_setup(){
|
||||
pinMode(PIN_BUTTON_SELECT, INPUT);
|
||||
digitalWrite(PIN_BUTTON_SELECT, HIGH);
|
||||
|
||||
pinMode(PIN_BUTTON_UP, INPUT);
|
||||
digitalWrite(PIN_BUTTON_UP, HIGH);
|
||||
|
||||
pinMode(PIN_BUTTON_DOWN, INPUT);
|
||||
digitalWrite(PIN_BUTTON_DOWN, HIGH);
|
||||
|
||||
pinMode(PIN_BUTTON_LEFT, INPUT);
|
||||
digitalWrite(PIN_BUTTON_LEFT, HIGH);
|
||||
|
||||
pinMode(PIN_BUTTON_RIGHT, INPUT);
|
||||
digitalWrite(PIN_BUTTON_RIGHT, HIGH);
|
||||
|
||||
this->_reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected.
|
||||
*/
|
||||
void JoystickController::_updateDirection(){
|
||||
const int NONE = 0;
|
||||
const int POSITIVE = 1;
|
||||
const int NEGATIVE = -1;
|
||||
|
||||
int x = analogRead(PIN_ANALOG_X);
|
||||
int y = analogRead(PIN_ANALOG_Y);
|
||||
|
||||
int directX = NONE;
|
||||
int directY = NONE;
|
||||
|
||||
if (x < _threshouldLow){
|
||||
directX = NEGATIVE;
|
||||
}
|
||||
|
||||
if (x > _threshouldHigh){
|
||||
directX = POSITIVE;
|
||||
}
|
||||
|
||||
if (y < _threshouldLow){
|
||||
directY = NEGATIVE;
|
||||
}
|
||||
|
||||
if (y > _threshouldHigh){
|
||||
directY = POSITIVE;
|
||||
}
|
||||
|
||||
if (directX == NONE){
|
||||
if (directY == POSITIVE){
|
||||
_direction = DIRECTION_UP;
|
||||
}
|
||||
if (directY == NEGATIVE){
|
||||
_direction = DIRECTION_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (directX == POSITIVE){
|
||||
if (directY == NONE){
|
||||
_direction = DIRECTION_RIGHT;
|
||||
}
|
||||
if (directY == POSITIVE){
|
||||
_direction = DIRECTION_UP_RIGHT;
|
||||
}
|
||||
if (directY == NEGATIVE){
|
||||
_direction = DIRECTION_DOWN_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
if (directX == NEGATIVE){
|
||||
if (directY == NONE){
|
||||
_direction = DIRECTION_LEFT;
|
||||
}
|
||||
if (directY == POSITIVE){
|
||||
_direction = DIRECTION_UP_LEFT;
|
||||
}
|
||||
if (directY == NEGATIVE){
|
||||
_direction = DIRECTION_DOWN_LEFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected.
|
||||
*/
|
||||
void JoystickController::_updateButtons(){
|
||||
int S = digitalRead(PIN_BUTTON_SELECT);
|
||||
int U = digitalRead(PIN_BUTTON_UP);
|
||||
int D = digitalRead(PIN_BUTTON_DOWN);
|
||||
int L = digitalRead(PIN_BUTTON_LEFT);
|
||||
int R = digitalRead(PIN_BUTTON_RIGHT);
|
||||
|
||||
if (this->_buttonPressed(S)){
|
||||
_selectButtonPressed = true;
|
||||
}
|
||||
|
||||
if (this->_buttonPressed(U)){
|
||||
_upButtonPressed = true;
|
||||
}
|
||||
|
||||
if (this->_buttonPressed(D)){
|
||||
_downButtonPressed = true;
|
||||
}
|
||||
|
||||
if (this->_buttonPressed(L)){
|
||||
_leftButtonPressed = true;
|
||||
}
|
||||
|
||||
if (this->_buttonPressed(R)){
|
||||
_rightButtonPressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected.
|
||||
*/
|
||||
bool JoystickController::_buttonPressed(int state){
|
||||
return (state == LOW);
|
||||
}
|
||||
71
Projects/libraries/Installed_libs/JoystickController/JoystickController.h
Executable file
71
Projects/libraries/Installed_libs/JoystickController/JoystickController.h
Executable file
@@ -0,0 +1,71 @@
|
||||
#ifndef __JOYSTICKCONTROLLER_H__
|
||||
#define __JOYSTICKCONTROLLER_H__
|
||||
|
||||
class JoystickController{
|
||||
protected:
|
||||
static const int DEFAULT_LOW = 490;
|
||||
static const int DEFAULT_HIGH = 530;
|
||||
|
||||
int _threshouldLow;
|
||||
int _threshouldHigh;
|
||||
|
||||
int _direction;
|
||||
bool _selectButtonPressed;
|
||||
bool _upButtonPressed;
|
||||
bool _downButtonPressed;
|
||||
bool _leftButtonPressed;
|
||||
bool _rightButtonPressed;
|
||||
|
||||
void _setup();
|
||||
void _reset();
|
||||
void _updateDirection();
|
||||
void _updateButtons();
|
||||
bool _buttonPressed(int state);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Directions in the integer format.
|
||||
*/
|
||||
static const int DIRECTION_NONE = 0;
|
||||
static const int DIRECTION_UP = 1;
|
||||
static const int DIRECTION_UP_RIGHT = 2;
|
||||
static const int DIRECTION_RIGHT = 3;
|
||||
static const int DIRECTION_DOWN_RIGHT = 4;
|
||||
static const int DIRECTION_DOWN = 5;
|
||||
static const int DIRECTION_DOWN_LEFT = 6;
|
||||
static const int DIRECTION_LEFT = 7;
|
||||
static const int DIRECTION_UP_LEFT = 8;
|
||||
|
||||
/**
|
||||
* Constructor. The first argument specifies the lower threshould value for the directional key pad,
|
||||
* below which the controller is assumed to set left/down in the horizontal/vertical direction.
|
||||
* The second argument specifies the upper threshould value,
|
||||
* above which the controller is assumed to set right/up in the horizontal/vertical direction.
|
||||
*/
|
||||
JoystickController(int low = DEFAULT_LOW, int high = DEFAULT_HIGH);
|
||||
|
||||
/**
|
||||
* Must get called in the main loop.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Returns the current direction in the integer format.
|
||||
*/
|
||||
int getDirection();
|
||||
|
||||
/**
|
||||
* Returns true if a button is being pressed, otherwise false.
|
||||
*/
|
||||
bool upButtonPressed();
|
||||
bool downButtonPressed();
|
||||
bool leftButtonPressed();
|
||||
bool rightButtonPressed();
|
||||
|
||||
/**
|
||||
* Returns true if the select button (directional keypad) is being pressed, otherwise false.
|
||||
*/
|
||||
bool selectButtonPressed();
|
||||
};
|
||||
|
||||
#endif
|
||||
7
Projects/libraries/Installed_libs/JoystickController/LICENSE
Executable file
7
Projects/libraries/Installed_libs/JoystickController/LICENSE
Executable file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2012 boreal-kiss.com
|
||||
|
||||
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.
|
||||
120
Projects/libraries/Installed_libs/JoystickController/README.md
Executable file
120
Projects/libraries/Installed_libs/JoystickController/README.md
Executable file
@@ -0,0 +1,120 @@
|
||||
# JoystickController
|
||||
|
||||
Fully compatible with SparkFun's [Arduino joystick shield](https://www.sparkfun.com/products/9760?). The library lets you easily fetch the current status of the joystick (demo video is [here](https://vimeo.com/49010406)). Implementation is quite simple;
|
||||
|
||||
JoystickController(int low = DEFAULT_LOW, int high = DEFAULT_HIGH)
|
||||
|
||||
is a constructor. The first argument specifies the lower threshold value for the directional key pad, below which the controller is assumed to set left/down in the horizontal/vertical direction. The second argument specifies the upper threshold value, above which the controller is assumed to set right/up in the horizontal/vertical direction. If arguments are not specified, the following default values will be used:
|
||||
|
||||
static const int DEFAULT_LOW = 490;
|
||||
static const int DEFAULT_HIGH = 530;
|
||||
|
||||
For more information about the threshold see the following article; [How do I find the current direction of the joystick?](http://www.sparkfun.com/tutorials/171#direction)
|
||||
|
||||
void update()
|
||||
|
||||
must get called in the main loop in order for the library to communicate with the joystick.
|
||||
|
||||
int getDirection()
|
||||
|
||||
returns the current direction of the directional keypad as integer values that are defined as class static variables:
|
||||
|
||||
static const int DIRECTION_NONE = 0;
|
||||
static const int DIRECTION_UP = 1;
|
||||
static const int DIRECTION_UP_RIGHT = 2;
|
||||
static const int DIRECTION_RIGHT = 3;
|
||||
static const int DIRECTION_DOWN_RIGHT = 4;
|
||||
static const int DIRECTION_DOWN = 5;
|
||||
static const int DIRECTION_DOWN_LEFT = 6;
|
||||
static const int DIRECTION_LEFT = 7;
|
||||
static const int DIRECTION_UP_LEFT = 8;
|
||||
|
||||
Finally buttons' status can be fetched from the following functions:
|
||||
|
||||
bool upButtonPressed()
|
||||
bool downButtonPressed()
|
||||
bool leftButtonPressed()
|
||||
bool rightButtonPressed()
|
||||
bool selectButtonPressed()
|
||||
|
||||
They return true if a button is being pressed, otherwise false.
|
||||
|
||||
## Example
|
||||
|
||||
Here is a simple example for the library implementation.
|
||||
|
||||
#include "JoystickController.h"
|
||||
|
||||
JoystickController controller;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
controller.update();
|
||||
|
||||
if (controller.selectButtonPressed()){
|
||||
Serial.println("S");
|
||||
}
|
||||
|
||||
if (controller.upButtonPressed()){
|
||||
Serial.println("U");
|
||||
}
|
||||
|
||||
if (controller.downButtonPressed()){
|
||||
Serial.println("D");
|
||||
}
|
||||
|
||||
if (controller.leftButtonPressed()){
|
||||
Serial.println("L");
|
||||
}
|
||||
|
||||
if (controller.rightButtonPressed()){
|
||||
Serial.println("R");
|
||||
}
|
||||
|
||||
int direct = controller.getDirection();
|
||||
|
||||
switch (direct){
|
||||
case JoystickController::DIRECTION_UP:
|
||||
Serial.println("UP");
|
||||
break;
|
||||
case JoystickController::DIRECTION_UP_RIGHT:
|
||||
Serial.println("UP-RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_RIGHT:
|
||||
Serial.println("RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN_RIGHT:
|
||||
Serial.println("DOWN-RIGHT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN:
|
||||
Serial.println("DOWN");
|
||||
break;
|
||||
case JoystickController::DIRECTION_DOWN_LEFT:
|
||||
Serial.println("DOWN-LEFT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_LEFT:
|
||||
Serial.println("LEFT");
|
||||
break;
|
||||
case JoystickController::DIRECTION_UP_LEFT:
|
||||
Serial.println("UP-LEFT");
|
||||
break;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
## Related articles
|
||||
|
||||
* [Arduino joystick controller library](http://blog.boreal-kiss.net/2012/09/07/arduino-joystick-controller-library/)
|
||||
|
||||
## License
|
||||
|
||||
This project is provided under the terms of the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
|
||||
## Contact
|
||||
|
||||
* [http://blog.boreal-kiss.net/](http://blog.boreal-kiss.net/)
|
||||
* [http://twitter.com/borealkiss](http://twitter.com/borealkiss)
|
||||
35
Projects/libraries/Installed_libs/JoystickController/keywords.txt
Executable file
35
Projects/libraries/Installed_libs/JoystickController/keywords.txt
Executable file
@@ -0,0 +1,35 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map for JoystickController
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
JoystickController KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
update KEYWORD2
|
||||
getDirection KEYWORD2
|
||||
selectButtonPressed KEYWORD2
|
||||
upButtonPressed KEYWORD2
|
||||
downButtonPressed KEYWORD2
|
||||
leftButtonPressed KEYWORD2
|
||||
rightButtonPressed KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
DIRECTION_NONE LITERAL1
|
||||
DIRECTION_UP LITERAL1
|
||||
DIRECTION_UP_RIGHT LITERAL1
|
||||
DIRECTION_RIGHT LITERAL1
|
||||
DIRECTION_DOWN_RIGHT LITERAL1
|
||||
DIRECTION_DOWN LITERAL1
|
||||
DIRECTION_DOWN_LEFT LITERAL1
|
||||
DIRECTION_LEFT LITERAL1
|
||||
DIRECTION_UP_LEFT LITERAL1
|
||||
293
Projects/libraries/Installed_libs/Keypad/Keypad.cpp
Executable file
293
Projects/libraries/Installed_libs/Keypad/Keypad.cpp
Executable file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.cpp
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
// <<constructor>> Allows custom keymap, pin configuration, and keypad sizes.
|
||||
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) {
|
||||
rowPins = row;
|
||||
columnPins = col;
|
||||
sizeKpd.rows = numRows;
|
||||
sizeKpd.columns = numCols;
|
||||
|
||||
begin(userKeymap);
|
||||
|
||||
setDebounceTime(10);
|
||||
setHoldTime(500);
|
||||
keypadEventListener = 0;
|
||||
|
||||
startTime = 0;
|
||||
single_key = false;
|
||||
}
|
||||
|
||||
// Let the user define a keymap - assume the same row/column count as defined in constructor
|
||||
void Keypad::begin(char *userKeymap) {
|
||||
keymap = userKeymap;
|
||||
}
|
||||
|
||||
// Returns a single key only. Retained for backwards compatibility.
|
||||
char Keypad::getKey() {
|
||||
single_key = true;
|
||||
|
||||
if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED))
|
||||
return key[0].kchar;
|
||||
|
||||
single_key = false;
|
||||
|
||||
return NO_KEY;
|
||||
}
|
||||
|
||||
// Populate the key list.
|
||||
bool Keypad::getKeys() {
|
||||
bool keyActivity = false;
|
||||
|
||||
// Limit how often the keypad is scanned. This makes the loop() run 10 times as fast.
|
||||
if ( (millis()-startTime)>debounceTime ) {
|
||||
scanKeys();
|
||||
keyActivity = updateList();
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
return keyActivity;
|
||||
}
|
||||
|
||||
// Private : Hardware scan
|
||||
void Keypad::scanKeys() {
|
||||
// Re-intialize the row pins. Allows sharing these pins with other hardware.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
pin_mode(rowPins[r],INPUT_PULLUP);
|
||||
}
|
||||
|
||||
// bitMap stores ALL the keys that are being pressed.
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
pin_mode(columnPins[c],OUTPUT);
|
||||
pin_write(columnPins[c], LOW); // Begin column pulse output.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
bitWrite(bitMap[r], c, !pin_read(rowPins[r])); // keypress is active low so invert to high.
|
||||
}
|
||||
// Set pin to high impedance input. Effectively ends column pulse.
|
||||
pin_write(columnPins[c],HIGH);
|
||||
pin_mode(columnPins[c],INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the list without rearranging the keys. Returns true if any keys on the list changed state.
|
||||
bool Keypad::updateList() {
|
||||
|
||||
bool anyActivity = false;
|
||||
|
||||
// Delete any IDLE keys
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kstate==IDLE) {
|
||||
key[i].kchar = NO_KEY;
|
||||
key[i].kcode = -1;
|
||||
key[i].stateChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new keys to empty slots in the key list.
|
||||
for (byte r=0; r<sizeKpd.rows; r++) {
|
||||
for (byte c=0; c<sizeKpd.columns; c++) {
|
||||
boolean button = bitRead(bitMap[r],c);
|
||||
char keyChar = keymap[r * sizeKpd.columns + c];
|
||||
int keyCode = r * sizeKpd.columns + c;
|
||||
int idx = findInList (keyCode);
|
||||
// Key is already on the list so set its next state.
|
||||
if (idx > -1) {
|
||||
nextKeyState(idx, button);
|
||||
}
|
||||
// Key is NOT on the list so add it.
|
||||
if ((idx == -1) && button) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar==NO_KEY) { // Find an empty slot or don't add key to list.
|
||||
key[i].kchar = keyChar;
|
||||
key[i].kcode = keyCode;
|
||||
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
|
||||
nextKeyState (i, button);
|
||||
break; // Don't fill all the empty slots with the same key.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report if the user changed the state of any key.
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].stateChanged) anyActivity = true;
|
||||
}
|
||||
|
||||
return anyActivity;
|
||||
}
|
||||
|
||||
// Private
|
||||
// This function is a state machine but is also used for debouncing the keys.
|
||||
void Keypad::nextKeyState(byte idx, boolean button) {
|
||||
key[idx].stateChanged = false;
|
||||
|
||||
switch (key[idx].kstate) {
|
||||
case IDLE:
|
||||
if (button==CLOSED) {
|
||||
transitionTo (idx, PRESSED);
|
||||
holdTimer = millis(); } // Get ready for next HOLD state.
|
||||
break;
|
||||
case PRESSED:
|
||||
if ((millis()-holdTimer)>holdTime) // Waiting for a key HOLD...
|
||||
transitionTo (idx, HOLD);
|
||||
else if (button==OPEN) // or for a key to be RELEASED.
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case HOLD:
|
||||
if (button==OPEN)
|
||||
transitionTo (idx, RELEASED);
|
||||
break;
|
||||
case RELEASED:
|
||||
transitionTo (idx, IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// New in 2.1
|
||||
bool Keypad::isPressed(char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if ( key[i].kchar == keyChar ) {
|
||||
if ( (key[i].kstate == PRESSED) && key[i].stateChanged )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // Not pressed.
|
||||
}
|
||||
|
||||
// Search by character for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (char keyChar) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kchar == keyChar) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Search by code for a key in the list of active keys.
|
||||
// Returns -1 if not found or the index into the list of active keys.
|
||||
int Keypad::findInList (int keyCode) {
|
||||
for (byte i=0; i<LIST_MAX; i++) {
|
||||
if (key[i].kcode == keyCode) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// New in 2.0
|
||||
char Keypad::waitForKey() {
|
||||
char waitKey = NO_KEY;
|
||||
while( (waitKey = getKey()) == NO_KEY ); // Block everything while waiting for a keypress.
|
||||
return waitKey;
|
||||
}
|
||||
|
||||
// Backwards compatibility function.
|
||||
KeyState Keypad::getState() {
|
||||
return key[0].kstate;
|
||||
}
|
||||
|
||||
// The end user can test for any changes in state before deciding
|
||||
// if any variables, etc. needs to be updated in their code.
|
||||
bool Keypad::keyStateChanged() {
|
||||
return key[0].stateChanged;
|
||||
}
|
||||
|
||||
// The number of keys on the key list, key[LIST_MAX], equals the number
|
||||
// of bytes in the key list divided by the number of bytes in a Key object.
|
||||
byte Keypad::numKeys() {
|
||||
return sizeof(key)/sizeof(Key);
|
||||
}
|
||||
|
||||
// Minimum debounceTime is 1 mS. Any lower *will* slow down the loop().
|
||||
void Keypad::setDebounceTime(uint debounce) {
|
||||
debounce<1 ? debounceTime=1 : debounceTime=debounce;
|
||||
}
|
||||
|
||||
void Keypad::setHoldTime(uint hold) {
|
||||
holdTime = hold;
|
||||
}
|
||||
|
||||
void Keypad::addEventListener(void (*listener)(char)){
|
||||
keypadEventListener = listener;
|
||||
}
|
||||
|
||||
void Keypad::transitionTo(byte idx, KeyState nextState) {
|
||||
key[idx].kstate = nextState;
|
||||
key[idx].stateChanged = true;
|
||||
|
||||
// Sketch used the getKey() function.
|
||||
// Calls keypadEventListener only when the first key in slot 0 changes state.
|
||||
if (single_key) {
|
||||
if ( (keypadEventListener!=NULL) && (idx==0) ) {
|
||||
keypadEventListener(key[0].kchar);
|
||||
}
|
||||
}
|
||||
// Sketch used the getKeys() function.
|
||||
// Calls keypadEventListener on any key that changes state.
|
||||
else {
|
||||
if (keypadEventListener!=NULL) {
|
||||
keypadEventListener(key[idx].kchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added decision logic to compile WProgram.h or Arduino.h
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Every time a state changes the keypadEventListener will trigger, if set.
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime. setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
156
Projects/libraries/Installed_libs/Keypad/Keypad.h
Executable file
156
Projects/libraries/Installed_libs/Keypad/Keypad.h
Executable file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
||
|
||||
|| @file Keypad.h
|
||||
|| @version 3.1
|
||||
|| @author Mark Stanley, Alexander Brevig
|
||||
|| @contact mstanley@technologist.com, alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | This library provides a simple interface for using matrix
|
||||
|| | keypads. It supports multiple keypresses while maintaining
|
||||
|| | backwards compatibility with the old single key library.
|
||||
|| | It also supports user selectable pins and definable keymaps.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEYPAD_H
|
||||
#define KEYPAD_H
|
||||
|
||||
#include "utility/Key.h"
|
||||
|
||||
// Arduino versioning.
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
// bperrybap - Thanks for a well reasoned argument and the following macro(s).
|
||||
// See http://arduino.cc/forum/index.php/topic,142041.msg1069480.html#msg1069480
|
||||
#ifndef INPUT_PULLUP
|
||||
#warning "Using pinMode() INPUT_PULLUP AVR emulation"
|
||||
#define INPUT_PULLUP 0x2
|
||||
#define pinMode(_pin, _mode) _mypinMode(_pin, _mode)
|
||||
#define _mypinMode(_pin, _mode) \
|
||||
do { \
|
||||
if(_mode == INPUT_PULLUP) \
|
||||
pinMode(_pin, INPUT); \
|
||||
digitalWrite(_pin, 1); \
|
||||
if(_mode != INPUT_PULLUP) \
|
||||
pinMode(_pin, _mode); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef char KeypadEvent;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0
|
||||
// by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :)
|
||||
typedef struct {
|
||||
byte rows;
|
||||
byte columns;
|
||||
} KeypadSize;
|
||||
|
||||
#define LIST_MAX 10 // Max number of keys on the active list.
|
||||
#define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns)
|
||||
#define makeKeymap(x) ((char*)x)
|
||||
|
||||
|
||||
//class Keypad : public Key, public HAL_obj {
|
||||
class Keypad : public Key {
|
||||
public:
|
||||
|
||||
Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
|
||||
|
||||
virtual void pin_mode(byte pinNum, byte mode) { pinMode(pinNum, mode); }
|
||||
virtual void pin_write(byte pinNum, boolean level) { digitalWrite(pinNum, level); }
|
||||
virtual int pin_read(byte pinNum) { return digitalRead(pinNum); }
|
||||
|
||||
uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns.
|
||||
Key key[LIST_MAX];
|
||||
unsigned long holdTimer;
|
||||
|
||||
char getKey();
|
||||
bool getKeys();
|
||||
KeyState getState();
|
||||
void begin(char *userKeymap);
|
||||
bool isPressed(char keyChar);
|
||||
void setDebounceTime(uint);
|
||||
void setHoldTime(uint);
|
||||
void addEventListener(void (*listener)(char));
|
||||
int findInList(char keyChar);
|
||||
int findInList(int keyCode);
|
||||
char waitForKey();
|
||||
bool keyStateChanged();
|
||||
byte numKeys();
|
||||
|
||||
private:
|
||||
unsigned long startTime;
|
||||
char *keymap;
|
||||
byte *rowPins;
|
||||
byte *columnPins;
|
||||
KeypadSize sizeKpd;
|
||||
uint debounceTime;
|
||||
uint holdTime;
|
||||
bool single_key;
|
||||
|
||||
void scanKeys();
|
||||
bool updateList();
|
||||
void nextKeyState(byte n, boolean button);
|
||||
void transitionTo(byte n, KeyState nextState);
|
||||
void (*keypadEventListener)(char);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible)
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
|
||||
|| | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects.
|
||||
|| | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys.
|
||||
|| | 2.0 2011-12-29 - Mark Stanley : Added waitForKey().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState().
|
||||
|| | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite.
|
||||
|| | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile,
|
||||
|| | WProgram.h or Arduino.h.
|
||||
|| | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes
|
||||
|| | the keypadEventListener will trigger, if set
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of
|
||||
|| | microseconds before a HOLD state triggers
|
||||
|| | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo
|
||||
|| | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable
|
||||
|| | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime()
|
||||
|| | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener
|
||||
|| | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing
|
||||
|| | 1.2 2009-05-09 - Alexander Brevig : Changed getKey()
|
||||
|| | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private
|
||||
|| | 1.0 2007-XX-XX - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
@@ -0,0 +1,37 @@
|
||||
/* @file CustomKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates changing the keypad size and key values.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 4; //four columns
|
||||
//define the cymbols on the buttons of the keypads
|
||||
char hexaKeys[ROWS][COLS] = {
|
||||
{'0','1','2','3'},
|
||||
{'4','5','6','7'},
|
||||
{'8','9','A','B'},
|
||||
{'C','D','E','F'}
|
||||
};
|
||||
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad
|
||||
|
||||
//initialize an instance of class NewKeypad
|
||||
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char customKey = customKeypad.getKey();
|
||||
|
||||
if (customKey){
|
||||
Serial.println(customKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/* @file DynamicKeypad.pde
|
||||
|| @version 1.2
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| 07/11/12 - Re-modified (from DynamicKeypadJoe2) to use direct-connect kpds
|
||||
|| 02/28/12 - Modified to use I2C i/o G. D. (Joe) Young
|
||||
||
|
||||
||
|
||||
|| @dificulty: Intermediate
|
||||
||
|
||||
|| @description
|
||||
|| | This is a demonstration of keypadEvents. It's used to switch between keymaps
|
||||
|| | while using only one keypad. The main concepts being demonstrated are:
|
||||
|| |
|
||||
|| | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding.
|
||||
|| | How to use setHoldTime() and why.
|
||||
|| | Making more than one thing happen with the same key.
|
||||
|| | Assigning and changing keymaps on the fly.
|
||||
|| |
|
||||
|| | Another useful feature is also included with this demonstration although
|
||||
|| | it's not really one of the concepts that I wanted to show you. If you look
|
||||
|| | at the code in the PRESSED event you will see that the first section of that
|
||||
|| | code is used to scroll through three different letters on each key. For
|
||||
|| | example, pressing the '2' key will step through the letters 'd', 'e' and 'f'.
|
||||
|| |
|
||||
|| |
|
||||
|| | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding
|
||||
|| | Very simply, the PRESSED event occurs imediately upon detecting a pressed
|
||||
|| | key and will not happen again until after a RELEASED event. When the HOLD
|
||||
|| | event fires it always falls between PRESSED and RELEASED. However, it will
|
||||
|| | only occur if a key has been pressed for longer than the setHoldTime() interval.
|
||||
|| |
|
||||
|| | How to use setHoldTime() and why
|
||||
|| | Take a look at keypad.setHoldTime(500) in the code. It is used to set the
|
||||
|| | time delay between a PRESSED event and the start of a HOLD event. The value
|
||||
|| | 500 is in milliseconds (mS) and is equivalent to half a second. After pressing
|
||||
|| | a key for 500mS the HOLD event will fire and any code contained therein will be
|
||||
|| | executed. This event will stay active for as long as you hold the key except
|
||||
|| | in the case of bug #1 listed above.
|
||||
|| |
|
||||
|| | Making more than one thing happen with the same key.
|
||||
|| | If you look under the PRESSED event (case PRESSED:) you will see that the '#'
|
||||
|| | is used to print a new line, Serial.println(). But take a look at the first
|
||||
|| | half of the HOLD event and you will see the same key being used to switch back
|
||||
|| | and forth between the letter and number keymaps that were created with alphaKeys[4][5]
|
||||
|| | and numberKeys[4][5] respectively.
|
||||
|| |
|
||||
|| | Assigning and changing keymaps on the fly
|
||||
|| | You will see that the '#' key has been designated to perform two different functions
|
||||
|| | depending on how long you hold it down. If you press the '#' key for less than the
|
||||
|| | setHoldTime() then it will print a new line. However, if you hold if for longer
|
||||
|| | than that it will switch back and forth between numbers and letters. You can see the
|
||||
|| | keymap changes in the HOLD event.
|
||||
|| |
|
||||
|| |
|
||||
|| | In addition...
|
||||
|| | You might notice a couple of things that you won't find in the Arduino language
|
||||
|| | reference. The first would be #include <ctype.h>. This is a standard library from
|
||||
|| | the C programming language and though I don't normally demonstrate these types of
|
||||
|| | things from outside the Arduino language reference I felt that its use here was
|
||||
|| | justified by the simplicity that it brings to this sketch.
|
||||
|| | That simplicity is provided by the two calls to isalpha(key) and isdigit(key).
|
||||
|| | The first one is used to decide if the key that was pressed is any letter from a-z
|
||||
|| | or A-Z and the second one decides if the key is any number from 0-9. The return
|
||||
|| | value from these two functions is either a zero or some positive number greater
|
||||
|| | than zero. This makes it very simple to test a key and see if it is a number or
|
||||
|| | a letter. So when you see the following:
|
||||
|| |
|
||||
|| | if (isalpha(key)) // this tests to see if your key was a letter
|
||||
|| |
|
||||
|| | And the following may be more familiar to some but it is equivalent:
|
||||
|| |
|
||||
|| | if (isalpha(key) != 0) // this tests to see if your key was a letter
|
||||
|| |
|
||||
|| | And Finally...
|
||||
|| | To better understand how the event handler affects your code you will need to remember
|
||||
|| | that it gets called only when you press, hold or release a key. However, once a key
|
||||
|| | is pressed or held then the event handler gets called at the full speed of the loop().
|
||||
|| |
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
#include <ctype.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
// Define the keymaps. The blank spot (lower left) is the space character.
|
||||
char alphaKeys[ROWS][COLS] = {
|
||||
{ 'a','d','g' },
|
||||
{ 'j','m','p' },
|
||||
{ 's','v','y' },
|
||||
{ ' ','.','#' }
|
||||
};
|
||||
|
||||
char numberKeys[ROWS][COLS] = {
|
||||
{ '1','2','3' },
|
||||
{ '4','5','6' },
|
||||
{ '7','8','9' },
|
||||
{ ' ','0','#' }
|
||||
};
|
||||
|
||||
boolean alpha = false; // Start with the numeric keypad.
|
||||
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
// Create two new keypads, one is a number pad and the other is a letter pad.
|
||||
Keypad numpad( makeKeymap(numberKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) );
|
||||
Keypad ltrpad( makeKeymap(alphaKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) );
|
||||
|
||||
|
||||
unsigned long startTime;
|
||||
const byte ledPin = 13; // Use the LED on pin 13.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
pinMode(ledPin, OUTPUT);
|
||||
digitalWrite(ledPin, LOW); // Turns the LED on.
|
||||
ltrpad.begin( makeKeymap(alphaKeys) );
|
||||
numpad.begin( makeKeymap(numberKeys) );
|
||||
ltrpad.addEventListener(keypadEvent_ltr); // Add an event listener.
|
||||
ltrpad.setHoldTime(500); // Default is 1000mS
|
||||
numpad.addEventListener(keypadEvent_num); // Add an event listener.
|
||||
numpad.setHoldTime(500); // Default is 1000mS
|
||||
}
|
||||
|
||||
char key;
|
||||
|
||||
void loop() {
|
||||
|
||||
if( alpha )
|
||||
key = ltrpad.getKey( );
|
||||
else
|
||||
key = numpad.getKey( );
|
||||
|
||||
if (alpha && millis()-startTime>100) { // Flash the LED if we are using the letter keymap.
|
||||
digitalWrite(ledPin,!digitalRead(ledPin));
|
||||
startTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
static char virtKey = NO_KEY; // Stores the last virtual key press. (Alpha keys only)
|
||||
static char physKey = NO_KEY; // Stores the last physical key press. (Alpha keys only)
|
||||
static char buildStr[12];
|
||||
static byte buildCount;
|
||||
static byte pressCount;
|
||||
|
||||
static byte kpadState;
|
||||
|
||||
// Take care of some special events.
|
||||
|
||||
void keypadEvent_ltr(KeypadEvent key) {
|
||||
// in here when in alpha mode.
|
||||
kpadState = ltrpad.getState( );
|
||||
swOnState( key );
|
||||
} // end ltrs keypad events
|
||||
|
||||
void keypadEvent_num( KeypadEvent key ) {
|
||||
// in here when using number keypad
|
||||
kpadState = numpad.getState( );
|
||||
swOnState( key );
|
||||
} // end numbers keypad events
|
||||
|
||||
void swOnState( char key ) {
|
||||
switch( kpadState ) {
|
||||
case PRESSED:
|
||||
if (isalpha(key)) { // This is a letter key so we're using the letter keymap.
|
||||
if (physKey != key) { // New key so start with the first of 3 characters.
|
||||
pressCount = 0;
|
||||
virtKey = key;
|
||||
physKey = key;
|
||||
}
|
||||
else { // Pressed the same key again...
|
||||
virtKey++; // so select the next character on that key.
|
||||
pressCount++; // Tracks how many times we press the same key.
|
||||
}
|
||||
if (pressCount > 2) { // Last character reached so cycle back to start.
|
||||
pressCount = 0;
|
||||
virtKey = key;
|
||||
}
|
||||
Serial.print(virtKey); // Used for testing.
|
||||
}
|
||||
if (isdigit(key) || key == ' ' || key == '.')
|
||||
Serial.print(key);
|
||||
if (key == '#')
|
||||
Serial.println();
|
||||
break;
|
||||
|
||||
case HOLD:
|
||||
if (key == '#') { // Toggle between keymaps.
|
||||
if (alpha == true) { // We are currently using a keymap with letters
|
||||
alpha = false; // Now we want a keymap with numbers.
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
else { // We are currently using a keymap with numbers
|
||||
alpha = true; // Now we want a keymap with letters.
|
||||
}
|
||||
}
|
||||
else { // Some key other than '#' was pressed.
|
||||
buildStr[buildCount++] = (isalpha(key)) ? virtKey : key;
|
||||
buildStr[buildCount] = '\0';
|
||||
Serial.println();
|
||||
Serial.println(buildStr);
|
||||
}
|
||||
break;
|
||||
|
||||
case RELEASED:
|
||||
if (buildCount >= sizeof(buildStr)) buildCount = 0; // Our string is full. Start fresh.
|
||||
break;
|
||||
} // end switch-case
|
||||
}// end switch on state function
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/* @file EventSerialKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates using the KeypadEvent.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'*','0','#'}
|
||||
};
|
||||
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
byte ledPin = 13;
|
||||
|
||||
boolean blink = false;
|
||||
boolean ledPin_state;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
pinMode(ledPin, OUTPUT); // Sets the digital pin as output.
|
||||
digitalWrite(ledPin, HIGH); // Turn the LED on.
|
||||
ledPin_state = digitalRead(ledPin); // Store initial LED state. HIGH when LED is on.
|
||||
keypad.addEventListener(keypadEvent); // Add an event listener for this keypad
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = keypad.getKey();
|
||||
|
||||
if (key) {
|
||||
Serial.println(key);
|
||||
}
|
||||
if (blink){
|
||||
digitalWrite(ledPin,!digitalRead(ledPin)); // Change the ledPin from Hi2Lo or Lo2Hi.
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
// Taking care of some special events.
|
||||
void keypadEvent(KeypadEvent key){
|
||||
switch (keypad.getState()){
|
||||
case PRESSED:
|
||||
if (key == '#') {
|
||||
digitalWrite(ledPin,!digitalRead(ledPin));
|
||||
ledPin_state = digitalRead(ledPin); // Remember LED state, lit or unlit.
|
||||
}
|
||||
break;
|
||||
|
||||
case RELEASED:
|
||||
if (key == '*') {
|
||||
digitalWrite(ledPin,ledPin_state); // Restore LED state from before it started blinking.
|
||||
blink = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOLD:
|
||||
if (key == '*') {
|
||||
blink = true; // Blink the LED when holding the * key.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* @file HelloKeypad.pde
|
||||
|| @version 1.0
|
||||
|| @author Alexander Brevig
|
||||
|| @contact alexanderbrevig@gmail.com
|
||||
||
|
||||
|| @description
|
||||
|| | Demonstrates the simplest use of the matrix Keypad library.
|
||||
|| #
|
||||
*/
|
||||
#include <Keypad.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'*','0','#'}
|
||||
};
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = keypad.getKey();
|
||||
|
||||
if (key){
|
||||
Serial.println(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <Keypad.h>
|
||||
|
||||
|
||||
const byte ROWS = 2; // use 4X4 keypad for both instances
|
||||
const byte COLS = 2;
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2'},
|
||||
{'3','4'}
|
||||
};
|
||||
byte rowPins[ROWS] = {5, 4}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {7, 6}; //connect to the column pinouts of the keypad
|
||||
Keypad kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
|
||||
const byte ROWSR = 2;
|
||||
const byte COLSR = 2;
|
||||
char keysR[ROWSR][COLSR] = {
|
||||
{'a','b'},
|
||||
{'c','d'}
|
||||
};
|
||||
byte rowPinsR[ROWSR] = {3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPinsR[COLSR] = {7, 6}; //connect to the column pinouts of the keypad
|
||||
Keypad kpdR( makeKeymap(keysR), rowPinsR, colPinsR, ROWSR, COLSR );
|
||||
|
||||
|
||||
const byte ROWSUR = 4;
|
||||
const byte COLSUR = 1;
|
||||
char keysUR[ROWSUR][COLSUR] = {
|
||||
{'M'},
|
||||
{'A'},
|
||||
{'R'},
|
||||
{'K'}
|
||||
};
|
||||
// Digitran keypad, bit numbers of PCF8574 i/o port
|
||||
byte rowPinsUR[ROWSUR] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPinsUR[COLSUR] = {8}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad kpdUR( makeKeymap(keysUR), rowPinsUR, colPinsUR, ROWSUR, COLSUR );
|
||||
|
||||
|
||||
void setup(){
|
||||
// Wire.begin( );
|
||||
kpdUR.begin( makeKeymap(keysUR) );
|
||||
kpdR.begin( makeKeymap(keysR) );
|
||||
kpd.begin( makeKeymap(keys) );
|
||||
Serial.begin(9600);
|
||||
Serial.println( "start" );
|
||||
}
|
||||
|
||||
//byte alternate = false;
|
||||
char key, keyR, keyUR;
|
||||
void loop(){
|
||||
|
||||
// alternate = !alternate;
|
||||
key = kpd.getKey( );
|
||||
keyUR = kpdUR.getKey( );
|
||||
keyR = kpdR.getKey( );
|
||||
|
||||
if (key){
|
||||
Serial.println(key);
|
||||
}
|
||||
if( keyR ) {
|
||||
Serial.println( keyR );
|
||||
}
|
||||
if( keyUR ) {
|
||||
Serial.println( keyUR );
|
||||
}
|
||||
}
|
||||
78
Projects/libraries/Installed_libs/Keypad/examples/MultiKey/MultiKey.ino
Executable file
78
Projects/libraries/Installed_libs/Keypad/examples/MultiKey/MultiKey.ino
Executable file
@@ -0,0 +1,78 @@
|
||||
/* @file MultiKey.ino
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | The latest version, 3.0, of the keypad library supports up to 10
|
||||
|| | active keys all being pressed at the same time. This sketch is an
|
||||
|| | example of how you can get multiple key presses from a keypad or
|
||||
|| | keyboard.
|
||||
|| #
|
||||
*/
|
||||
|
||||
#include <Keypad.h>
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'*','0','#'}
|
||||
};
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the kpd
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the kpd
|
||||
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
unsigned long loopCount;
|
||||
unsigned long startTime;
|
||||
String msg;
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
loopCount = 0;
|
||||
startTime = millis();
|
||||
msg = "";
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
loopCount++;
|
||||
if ( (millis()-startTime)>5000 ) {
|
||||
Serial.print("Average loops per second = ");
|
||||
Serial.println(loopCount/5);
|
||||
startTime = millis();
|
||||
loopCount = 0;
|
||||
}
|
||||
|
||||
// Fills kpd.key[ ] array with up-to 10 active keys.
|
||||
// Returns true if there are ANY active keys.
|
||||
if (kpd.getKeys())
|
||||
{
|
||||
for (int i=0; i<LIST_MAX; i++) // Scan the whole key list.
|
||||
{
|
||||
if ( kpd.key[i].stateChanged ) // Only find keys that have changed state.
|
||||
{
|
||||
switch (kpd.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
|
||||
case PRESSED:
|
||||
msg = " PRESSED.";
|
||||
break;
|
||||
case HOLD:
|
||||
msg = " HOLD.";
|
||||
break;
|
||||
case RELEASED:
|
||||
msg = " RELEASED.";
|
||||
break;
|
||||
case IDLE:
|
||||
msg = " IDLE.";
|
||||
}
|
||||
Serial.print("Key ");
|
||||
Serial.print(kpd.key[i].kchar);
|
||||
Serial.println(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End loop
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <Keypad.h>
|
||||
|
||||
|
||||
const byte ROWS = 4; //four rows
|
||||
const byte COLS = 3; //three columns
|
||||
char keys[ROWS][COLS] = {
|
||||
{'1','2','3'},
|
||||
{'4','5','6'},
|
||||
{'7','8','9'},
|
||||
{'*','0','#'}
|
||||
};
|
||||
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
|
||||
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
|
||||
|
||||
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
|
||||
|
||||
unsigned long loopCount = 0;
|
||||
unsigned long timer_t = 0;
|
||||
|
||||
void setup(){
|
||||
Serial.begin(9600);
|
||||
|
||||
// Try playing with different debounceTime settings to see how it affects
|
||||
// the number of times per second your loop will run. The library prevents
|
||||
// setting it to anything below 1 millisecond.
|
||||
kpd.setDebounceTime(10); // setDebounceTime(mS)
|
||||
}
|
||||
|
||||
void loop(){
|
||||
char key = kpd.getKey();
|
||||
|
||||
// Report the number of times through the loop in 1 second. This will give
|
||||
// you a relative idea of just how much the debounceTime has changed the
|
||||
// speed of your code. If you set a high debounceTime your loopCount will
|
||||
// look good but your keypresses will start to feel sluggish.
|
||||
if ((millis() - timer_t) > 1000) {
|
||||
Serial.print("Your loop code ran ");
|
||||
Serial.print(loopCount);
|
||||
Serial.println(" times over the last second");
|
||||
loopCount = 0;
|
||||
timer_t = millis();
|
||||
}
|
||||
loopCount++;
|
||||
if(key)
|
||||
Serial.println(key);
|
||||
}
|
||||
38
Projects/libraries/Installed_libs/Keypad/keywords.txt
Executable file
38
Projects/libraries/Installed_libs/Keypad/keywords.txt
Executable file
@@ -0,0 +1,38 @@
|
||||
# Keypad Library data types
|
||||
KeyState KEYWORD1
|
||||
Keypad KEYWORD1
|
||||
KeypadEvent KEYWORD1
|
||||
|
||||
# Keypad Library constants
|
||||
NO_KEY LITERAL1
|
||||
IDLE LITERAL1
|
||||
PRESSED LITERAL1
|
||||
HOLD LITERAL1
|
||||
RELEASED LITERAL1
|
||||
|
||||
# Keypad Library methods & functions
|
||||
addEventListener KEYWORD2
|
||||
bitMap KEYWORD2
|
||||
findKeyInList KEYWORD2
|
||||
getKey KEYWORD2
|
||||
getKeys KEYWORD2
|
||||
getState KEYWORD2
|
||||
holdTimer KEYWORD2
|
||||
isPressed KEYWORD2
|
||||
keyStateChanged KEYWORD2
|
||||
numKeys KEYWORD2
|
||||
pin_mode KEYWORD2
|
||||
pin_write KEYWORD2
|
||||
pin_read KEYWORD2
|
||||
setDebounceTime KEYWORD2
|
||||
setHoldTime KEYWORD2
|
||||
waitForKey KEYWORD2
|
||||
|
||||
# this is a macro that converts 2d arrays to pointers
|
||||
makeKeymap KEYWORD2
|
||||
|
||||
# List of objects created in the example sketches.
|
||||
kpd KEYWORD3
|
||||
keypad KEYWORD3
|
||||
kbrd KEYWORD3
|
||||
keyboard KEYWORD3
|
||||
61
Projects/libraries/Installed_libs/Keypad/utility/Key.cpp
Executable file
61
Projects/libraries/Installed_libs/Keypad/utility/Key.cpp
Executable file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|| @file Key.cpp
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
#include <Key.h>
|
||||
|
||||
|
||||
// default constructor
|
||||
Key::Key() {
|
||||
kchar = NO_KEY;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
// constructor
|
||||
Key::Key(char userKeyChar) {
|
||||
kchar = userKeyChar;
|
||||
kcode = -1;
|
||||
kstate = IDLE;
|
||||
stateChanged = false;
|
||||
}
|
||||
|
||||
|
||||
void Key::key_update (char userKeyChar, KeyState userState, boolean userStatus) {
|
||||
kchar = userKeyChar;
|
||||
kstate = userState;
|
||||
stateChanged = userStatus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
73
Projects/libraries/Installed_libs/Keypad/utility/Key.h
Executable file
73
Projects/libraries/Installed_libs/Keypad/utility/Key.h
Executable file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
||
|
||||
|| @file Key.h
|
||||
|| @version 1.0
|
||||
|| @author Mark Stanley
|
||||
|| @contact mstanley@technologist.com
|
||||
||
|
||||
|| @description
|
||||
|| | Key class provides an abstract definition of a key or button
|
||||
|| | and was initially designed to be used in conjunction with a
|
||||
|| | state-machine.
|
||||
|| #
|
||||
||
|
||||
|| @license
|
||||
|| | This library is free software; you can redistribute it and/or
|
||||
|| | modify it under the terms of the GNU Lesser General Public
|
||||
|| | License as published by the Free Software Foundation; version
|
||||
|| | 2.1 of the License.
|
||||
|| |
|
||||
|| | This library is distributed in the hope that it will be useful,
|
||||
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
|| | Lesser General Public License for more details.
|
||||
|| |
|
||||
|| | You should have received a copy of the GNU Lesser General Public
|
||||
|| | License along with this library; if not, write to the Free Software
|
||||
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|| #
|
||||
||
|
||||
*/
|
||||
|
||||
#ifndef KEY_H
|
||||
#define KEY_H
|
||||
|
||||
// Arduino versioning.
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h" // for digitalRead, digitalWrite, etc
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#define OPEN LOW
|
||||
#define CLOSED HIGH
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef enum{ IDLE, PRESSED, HOLD, RELEASED } KeyState;
|
||||
|
||||
const char NO_KEY = '\0';
|
||||
|
||||
class Key {
|
||||
public:
|
||||
// members
|
||||
char kchar;
|
||||
int kcode;
|
||||
KeyState kstate;
|
||||
boolean stateChanged;
|
||||
|
||||
// methods
|
||||
Key();
|
||||
Key(char userKeyChar);
|
||||
void key_update(char userKeyChar, KeyState userState, boolean userStatus);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|| @changelog
|
||||
|| | 1.0 2012-06-04 - Mark Stanley : Initial Release
|
||||
|| #
|
||||
*/
|
||||
231
Projects/libraries/Installed_libs/NewPing/NewPing.cpp
Executable file
231
Projects/libraries/Installed_libs/NewPing/NewPing.cpp
Executable file
@@ -0,0 +1,231 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Created by Tim Eckel - teckel@leethost.com
|
||||
// Copyright 2012 License: GNU GPL v3 http://www.gnu.org/licenses/gpl-3.0.html
|
||||
//
|
||||
// See "NewPing.h" for purpose, syntax, version history, links, and more.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "NewPing.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// NewPing constructor
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, int max_cm_distance) {
|
||||
_triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
|
||||
_echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin.
|
||||
|
||||
_triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin.
|
||||
_echoInput = portInputRegister(digitalPinToPort(echo_pin)); // Get the input port register for the echo pin.
|
||||
|
||||
_triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin.
|
||||
|
||||
_maxEchoTime = min(max_cm_distance, MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.
|
||||
|
||||
#if DISABLE_ONE_PIN == true
|
||||
*_triggerMode |= _triggerBit; // Set trigger pin to output.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Standard ping methods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
unsigned int NewPing::ping() {
|
||||
if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function.
|
||||
while (*_echoInput & _echoBit) // Wait for the ping echo.
|
||||
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
|
||||
return (micros() - (_max_time - _maxEchoTime) - 5); // Calculate ping time, 5uS of overhead.
|
||||
}
|
||||
|
||||
|
||||
unsigned int NewPing::ping_in() {
|
||||
unsigned int echoTime = NewPing::ping(); // Calls the ping method and returns with the ping echo distance in uS.
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
|
||||
}
|
||||
|
||||
|
||||
unsigned int NewPing::ping_cm() {
|
||||
unsigned int echoTime = NewPing::ping(); // Calls the ping method and returns with the ping echo distance in uS.
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
|
||||
}
|
||||
|
||||
|
||||
unsigned int NewPing::ping_median(uint8_t it) {
|
||||
unsigned int uS[it], last;
|
||||
uint8_t j, i = 0;
|
||||
uS[0] = NO_ECHO;
|
||||
while (i < it) {
|
||||
last = ping(); // Send ping.
|
||||
if (last == NO_ECHO) { // Ping out of range.
|
||||
it--; // Skip, don't include as part of median.
|
||||
last = _maxEchoTime; // Adjust "last" variable so delay is correct length.
|
||||
} else { // Ping in range, include as part of median.
|
||||
if (i > 0) { // Don't start sort till second ping.
|
||||
for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
|
||||
uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
|
||||
} else j = 0; // First ping is starting point for sort.
|
||||
uS[j] = last; // Add last ping to array in sorted position.
|
||||
i++; // Move to next ping.
|
||||
}
|
||||
if (i < it) delay(PING_MEDIAN_DELAY - (last >> 10)); // Millisecond delay between pings.
|
||||
}
|
||||
return (uS[it >> 1]); // Return the ping distance median.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Standard ping method support functions (not called directly)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
boolean NewPing::ping_trigger() {
|
||||
#if DISABLE_ONE_PIN != true
|
||||
*_triggerMode |= _triggerBit; // Set trigger pin to output.
|
||||
#endif
|
||||
*_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is.
|
||||
delayMicroseconds(4); // Wait for pin to go low, testing shows it needs 4uS to work every time.
|
||||
*_triggerOutput |= _triggerBit; // Set trigger pin high, this tells the sensor to send out a ping.
|
||||
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
|
||||
*_triggerOutput &= ~_triggerBit; // Set trigger pin back to low.
|
||||
#if DISABLE_ONE_PIN != true
|
||||
*_triggerMode &= ~_triggerBit; // Set trigger pin to input (when using one Arduino pin this is technically setting the echo pin to input as both are tied to the same Arduino pin).
|
||||
#endif
|
||||
|
||||
_max_time = micros() + MAX_SENSOR_DELAY; // Set a timeout for the ping to trigger.
|
||||
while (*_echoInput & _echoBit && micros() <= _max_time) {} // Wait for echo pin to clear.
|
||||
while (!(*_echoInput & _echoBit)) // Wait for ping to start.
|
||||
if (micros() > _max_time) return false; // Something went wrong, abort.
|
||||
|
||||
_max_time = micros() + _maxEchoTime; // Ping started, set the timeout.
|
||||
return true; // Ping started successfully.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer interrupt ping methods (won't work with ATmega8 and ATmega128)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void NewPing::ping_timer(void (*userFunc)(void)) {
|
||||
if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer.
|
||||
timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS.
|
||||
}
|
||||
|
||||
|
||||
boolean NewPing::check_timer() {
|
||||
if (micros() > _max_time) { // Outside the timeout limit.
|
||||
timer_stop(); // Disable timer interrupt
|
||||
return false; // Cancel ping timer.
|
||||
}
|
||||
|
||||
if (!(*_echoInput & _echoBit)) { // Ping echo received.
|
||||
timer_stop(); // Disable timer interrupt
|
||||
ping_result = (micros() - (_max_time - _maxEchoTime) - 13); // Calculate ping time, 13uS of overhead.
|
||||
return true; // Return ping echo true.
|
||||
}
|
||||
|
||||
return false; // Return false because there's no ping echo yet.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer2/Timer4 interrupt methods (can be used for non-ultrasonic needs)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Variables used for timer functions
|
||||
void (*intFunc)();
|
||||
void (*intFunc2)();
|
||||
unsigned long _ms_cnt_reset;
|
||||
volatile unsigned long _ms_cnt;
|
||||
|
||||
|
||||
void NewPing::timer_us(unsigned int frequency, void (*userFunc)(void)) {
|
||||
timer_setup(); // Configure the timer interrupt.
|
||||
intFunc = userFunc; // User's function to call when there's a timer event.
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
OCR4C = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
|
||||
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
|
||||
#else
|
||||
OCR2A = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
|
||||
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_ms(unsigned long frequency, void (*userFunc)(void)) {
|
||||
timer_setup(); // Configure the timer interrupt.
|
||||
intFunc = NewPing::timer_ms_cntdwn; // Timer events are sent here once every ms till user's frequency is reached.
|
||||
intFunc2 = userFunc; // User's function to call when user's frequency is reached.
|
||||
_ms_cnt = _ms_cnt_reset = frequency; // Current ms counter and reset value.
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
OCR4C = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
|
||||
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
|
||||
#else
|
||||
OCR2A = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
|
||||
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_stop() { // Disable timer interrupt.
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
TIMSK4 = 0;
|
||||
#else
|
||||
TIMSK2 &= ~(1<<OCIE2A);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Timer2/Timer4 interrupt method support functions (not called directly)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void NewPing::timer_setup() {
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
timer_stop(); // Disable Timer4 interrupt.
|
||||
TCCR4A = TCCR4C = TCCR4D = TCCR4E = 0;
|
||||
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4); // Set Timer4 prescaler to 64 (4uS/count, 4uS-1020uS range).
|
||||
TIFR4 = (1<<TOV4);
|
||||
TCNT4 = 0; // Reset Timer4 counter.
|
||||
#else
|
||||
timer_stop(); // Disable Timer2 interrupt.
|
||||
ASSR &= ~(1<<AS2); // Set clock, not pin.
|
||||
TCCR2A = (1<<WGM21); // Set Timer2 to CTC mode.
|
||||
TCCR2B = (1<<CS22); // Set Timer2 prescaler to 64 (4uS/count, 4uS-1020uS range).
|
||||
TCNT2 = 0; // Reset Timer2 counter.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NewPing::timer_ms_cntdwn() {
|
||||
if (!_ms_cnt--) { // Count down till we reach zero.
|
||||
intFunc2(); // Scheduled time reached, run the main timer event function.
|
||||
_ms_cnt = _ms_cnt_reset; // Reset the ms timer.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
|
||||
ISR(TIMER4_OVF_vect) {
|
||||
#else
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
#endif
|
||||
if(intFunc) intFunc(); // If wrapped function is set, call it.
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Conversion methods (rounds result to nearest inch or cm).
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
unsigned int NewPing::convert_in(unsigned int echoTime) {
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
|
||||
}
|
||||
|
||||
|
||||
unsigned int NewPing::convert_cm(unsigned int echoTime) {
|
||||
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
|
||||
}
|
||||
162
Projects/libraries/Installed_libs/NewPing/NewPing.h
Executable file
162
Projects/libraries/Installed_libs/NewPing/NewPing.h
Executable file
@@ -0,0 +1,162 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// NewPing Library - v1.5 - 08/15/2012
|
||||
//
|
||||
// AUTHOR/LICENSE:
|
||||
// Created by Tim Eckel - teckel@leethost.com
|
||||
// Copyright 2012 License: GNU GPL v3 http://www.gnu.org/licenses/gpl-3.0.html
|
||||
//
|
||||
// LINKS:
|
||||
// Project home: http://code.google.com/p/arduino-new-ping/
|
||||
// Blog: http://arduino.cc/forum/index.php/topic,106043.0.html
|
||||
//
|
||||
// DISCLAIMER:
|
||||
// This software is furnished "as is", without technical support, and with no
|
||||
// warranty, express or implied, as to its usefulness for any purpose.
|
||||
//
|
||||
// BACKGROUND:
|
||||
// When I first received an ultrasonic sensor I was not happy with how poorly
|
||||
// it worked. Quickly I realized the problem wasn't the sensor, it was the
|
||||
// available ping and ultrasonic libraries causing the problem. The NewPing
|
||||
// library totally fixes these problems, adds many new features, and breaths
|
||||
// new life into these very affordable distance sensors.
|
||||
//
|
||||
// FEATURES:
|
||||
// * Works with many different ultrasonic sensor models: SR04, SRF05, SRF06, DYP-ME007 & Parallax PING)))<29>.
|
||||
// * Interface with all but the SRF06 sensor using only one Arduino pin.
|
||||
// * Doesn't lag for a full second if no ping/echo is received.
|
||||
// * Ping sensors consistently and reliably at up to 30 times per second.
|
||||
// * Timer interrupt method for event-driven sketches.
|
||||
// * Built-in digital filter method ping_median() for easy error correction.
|
||||
// * Uses port registers for a faster pin interface and smaller code size.
|
||||
// * Allows you to set a maximum distance where pings beyond that distance are read as no ping "clear".
|
||||
// * Ease of using multiple sensors (example sketch with 15 sensors).
|
||||
// * More accurate distance calculation (cm, inches & uS).
|
||||
// * Doesn't use pulseIn, which is slow and gives incorrect results with some ultrasonic sensor models.
|
||||
// * Actively developed with features being added and bugs/issues addressed.
|
||||
//
|
||||
// CONSTRUCTOR:
|
||||
// NewPing sonar(trigger_pin, echo_pin [, max_cm_distance])
|
||||
// trigger_pin & echo_pin - Arduino pins connected to sensor trigger and echo.
|
||||
// NOTE: To use the same Arduino pin for trigger and echo, specify the same pin for both values.
|
||||
// max_cm_distance - [Optional] Maximum distance you wish to sense. Default=500cm.
|
||||
//
|
||||
// SYNTAX:
|
||||
// sonar.ping() - Send a ping and get the echo time (in microseconds) as a result.
|
||||
// sonar.ping_in() - Send a ping and get the distance in whole inches.
|
||||
// sonar.ping_cm() - Send a ping and get the distance in whole centimeters.
|
||||
// sonar.ping_median(iterations) - Do multiple pings (default=5), discard out of range pings and return median in microseconds.
|
||||
// sonar.convert_in(echoTime) - Convert echoTime from microseconds to inches (rounds to nearest inch).
|
||||
// sonar.convert_cm(echoTime) - Convert echoTime from microseconds to centimeters (rounds to nearest cm).
|
||||
// sonar.ping_timer(function) - Send a ping and call function to test if ping is complete.
|
||||
// sonar.check_timer() - Check if ping has returned within the set distance limit.
|
||||
// NewPing::timer_us(frequency, function) - Call function every frequency microseconds.
|
||||
// NewPing::timer_ms(frequency, function) - Call function every frequency milliseconds.
|
||||
// NewPing::timer_stop() - Stop the timer.
|
||||
//
|
||||
// HISTORY:
|
||||
// 08/15/2012 v1.5 - Added ping_median() method which does a user specified
|
||||
// number of pings (default=5) and returns the median ping in microseconds
|
||||
// (out of range pings ignored). This is a very effective digital filter.
|
||||
// Optimized for smaller compiled size (even smaller than skteches that
|
||||
// don't use a library).
|
||||
//
|
||||
// 07/14/2012 v1.4 - Added support for the Parallax PING)))<29> sensor. Interface
|
||||
// with all but the SRF06 sensor using only one Arduino pin. You can also
|
||||
// interface with the SRF06 using one pin if you install a 0.1uf capacitor
|
||||
// on the trigger and echo pins of the sensor then tie the trigger pin to
|
||||
// the Arduino pin (doesn't work with Teensy). To use the same Arduino pin
|
||||
// for trigger and echo, specify the same pin for both values. Various bug
|
||||
// fixes.
|
||||
//
|
||||
// 06/08/2012 v1.3 - Big feature addition, event-driven ping! Uses Timer2
|
||||
// interrupt, so be mindful of PWM or timing conflicts messing with Timer2
|
||||
// may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 10 on
|
||||
// Mega, and Tone library). Simple to use timer interrupt functions you can
|
||||
// use in your sketches totaly unrelated to ultrasonic sensors (don't use if
|
||||
// you're also using NewPing's ping_timer because both use Timer2 interrupts).
|
||||
// Loop counting ping method deleted in favor of timing ping method after
|
||||
// inconsistant results kept surfacing with the loop timing ping method.
|
||||
// Conversion to cm and inches now rounds to the nearest cm or inch. Code
|
||||
// optimized to save program space and fixed a couple minor bugs here and
|
||||
// there. Many new comments added as well as line spacing to group code
|
||||
// sections for better source readability.
|
||||
//
|
||||
// 05/25/2012 v1.2 - Lots of code clean-up thanks to Adruino Forum members.
|
||||
// Rebuilt the ping timing code from scratch, ditched the pulseIn code as it
|
||||
// doesn't give correct results (at least with ping sensors). The NewPing
|
||||
// library is now VERY accurate and the code was simplified as a bonus.
|
||||
// Smaller and faster code as well. Fixed some issues with very close ping
|
||||
// results when converting to inches. All functions now return 0 only when
|
||||
// there's no ping echo (out of range) and a positive value for a successful
|
||||
// ping. This can effectively be used to detect if something is out of range
|
||||
// or in-range and at what distance. Now compatible with Arduino 0023.
|
||||
//
|
||||
// 05/16/2012 v1.1 - Changed all I/O functions to use low-level port registers
|
||||
// for ultra-fast and lean code (saves from 174 to 394 bytes). Tested on both
|
||||
// the Arduino Uno and Teensy 2.0 but should work on all Arduino-based
|
||||
// platforms because it calls standard functions to retrieve port registers
|
||||
// and bit masks. Also made a couple minor fixes to defines.
|
||||
//
|
||||
// 05/15/2012 v1.0 - Initial release.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef NewPing_h
|
||||
#define NewPing_h
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <pins_arduino.h>
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
// Shoudln't need to changed these values unless you have a specific need to do so.
|
||||
#define MAX_SENSOR_DISTANCE 500 // Maximum sensor distance can be as high as 500cm, no reason to wait for ping longer than sound takes to travel this distance and back.
|
||||
#define US_ROUNDTRIP_IN 146 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space.
|
||||
#define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space.
|
||||
#define DISABLE_ONE_PIN false // Set to "true" to save up to 26 bytes of compiled code space if you're not using one pin sensor connections.
|
||||
|
||||
// Probably shoudln't change these values unless you really know what you're doing.
|
||||
#define NO_ECHO 0 // Value returned if there's no ping echo within the specified MAX_SENSOR_DISTANCE or max_cm_distance.
|
||||
#define MAX_SENSOR_DELAY 18000 // Maximum uS it takes for sensor to start the ping (SRF06 is the highest measured, just under 18ms).
|
||||
#define ECHO_TIMER_FREQ 24 // Frequency to check for a ping echo (every 24uS is about 0.4cm accuracy).
|
||||
#define PING_MEDIAN_DELAY 29 // Millisecond delay between pings in the ping_median method.
|
||||
|
||||
// Conversion from uS to distance (round result to nearest cm or inch).
|
||||
#define NewPingConvert(echoTime, conversionFactor) (max((echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0)))
|
||||
|
||||
|
||||
class NewPing {
|
||||
public:
|
||||
NewPing(uint8_t trigger_pin, uint8_t echo_pin, int max_cm_distance = MAX_SENSOR_DISTANCE);
|
||||
unsigned int ping();
|
||||
unsigned int ping_in();
|
||||
unsigned int ping_cm();
|
||||
unsigned int ping_median(uint8_t it = 5);
|
||||
unsigned int convert_in(unsigned int echoTime);
|
||||
unsigned int convert_cm(unsigned int echoTime);
|
||||
void ping_timer(void (*userFunc)(void));
|
||||
boolean check_timer();
|
||||
unsigned long ping_result;
|
||||
static void timer_us(unsigned int frequency, void (*userFunc)(void));
|
||||
static void timer_ms(unsigned long frequency, void (*userFunc)(void));
|
||||
static void timer_stop();
|
||||
private:
|
||||
boolean ping_trigger();
|
||||
boolean ping_wait_timer();
|
||||
uint8_t _triggerBit;
|
||||
uint8_t _echoBit;
|
||||
volatile uint8_t *_triggerOutput;
|
||||
volatile uint8_t *_triggerMode;
|
||||
volatile uint8_t *_echoInput;
|
||||
unsigned int _maxEchoTime;
|
||||
unsigned long _max_time;
|
||||
static void timer_setup();
|
||||
static void timer_ms_cntdwn();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
|
||||
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
|
||||
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
|
||||
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
|
||||
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
|
||||
// would normally process the sensor results in this function (for example, decide if a robot needs to
|
||||
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
|
||||
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
|
||||
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <NewPing.h>
|
||||
|
||||
#define SONAR_NUM 15 // Number or sensors.
|
||||
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
|
||||
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
|
||||
|
||||
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
|
||||
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
|
||||
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
|
||||
|
||||
NewPing sonar[SONAR_NUM] = { // Sensor object array.
|
||||
NewPing(41, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
|
||||
NewPing(43, 44, MAX_DISTANCE),
|
||||
NewPing(45, 20, MAX_DISTANCE),
|
||||
NewPing(21, 22, MAX_DISTANCE),
|
||||
NewPing(23, 24, MAX_DISTANCE),
|
||||
NewPing(25, 26, MAX_DISTANCE),
|
||||
NewPing(27, 28, MAX_DISTANCE),
|
||||
NewPing(29, 30, MAX_DISTANCE),
|
||||
NewPing(31, 32, MAX_DISTANCE),
|
||||
NewPing(34, 33, MAX_DISTANCE),
|
||||
NewPing(35, 36, MAX_DISTANCE),
|
||||
NewPing(37, 38, MAX_DISTANCE),
|
||||
NewPing(39, 40, MAX_DISTANCE),
|
||||
NewPing(50, 51, MAX_DISTANCE),
|
||||
NewPing(52, 53, MAX_DISTANCE)
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
|
||||
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
|
||||
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
|
||||
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
|
||||
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
|
||||
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
|
||||
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
|
||||
currentSensor = i; // Sensor being accessed.
|
||||
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
|
||||
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
|
||||
}
|
||||
}
|
||||
// The rest of your code would go here.
|
||||
}
|
||||
|
||||
void echoCheck() { // If ping received, set the sensor distance to array.
|
||||
if (sonar[currentSensor].check_timer())
|
||||
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
|
||||
}
|
||||
|
||||
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
|
||||
for (uint8_t i = 0; i < SONAR_NUM; i++) {
|
||||
Serial.print(i);
|
||||
Serial.print("=");
|
||||
Serial.print(cm[i]);
|
||||
Serial.print("cm ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// This example shows how to use NewPing's ping_timer method which uses the Timer2 interrupt to get the
|
||||
// ping time. The advantage of using this method over the standard ping method is that it permits a more
|
||||
// event-driven sketch which allows you to appear to do two things at once. An example would be to ping
|
||||
// an ultrasonic sensor for a possible collision while at the same time navigating. This allows a
|
||||
// properly developed sketch to multitask. Be aware that because the ping_timer method uses Timer2,
|
||||
// other features or libraries that also use Timer2 would be effected. For example, the PWM function on
|
||||
// pins 3 & 11 on Arduino Uno (pins 9 and 11 on Arduino Mega) and the Tone library. Note, only the PWM
|
||||
// functionality of the pins is lost (as they use Timer2 to do PWM), the pins are still available to use.
|
||||
// NOTE: For Teensy/Leonardo (ATmega32U4) the library uses Timer4 instead of Timer2.
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <NewPing.h>
|
||||
|
||||
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor.
|
||||
#define ECHO_PIN 11 // Arduino pin tied to echo pin on ping sensor.
|
||||
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
|
||||
|
||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||
|
||||
unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
|
||||
unsigned long pingTimer; // Holds the next ping time.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
|
||||
pingTimer = millis(); // Start now.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
|
||||
if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping.
|
||||
pingTimer += pingSpeed; // Set the next ping time.
|
||||
sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
|
||||
}
|
||||
// Do other stuff here, really. Think of it as multi-tasking.
|
||||
}
|
||||
|
||||
void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
|
||||
// Don't do anything here!
|
||||
if (sonar.check_timer()) { // This is how you check to see if the ping was received.
|
||||
// Here's where you can add code.
|
||||
Serial.print("Ping: ");
|
||||
Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
|
||||
Serial.println("cm");
|
||||
}
|
||||
// Don't do anything here!
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Example NewPing library sketch that does a ping about 20 times per second.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include <NewPing.h>
|
||||
|
||||
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
|
||||
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
|
||||
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
|
||||
|
||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
|
||||
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
|
||||
Serial.print("Ping: ");
|
||||
Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
|
||||
Serial.println("cm");
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// While the NewPing library's primary goal is to interface with ultrasonic sensors, interfacing with
|
||||
// the Timer2 interrupt was a result of creating an interrupt-based ping method. Since these Timer2
|
||||
// interrupt methods were built, the library may as well provide the functionality to use these methods
|
||||
// in your sketches. This shows how simple it is (no ultrasonic sensor required). Keep in mind that
|
||||
// these methods use Timer2, as does NewPing's ping_timer method for using ultrasonic sensors. You
|
||||
// can't use ping_timer at the same time you're using timer_ms or timer_us as all use the same timer.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include <NewPing.h>
|
||||
|
||||
#define LED_PIN 13 // Pin with LED attached.
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
NewPing::timer_ms(500, toggleLED); // Create a Timer2 interrupt that calls toggleLED in your sketch once every 500 milliseconds.
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Do anything here, the Timer2 interrupt will take care of the flashing LED without your intervention.
|
||||
}
|
||||
|
||||
void toggleLED() {
|
||||
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED.
|
||||
}
|
||||
29
Projects/libraries/Installed_libs/NewPing/keywords.txt
Executable file
29
Projects/libraries/Installed_libs/NewPing/keywords.txt
Executable file
@@ -0,0 +1,29 @@
|
||||
###################################
|
||||
# Syntax Coloring Map For NewPing
|
||||
###################################
|
||||
|
||||
###################################
|
||||
# Datatypes (KEYWORD1)
|
||||
###################################
|
||||
|
||||
NewPing KEYWORD1
|
||||
|
||||
###################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
###################################
|
||||
|
||||
ping KEYWORD2
|
||||
ping_in KEYWORD2
|
||||
ping_cm KEYWORD2
|
||||
ping_median KEYWORD2
|
||||
ping_timer KEYWORD2
|
||||
check_timer KEYWORD2
|
||||
timer_us KEYWORD2
|
||||
timer_ms KEYWORD2
|
||||
timer_stop KEYWORD2
|
||||
convert_in KEYWORD2
|
||||
convert_cm KEYWORD2
|
||||
|
||||
###################################
|
||||
# Constants (LITERAL1)
|
||||
###################################
|
||||
5
Projects/libraries/Installed_libs/ST2_Arduino/.gitignore
vendored
Executable file
5
Projects/libraries/Installed_libs/ST2_Arduino/.gitignore
vendored
Executable file
@@ -0,0 +1,5 @@
|
||||
*.pyc
|
||||
*.cache
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
.build
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"cmd": ["ino", "clean"],
|
||||
"selector": "source.c++.arduino",
|
||||
"working_dir": "$file_path/..",
|
||||
"path": "/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"cmd": ["ino", "build"],
|
||||
"selector": "source.c++.arduino",
|
||||
"working_dir": "$file_path/..",
|
||||
"path": "/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"cmd": ["sh", "-c", "ino build && ino upload"],
|
||||
"windows": {
|
||||
"shell": true,
|
||||
"cmd": ["ino", "build", "&;", "ino", "upload"]
|
||||
},
|
||||
"selector": "source.c++.arduino",
|
||||
"working_dir": "$file_path/..",
|
||||
"path": "/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"cmd": ["ino", "upload"],
|
||||
"selector": "source.c++.arduino",
|
||||
"working_dir": "$file_path/..",
|
||||
"path": "/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin"
|
||||
}
|
||||
128
Projects/libraries/Installed_libs/ST2_Arduino/Arduino.sublime-completions
Executable file
128
Projects/libraries/Installed_libs/ST2_Arduino/Arduino.sublime-completions
Executable file
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"scope": "source.c++.arduino",
|
||||
"completions": [
|
||||
"HIGH",
|
||||
"LOW",
|
||||
"INPUT",
|
||||
"OUTPUT",
|
||||
"DEC",
|
||||
"BIN",
|
||||
"HEX",
|
||||
"OCT",
|
||||
"BYTE",
|
||||
"PI",
|
||||
"HALF_PI",
|
||||
"TWO_PI",
|
||||
"LSBFIRST",
|
||||
"MSBFIRST",
|
||||
"CHANGE",
|
||||
"FALLING",
|
||||
"RISING",
|
||||
"DEFAULT",
|
||||
"EXTERNAL",
|
||||
"INTERAL",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"char",
|
||||
"class",
|
||||
"continue",
|
||||
"default",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"false",
|
||||
"float",
|
||||
"for",
|
||||
"if",
|
||||
"int",
|
||||
"long",
|
||||
"new",
|
||||
"null",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"signed",
|
||||
"static",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"try",
|
||||
"true",
|
||||
"unsigned",
|
||||
"void",
|
||||
"while",
|
||||
"word",
|
||||
"boolean",
|
||||
"byte",
|
||||
"char",
|
||||
"float",
|
||||
"int",
|
||||
"long",
|
||||
"word",
|
||||
"abs",
|
||||
"acos",
|
||||
"asin",
|
||||
"atan",
|
||||
"atan2",
|
||||
"ceil",
|
||||
"constrain",
|
||||
"cos",
|
||||
"degrees",
|
||||
"exp",
|
||||
"floor",
|
||||
"log",
|
||||
"map",
|
||||
"max",
|
||||
"min",
|
||||
"radians",
|
||||
"random",
|
||||
"randomSeed",
|
||||
"round",
|
||||
"sin",
|
||||
"sq",
|
||||
"sqrt",
|
||||
"tan",
|
||||
"bitRead",
|
||||
"bitWrite",
|
||||
"bitSet",
|
||||
"bitClear",
|
||||
"bit",
|
||||
"highByte",
|
||||
"lowByte",
|
||||
"analogReference",
|
||||
"analogRead",
|
||||
"analogWrite",
|
||||
"attachInterrupt",
|
||||
"detachInterrupt",
|
||||
"delay",
|
||||
"delayMicroseconds",
|
||||
"digitalWrite",
|
||||
"digitalRead",
|
||||
"interrupts",
|
||||
"millis",
|
||||
"micros",
|
||||
"noInterrupts",
|
||||
"noTone",
|
||||
"pinMode",
|
||||
"pulseIn",
|
||||
"shiftOut",
|
||||
"tone",
|
||||
"Serial",
|
||||
"Serial1",
|
||||
"Serial2",
|
||||
"Serial3",
|
||||
"begin",
|
||||
"end",
|
||||
"read",
|
||||
"print",
|
||||
"println",
|
||||
"available",
|
||||
"flush",
|
||||
"setup",
|
||||
"loop"
|
||||
]
|
||||
}
|
||||
62
Projects/libraries/Installed_libs/ST2_Arduino/Arduino.tmLanguage
Executable file
62
Projects/libraries/Installed_libs/ST2_Arduino/Arduino.tmLanguage
Executable file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>pde</string>
|
||||
<string>ino</string>
|
||||
</array>
|
||||
<key>foldingStartMarker</key>
|
||||
<string>/\*\*|\{\s*$</string>
|
||||
<key>foldingStopMarker</key>
|
||||
<string>\*\*/|^\s*\}</string>
|
||||
<key>name</key>
|
||||
<string>Arduino</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#special_block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(HIGH|LOW|INPUT|OUTPUT|DEC|BIN|HEX|OCT|BYTE|PI|HALF_PI|TWO_PI|LSBFIRST|MSBFIRST|CHANGE|FALLING|RISING|DEFAULT|EXTERNAL|INTERNAL|INTERNAL1V1|INTERNAL2V56|null)\b</string>
|
||||
<key>name</key>
|
||||
<string>constant.c++.arduino</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(boolean|byte|word)\b</string>
|
||||
<key>name</key>
|
||||
<string>storage.c++.arduino</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(abs|acos|asin|atan|atan2|ceil|constrain|cos|degrees|exp|floor|log|map|max|min|radians|random|randomSeed|round|sin|sq|sqrt|tan|bitRead|bitWrite|bitSet|bitClear|bit|highByte|lowByte|analogReference|analogRead|analogWrite|attachInterrupt|detachInterrupt|delay|delayMicroseconds|digitalWrite|digitalRead|interrupts|millis|micros|noInterrupts|noTone|pinMode|pulseIn|shiftOut|tone|begin|end|read|print|println|available|flush|setup|loop)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.function.c++.arduino</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(Serial\d?)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.class.c++.arduino</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(private|protected|public)</string>
|
||||
<key>name</key>
|
||||
<string>storage.modifier.c++.arduino</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>scopeName</key>
|
||||
<string>source.c++.arduino</string>
|
||||
<key>uuid</key>
|
||||
<string>65E5AFAE-4AE7-4DAE-837B-1B99810E464C</string>
|
||||
</dict>
|
||||
</plist>
|
||||
26
Projects/libraries/Installed_libs/ST2_Arduino/Default.sublime-commands
Executable file
26
Projects/libraries/Installed_libs/ST2_Arduino/Default.sublime-commands
Executable file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"caption": "New sketch",
|
||||
"command": "new_sketch"
|
||||
},
|
||||
{
|
||||
"caption": "Open Arduino Libraries",
|
||||
"command": "open_arduino_libraries"
|
||||
},
|
||||
{
|
||||
"caption": "Compile Arduino sketch",
|
||||
"command": "compile"
|
||||
},
|
||||
{
|
||||
"caption": "Upload Arduino sketch",
|
||||
"command": "upload"
|
||||
},
|
||||
{
|
||||
"caption": "Compile and Upload Arduino sketch",
|
||||
"command": "compile_upload"
|
||||
},
|
||||
{
|
||||
"caption": "Clean Arduino sketch",
|
||||
"command": "clean"
|
||||
}
|
||||
]
|
||||
5
Projects/libraries/Installed_libs/ST2_Arduino/Default.sublime-keymap
Executable file
5
Projects/libraries/Installed_libs/ST2_Arduino/Default.sublime-keymap
Executable file
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{ "keys": ["super+ctrl+shift+b"], "command": "compile" },
|
||||
{ "keys": ["super+ctrl+shift+u"], "command": "upload"},
|
||||
{ "keys": ["super+ctrl+shift+c"], "command": "clean"}
|
||||
]
|
||||
7
Projects/libraries/Installed_libs/ST2_Arduino/LICENSE
Executable file
7
Projects/libraries/Installed_libs/ST2_Arduino/LICENSE
Executable file
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2012 Robby Colvin
|
||||
|
||||
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.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user