NEC Near Field Communication RF module library for mbed H001-000003-001 (950MHz), H001-000013-001 (920MHz), TY24FM-E2024 (2.4GHz)

Dependents:   NECnfc_sample Drone_air Drone_ground

NEC Near Field Communication RF module library

NEC製の近距離無線モジュール用のライブラリです。

詳細はこちら

NECnfc.cpp

Committer:
okini3939
Date:
2012-07-17
Revision:
0:337524afec9b
Child:
1:5d157700a95d

File content as of revision 0:337524afec9b:

/**
 * NEC Near Field Communication RF module library for mbed
 * Copyright (c) 2012 Suga
 * Released under the MIT License: http://mbed.org/license/mit
 */

/** @file
 * @brief NEC Near Field Communication RF module library for mbed
 * @note H001-000003-001 (950MHz), TY24FM-E2024 (2.4GHz)
 */

#include "mbed.h"
#include "NECnfc.h"
#include "dbg.h"
#include <string.h>


// host to network short
#define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) )
#define ntohs( x ) htons(x)
// host to network long
#define htonl( x ) ( (( (x) << 24 ) & 0xFF000000)  \
                   | (( (x) <<  8 ) & 0x00FF0000)  \
                   | (( (x) >>  8 ) & 0x0000FF00)  \
                   | (( (x) >> 24 ) & 0x000000FF)  )
#define ntohl( x ) htonl(x)


NECnfc::NECnfc (PinName p_tx, PinName p_rx, PinName p_reset) : rf(p_tx, p_rx), reset(p_reset) {
    rxbuf = (char *)&rxmsg;
    msgno = 0;
    rxlen = 0;
    rxmode = 0;
    rxflg = 0;
}

int NECnfc::begin (int ch, NECBAUD baud, NECUART uart, NECPWR power, NECTYPE type) {
    int no;
    struct ifMessage ifmsg;
    // high power, retry 0
    char rfconf9[] = {power, ch, baud, 1, 0, uart, 1, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x00, 0x00, 0x83, 0x41};
    char rfconf2[] = {ch, power, 0, 1, 2, 1, 0, 1, 0, 1, 2, 0xff, 0xff,
        0, 0, 0, 1, 0, 0x00, 0x00, 0x83, 0x41};
    
    rf.baud(38400);
    rf.attach(this, &NECnfc::isr_rx, Serial::RxIrq);

    reset = 0; // reset
    wait_ms(100);
    reset = 1;
    wait_ms(100);

    if (type == NECTYPE_950MHz) {
        no = send(NECMSG_WRITE_CONFIG, 0xffffffff, rfconf9, sizeof(rfconf9));
    } else {
        return 0;
        rfconf2[1] = (power == NECPWR_HIGH ? 8 : 0);
        no = send(NECMSG_WRITE_CONFIG, 0xffffffff, rfconf2, sizeof(rfconf2));
    }
    DBG("rfconf %d\r\n", no);
    if (! read(&ifmsg) || ifmsg.msgid != NECMSG_ACK || ifmsg.msgno != no) {
        return -1;
    }

    switch (uart) {
    case UART_4800:
        rf.baud(4800);
        break;
    case UART_9600:
        rf.baud(9600);
        break;
    case UART_19200:
        rf.baud(19200);
        break;
    case UART_38400:
        rf.baud(38400);
        break;
    case UART_56700:
        rf.baud(56700);
        break;
    case UART_115200:
        rf.baud(115200);
        break;
    }

    return 0;
}

void NECnfc::isr_rx () {
    char dat;
    
    dat = rf.getc();
    DBG("%02x ", dat);
    
    if (dat == 0x0f) {
        // start (1/2)
        rxmode = 1;
    } else
    if (rxmode == 1) {
        if (dat == 0x5a) {
            // start (2/2)
            rxmode = 2;
            rxlen = 0;
            rxbuf[rxlen] = 0x0f;
            rxlen ++;
            rxbuf[rxlen] = dat;
            rxlen ++;
        } else {
            if (rxlen) {
                // continue (data)
                rxmode = 2;
                rxbuf[rxlen] = 0x0f;
                rxlen ++;
                rxbuf[rxlen] = dat;
                rxlen ++;
            } else {
                // unknown
                rxmode = 0;
            }
        }
    } else
    if (rxmode == 2) {
        // data
        rxbuf[rxlen] = dat;
        rxlen ++;
        if (rxlen >= rxmsg.length) {
            rxmode = 3;
            rxflg = 1;
        }
    }
}

int NECnfc::send (int msgid, unsigned long dest, char *param, int len) {
    int i;
    struct ifMessage ifmsg;
    unsigned char *buf = (unsigned char *)&ifmsg;

    if (len > 240) len = 240;
    msgno ++;
    ifmsg.start = htons(0x0f5a);
    ifmsg.length = 13 + len;
    ifmsg.msgid = msgid;
    ifmsg.msgno = msgno;
    ifmsg.dstid = htonl(dest);
    ifmsg.srcid = htonl(0xffffffff);
    memcpy(ifmsg.parameter, param, len);
    
    for (i = 0; i < ifmsg.length; i ++) {
        rf.putc(buf[i]);
    }

    return ifmsg.msgno;
}

int NECnfc::read (struct ifMessage *ifmsg, int timeout) {
    Timer timer;

    timer.start();
    while (timer.read_ms() < timeout) {
        if (rxflg) {
            memcpy(ifmsg, &rxmsg, rxlen);
            rxflg = 0;
            rxmode = 0;
            return rxlen;
        }
    }
    return 0;
}

int NECnfc::readable () {
    return rxflg;
}