NFC API for mbed using the MicroNFCBoard as a peripheral
Dependents: MicroNFCBoardAPI_P2P_Client MicroNFCBoardAPI_Blink MicroNFCBoardAPI_Tag_Emulator MicroNFCBoardAPI_Tag_Reader ... more
transport.cpp
- Committer:
- AppNearMe
- Date:
- 2015-04-24
- Revision:
- 0:07fa9c0dd549
- Child:
- 1:1d246e0872c6
File content as of revision 0:07fa9c0dd549:
/** * \file transport.cpp * \copyright Copyright (c) AppNearMe Ltd 2015 * \author Donatien Garnier */ #include "transport.h" //MSB first #define WRITE_UINT32( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 24 ) & 0xFF; \ *(((uint8_t*)(addr)) + 1) = ((val) >> 16 ) & 0xFF; \ *(((uint8_t*)(addr)) + 2) = ((val) >> 8 ) & 0xFF; \ *(((uint8_t*)(addr)) + 3) = ((val) >> 0 ) & 0xFF; } while(0) #define WRITE_UINT16( addr, val ) do{ *(((uint8_t*)(addr)) + 0) = ((val) >> 8 ) & 0xFF; \ *(((uint8_t*)(addr)) + 1) = ((val) >> 0 ) & 0xFF; } while(0) //MSB first #define READ_UINT32( addr, val ) do{ val = (*(((uint8_t*)(addr)) + 0) << 24 ) \ | (*(((uint8_t*)(addr)) + 1) << 16 ) \ | (*(((uint8_t*)(addr)) + 2) << 8 ) \ | (*(((uint8_t*)(addr)) + 3) << 0 ); } while(0) #define READ_UINT16( addr, val ) do{ val = (*(((uint8_t*)(addr)) + 0) << 8 ) \ | (*(((uint8_t*)(addr)) + 1) << 0 ); } while(0) Transport::Transport(PinName mosi, PinName miso, PinName sck, PinName cs, PinName irq) : \ _cs(cs), _spi(mosi, miso, sck), _int(irq) { } void Transport::init() { _spi.format(8, 1); _spi.frequency(100000); _cs = 1; for(int i = 0; i < 64; i++) { _cs = 0; _spi.write(0); _cs = 1; } } void Transport::reset() { uint8_t out[] = {0}; command(Transport::RESET, out, sizeof(out), NULL, 0); } bool Transport::statusChanged() { return (_int.read() != 0); } uint32_t Transport::status() { uint8_t in[4]; command(Transport::GET_STATUS, NULL, 0, in, sizeof(in)); uint32_t status; READ_UINT32(&in[0], status); return status; } void Transport::nfcPoll(bool enable) { uint8_t out[] = {enable?1:0}; command(Transport::NFC_POLL, out, sizeof(out), NULL, 0); } void Transport::nfcOperation(bool readOp, bool writeOp) { uint8_t out[1]; if(readOp) { out[0] = 1; } else if(writeOp) { out[0] = 2; } else { out[0] = 0; } command(Transport::NFC_OPERATION, out, sizeof(out), NULL, 0); } void Transport::nfcGetInfoIsoA(uint8_t* atqa, uint8_t* sak, uint8_t* uid, size_t* pUidLength) { uint8_t in[2 + 1 + 1 + 10]; command(Transport::NFC_GET_INFO, NULL, 0, in, sizeof(in)); memcpy(atqa, &in[0], 2); *sak = in[2]; *pUidLength = in[3]; memcpy(uid, &in[4], *pUidLength); } void Transport::nfcGetMessageInfo(size_t* pRecordCount) { uint8_t in[2]; command(Transport::NFC_GET_MESSAGE_INFO, NULL, 0, in, sizeof(in)); READ_UINT16(&in[0], *pRecordCount); } void Transport::nfcSetMessageInfo(size_t recordCount) { uint8_t out[2]; WRITE_UINT16(&out[0], recordCount); command(Transport::NFC_SET_MESSAGE_INFO, out, sizeof(out), NULL, 0); } void Transport::nfcGetRecordInfo(size_t recordNumber, uint16_t* pType, uint16_t* info, size_t infoCount) { uint8_t out[2]; uint8_t in[2+2*infoCount]; WRITE_UINT16(&out[0], recordNumber); command(Transport::NFC_GET_RECORD_INFO, out, sizeof(out), in, sizeof(in)); READ_UINT16(&in[0], *pType); for(int i = 0; i < infoCount; i++) { READ_UINT16(&in[2+2*i], info[i]); } } void Transport::nfcSetRecordInfo(size_t recordNumber, uint16_t type, uint16_t* info, size_t infoCount) { uint8_t out[2+2+2*infoCount]; WRITE_UINT16(&out[0], recordNumber); WRITE_UINT16(&out[2], type); for(int i = 0; i < infoCount; i++) { WRITE_UINT16(&out[2+2+2*i], info[i]); } command(Transport::NFC_SET_RECORD_INFO, out, sizeof(out), NULL, 0); } void Transport::nfcGetRecordData(size_t recordNumber, size_t item, size_t offset, uint8_t* data, size_t length) { uint8_t out[7]; WRITE_UINT16(&out[0], recordNumber); out[2] = item; WRITE_UINT16(&out[3], offset); WRITE_UINT16(&out[5], length); command(Transport::NFC_GET_RECORD_DATA, out, sizeof(out), data, length); } void Transport::nfcSetRecordData(size_t recordNumber, size_t item, size_t offset, uint8_t* data, size_t length) { uint8_t out[7+length]; WRITE_UINT16(&out[0], recordNumber); out[2] = item; WRITE_UINT16(&out[3], offset); WRITE_UINT16(&out[5], length); memcpy(&out[7], data, length); command(Transport::NFC_SET_RECORD_DATA, out, sizeof(out), NULL, 0); } void Transport::nfcPrepareMessage(bool lock, bool generate) { uint8_t out[1]; if(lock) { out[0] = 1; } else if(generate) { out[0] = 2; } else { out[0] = 0; } command(Transport::NFC_POLL, out, sizeof(out), NULL, 0); } void Transport::nfcDecodePrefix(uint8_t prefix, char* data, size_t* pDataLength) { uint8_t out[] = { prefix }; uint8_t in[2 + 36]; //max prefix length is 36 command(Transport::NFC_DECODE_PREFIX, out, sizeof(out), in, sizeof(in)); size_t length; READ_UINT16(&in[0], length); if(length < *pDataLength) { *pDataLength = length; } memcpy(data, &in[2], *pDataLength); } void Transport::nfcEncodePrefix(uint8_t* pPrefix, char* data, size_t dataLength) { uint8_t out[2 + dataLength]; uint8_t in[1]; WRITE_UINT16(&out[0], dataLength); memcpy(data, &out[2], dataLength); command(Transport::NFC_ENCODE_PREFIX, out, sizeof(out), in, sizeof(in)); *pPrefix = in[0]; } void Transport::leds(bool led1, bool led2) { uint8_t out[] = {led1?1:0, led2?1:0}; command(Transport::LEDS, out, sizeof(out), NULL, 0); } Transport::CommandError Transport::command(Transport::CommandCode command, uint8_t* outBuf, size_t outLength, uint8_t* inBuf, size_t inLength) { _cs = 0; _spi.write((uint8_t)((outLength + 1) & 0xFF)); _cs = 1; _cs = 0; _spi.write((uint8_t)(command & 0xFF)); _cs = 1; for(int i = 0; i < outLength; i++) { _cs = 0; _spi.write(outBuf[i]); _cs = 1; } size_t length = 0; while(length == 0) { _cs = 0; length = _spi.write(0); _cs = 1; } _cs = 0; Transport::CommandCode retCmd = (Transport::CommandCode)_spi.write(0); length--; _cs = 1; _cs = 0; Transport::CommandError ret = (Transport::CommandError)_spi.write(0); length--; _cs = 1; for(int i = 0; i < length; i++) { _cs = 0; if(i < inLength) { inBuf[i] = _spi.write(0); } else { _spi.write(0); } _cs = 1; } return ret; }