ChoroQ

TransmitterChoroQ.cpp

Committer:
shintamainjp
Date:
2010-09-19
Revision:
1:97921a2adf78
Parent:
0:2a40e6db61c2

File content as of revision 1:97921a2adf78:

/**
 * CHORO Q HYBRID transmitter (Version 0.0.1)
 *
 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
 * http://shinta.main.jp/
 */

#include "TransmitterChoroQ.h"

#define LOCK()
#define UNLOCK()

    /**
     * Constructor.
     *
     * @param txpin Pin for transmit IR signal.
     */
TransmitterChoroQ::TransmitterChoroQ(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.bitlength = 0;
}

    /**
     * Destructor.
     */
TransmitterChoroQ::~TransmitterChoroQ() {
}

    /**
     * Get state.
     *
     * @return Current state.
     */
TransmitterChoroQ::State TransmitterChoroQ::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 TransmitterChoroQ::setData(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.bitlength = bitlength;
    const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0);
    for (int i = 0; i < n; i++) {
        data.buffer[i] = buf[i];
    }

    static const double correction = 1.20;
    ticker.detach();
    ticker.attach_us(this, &TransmitterChoroQ::tick, TUS_TAKARATOMY * correction);

    UNLOCK();
    return bitlength;
}

void TransmitterChoroQ::tick(void) {
    LOCK();
    switch (work.state) {
        case Idle:
            work.bitcount = 0;
            work.leader = 0;
            work.data = 0;
            work.trailer = 0;
            break;
        case Leader:
            /*
             * TAKARA TOMY.
             */
            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;
            }
            break;
        case Data:
            /*
             * TAKARA TOMY.
             */
            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;
            }
            break;
        case Trailer:
            /*
             * TAKARA TOMY.
             */
            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();
            }
            break;
        default:
            break;
    }
    UNLOCK();
}