Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: NECnfc_sample Drone_air Drone_ground
NECnfc.cpp@2:9e108187ccfe, 2015-08-27 (annotated)
- Committer:
- okini3939
- Date:
- Thu Aug 27 05:41:24 2015 +0000
- Revision:
- 2:9e108187ccfe
- Parent:
- 1:5d157700a95d
- Child:
- 4:07e752ff8dce
920MHz supported
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| okini3939 | 0:337524afec9b | 1 | /** |
| okini3939 | 0:337524afec9b | 2 | * NEC Near Field Communication RF module library for mbed |
| okini3939 | 0:337524afec9b | 3 | * Copyright (c) 2012 Suga |
| okini3939 | 0:337524afec9b | 4 | * Released under the MIT License: http://mbed.org/license/mit |
| okini3939 | 0:337524afec9b | 5 | */ |
| okini3939 | 0:337524afec9b | 6 | |
| okini3939 | 0:337524afec9b | 7 | /** @file |
| okini3939 | 0:337524afec9b | 8 | * @brief NEC Near Field Communication RF module library for mbed |
| okini3939 | 2:9e108187ccfe | 9 | * @note H001-000003-001 (950MHz), TY24FM-E2024 (2.4GHz), H001-000013-001 (920MHz) |
| okini3939 | 0:337524afec9b | 10 | */ |
| okini3939 | 0:337524afec9b | 11 | |
| okini3939 | 0:337524afec9b | 12 | #include "mbed.h" |
| okini3939 | 0:337524afec9b | 13 | #include "NECnfc.h" |
| okini3939 | 0:337524afec9b | 14 | #include <string.h> |
| okini3939 | 0:337524afec9b | 15 | |
| okini3939 | 0:337524afec9b | 16 | |
| okini3939 | 0:337524afec9b | 17 | // host to network short |
| okini3939 | 0:337524afec9b | 18 | #define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) ) |
| okini3939 | 0:337524afec9b | 19 | #define ntohs( x ) htons(x) |
| okini3939 | 0:337524afec9b | 20 | // host to network long |
| okini3939 | 0:337524afec9b | 21 | #define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \ |
| okini3939 | 0:337524afec9b | 22 | | (( (x) << 8 ) & 0x00FF0000) \ |
| okini3939 | 0:337524afec9b | 23 | | (( (x) >> 8 ) & 0x0000FF00) \ |
| okini3939 | 0:337524afec9b | 24 | | (( (x) >> 24 ) & 0x000000FF) ) |
| okini3939 | 0:337524afec9b | 25 | #define ntohl( x ) htonl(x) |
| okini3939 | 0:337524afec9b | 26 | |
| okini3939 | 0:337524afec9b | 27 | |
| okini3939 | 0:337524afec9b | 28 | NECnfc::NECnfc (PinName p_tx, PinName p_rx, PinName p_reset) : rf(p_tx, p_rx), reset(p_reset) { |
| okini3939 | 0:337524afec9b | 29 | rxbuf = (char *)&rxmsg; |
| okini3939 | 0:337524afec9b | 30 | msgno = 0; |
| okini3939 | 0:337524afec9b | 31 | rxlen = 0; |
| okini3939 | 0:337524afec9b | 32 | rxmode = 0; |
| okini3939 | 0:337524afec9b | 33 | rxflg = 0; |
| okini3939 | 0:337524afec9b | 34 | } |
| okini3939 | 0:337524afec9b | 35 | |
| okini3939 | 0:337524afec9b | 36 | int NECnfc::begin (int ch, NECBAUD baud, NECUART uart, NECPWR power, NECTYPE type) { |
| okini3939 | 0:337524afec9b | 37 | int no; |
| okini3939 | 0:337524afec9b | 38 | struct ifMessage ifmsg; |
| okini3939 | 0:337524afec9b | 39 | // high power, retry 0 |
| okini3939 | 0:337524afec9b | 40 | char rfconf9[] = {power, ch, baud, 1, 0, uart, 1, 0xff, 0xff, |
| okini3939 | 0:337524afec9b | 41 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| okini3939 | 2:9e108187ccfe | 42 | (NEC_SYSTEMID >> 8), (NEC_SYSTEMID & 0xff), (NEC_PRODUCTID >> 8), (NEC_PRODUCTID & 0xff)}; |
| okini3939 | 2:9e108187ccfe | 43 | char rfconf2[] = {ch, 0, 0x01, 0x08, 0x08, 0x01, 0x04, 0x0a, 0x05, 0x03, 0x05, |
| okini3939 | 2:9e108187ccfe | 44 | 0xff, 0xff, 0x00, 0, 0, 0x01, 0x51, |
| okini3939 | 2:9e108187ccfe | 45 | (NEC_SYSTEMID >> 8), (NEC_SYSTEMID & 0xff), (NEC_PRODUCTID >> 8), (NEC_PRODUCTID & 0xff)}; |
| okini3939 | 0:337524afec9b | 46 | |
| okini3939 | 0:337524afec9b | 47 | rf.baud(38400); |
| okini3939 | 0:337524afec9b | 48 | rf.attach(this, &NECnfc::isr_rx, Serial::RxIrq); |
| okini3939 | 0:337524afec9b | 49 | |
| okini3939 | 0:337524afec9b | 50 | reset = 0; // reset |
| okini3939 | 0:337524afec9b | 51 | wait_ms(100); |
| okini3939 | 0:337524afec9b | 52 | reset = 1; |
| okini3939 | 0:337524afec9b | 53 | wait_ms(100); |
| okini3939 | 0:337524afec9b | 54 | |
| okini3939 | 2:9e108187ccfe | 55 | switch (type) { |
| okini3939 | 2:9e108187ccfe | 56 | case TYPE_950MHz: |
| okini3939 | 2:9e108187ccfe | 57 | if (power == PWR_LOW && (ch < 1 || ch > 33)) return -1; |
| okini3939 | 2:9e108187ccfe | 58 | if (power >= PWR_MID && (ch < 17 || ch > 31)) return -1; |
| okini3939 | 0:337524afec9b | 59 | no = send(NECMSG_WRITE_CONFIG, 0xffffffff, rfconf9, sizeof(rfconf9)); |
| okini3939 | 2:9e108187ccfe | 60 | break; |
| okini3939 | 2:9e108187ccfe | 61 | case TYPE_920MHz: |
| okini3939 | 2:9e108187ccfe | 62 | if (power <= PWR_MID && (ch < 24 || ch > 38)) return -1; |
| okini3939 | 2:9e108187ccfe | 63 | if (power >= PWR_HIGH && (ch < 24 || ch > 37 || ch == 32)) return -1; |
| okini3939 | 2:9e108187ccfe | 64 | no = send(NECMSG_WRITE_CONFIG, 0xffffffff, rfconf9, sizeof(rfconf9)); |
| okini3939 | 2:9e108187ccfe | 65 | break; |
| okini3939 | 2:9e108187ccfe | 66 | case TYPE_2400MHz: |
| okini3939 | 2:9e108187ccfe | 67 | if (ch < 0 || ch > 15) return -1; |
| okini3939 | 2:9e108187ccfe | 68 | uart = UART_38400; |
| okini3939 | 2:9e108187ccfe | 69 | rfconf2[1] = (power >= PWR_HIGH ? 0x0f : 0x00); |
| okini3939 | 0:337524afec9b | 70 | no = send(NECMSG_WRITE_CONFIG, 0xffffffff, rfconf2, sizeof(rfconf2)); |
| okini3939 | 0:337524afec9b | 71 | } |
| okini3939 | 0:337524afec9b | 72 | if (! read(&ifmsg) || ifmsg.msgid != NECMSG_ACK || ifmsg.msgno != no) { |
| okini3939 | 0:337524afec9b | 73 | return -1; |
| okini3939 | 0:337524afec9b | 74 | } |
| okini3939 | 0:337524afec9b | 75 | |
| okini3939 | 0:337524afec9b | 76 | switch (uart) { |
| okini3939 | 0:337524afec9b | 77 | case UART_4800: |
| okini3939 | 0:337524afec9b | 78 | rf.baud(4800); |
| okini3939 | 0:337524afec9b | 79 | break; |
| okini3939 | 0:337524afec9b | 80 | case UART_9600: |
| okini3939 | 0:337524afec9b | 81 | rf.baud(9600); |
| okini3939 | 0:337524afec9b | 82 | break; |
| okini3939 | 0:337524afec9b | 83 | case UART_19200: |
| okini3939 | 0:337524afec9b | 84 | rf.baud(19200); |
| okini3939 | 0:337524afec9b | 85 | break; |
| okini3939 | 0:337524afec9b | 86 | case UART_38400: |
| okini3939 | 0:337524afec9b | 87 | rf.baud(38400); |
| okini3939 | 0:337524afec9b | 88 | break; |
| okini3939 | 0:337524afec9b | 89 | case UART_56700: |
| okini3939 | 0:337524afec9b | 90 | rf.baud(56700); |
| okini3939 | 0:337524afec9b | 91 | break; |
| okini3939 | 0:337524afec9b | 92 | case UART_115200: |
| okini3939 | 0:337524afec9b | 93 | rf.baud(115200); |
| okini3939 | 0:337524afec9b | 94 | break; |
| okini3939 | 0:337524afec9b | 95 | } |
| okini3939 | 0:337524afec9b | 96 | |
| okini3939 | 0:337524afec9b | 97 | return 0; |
| okini3939 | 0:337524afec9b | 98 | } |
| okini3939 | 0:337524afec9b | 99 | |
| okini3939 | 0:337524afec9b | 100 | void NECnfc::isr_rx () { |
| okini3939 | 0:337524afec9b | 101 | char dat; |
| okini3939 | 0:337524afec9b | 102 | |
| okini3939 | 0:337524afec9b | 103 | dat = rf.getc(); |
| okini3939 | 2:9e108187ccfe | 104 | DBG(" %02x", dat); |
| okini3939 | 0:337524afec9b | 105 | |
| okini3939 | 0:337524afec9b | 106 | if (dat == 0x0f) { |
| okini3939 | 0:337524afec9b | 107 | // start (1/2) |
| okini3939 | 0:337524afec9b | 108 | rxmode = 1; |
| okini3939 | 0:337524afec9b | 109 | } else |
| okini3939 | 0:337524afec9b | 110 | if (rxmode == 1) { |
| okini3939 | 0:337524afec9b | 111 | if (dat == 0x5a) { |
| okini3939 | 0:337524afec9b | 112 | // start (2/2) |
| okini3939 | 0:337524afec9b | 113 | rxmode = 2; |
| okini3939 | 0:337524afec9b | 114 | rxlen = 0; |
| okini3939 | 0:337524afec9b | 115 | rxbuf[rxlen] = 0x0f; |
| okini3939 | 0:337524afec9b | 116 | rxlen ++; |
| okini3939 | 0:337524afec9b | 117 | rxbuf[rxlen] = dat; |
| okini3939 | 0:337524afec9b | 118 | rxlen ++; |
| okini3939 | 0:337524afec9b | 119 | } else { |
| okini3939 | 0:337524afec9b | 120 | if (rxlen) { |
| okini3939 | 0:337524afec9b | 121 | // continue (data) |
| okini3939 | 0:337524afec9b | 122 | rxmode = 2; |
| okini3939 | 0:337524afec9b | 123 | rxbuf[rxlen] = 0x0f; |
| okini3939 | 0:337524afec9b | 124 | rxlen ++; |
| okini3939 | 0:337524afec9b | 125 | rxbuf[rxlen] = dat; |
| okini3939 | 0:337524afec9b | 126 | rxlen ++; |
| okini3939 | 0:337524afec9b | 127 | } else { |
| okini3939 | 0:337524afec9b | 128 | // unknown |
| okini3939 | 0:337524afec9b | 129 | rxmode = 0; |
| okini3939 | 0:337524afec9b | 130 | } |
| okini3939 | 0:337524afec9b | 131 | } |
| okini3939 | 0:337524afec9b | 132 | } else |
| okini3939 | 0:337524afec9b | 133 | if (rxmode == 2) { |
| okini3939 | 0:337524afec9b | 134 | // data |
| okini3939 | 0:337524afec9b | 135 | rxbuf[rxlen] = dat; |
| okini3939 | 0:337524afec9b | 136 | rxlen ++; |
| okini3939 | 0:337524afec9b | 137 | if (rxlen >= rxmsg.length) { |
| okini3939 | 0:337524afec9b | 138 | rxmode = 3; |
| okini3939 | 0:337524afec9b | 139 | rxflg = 1; |
| okini3939 | 0:337524afec9b | 140 | } |
| okini3939 | 0:337524afec9b | 141 | } |
| okini3939 | 0:337524afec9b | 142 | } |
| okini3939 | 0:337524afec9b | 143 | |
| okini3939 | 2:9e108187ccfe | 144 | int NECnfc::send (NECMSG msgid, unsigned long dest, char *param, int len) { |
| okini3939 | 0:337524afec9b | 145 | int i; |
| okini3939 | 0:337524afec9b | 146 | struct ifMessage ifmsg; |
| okini3939 | 0:337524afec9b | 147 | unsigned char *buf = (unsigned char *)&ifmsg; |
| okini3939 | 0:337524afec9b | 148 | |
| okini3939 | 2:9e108187ccfe | 149 | if (len > NEC_MAXLENGTH) len = NEC_MAXLENGTH; |
| okini3939 | 0:337524afec9b | 150 | msgno ++; |
| okini3939 | 0:337524afec9b | 151 | ifmsg.start = htons(0x0f5a); |
| okini3939 | 0:337524afec9b | 152 | ifmsg.length = 13 + len; |
| okini3939 | 0:337524afec9b | 153 | ifmsg.msgid = msgid; |
| okini3939 | 0:337524afec9b | 154 | ifmsg.msgno = msgno; |
| okini3939 | 0:337524afec9b | 155 | ifmsg.dstid = htonl(dest); |
| okini3939 | 0:337524afec9b | 156 | ifmsg.srcid = htonl(0xffffffff); |
| okini3939 | 0:337524afec9b | 157 | memcpy(ifmsg.parameter, param, len); |
| okini3939 | 0:337524afec9b | 158 | |
| okini3939 | 2:9e108187ccfe | 159 | DBG("\r\n"); |
| okini3939 | 0:337524afec9b | 160 | for (i = 0; i < ifmsg.length; i ++) { |
| okini3939 | 0:337524afec9b | 161 | rf.putc(buf[i]); |
| okini3939 | 2:9e108187ccfe | 162 | DBG("_%02x", buf[i]); |
| okini3939 | 0:337524afec9b | 163 | } |
| okini3939 | 2:9e108187ccfe | 164 | DBG("\r\n"); |
| okini3939 | 0:337524afec9b | 165 | |
| okini3939 | 0:337524afec9b | 166 | return ifmsg.msgno; |
| okini3939 | 0:337524afec9b | 167 | } |
| okini3939 | 0:337524afec9b | 168 | |
| okini3939 | 0:337524afec9b | 169 | int NECnfc::read (struct ifMessage *ifmsg, int timeout) { |
| okini3939 | 0:337524afec9b | 170 | Timer timer; |
| okini3939 | 0:337524afec9b | 171 | |
| okini3939 | 0:337524afec9b | 172 | timer.start(); |
| okini3939 | 0:337524afec9b | 173 | while (timer.read_ms() < timeout) { |
| okini3939 | 0:337524afec9b | 174 | if (rxflg) { |
| okini3939 | 0:337524afec9b | 175 | memcpy(ifmsg, &rxmsg, rxlen); |
| okini3939 | 0:337524afec9b | 176 | rxflg = 0; |
| okini3939 | 0:337524afec9b | 177 | rxmode = 0; |
| okini3939 | 0:337524afec9b | 178 | return rxlen; |
| okini3939 | 0:337524afec9b | 179 | } |
| okini3939 | 0:337524afec9b | 180 | } |
| okini3939 | 0:337524afec9b | 181 | return 0; |
| okini3939 | 0:337524afec9b | 182 | } |
| okini3939 | 0:337524afec9b | 183 | |
| okini3939 | 0:337524afec9b | 184 | int NECnfc::readable () { |
| okini3939 | 0:337524afec9b | 185 | return rxflg; |
| okini3939 | 0:337524afec9b | 186 | } |