.info: http://mbed.org/users/shintamainjp/libraries/RemoteIR/lg7h90
XxXxXxXxXxXxXxXxXxXxXxXxXxXx ReceiverIR.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx
/**
* IR receiver (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#include "ReceiverIR.h"
#define LOCK()
#define UNLOCK()
#define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
/**
* Constructor.
*
* @param rxpin Pin for receive IR signal.
*/
ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) {
init_state();
evt.fall(this, &ReceiverIR::isr_fall);
evt.rise(this, &ReceiverIR::isr_rise);
evt.mode(PullUp);
ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000);
}
/**
* Destructor.
*/
ReceiverIR::~ReceiverIR() {
}
/**
* Get state.
*
* @return Current state.
*/
ReceiverIR::State ReceiverIR::getState() {
LOCK();
State s = work.state;
UNLOCK();
return s;
}
/**
* Get data.
*
* @param format Pointer to format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the buffer.
*
* @return Data bit length.
*/
int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) {
LOCK();
if (bitlength < data.bitcount) {
UNLOCK();
return -1;
}
const int nbits = data.bitcount;
const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0);
*format = data.format;
for (int i = 0; i < nbytes; i++) {
buf[i] = data.buffer[i];
}
init_state();
UNLOCK();
return nbits;
}
void ReceiverIR::init_state(void) {
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
work.state = Idle;
data.format = RemoteIR::UNKNOWN;
data.bitcount = 0;
timer.stop();
timer.reset();
for (int i = 0; i < sizeof(data.buffer); i++) {
data.buffer[i] = 0;
}
}
void ReceiverIR::isr_wdt(void) {
LOCK();
static int cnt = 0;
if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
cnt++;
if (cnt > 50) {
#if 0
printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
work.c1,
work.c2,
work.c3,
work.d1,
work.d2,
work.state,
data.format,
data.bitcount);
#endif
init_state();
cnt = 0;
}
} else {
cnt = 0;
}
UNLOCK();
}
void ReceiverIR::isr_fall(void) {
LOCK();
switch (work.state) {
case Idle:
if (work.c1 < 0) {
timer.start();
work.c1 = timer.read_us();
} else {
work.c3 = timer.read_us();
int a = work.c2 - work.c1;
int b = work.c3 - work.c2;
if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) {
/*
* NEC.
*/
data.format = RemoteIR::NEC;
work.state = Receiving;
data.bitcount = 0;
} else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) {
/*
* NEC Repeat.
*/
data.format = RemoteIR::NEC_REPEAT;
work.state = Received;
data.bitcount = 0;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
} else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) {
/*
* AEHA.
*/
data.format = RemoteIR::AEHA;
work.state = Receiving;
data.bitcount = 0;
} else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) {
/*
* AEHA Repeat.
*/
data.format = RemoteIR::AEHA_REPEAT;
work.state = Received;
data.bitcount = 0;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
} else {
init_state();
}
}
break;
case Receiving:
if (RemoteIR::NEC == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_NEC * 3)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_NEC * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* Length of NEC is always 32 bits.
*/
if (32 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5);
#endif
} else if (RemoteIR::AEHA == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_AEHA * 3)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_AEHA * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* Typical length of AEHA is 48 bits.
* Please check a specification of your remote controller if you find a problem.
*/
if (48 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5);
#endif
} else if (RemoteIR::SONY == data.format) {
work.d1 = timer.read_us();
}
break;
case Received:
break;
default:
break;
}
UNLOCK();
}
void ReceiverIR::isr_rise(void) {
LOCK();
switch (work.state) {
case Idle:
if (0 <= work.c1) {
work.c2 = timer.read_us();
int a = work.c2 - work.c1;
if (InRange(a, RemoteIR::TUS_SONY * 4)) {
data.format = RemoteIR::SONY;
work.state = Receiving;
data.bitcount = 0;
} else {
static const int MINIMUM_LEADER_WIDTH = 150;
if (a < MINIMUM_LEADER_WIDTH) {
init_state();
}
}
} else {
init_state();
}
break;
case Receiving:
if (RemoteIR::NEC == data.format) {
work.d1 = timer.read_us();
} else if (RemoteIR::AEHA == data.format) {
work.d1 = timer.read_us();
} else if (RemoteIR::SONY == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_SONY * 2)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_SONY * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* How do I know the correct length? (6bits, 12bits, 15bits, 20bits...)
* By a model only?
* Please check a specification of your remote controller if you find a problem.
*/
if (12 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4);
#endif
}
break;
case Received:
break;
default:
break;
}
UNLOCK();
}
void ReceiverIR::isr_timeout(void) {
LOCK();
#if 0
printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
work.c1,
work.c2,
work.c3,
work.d1,
work.d2,
work.state,
data.format,
data.bitcount);
#endif
if (work.state == Receiving) {
work.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
UNLOCK();
}
* IR receiver (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#include "ReceiverIR.h"
#define LOCK()
#define UNLOCK()
#define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
/**
* Constructor.
*
* @param rxpin Pin for receive IR signal.
*/
ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) {
init_state();
evt.fall(this, &ReceiverIR::isr_fall);
evt.rise(this, &ReceiverIR::isr_rise);
evt.mode(PullUp);
ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000);
}
/**
* Destructor.
*/
ReceiverIR::~ReceiverIR() {
}
/**
* Get state.
*
* @return Current state.
*/
ReceiverIR::State ReceiverIR::getState() {
LOCK();
State s = work.state;
UNLOCK();
return s;
}
/**
* Get data.
*
* @param format Pointer to format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the buffer.
*
* @return Data bit length.
*/
int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) {
LOCK();
if (bitlength < data.bitcount) {
UNLOCK();
return -1;
}
const int nbits = data.bitcount;
const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0);
*format = data.format;
for (int i = 0; i < nbytes; i++) {
buf[i] = data.buffer[i];
}
init_state();
UNLOCK();
return nbits;
}
void ReceiverIR::init_state(void) {
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
work.state = Idle;
data.format = RemoteIR::UNKNOWN;
data.bitcount = 0;
timer.stop();
timer.reset();
for (int i = 0; i < sizeof(data.buffer); i++) {
data.buffer[i] = 0;
}
}
void ReceiverIR::isr_wdt(void) {
LOCK();
static int cnt = 0;
if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
cnt++;
if (cnt > 50) {
#if 0
printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
work.c1,
work.c2,
work.c3,
work.d1,
work.d2,
work.state,
data.format,
data.bitcount);
#endif
init_state();
cnt = 0;
}
} else {
cnt = 0;
}
UNLOCK();
}
void ReceiverIR::isr_fall(void) {
LOCK();
switch (work.state) {
case Idle:
if (work.c1 < 0) {
timer.start();
work.c1 = timer.read_us();
} else {
work.c3 = timer.read_us();
int a = work.c2 - work.c1;
int b = work.c3 - work.c2;
if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) {
/*
* NEC.
*/
data.format = RemoteIR::NEC;
work.state = Receiving;
data.bitcount = 0;
} else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) {
/*
* NEC Repeat.
*/
data.format = RemoteIR::NEC_REPEAT;
work.state = Received;
data.bitcount = 0;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
} else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) {
/*
* AEHA.
*/
data.format = RemoteIR::AEHA;
work.state = Receiving;
data.bitcount = 0;
} else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) {
/*
* AEHA Repeat.
*/
data.format = RemoteIR::AEHA_REPEAT;
work.state = Received;
data.bitcount = 0;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
} else {
init_state();
}
}
break;
case Receiving:
if (RemoteIR::NEC == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_NEC * 3)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_NEC * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* Length of NEC is always 32 bits.
*/
if (32 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5);
#endif
} else if (RemoteIR::AEHA == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_AEHA * 3)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_AEHA * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* Typical length of AEHA is 48 bits.
* Please check a specification of your remote controller if you find a problem.
*/
if (48 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5);
#endif
} else if (RemoteIR::SONY == data.format) {
work.d1 = timer.read_us();
}
break;
case Received:
break;
default:
break;
}
UNLOCK();
}
void ReceiverIR::isr_rise(void) {
LOCK();
switch (work.state) {
case Idle:
if (0 <= work.c1) {
work.c2 = timer.read_us();
int a = work.c2 - work.c1;
if (InRange(a, RemoteIR::TUS_SONY * 4)) {
data.format = RemoteIR::SONY;
work.state = Receiving;
data.bitcount = 0;
} else {
static const int MINIMUM_LEADER_WIDTH = 150;
if (a < MINIMUM_LEADER_WIDTH) {
init_state();
}
}
} else {
init_state();
}
break;
case Receiving:
if (RemoteIR::NEC == data.format) {
work.d1 = timer.read_us();
} else if (RemoteIR::AEHA == data.format) {
work.d1 = timer.read_us();
} else if (RemoteIR::SONY == data.format) {
work.d2 = timer.read_us();
int a = work.d2 - work.d1;
if (InRange(a, RemoteIR::TUS_SONY * 2)) {
data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
} else if (InRange(a, RemoteIR::TUS_SONY * 1)) {
data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
}
data.bitcount++;
#if 0
/*
* How do I know the correct length? (6bits, 12bits, 15bits, 20bits...)
* By a model only?
* Please check a specification of your remote controller if you find a problem.
*/
if (12 <= data.bitcount) {
data.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
#else
/*
* Set timeout for tail detection automatically.
*/
timeout.detach();
timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4);
#endif
}
break;
case Received:
break;
default:
break;
}
UNLOCK();
}
void ReceiverIR::isr_timeout(void) {
LOCK();
#if 0
printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
work.c1,
work.c2,
work.c3,
work.d1,
work.d2,
work.state,
data.format,
data.bitcount);
#endif
if (work.state == Receiving) {
work.state = Received;
work.c1 = -1;
work.c2 = -1;
work.c3 = -1;
work.d1 = -1;
work.d2 = -1;
}
UNLOCK();
}
XxXxXxXxXxXxXxXxXxXxXxXxXxXx ReceiverIR.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx
/**
* IR receiver (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _RECEIVER_IR_H_
#define _RECEIVER_IR_H_
#include <mbed.h>
#include "RemoteIR.h"
/**
* IR receiver class.
*/
class ReceiverIR {
public:
/**
* Constructor.
*
* @param rxpin Pin for receive IR signal.
*/
explicit ReceiverIR(PinName rxpin);
/**
* Destructor.
*/
~ReceiverIR();
/**
* State.
*/
typedef enum {
Idle,
Receiving,
Received
} State;
/**
* Get state.
*
* @return Current state.
*/
State getState();
/**
* Get data.
*
* @param format Pointer to format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the buffer.
*
* @return Data bit length.
*/
int getData(RemoteIR::Format *format, uint8_t *buf, int bitlength);
private:
typedef struct {
RemoteIR::Format format;
int bitcount;
uint8_t buffer[64];
} data_t;
typedef struct {
State state;
int c1;
int c2;
int c3;
int d1;
int d2;
} work_t;
InterruptIn evt; /**< Interrupt based input for input. */
Timer timer; /**< Timer for WDT. */
Ticker ticker; /**< Tciker for tick. */
Timeout timeout; /**< Timeout for tail. */
data_t data;
work_t work;
void init_state(void);
void isr_wdt(void);
void isr_fall(void);
void isr_rise(void);
/**
* ISR timeout for tail detection.
*/
void isr_timeout(void);
};
#endif
* IR receiver (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _RECEIVER_IR_H_
#define _RECEIVER_IR_H_
#include <mbed.h>
#include "RemoteIR.h"
/**
* IR receiver class.
*/
class ReceiverIR {
public:
/**
* Constructor.
*
* @param rxpin Pin for receive IR signal.
*/
explicit ReceiverIR(PinName rxpin);
/**
* Destructor.
*/
~ReceiverIR();
/**
* State.
*/
typedef enum {
Idle,
Receiving,
Received
} State;
/**
* Get state.
*
* @return Current state.
*/
State getState();
/**
* Get data.
*
* @param format Pointer to format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the buffer.
*
* @return Data bit length.
*/
int getData(RemoteIR::Format *format, uint8_t *buf, int bitlength);
private:
typedef struct {
RemoteIR::Format format;
int bitcount;
uint8_t buffer[64];
} data_t;
typedef struct {
State state;
int c1;
int c2;
int c3;
int d1;
int d2;
} work_t;
InterruptIn evt; /**< Interrupt based input for input. */
Timer timer; /**< Timer for WDT. */
Ticker ticker; /**< Tciker for tick. */
Timeout timeout; /**< Timeout for tail. */
data_t data;
work_t work;
void init_state(void);
void isr_wdt(void);
void isr_fall(void);
void isr_rise(void);
/**
* ISR timeout for tail detection.
*/
void isr_timeout(void);
};
#endif
XxXxXxXxXxXxXxXxXxXxXxXxXxXx TransmitterIR.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXx
/**
* IR transmitter (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#include "TransmitterIR.h"
#define LOCK()
#define UNLOCK()
/**
* Constructor.
*
* @param txpin Pin for transmit IR signal.
*/
TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) {
tx.write(0.0);
tx.period_us(26.3);
work.state = Idle;
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
data.format = RemoteIR::UNKNOWN;
data.bitlength = 0;
}
/**
* Destructor.
*/
TransmitterIR::~TransmitterIR() {
}
/**
* Get state.
*
* @return Current state.
*/
TransmitterIR::State TransmitterIR::getState(void) {
LOCK();
State s = work.state;
UNLOCK();
return s;
}
/**
* Set data.
*
* @param format Format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the data.
*
* @return Data bit length.
*/
int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) {
LOCK();
if (work.state != Idle) {
UNLOCK();
return -1;
}
work.state = Leader;
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
data.format = format;
data.bitlength = bitlength;
const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
for (int i = 0; i < n; i++) {
data.buffer[i] = buf[i];
}
switch (format) {
case RemoteIR::NEC:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_NEC);
break;
case RemoteIR::AEHA:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_AEHA);
break;
case RemoteIR::SONY:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_SONY);
break;
}
UNLOCK();
return bitlength;
}
void TransmitterIR::tick(void) {
LOCK();
switch (work.state) {
case Idle:
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
break;
case Leader:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
static const int LEADER_NEC_HEAD = 16;
static const int LEADER_NEC_TAIL = 8;
if (work.leader < LEADER_NEC_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) {
work.state = Data;
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
static const int LEADER_AEHA_HEAD = 8;
static const int LEADER_AEHA_TAIL = 4;
if (work.leader < LEADER_AEHA_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) {
work.state = Data;
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
static const int LEADER_SONY_HEAD = 4;
static const int LEADER_SONY_TAIL = 0;
if (work.leader < LEADER_SONY_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) {
work.state = Data;
}
} else {
}
break;
case Data:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
if (work.data == 0) {
tx.write(0.5);
work.data++;
} else {
tx.write(0.0);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (3 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
if (work.data == 0) {
tx.write(0.5);
work.data++;
} else {
tx.write(0.0);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (3 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
if (work.data == 0) {
tx.write(0.0);
work.data++;
} else {
tx.write(0.5);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (2 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else {
}
break;
case Trailer:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
static const int TRAILER_NEC_HEAD = 1;
static const int TRAILER_NEC_TAIL = 2;
if (work.trailer < TRAILER_NEC_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
static const int TRAILER_AEHA_HEAD = 1;
static const int TRAILER_AEHA_TAIL = 8000 / RemoteIR::TUS_AEHA;
if (work.trailer < TRAILER_AEHA_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
static const int TRAILER_SONY_HEAD = 0;
static const int TRAILER_SONY_TAIL = 0;
if (work.trailer < TRAILER_SONY_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else {
}
break;
default:
break;
}
UNLOCK();
}
* IR transmitter (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#include "TransmitterIR.h"
#define LOCK()
#define UNLOCK()
/**
* Constructor.
*
* @param txpin Pin for transmit IR signal.
*/
TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) {
tx.write(0.0);
tx.period_us(26.3);
work.state = Idle;
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
data.format = RemoteIR::UNKNOWN;
data.bitlength = 0;
}
/**
* Destructor.
*/
TransmitterIR::~TransmitterIR() {
}
/**
* Get state.
*
* @return Current state.
*/
TransmitterIR::State TransmitterIR::getState(void) {
LOCK();
State s = work.state;
UNLOCK();
return s;
}
/**
* Set data.
*
* @param format Format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the data.
*
* @return Data bit length.
*/
int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) {
LOCK();
if (work.state != Idle) {
UNLOCK();
return -1;
}
work.state = Leader;
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
data.format = format;
data.bitlength = bitlength;
const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
for (int i = 0; i < n; i++) {
data.buffer[i] = buf[i];
}
switch (format) {
case RemoteIR::NEC:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_NEC);
break;
case RemoteIR::AEHA:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_AEHA);
break;
case RemoteIR::SONY:
ticker.detach();
ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_SONY);
break;
}
UNLOCK();
return bitlength;
}
void TransmitterIR::tick(void) {
LOCK();
switch (work.state) {
case Idle:
work.bitcount = 0;
work.leader = 0;
work.data = 0;
work.trailer = 0;
break;
case Leader:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
static const int LEADER_NEC_HEAD = 16;
static const int LEADER_NEC_TAIL = 8;
if (work.leader < LEADER_NEC_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) {
work.state = Data;
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
static const int LEADER_AEHA_HEAD = 8;
static const int LEADER_AEHA_TAIL = 4;
if (work.leader < LEADER_AEHA_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) {
work.state = Data;
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
static const int LEADER_SONY_HEAD = 4;
static const int LEADER_SONY_TAIL = 0;
if (work.leader < LEADER_SONY_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.leader++;
if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) {
work.state = Data;
}
} else {
}
break;
case Data:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
if (work.data == 0) {
tx.write(0.5);
work.data++;
} else {
tx.write(0.0);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (3 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
if (work.data == 0) {
tx.write(0.5);
work.data++;
} else {
tx.write(0.0);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (3 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
if (work.data == 0) {
tx.write(0.0);
work.data++;
} else {
tx.write(0.5);
if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) {
if (2 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
} else {
if (1 <= work.data) {
work.bitcount++;
work.data = 0;
} else {
work.data++;
}
}
}
if (data.bitlength <= work.bitcount) {
work.state = Trailer;
}
} else {
}
break;
case Trailer:
if (data.format == RemoteIR::NEC) {
/*
* NEC.
*/
static const int TRAILER_NEC_HEAD = 1;
static const int TRAILER_NEC_TAIL = 2;
if (work.trailer < TRAILER_NEC_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else if (data.format == RemoteIR::AEHA) {
/*
* AEHA.
*/
static const int TRAILER_AEHA_HEAD = 1;
static const int TRAILER_AEHA_TAIL = 8000 / RemoteIR::TUS_AEHA;
if (work.trailer < TRAILER_AEHA_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else if (data.format == RemoteIR::SONY) {
/*
* SONY.
*/
static const int TRAILER_SONY_HEAD = 0;
static const int TRAILER_SONY_TAIL = 0;
if (work.trailer < TRAILER_SONY_HEAD) {
tx.write(0.5);
} else {
tx.write(0.0);
}
work.trailer++;
if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) {
work.state = Idle;
//ticker.detach();
}
} else {
}
break;
default:
break;
}
UNLOCK();
}
XxXxXxXxXxXxXxXxXxXxXxXxXxXx TransmitterIR.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx
/**
* IR transmitter (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _TRANSMITTER_IR_H_
#define _TRANSMITTER_IR_H_
#include <mbed.h>
#include "RemoteIR.h"
/**
* IR transmitter class.
*/
class TransmitterIR {
public:
/**
* Constructor.
*
* @param txpin Pin for transmit IR signal.
*/
explicit TransmitterIR(PinName txpin);
/**
* Destructor.
*/
~TransmitterIR();
typedef enum {
Idle,
Leader,
Data,
Trailer
} State;
/**
* Get state.
*
* @return Current state.
*/
State getState(void);
/**
* Set data.
*
* @param format Format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the data.
*
* @return Data bit length.
*/
int setData(RemoteIR::Format format, uint8_t *buf, int bitlength);
private:
typedef struct {
State state;
int bitcount;
int leader;
int data;
int trailer;
} work_t;
typedef struct {
RemoteIR::Format format;
int bitlength;
uint8_t buffer[64];
} data_t;
PwmOut tx;
Ticker ticker;
data_t data;
work_t work;
void tick();
};
#endif
* IR transmitter (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _TRANSMITTER_IR_H_
#define _TRANSMITTER_IR_H_
#include <mbed.h>
#include "RemoteIR.h"
/**
* IR transmitter class.
*/
class TransmitterIR {
public:
/**
* Constructor.
*
* @param txpin Pin for transmit IR signal.
*/
explicit TransmitterIR(PinName txpin);
/**
* Destructor.
*/
~TransmitterIR();
typedef enum {
Idle,
Leader,
Data,
Trailer
} State;
/**
* Get state.
*
* @return Current state.
*/
State getState(void);
/**
* Set data.
*
* @param format Format.
* @param buf Buffer of a data.
* @param bitlength Bit length of the data.
*
* @return Data bit length.
*/
int setData(RemoteIR::Format format, uint8_t *buf, int bitlength);
private:
typedef struct {
State state;
int bitcount;
int leader;
int data;
int trailer;
} work_t;
typedef struct {
RemoteIR::Format format;
int bitlength;
uint8_t buffer[64];
} data_t;
PwmOut tx;
Ticker ticker;
data_t data;
work_t work;
void tick();
};
#endif
XxXxXxXxXxXxXxXxXxXxXxXxXxXx RemoteIR.h XxXxXxXxXxXxXxXxXxXxXxXxXxXx
/**
* IR remote common class (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _REMOTE_IR_H_
#define _REMOTE_IR_H_
class RemoteIR {
public:
typedef enum {
UNKNOWN,
NEC,
NEC_REPEAT,
AEHA,
AEHA_REPEAT,
SONY
} Format;
static const int TUS_NEC = 562;
static const int TUS_AEHA = 425;
static const int TUS_SONY = 600;
private:
RemoteIR();
};
#endif
* IR remote common class (Version 0.0.4)
*
* Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
* http://shinta.main.jp/
*/
#ifndef _REMOTE_IR_H_
#define _REMOTE_IR_H_
class RemoteIR {
public:
typedef enum {
UNKNOWN,
NEC,
NEC_REPEAT,
AEHA,
AEHA_REPEAT,
SONY
} Format;
static const int TUS_NEC = 562;
static const int TUS_AEHA = 425;
static const int TUS_SONY = 600;
private:
RemoteIR();
};
#endif
XxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXx
No comments:
Post a Comment