Moved to /rf
authorKevin Townsend <kevin@ktownsend.com>
Sat, 10 Mar 2012 00:44:48 +0000 (01:44 +0100)
committerKevin Townsend <kevin@ktownsend.com>
Sat, 10 Mar 2012 00:44:48 +0000 (01:44 +0100)
42 files changed:
drivers/chibi/chb.c [deleted file]
drivers/chibi/chb.h [deleted file]
drivers/chibi/chb_buf.c [deleted file]
drivers/chibi/chb_buf.h [deleted file]
drivers/chibi/chb_drvr.c [deleted file]
drivers/chibi/chb_drvr.h [deleted file]
drivers/chibi/chb_eeprom.c [deleted file]
drivers/chibi/chb_eeprom.h [deleted file]
drivers/chibi/chb_spi.c [deleted file]
drivers/chibi/chb_spi.h [deleted file]
drivers/chibi/types.h [deleted file]
drivers/rf/chibi/chb.c [new file with mode: 0644]
drivers/rf/chibi/chb.h [new file with mode: 0644]
drivers/rf/chibi/chb_buf.c [new file with mode: 0644]
drivers/rf/chibi/chb_buf.h [new file with mode: 0644]
drivers/rf/chibi/chb_drvr.c [new file with mode: 0644]
drivers/rf/chibi/chb_drvr.h [new file with mode: 0644]
drivers/rf/chibi/chb_eeprom.c [new file with mode: 0644]
drivers/rf/chibi/chb_eeprom.h [new file with mode: 0644]
drivers/rf/chibi/chb_spi.c [new file with mode: 0644]
drivers/rf/chibi/chb_spi.h [new file with mode: 0644]
drivers/rf/chibi/types.h [new file with mode: 0644]
drivers/rf/pn532/helpers/pn532_mifare.h [new file with mode: 0644]
drivers/rf/pn532/helpers/pn532_mifare_classic.c [new file with mode: 0644]
drivers/rf/pn532/helpers/pn532_mifare_classic.h [new file with mode: 0644]
drivers/rf/pn532/helpers/pn532_mifare_ultralight.c [new file with mode: 0644]
drivers/rf/pn532/helpers/pn532_mifare_ultralight.h [new file with mode: 0644]
drivers/rf/pn532/pn532.c [new file with mode: 0644]
drivers/rf/pn532/pn532.h [new file with mode: 0644]
drivers/rf/pn532/pn532_bus.h [new file with mode: 0644]
drivers/rf/pn532/pn532_bus_i2c.c [new file with mode: 0644]
drivers/rf/pn532/pn532_bus_uart.c [new file with mode: 0644]
drivers/sensors/pn532/helpers/pn532_mifare.h [deleted file]
drivers/sensors/pn532/helpers/pn532_mifare_classic.c [deleted file]
drivers/sensors/pn532/helpers/pn532_mifare_classic.h [deleted file]
drivers/sensors/pn532/helpers/pn532_mifare_ultralight.c [deleted file]
drivers/sensors/pn532/helpers/pn532_mifare_ultralight.h [deleted file]
drivers/sensors/pn532/pn532.c [deleted file]
drivers/sensors/pn532/pn532.h [deleted file]
drivers/sensors/pn532/pn532_bus.h [deleted file]
drivers/sensors/pn532/pn532_bus_i2c.c [deleted file]
drivers/sensors/pn532/pn532_bus_uart.c [deleted file]

diff --git a/drivers/chibi/chb.c b/drivers/chibi/chb.c
deleted file mode 100644 (file)
index 2c02f1a..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-    
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-    
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#include <stdio.h>
-#include <string.h>
-
-#include "chb.h"
-#include "chb_drvr.h"
-#include "chb_buf.h"
-
-static chb_pcb_t pcb;
-// these are for the duplicate checking and rejection
-static U8 prev_seq = 0xFF;
-static U16 prev_src_addr = 0xFFFE;
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_init()
-{
-    memset(&pcb, 0, sizeof(chb_pcb_t));
-    pcb.src_addr = chb_get_short_addr();
-    chb_drvr_init();
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-chb_pcb_t *chb_get_pcb()
-{
-    return &pcb;
-}
-
-/**************************************************************************/
-/*! 
-    Requires the dest addr, location to store data, and len of payload.
-    Returns the length of the hdr. 
-*/
-/**************************************************************************/
-static U8 chb_gen_hdr(U8 *hdr, U16 addr, U8 len)
-{
-    U8 *hdr_ptr = hdr;
-
-    // calc frame size and put in 0 position of array
-    // frame size = hdr sz + payload len + fcs len
-    *hdr_ptr++ = CHB_HDR_SZ + len + CHB_FCS_LEN;
-
-    // use default fcf byte 0 val but test for ack request. we won't request
-    // ack if broadcast. all other cases we will.
-    *hdr_ptr++ = CHB_FCF_BYTE_0 | ((addr != 0xFFFF) << CHB_ACK_REQ_POS);
-    *hdr_ptr++ = CHB_FCF_BYTE_1;
-
-    *hdr_ptr++ = pcb.seq++;
-
-    // fill out dest pan ID, dest addr, src addr
-    *(U16 *)hdr_ptr = CFG_CHIBI_PANID;
-    hdr_ptr += sizeof(U16);
-    *(U16 *)hdr_ptr = addr;
-    hdr_ptr += sizeof(U16);
-    *(U16 *)hdr_ptr = pcb.src_addr;
-    hdr_ptr += sizeof(U16);
-    
-    // return the len of the header
-    return hdr_ptr - hdr;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U8 chb_write(U16 addr, U8 *data, U8 len)
-{
-    // U8 status, frm_len, hdr_len, hdr[CHB_HDR_SZ + 1];
-    U8 status, frm_len, hdr[CHB_HDR_SZ + 1];
-    
-    while (len > 0)
-    {
-        // calculate which frame len to use. if greater than max payload, split
-        // up operation.
-        frm_len = (len > CHB_MAX_PAYLOAD) ? CHB_MAX_PAYLOAD : len;
-
-        // gen frame header
-        // hdr_len = chb_gen_hdr(hdr, addr, frm_len);
-        chb_gen_hdr(hdr, addr, frm_len);
-
-        // send data to chip
-        status = chb_tx(hdr, data, frm_len);
-    
-        if (status != CHB_SUCCESS)
-        {
-            switch (status)
-            {
-            case RADIO_SUCCESS:
-                // fall through
-            case CHB_SUCCESS_DATA_PENDING:
-                pcb.txd_success++;
-                break;
-
-            case CHB_NO_ACK:
-                pcb.txd_noack++;
-                break;
-
-            case CHB_CHANNEL_ACCESS_FAILURE:
-                pcb.txd_channel_fail++;
-                break;
-
-            default:
-                break;
-            }
-            return status;
-        }
-
-        // adjust len and restart
-        len = len - frm_len;
-    }
-    return CHB_SUCCESS;
-}
-
-/**************************************************************************/
-/*!
-    Read data from the buffer. Need to pass in a buffer of at leasts max frame
-    size and two 16-bit containers for the src and dest addresses.
-    The read function will automatically populate the addresses and the data with
-    the frm payload. It will then return the len of the payload.
-*/
-/**************************************************************************/
-U8 chb_read(chb_rx_data_t *rx)
-{
-    U8 i, len, seq, *data_ptr;
-
-    data_ptr = rx->data;
-
-    // first byte is always len. check it to make sure 
-    // we have a valid len byte.
-    if ((len = chb_buf_read()) > CHB_MAX_FRAME_LENGTH)
-    {
-        return 0;
-    }
-    *data_ptr++ = len;
-
-    // load the rest of the data into buffer
-    for (i=0; i<len; i++)
-    {
-        *data_ptr++ = chb_buf_read();
-    }
-
-    // we're using the buffer that's fed in as an argument as a temp
-    // buffer as well to save resources.
-    // we'll use it as temp storage to parse the frame. then move the frame
-    // down so that only the payload will be in the buffer.
-
-    // extract the sequence number
-    data_ptr = rx->data + 3;    // location of sequence number
-    seq = *data_ptr;
-
-    // parse the buffer and extract the dest and src addresses
-    data_ptr = rx->data + 6;                // location of dest addr
-    rx->dest_addr = *(U16 *)data_ptr;
-    data_ptr += sizeof(U16);
-    rx->src_addr = *(U16 *)data_ptr;
-    data_ptr += sizeof(U16);
-
-    // if the data in the rx buf is 0, then clear the rx_flag. otherwise, keep it raised
-    if (!chb_buf_get_len())
-    {
-        pcb.data_rcv = false;
-    }
-
-#if (CFG_CHIBI_PROMISCUOUS == 1)
-    // if we're in promiscuous mode, we don't want to do any duplicate rejection and we don't want to move the payload
-    // to the front of the buffer. We want to capture the full frame so just keep the frame intact and return the length.
-    return len;
-#else
-    // duplicate frame check (dupe check). we want to remove frames that have been already been received since they 
-    // are just retries. 
-    // note: this dupe check only removes duplicate frames from the previous transfer. if another frame from a different
-    // node comes in between the dupes, then the dupe will show up as a received frame.
-    if ((seq == prev_seq) && (rx->src_addr == prev_src_addr))
-    {
-        // this is a duplicate frame from a retry. the remote node thinks we didn't receive 
-        // it properly. discard.
-        return 0;
-    }
-    else
-    {
-        prev_seq = seq;
-        prev_src_addr = rx->src_addr;
-    }
-
-    // move the payload down to the beginning of the data buffer
-    memmove(rx->data, data_ptr, len - CHB_HDR_SZ);
-    // finally, return the len of the payload
-    return len - CHB_HDR_SZ - CHB_FCS_LEN;
-#endif
-}
-
diff --git a/drivers/chibi/chb.h b/drivers/chibi/chb.h
deleted file mode 100644 (file)
index 6fb7827..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#ifndef CHIBI_H
-#define CHIBI_H
-
-#include "types.h"
-
-#define CHB_HDR_SZ        9    // FCF + seq + pan_id + dest_addr + src_addr (2 + 1 + 2 + 2 + 2)
-#define CHB_FCS_LEN       2
-#define CHB_MAX_PAYLOAD   100
-
-
-// frame_type = data
-// security enabled = false
-// frame pending = false
-// ack request = false
-// pan ID compression = true
-#define CHB_FCF_BYTE_0    0x41    
-
-// dest addr = 16-bit
-// frame version = 802.15.4 (not 2003)
-// src addr = 16-bit
-#define CHB_FCF_BYTE_1    0x98
-
-#define CHB_ACK_REQ_POS   5
-
-enum
-{
-    CHB_SUCCESS                 = 0,
-    CHB_SUCCESS_DATA_PENDING    = 1,
-    CHB_CHANNEL_ACCESS_FAILURE  = 3,
-    CHB_NO_ACK                  = 5,
-    CHB_INVALID                 = 7
-};
-
-// Chibi Protocol control block
-typedef struct
-{
-    U16 src_addr;
-    U8 seq;
-    volatile bool data_rcv;
-    volatile bool tx_end;
-
-    // stats
-    U16 rcvd_xfers;
-    U16 txd_success;
-    U16 txd_noack;
-    U16 txd_channel_fail;
-    U16 overflow;
-    U16 underrun;
-    U8 battlow;
-    U8 ed;
-    U8 crc;
-} chb_pcb_t;
-
-typedef struct
-{
-    U8 len;
-    U16 src_addr;
-    U16 dest_addr;
-    U8 data[CHB_MAX_PAYLOAD];
-} chb_rx_data_t;
-
-void chb_init();
-chb_pcb_t *chb_get_pcb();
-U8 chb_write(U16 addr, U8 *data, U8 len);
-U8 chb_read(chb_rx_data_t *rx);
-
-#endif
diff --git a/drivers/chibi/chb_buf.c b/drivers/chibi/chb_buf.c
deleted file mode 100644 (file)
index a08c856..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#include <stdio.h>
-#include "chb_buf.h"
-#include "projectconfig.h"
-
-static U8 chb_buf[CFG_CHIBI_BUFFERSIZE];
-static volatile U32 rd_ptr, wr_ptr;
-static volatile U32 len;
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_buf_init()
-{
-    rd_ptr = 0;
-    wr_ptr = 0;
-    len = 0;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_buf_write(U8 data)
-{
-    chb_buf[wr_ptr] = data;
-    wr_ptr = (wr_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
-    len++;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U8 chb_buf_read()
-{
-    U8 data;
-
-    data = chb_buf[rd_ptr];
-    rd_ptr = (rd_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
-    len--;
-    return data;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U32 chb_buf_get_len()
-{
-    return len;
-}
diff --git a/drivers/chibi/chb_buf.h b/drivers/chibi/chb_buf.h
deleted file mode 100644 (file)
index ec75812..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#ifndef CHB_BUF_H
-#define CHB_BUF_H
-
-#include "types.h"
-
-void chb_buf_init();
-void chb_buf_write(U8 data);
-U8 chb_buf_read();
-U32 chb_buf_get_len();
-
-#endif
diff --git a/drivers/chibi/chb_drvr.c b/drivers/chibi/chb_drvr.c
deleted file mode 100644 (file)
index fb78918..0000000
+++ /dev/null
@@ -1,925 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#include <stdio.h>
-#include "chb.h"
-#include "chb_drvr.h"
-#include "chb_buf.h"
-#include "chb_spi.h"
-#include "chb_eeprom.h"
-
-#include "core/systick/systick.h"
-#include "core/timer16/timer16.h"
-
-// store string messages in flash rather than RAM
-const char chb_err_overflow[] = "BUFFER FULL. TOSSING INCOMING DATA\r\n";
-const char chb_err_init[] = "RADIO NOT INITIALIZED PROPERLY\r\n";
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-static U8 chb_get_state()
-{
-    return chb_reg_read(TRX_STATUS) & 0x1f;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-static U8 chb_get_status()
-{
-    return chb_reg_read(TRX_STATE) >> CHB_TRAC_STATUS_POS;
-}
-
-/**************************************************************************/
-/*!
-    Cause a blocking delay for x microseconds
-*/
-/**************************************************************************/
-static void chb_delay_us(U16 usec)
-{
-  // Determine maximum delay using a 16 bit timer
-  // ToDo: Move this to a macro or fixed value!
-  uint32_t maxus = 0xFFFF / (CFG_CPU_CCLK / 1000000);
-
-  // Check if delay can be done in one operation
-  if (usec <= maxus)
-  {
-    timer16DelayUS(0, usec);
-    return;
-  }
-
-  // Split delay into several steps (to stay within limit of 16-bit timer)
-  do
-  {
-    if (usec >= maxus)
-    {
-      timer16DelayUS(0, maxus);
-      usec -= maxus;
-    }
-    else
-    {
-      timer16DelayUS(0, usec);
-      usec = 0;
-    }
-  } while (usec > 0);
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_reset()
-{
-    CHB_RST_DISABLE();
-    CHB_SLPTR_DISABLE();
-
-    // wait a bit while transceiver wakes up
-    chb_delay_us(TIME_P_ON_TO_CLKM_AVAIL);
-
-    // reset the device
-    CHB_RST_ENABLE();
-    chb_delay_us(TIME_RST_PULSE_WIDTH);
-    CHB_RST_DISABLE();
-
-    // check that we have the part number that we're expecting
-    while (1)
-    {
-        // if you're stuck in this loop, that means that you're not reading
-        // the version and part number register correctly. possible that version number
-        // changes. if so, update version num in header file
-        if ((chb_reg_read(VERSION_NUM) == CHB_AT86RF212_VER_NUM) && (chb_reg_read(PART_NUM) == CHB_AT86RF212_PART_NUM)) 
-        {
-            break;
-        }
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U8 chb_reg_read(U8 addr)
-{
-    U8 val = 0;
-
-    /* Add the register read command to the register address. */
-    addr |= 0x80;
-
-    CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE();
-
-    /*Send Register address and read register content.*/
-    val = chb_xfer_byte(addr);
-    val = chb_xfer_byte(val);
-
-    CHB_SPI_DISABLE();
-    CHB_LEAVE_CRIT();
-
-    return val;
-}
-
-/**************************************************************************/
-/*! 
-*/
-/**************************************************************************/
-U16 chb_reg_read16(U8 addr)
-{
-    U8 i;
-    U16 val = 0;
-
-    for (i=0; i<2; i++)
-    {
-        addr |= chb_reg_read(addr + i) << (8 * i);
-    }
-    return val;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_reg_write(U8 addr, U8 val)
-{
-    // U8 dummy; 
-
-    /* Add the Register Write command to the address. */
-    addr |= 0xC0;
-
-    CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE();
-
-    /*Send Register address and write register content.*/
-    // dummy = chb_xfer_byte(addr);
-    // dummy = chb_xfer_byte(val);
-    chb_xfer_byte(addr);
-    chb_xfer_byte(val);
-
-    CHB_SPI_DISABLE();
-    CHB_LEAVE_CRIT();
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_reg_write16(U8 addr, U16 val)
-{
-    U8 i;
-
-    for (i=0; i<2; i++)
-    {
-        chb_reg_write(addr + i, val >> (8 * i));
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_reg_write64(U8 addr, U8 *val)
-{
-    U8 i;
-
-    for (i=0; i<8; i++)
-    {
-        chb_reg_write(addr + i, *(val + i));
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask)
-{
-    U8 tmp;
-
-    tmp = chb_reg_read(addr);
-    val &= mask;                // mask off stray bits from val
-    tmp &= ~mask;               // mask off bits in reg val
-    tmp |= val;                 // copy val into reg val
-    chb_reg_write(addr, tmp);   // write back to reg
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len)
-{
-    //U8 i, dummy;
-    U8 i;
-
-    // dont allow transmission longer than max frame size
-    if ((hdr_len + data_len) > 127)
-    {
-        return;
-    }
-
-    // initiate spi transaction
-    CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE(); 
-
-    // send fifo write command
-    // dummy = chb_xfer_byte(CHB_SPI_CMD_FW);
-    chb_xfer_byte(CHB_SPI_CMD_FW);
-
-    // write hdr contents to fifo
-    for (i=0; i<hdr_len; i++)
-    {
-        // dummy = chb_xfer_byte(*hdr++);
-        chb_xfer_byte(*hdr++);
-    }
-
-    // write data contents to fifo
-    for (i=0; i<data_len; i++)
-    {
-        // dummy = chb_xfer_byte(*data++);
-        chb_xfer_byte(*data++);
-    }
-
-    // terminate spi transaction
-    CHB_SPI_DISABLE(); 
-    CHB_LEAVE_CRIT();
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-static void chb_frame_read()
-{
-    U8 i, len, data;
-
-    // CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE();
-
-    /*Send frame read command and read the length.*/
-    chb_xfer_byte(CHB_SPI_CMD_FR);
-    len = chb_xfer_byte(0);
-
-    /*Check for correct frame length.*/
-    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
-    {
-        // check to see if there is room to write the frame in the buffer. if not, then drop it
-        if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len()))
-        {
-            chb_buf_write(len);
-            
-            for (i=0; i<len; i++)
-            {
-                data = chb_xfer_byte(0);
-                chb_buf_write(data);
-            }
-        }
-        else
-        {
-            // we've overflowed the buffer. toss the data and do some housekeeping
-            chb_pcb_t *pcb = chb_get_pcb();
-
-            // read out the data and throw it away
-            for (i=0; i<len; i++)
-            {
-                data = chb_xfer_byte(0);
-            }
-
-            // Increment the overflow stat
-            pcb->overflow++;
-
-            // print the error message
-            printf(chb_err_overflow);
-        }
-    }
-
-    CHB_SPI_DISABLE();
-    CHB_LEAVE_CRIT();
-}
-
-/**************************************************************************/
-/*!
-    Read directly from the SRAM on the radio. This is only used for debugging
-    purposes.
-*/
-/**************************************************************************/
-#ifdef CHB_DEBUG
-void chb_sram_read(U8 addr, U8 len, U8 *data)
-{
-    U8 i, dummy;
-
-    CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE();
-
-    /*Send SRAM read command.*/
-    dummy = chb_xfer_byte(CHB_SPI_CMD_SR);
-
-    /*Send address where to start reading.*/
-    dummy = chb_xfer_byte(addr);
-
-    for (i=0; i<len; i++)
-    {
-        *data++ = chb_xfer_byte(0);
-    }
-
-    CHB_SPI_DISABLE();
-    CHB_LEAVE_CRIT();
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_sram_write(U8 addr, U8 len, U8 *data)
-{    
-    U8 i, dummy;
-
-    CHB_ENTER_CRIT();
-    CHB_SPI_ENABLE();
-
-    /*Send SRAM write command.*/
-    dummy = chb_xfer_byte(CHB_SPI_CMD_SW);
-
-    /*Send address where to start writing to.*/
-    dummy = chb_xfer_byte(addr);
-
-    for (i=0; i<len; i++)
-    {
-        dummy = chb_xfer_byte(*data++);
-    }
-
-    CHB_SPI_DISABLE();
-    CHB_LEAVE_CRIT();
-}
-#endif
-
-/**************************************************************************/
-/*!
-    Set the channel mode, BPSK, OQPSK, etc...
-*/
-/**************************************************************************/
-void chb_set_mode(U8 mode)
-{
-    switch (mode)
-    {
-    case OQPSK_868MHZ:
-        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);                 // 802.15.4-2006, channel page 2, channel 0 (868 MHz, Europe)
-        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
-        break;
-    case OQPSK_915MHZ:
-        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);                 // 802.15.4-2006, channel page 2, channels 1-10 (915 MHz, US)
-        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
-        break;
-    case OQPSK_780MHZ:
-        chb_reg_read_mod_write(TRX_CTRL_2, 0x1c, 0x3f);                 // 802.15.4-2006, channel page 5, channel 0-3 (780 MHz, China)
-        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
-        break;
-    case BPSK40_915MHZ:
-        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 40 kbps
-        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
-        break;
-    case BPSK20_868MHZ:
-        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 20 kbps
-        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
-        break;
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U8 chb_set_channel(U8 channel)
-{
-    U8 state;
-    
-#if (CHB_CHINA == 1)
-
-    // this if for China only which uses a 780 MHz frequency band
-    if ((chb_reg_read(TRX_CTRL2) & 0x3f) != 0x1c)
-    {
-        chb_reg_read_mod_write(TRX_CTRL2, 0x1c, 0x3f);
-    }
-    
-    if (channel > 3)
-    {
-        channel = 0;
-    }
-
-    channel = (channel << 1) + 11;      
-
-    chb_reg_read_mod_write(CC_CTRL_1, 0x4, 0x7);                // set 769 MHz base frequency for China
-    chb_reg_write(CC_CTRL_0, channel);                          // set the center frequency for the channel
-
-#else
-    //if (channel == 0)
-    //{
-    //    // Channel 0 is for European use only. make sure we are using channel page 2,
-    //    // channel 0 settings for 100 kbps
-    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08)
-    //    {
-    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);
-    //    }
-    //}
-    //else if (channel > 10)
-    //{
-    //    // if the channel is out of bounds for page 2, then default to channel 1 and 
-    //    // assume we're on the US frequency of 915 MHz
-    //    channel = 1;
-    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
-    //    {
-    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
-    //    }
-    //}
-    //else
-    //{
-    //    // Channels 1-10 are for US frequencies of 915 MHz
-    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
-    //    {
-    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
-    //    }
-    //}
-        
-    chb_reg_read_mod_write(PHY_CC_CCA, channel, 0x1f); 
-#endif
-
-    // add a delay to allow the PLL to lock if in active mode.
-    state = chb_get_state();
-    if ((state == RX_ON) || (state == PLL_ON))
-    {
-        chb_delay_us(TIME_PLL_LOCK_TIME);
-    }
-
-    return ((chb_reg_read(PHY_CC_CCA) & 0x1f) == channel) ? RADIO_SUCCESS : RADIO_TIMED_OUT;
-}
-
-/**************************************************************************/
-/*!
-    Set the power level
-*/
-/**************************************************************************/
-void chb_set_pwr(U8 val)
-{
-    chb_reg_write(PHY_TX_PWR, val);
-}
-
-/**************************************************************************/
-/*!
-    Set the TX/RX state machine state. Some manual manipulation is required 
-    for certain operations. Check the datasheet for more details on the state 
-    machine and manipulations.
-*/
-/**************************************************************************/
-U8 chb_set_state(U8 state)
-{
-    U8 curr_state, delay;
-
-    // if we're sleeping then don't allow transition
-    if (gpioGetValue(CHB_SLPTRPORT, CHB_SLPTRPIN))
-    {
-        return RADIO_WRONG_STATE;
-    }
-
-    // if we're in a transition state, wait for the state to become stable
-    curr_state = chb_get_state();
-    if ((curr_state == BUSY_TX_ARET) || (curr_state == BUSY_RX_AACK) || (curr_state == BUSY_RX) || (curr_state == BUSY_TX))
-    {
-        while (chb_get_state() == curr_state);
-    }
-
-    // At this point it is clear that the requested new_state is:
-    // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
-    // we need to handle some special cases before we transition to the new state
-    switch (state)
-    {
-    case TRX_OFF:
-        /* Go to TRX_OFF from any state. */
-        CHB_SLPTR_DISABLE();
-        chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1f);
-        chb_delay_us(TIME_ALL_STATES_TRX_OFF);
-        break;
-
-    case TX_ARET_ON:
-        if (curr_state == RX_AACK_ON)
-        {
-            /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
-            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
-            chb_delay_us(TIME_RX_ON_PLL_ON);
-        }
-        break;
-
-    case RX_AACK_ON:
-        if (curr_state == TX_ARET_ON)
-        {
-            /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
-            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
-            chb_delay_us(TIME_RX_ON_PLL_ON);
-        }
-        break;
-    }
-
-    /* Now we're okay to transition to any new state. */
-    chb_reg_read_mod_write(TRX_STATE, state, 0x1f);
-
-    /* When the PLL is active most states can be reached in 1us. However, from */
-    /* TRX_OFF the PLL needs time to activate. */
-    delay = (curr_state == TRX_OFF) ? TIME_TRX_OFF_PLL_ON : TIME_RX_ON_PLL_ON;
-    chb_delay_us(delay);
-
-    if (chb_get_state() == state)
-    {
-        return RADIO_SUCCESS;
-    }
-    return RADIO_TIMED_OUT;
-}
-
-/**************************************************************************/
-/*! 
-*/
-/**************************************************************************/
-void chb_set_ieee_addr(U8 *addr)
-{
-    chb_eeprom_write(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8); 
-    chb_reg_write64(IEEE_ADDR_0, addr); 
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_get_ieee_addr(U8 *addr)
-{
-    chb_eeprom_read(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8);
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_set_short_addr(U16 addr)
-{
-    U8 *addr_ptr = (U8 *)&addr;
-    chb_pcb_t *pcb = chb_get_pcb();
-
-    chb_eeprom_write(CFG_EEPROM_CHIBI_SHORTADDR, addr_ptr, 2);
-    chb_reg_write16(SHORT_ADDR_0, addr);
-    pcb->src_addr = addr;
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-U16 chb_get_short_addr()
-{
-    int16_t addr;
-
-    chb_eeprom_read(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t*)&addr, 2);
-    return addr;       
-}
-/**************************************************************************/
-/*!
-    Set the high gain mode pin for the CC1190
-*/
-/**************************************************************************/
-#if (CHB_CC1190_PRESENT)
-void chb_set_hgm(U8 enb)
-{
-    if (enb)
-    {
-        gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 1);
-    }
-    else
-    {
-        gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 0);
-    }
-}
-#endif
-
-/**************************************************************************/
-/*!
-    Load the data into the fifo, initiate a transmission attempt,
-    and return the status of the transmission attempt.
-*/
-/**************************************************************************/
-U8 chb_tx(U8 *hdr, U8 *data, U8 len)
-{
-    U8 state = chb_get_state();
-    chb_pcb_t *pcb = chb_get_pcb();
-
-    if ((state == BUSY_TX) || (state == BUSY_TX_ARET))
-    {
-        return RADIO_WRONG_STATE;
-    }
-
-    // TODO: check why we need to transition to the off state before we go to tx_aret_on
-    chb_set_state(TRX_OFF);
-    chb_set_state(TX_ARET_ON);
-
-    // TODO: try and start the frame transmission by writing TX_START command instead of toggling
-    // sleep pin...i just feel like it's kind of weird...
-
-    // write frame to buffer. first write header into buffer (add 1 for len byte), then data. 
-    chb_frame_write(hdr, CHB_HDR_SZ + 1, data, len);
-
-    //Do frame transmission
-    chb_reg_read_mod_write(TRX_STATE, CMD_TX_START, 0x1F);
-
-    // wait for the transmission to end, signalled by the TRX END flag
-    while (!pcb->tx_end);
-    pcb->tx_end = false;
-
-    // check the status of the transmission
-    return chb_get_status();
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-static void chb_radio_init()
-{
-    U8 ieee_addr[8];
-
-    // reset chip
-    chb_reset();
-
-    // disable intps while we config the radio
-    chb_reg_write(IRQ_MASK, 0);
-
-    // force transceiver off while we configure the intps
-    chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1F);
-
-    // make sure the transceiver is in the off state before proceeding
-    while ((chb_reg_read(TRX_STATUS) & 0x1f) != TRX_OFF);
-
-    // set radio cfg parameters
-    // **note** uncomment if these will be set to something other than default
-    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS);
-    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS);
-    //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS);
-    //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0);     
-    //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS);
-    //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES);
-
-    // set frame version that we'll accept
-    chb_reg_read_mod_write(CSMA_SEED_1, CHB_FRM_VER << CHB_FVN_POS, 3 << CHB_FVN_POS);
-
-    // set interrupt mask
-    // re-enable intps while we config the radio
-    chb_reg_write(IRQ_MASK, (1<<IRQ_RX_START) | (1<<IRQ_TRX_END));
-
-    #if (CFG_CHIBI_PROMISCUOUS == 0)
-      // set autocrc mode
-      chb_reg_read_mod_write(TRX_CTRL_1, 1 << CHB_AUTO_CRC_POS, 1 << CHB_AUTO_CRC_POS);
-    #endif
-    // set up default phy modulation, data rate and power (Ex. OQPSK, 100 kbps, 868 MHz, 3dBm)
-    chb_set_mode(CFG_CHIBI_MODE);       // Defined in projectconfig.h
-    chb_set_pwr(CFG_CHIBI_POWER);       // Defined in projectconfig.h
-    chb_set_channel(CFG_CHIBI_CHANNEL); // Defined in projectconfig.h
-
-    // set fsm state
-    // put trx in rx auto ack mode
-    chb_set_state(RX_STATE);
-
-    // set pan ID
-    chb_reg_write16(PAN_ID_0, CFG_CHIBI_PANID); // Defined in projectconfig.h
-
-    // set short addr
-    // NOTE: Possibly get this from EEPROM
-    chb_reg_write16(SHORT_ADDR_0, chb_get_short_addr());
-
-    // set long addr
-    // NOTE: Possibly get this from EEPROM
-    chb_get_ieee_addr(ieee_addr);
-    chb_reg_write64(IEEE_ADDR_0, ieee_addr);
-
-#if (CHB_CC1190_PRESENT)
-    // set high gain mode pin to output and init to zero
-    gpioSetDir (CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 1);
-    gpioSetPullup (&CHB_CC1190_HGM_IOCONREG, gpioPullupMode_Inactive);
-    gpioSetValue (CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 0);
-
-    // set external power amp on AT86RF212
-    chb_reg_read_mod_write(TRX_CTRL_1, 1<<CHB_PA_EXT_EN_POS, 1<<CHB_PA_EXT_EN_POS);
-
-    // set power to lowest level possible
-    chb_set_pwr(0xd);   // set to -11 dBm
-#endif
-
-    // set interrupt/gpio pin to input
-    gpioSetDir (CHB_EINTPORT, CHB_EINTPIN, 0);
-
-    // set internal resistor on EINT pin to inactive
-    gpioSetPullup (&CHB_EINTPIN_IOCONREG, gpioPullupMode_Inactive);
-
-    // configure pin for interrupt
-    gpioSetInterrupt (CHB_EINTPORT,
-                      CHB_EINTPIN,
-                      gpioInterruptSense_Edge,        // Edge-sensitive
-                      gpioInterruptEdge_Single,       // Single edge
-                      gpioInterruptEvent_ActiveLow);  // High triggers interrupt
-
-    // enable interrupt
-    gpioIntEnable (CHB_EINTPORT,
-                   CHB_EINTPIN); 
-
-    if (chb_get_state() != RX_STATE)
-    {
-        // ERROR occurred initializing the radio. Print out error message.
-        printf(chb_err_init);
-    }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_drvr_init()
-{
-    // ToDo: Make sure gpioInit has been called
-    // ToDo: Make sure CT32B0 has been initialised and enabled
-
-    // config SPI for at86rf230 access
-    chb_spi_init();
-
-    // Setup 16-bit timer 0 (used for us delays)
-    timer16Init(0, 0xFFFF);
-    timer16Enable(0);
-
-    // Set sleep and reset as output
-    gpioSetDir(CHB_SLPTRPORT, CHB_SLPTRPIN, 1);
-    gpioSetDir(CHB_RSTPORT, CHB_RSTPIN, 1);
-
-    // configure IOs
-    gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1);  // Set sleep high
-    gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1);      // Set reset high
-
-    // Set internal resistors
-    gpioSetPullup (&CHB_SLPTRPIN_IOCONREG, gpioPullupMode_Inactive);
-    gpioSetPullup (&CHB_RSTPIN_IOCONREG, gpioPullupMode_Inactive);
-
-    // config radio
-    chb_radio_init();
-}
-
-/**************************************************************************/
-/*!
-    Enable or disable the radio's sleep mode.
-*/
-/**************************************************************************/
-void chb_sleep(U8 enb)
-{
-  if (enb)
-  {
-    // first we need to go to TRX OFF state
-    chb_set_state(TRX_OFF);
-
-    // set the SLPTR pin
-    // CHB_SLPTR_PORT |= _BV(CHB_SLPTR_PIN);
-    CHB_SLPTR_ENABLE();
-  }
-  else
-  {
-    // make sure the SLPTR pin is low first
-    // CHB_SLPTR_PORT &= ~(_BV(CHB_SLPTR_PIN));
-    CHB_SLPTR_DISABLE();
-
-    // we need to allow some time for the PLL to lock
-    chb_delay_us(TIME_SLEEP_TO_TRX_OFF);
-
-    // Turn the transceiver back on
-    chb_set_state(RX_STATE);
-  }
-}
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_ISR_Handler (void)
-{
-    // U8 dummy, state, intp_src = 0;
-    U8 state, intp_src = 0;
-    chb_pcb_t *pcb = chb_get_pcb();
-
-    CHB_ENTER_CRIT();
-
-    /*Read Interrupt source.*/
-    CHB_SPI_ENABLE();   
-
-    /*Send Register address and read register content.*/
-    // dummy = chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
-    chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
-    intp_src = chb_xfer_byte(0);
-
-    CHB_SPI_DISABLE();
-
-    while (intp_src)
-    {
-        /*Handle the incomming interrupt. Prioritized.*/
-        if ((intp_src & CHB_IRQ_RX_START_MASK))
-        {
-            intp_src &= ~CHB_IRQ_RX_START_MASK;
-        }
-        else if (intp_src & CHB_IRQ_TRX_END_MASK)
-        {
-            state = chb_get_state();
-
-            if ((state == RX_ON) || (state == RX_AACK_ON) || (state == BUSY_RX_AACK))
-            {
-                // get the ed measurement
-                pcb->ed = chb_reg_read(PHY_ED_LEVEL);
-
-                // get the crc
-                pcb->crc = (chb_reg_read(PHY_RSSI) & (1<<7)) ? 1 : 0;
-
-                // if the crc is not valid, then do not read the frame and set the rx flag
-                if (pcb->crc)
-                {
-                    // get the data
-                    chb_frame_read();
-                    pcb->rcvd_xfers++;
-                    pcb->data_rcv = true;
-                }
-            }
-            else
-            {
-                pcb->tx_end = true;
-            }
-            intp_src &= ~CHB_IRQ_TRX_END_MASK;
-            while (chb_set_state(RX_STATE) != RADIO_SUCCESS);
-        }
-        else if (intp_src & CHB_IRQ_TRX_UR_MASK)
-        {
-            intp_src &= ~CHB_IRQ_TRX_UR_MASK;
-            pcb->underrun++;
-        }
-        else if (intp_src & CHB_IRQ_PLL_UNLOCK_MASK)
-        {
-            intp_src &= ~CHB_IRQ_PLL_UNLOCK_MASK;
-        }
-        else if (intp_src & CHB_IRQ_PLL_LOCK_MASK)
-        {
-            intp_src &= ~CHB_IRQ_PLL_LOCK_MASK;
-        }
-        else if (intp_src & CHB_IRQ_BAT_LOW_MASK)
-        {
-            intp_src &= ~CHB_IRQ_BAT_LOW_MASK;
-            pcb->battlow++;
-        }
-        else
-        {
-        }
-    }
-    CHB_LEAVE_CRIT();
-}
diff --git a/drivers/chibi/chb_drvr.h b/drivers/chibi/chb_drvr.h
deleted file mode 100644 (file)
index 48990bb..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-#ifndef CHIBI_DRVR_H
-#define CHIBI_DRVR_H
-
-#include "types.h"
-#include "projectconfig.h"
-#include "core/gpio/gpio.h"
-
-#define CHB_CC1190_PRESENT      0       /// Set to 1 if CC1190 is being used
-#define CHB_CHINA               0
-#define CHB_EEPROM_IEEE_ADDR    CFG_CHIBI_EEPROM_IEEEADDR
-#define CHB_EEPROM_SHORT_ADDR   CFG_CHIBI_EEPROM_SHORTADDR
-#define CHB_AT86RF212_VER_NUM   0x01
-#define CHB_AT86RF212_PART_NUM  0x07
-// #define CHB_BPSK                0       // set to 1 if want to use BPSK rather than OQPSK
-
-#define CHB_SPI_CMD_RW      0xC0    /**<  Register Write (short mode). */
-#define CHB_SPI_CMD_RR      0x80    /**<  Register Read (short mode). */
-#define CHB_SPI_CMD_FW      0x60    /**<  Frame Transmit Mode (long mode). */
-#define CHB_SPI_CMD_FR      0x20    /**<  Frame Receive Mode (long mode). */
-#define CHB_SPI_CMD_SW      0x40    /**<  SRAM Write. */
-#define CHB_SPI_CMD_SR      0x00    /**<  SRAM Read. */
-#define CHB_SPI_CMD_RADDRM  0x7F    /**<  Register Address Mask. */
-
-#define CHB_IRQ_BAT_LOW_MASK        0x80  /**< Mask for the BAT_LOW interrupt. */
-#define CHB_IRQ_TRX_UR_MASK         0x40  /**< Mask for the TRX_UR interrupt. */
-#define CHB_IRQ_TRX_END_MASK        0x08  /**< Mask for the TRX_END interrupt. */
-#define CHB_IRQ_RX_START_MASK       0x04  /**< Mask for the RX_START interrupt. */
-#define CHB_IRQ_PLL_UNLOCK_MASK     0x02  /**< Mask for the PLL_UNLOCK interrupt. */
-#define CHB_IRQ_PLL_LOCK_MASK       0x01  /**< Mask for the PLL_LOCK interrupt. */
-
-#define CHB_EINTPORT          1
-#define CHB_EINTPIN           8
-#define CHB_EINTPIN_IOCONREG  IOCON_PIO1_8
-#define CHB_RSTPORT           1
-#define CHB_RSTPIN            9
-#define CHB_RSTPIN_IOCONREG   IOCON_PIO1_9
-#define CHB_SLPTRPORT         1
-#define CHB_SLPTRPIN          10
-#define CHB_SLPTRPIN_IOCONREG IOCON_PIO1_10
-
-// if CC1190 present, set up the ports and pins for high gain mode control
-#if (CHB_CC1190_PRESENT)
-    #define CHB_CC1190_HGM_PORT     1
-    #define CHB_CC1190_HGM_PIN      11
-    #define CHB_CC1190_HGM_IOCONREG IOCON_PIO1_11
-#endif
-
-//#define CHB_DDR_SLPTR       DDRF
-//#define CHB_DDR_RST         DDRF
-//#define CHB_RADIO_IRQ       INT6_vect
-//#define CHB_RADIO_IRQ_PIN   INT6
-    
-#define CHB_ENTER_CRIT()    __disable_irq()
-#define CHB_LEAVE_CRIT()    __enable_irq()
-#define CHB_RST_ENABLE()    do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 0); } while (0)
-#define CHB_RST_DISABLE()   do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1); } while (0)
-#define CHB_SLPTR_ENABLE()  do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1); } while (0)
-#define CHB_SLPTR_DISABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 0); } while (0)
-
-// CCA constants
-enum
-{
-    CCA_ED                    = 1,    /**< Use energy detection above threshold mode. */
-    CCA_CARRIER_SENSE         = 2,    /**< Use carrier sense mode. */
-    CCA_CARRIER_SENSE_WITH_ED = 3     /**< Use a combination of both energy detection and carrier sense. */
-};
-
-// configuration parameters
-enum
-{
-    CHB_CHANNEL             = 1,        // Replaced in projectconfig.h with CFG_CHIBI_CHANNEL
-    CHB_PAN_ID              = 0x1234,   // Replaced in projectconfig.h with CFG_CHIBI_PANID
-    CHB_TX_PWR              = 0x0,
-    CHB_SHORT_ADDR          = 0x0,
-    CHB_IEEE_ADDR           = 0x0,
-    CHB_MAX_FRAME_RETRIES   = 3,
-    CHB_MAX_CSMA_RETRIES    = 4,
-    CHB_CCA_MODE            = CCA_ED,
-    CHB_MIN_BE              = 3,
-    CHB_MAX_BE              = 5,
-    CHB_CCA_ED_THRES        = 0x7,
-    CHB_CSMA_SEED0          = 0,
-    CHB_CSMA_SEED1          = 0,
-    CHB_FRM_VER             = 1         // accept 802.15.4 ver 0 or 1 frames
-};
-
-// register addresses
-enum
-{
-    TRX_STATUS              = 0x01,
-    TRX_STATE               = 0x02,
-    TRX_CTRL_0              = 0x03,
-    TRX_CTRL_1              = 0x04,
-    PHY_TX_PWR              = 0x05,
-    PHY_RSSI                = 0x06,
-    PHY_ED_LEVEL            = 0x07,
-    PHY_CC_CCA              = 0x08,
-    CCA_THRES               = 0x09,
-    RX_CTRL                 = 0x0a,
-    SFD_VALUE               = 0x0b,
-    TRX_CTRL_2              = 0x0c,
-    ANT_DIV                 = 0x0d,
-    IRQ_MASK                = 0x0e,
-    IRQ_STATUS              = 0x0f,
-    VREG_CTRL               = 0x10,
-    BATMON                  = 0x11,
-    XOSC_CTRL               = 0x12,
-    CC_CTRL_0               = 0x13,
-    CC_CTRL_1               = 0x14,
-    RX_SYN                  = 0x15,
-    RF_CTRL_0               = 0x16,
-    XAH_CTRL_1              = 0x17,
-    FTN_CTRL                = 0x18,
-    RF_CTRL_1               = 0x19,
-    PLL_CF                  = 0x1a,
-    PLL_DCU                 = 0x1b,
-    PART_NUM                = 0x1c,
-    VERSION_NUM             = 0x1d,
-    MAN_ID_0                = 0x1e,
-    MAN_ID_1                = 0x1f,
-    SHORT_ADDR_0            = 0x20,
-    SHORT_ADDR_1            = 0x21,
-    PAN_ID_0                = 0x22,
-    PAN_ID_1                = 0x23,
-    IEEE_ADDR_0             = 0x24,
-    IEEE_ADDR_1             = 0x25,
-    IEEE_ADDR_2             = 0x26,
-    IEEE_ADDR_3             = 0x27,
-    IEEE_ADDR_4             = 0x28,
-    IEEE_ADDR_5             = 0x29,
-    IEEE_ADDR_6             = 0x2a,
-    IEEE_ADDR_7             = 0x2b,
-    XAH_CTRL_0              = 0x2c,
-    CSMA_SEED_0             = 0x2d,
-    CSMA_SEED_1             = 0x2e,
-    CSMA_BE                 = 0x2f
-};
-
-// random defines
-enum
-{
-    CHB_MAX_FRAME_RETRIES_POS   = 4,
-    CHB_MAX_CSMA_RETIRES_POS    = 1,
-    CHB_CSMA_SEED1_POS          = 0,
-    CHB_CCA_MODE_POS            = 5,
-    CHB_AUTO_CRC_POS            = 5,
-    CHB_TRX_END_POS             = 3,
-    CHB_TRAC_STATUS_POS         = 5,
-    CHB_FVN_POS                 = 6,
-    CHB_OQPSK_TX_OFFSET         = 2,
-    CHB_BPSK_TX_OFFSET          = 3,
-    CHB_MIN_FRAME_LENGTH        = 3,
-    CHB_MAX_FRAME_LENGTH        = 0x7f,
-    CHB_PA_EXT_EN_POS           = 7
-};
-
-// transceiver timing
-enum{
-    TIME_RST_PULSE_WIDTH        = 1, 
-    TIME_P_ON_TO_CLKM_AVAIL     = 380,
-    TIME_SLEEP_TO_TRX_OFF       = 240,
-    TIME_TRX_OFF_TO_SLEEP       = 35,
-    TIME_PLL_ON_TRX_OFF         = 1,
-    TIME_TRX_OFF_RX_ON          = 110,
-    TIME_RX_ON_TRX_OFF          = 1,
-    TIME_PLL_ON_RX_ON           = 1,
-    TIME_RX_ON_PLL_ON           = 1,
-    TIME_PLL_LOCK_TIME          = 110,
-    TIME_BUSY_TX_PLL_ON         = 32,
-    TIME_ALL_STATES_TRX_OFF     = 1,
-    TIME_RESET_TRX_OFF          = 26,
-    TIME_TRX_IRQ_DELAY          = 9,
-    TIME_TRX_OFF_PLL_ON         = 110,
-    TIME_IRQ_PROCESSING_DLY     = 32
-};
-
-// trac status
-enum{
-    TRAC_SUCCESS               = 0,
-    TRAC_SUCCESS_DATA_PENDING  = 1,
-    TRAC_WAIT_FOR_ACK          = 2,
-    TRAC_CHANNEL_ACCESS_FAIL   = 3,
-    TRAC_NO_ACK                = 5,
-    TRAC_INVALID               = 7
-};
-
-// radio statuses
-enum{
-    RADIO_SUCCESS = 0x40,                       /**< The requested service was performed successfully. */
-    RADIO_UNSUPPORTED_DEVICE,                   /**< The connected device is not an Atmel AT86RF212. */
-    RADIO_INVALID_ARGUMENT,                     /**< One or more of the supplied function arguments are invalid. */
-    RADIO_TIMED_OUT,                            /**< The requested service timed out. */
-    RADIO_WRONG_STATE,                          /**< The end-user tried to do an invalid state transition. */
-    RADIO_BUSY_STATE,                           /**< The radio transceiver is busy receiving or transmitting. */
-    RADIO_STATE_TRANSITION_FAILED,              /**< The requested state transition could not be completed. */
-    RADIO_CCA_IDLE,                             /**< Channel is clear, available to transmit a new frame. */
-    RADIO_CCA_BUSY,                             /**< Channel busy. */
-    RADIO_TRX_BUSY,                             /**< Transceiver is busy receiving or transmitting data. */
-    RADIO_BAT_LOW,                              /**< Measured battery voltage is lower than voltage threshold. */
-    RADIO_BAT_OK,                               /**< Measured battery voltage is above the voltage threshold. */
-    RADIO_CRC_FAILED,                           /**< The CRC failed for the actual frame. */
-    RADIO_CHANNEL_ACCESS_FAILURE,               /**< The channel access failed during the auto mode. */
-    RADIO_NO_ACK,                               /**< No acknowledge frame was received. */
-};
-
-// transceiver commands
-enum
-{
-    CMD_NOP                 = 0,
-    CMD_TX_START            = 2,
-    CMD_FORCE_TRX_OFF       = 3,
-    CMD_FORCE_PLL_ON        = 4,
-    CMD_RX_ON               = 6,
-    CMD_TRX_OFF             = 8,
-    CMD_PLL_ON              = 9,
-    CMD_RX_AACK_ON          = 22,
-    CMD_TX_ARET_ON          = 25
-};
-
-// transceiver states
-enum
-{
-    P_ON               = 0,
-    BUSY_RX            = 1,
-    BUSY_TX            = 2,
-    RX_ON              = 6,
-    TRX_OFF            = 8,
-    PLL_ON             = 9,
-    SLEEP              = 15,
-    BUSY_RX_AACK       = 17,
-    BUSY_TX_ARET       = 18,
-    RX_AACK_ON         = 22,
-    TX_ARET_ON         = 25,
-    RX_ON_NOCLK        = 28,
-    RX_AACK_ON_NOCLK   = 29,
-    BUSY_RX_AACK_NOCLK = 30,
-    TRANS_IN_PROG      = 31
-};
-
-// transceiver interrupt register
-enum 
-{
-    IRQ_PLL_LOCK                = 0,
-    IRQ_PLL_UNLOCK              = 1,
-    IRQ_RX_START                = 2,
-    IRQ_TRX_END                 = 3,
-    IRQ_CCA_ED_READY            = 4,
-    IRQ_AMI                     = 5,
-    IRQ_TRX_UR                  = 6,
-    IRQ_BAT_LOW                 = 7 
-}; 
-
-// transceiver modes
-enum
-{
-    OQPSK_868MHZ    = 0,
-    OQPSK_915MHZ    = 1,
-    OQPSK_780MHZ    = 2,
-    BPSK40_915MHZ   = 3,
-    BPSK20_868MHZ   = 4
-};
-
-// See Table 7-15 for details
-enum
-{
-  CHB_PWR_EU1_2DBM   = 0x63,    // EU (868MHz) Linearized PA mode
-  CHB_PWR_EU1_1DBM   = 0x64,    // Note: BPSK 20kbit/s only!
-  CHB_PWR_EU1_0DBM   = 0x65,
-  CHB_PWR_EU2_5DBM   = 0xE7,    // EU (868MHz) Boost mode (but > supply current)
-  CHB_PWR_EU2_4DBM   = 0xE8,    // 4-5dBM BPSK 20 kbit/s only!
-  CHB_PWR_EU2_3DBM   = 0xE9,    // 0-3dBM O-QPSK 100/200/400 kbit/s or BPSK
-  CHB_PWR_EU2_2DBM   = 0xEA,
-  CHB_PWR_EU2_1DBM   = 0xCB,
-  CHB_PWR_EU2_0DBM   = 0xAB,
-  CHB_PWR_NA_10DBM   = 0xC0,    // North America (915MHz)
-  CHB_PWR_NA_9DBM    = 0xA1,
-  CHB_PWR_NA_8DBM    = 0x81,
-  CHB_PWR_NA_7DBM    = 0x82,
-  CHB_PWR_NA_6DBM    = 0x83,
-  CHB_PWR_NA_5DBM    = 0x60,
-  CHB_PWR_NA_4DBM    = 0x61,
-  CHB_PWR_NA_3DBM    = 0x41,
-  CHB_PWR_NA_2DBM    = 0x42,
-  CHB_PWR_NA_1DBM    = 0x22,
-  CHB_PWR_NA_0DBM    = 0x23,
-  CHB_PWR_CHINA_5DBM = 0xE7,    // China (780MHz)
-  CHB_PWR_CHINA_4DBM = 0xE8,
-  CHB_PWR_CHINA_3DBM = 0xE9,
-  CHB_PWR_CHINA_2DBM = 0xEA,
-  CHB_PWR_CHINA_1DBM = 0xCA,
-  CHB_PWR_CHINA_0DBM = 0xAA
-};
-
-// define receive state based on promiscuous mode setting
-#if (CFG_CHIBI_PROMISCUOUS == 1)
-    #define RX_STATE RX_ON
-#else
-    #define RX_STATE RX_AACK_ON
-#endif
-// init 
-void chb_drvr_init();
-
-// data access
-U8 chb_reg_read(U8 addr);
-U16 chb_reg_read16(U8 addr);
-void chb_reg_write(U8 addr, U8 val);
-void chb_reg_write16(U8 addr, U16 val);
-void chb_reg_write64(U8 addr, U8 *val);
-void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask);
-void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len);
-
-// general configuration
-void chb_set_mode(U8 mode);
-U8 chb_set_channel(U8 channel);
-void chb_set_pwr(U8 val);
-void chb_set_ieee_addr(U8 *addr);
-void chb_get_ieee_addr(U8 *addr);
-void chb_set_short_addr(U16 addr);
-U16 chb_get_short_addr();
-U8 chb_set_state(U8 state);
-
-// Power management
-void chb_sleep(U8 enb);
-
-// data transmit
-U8 chb_tx(U8 *hdr, U8 *data, U8 len);
-
-#if (CHB_CC1190_PRESENT)
-    void chb_set_hgm(U8 enb);
-#endif
-
-#ifdef CHB_DEBUG
-// sram access
-void chb_sram_read(U8 addr, U8 len, U8 *data);
-void chb_sram_write(U8 addr, U8 len, U8 *data);
-#endif
-
-void chb_ISR_Handler (void);
-
-#endif
-
diff --git a/drivers/chibi/chb_eeprom.c b/drivers/chibi/chb_eeprom.c
deleted file mode 100644 (file)
index d7e5f09..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-/*!
-    \file 
-    \ingroup
-
-
-*/
-/**************************************************************************/
-#include "chb_eeprom.h"
-#include "drivers/eeprom/eeprom.h"
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_eeprom_write(uint16_t addr, uint8_t *buf, uint16_t size)
-{
-  // Write the address one byte at a time
-  uint16_t a = 0;
-  while (a < size)
-  {
-    eepromWriteU8(addr + a, buf[a]);
-    a++;
-  }
-}
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_eeprom_read(uint16_t addr, uint8_t *buf, uint16_t size)
-{
-  // Read the contents at address
-  eepromReadBuffer(addr, buf, size);
-}
-
diff --git a/drivers/chibi/chb_eeprom.h b/drivers/chibi/chb_eeprom.h
deleted file mode 100644 (file)
index 3c3df71..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-/*!
-    \file 
-    \ingroup
-
-
-*/
-/**************************************************************************/
-#ifndef CHB_EEPROM_H
-#define CHB_EEPROM_H
-
-#include "projectconfig.h"
-#include "types.h"
-
-void chb_eeprom_write(U16 addr, U8 *buf, U16 size);
-void chb_eeprom_read(U16 addr, U8 *buf, U16 size);
-
-#endif
diff --git a/drivers/chibi/chb_spi.c b/drivers/chibi/chb_spi.c
deleted file mode 100644 (file)
index e552184..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-/*!
-    \file 
-    \ingroup
-
-
-*/
-/**************************************************************************/
-#include "chb.h"
-#include "chb_spi.h"
-#include "core/ssp/ssp.h"
-
-/**************************************************************************/
-/*!
-
-*/
-/**************************************************************************/
-void chb_spi_init()
-{
-    // initialise spi, high between frames and transition on trailing edge
-    sspInit(0, sspClockPolarity_High, sspClockPhase_FallingEdge);
-
-    // set the slave select to idle
-    CHB_SPI_DISABLE();
-}
-
-/**************************************************************************/
-/*!
-    This function both reads and writes data. For write operations, include data
-    to be written as argument. For read ops, use dummy data as arg. Returned
-    data is read byte val.
-*/
-/**************************************************************************/
-U8 chb_xfer_byte(U8 data)
-{
-    /* Move on only if NOT busy and TX FIFO not full */
-    while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_MASK | SSP_SSP0SR_BSY_MASK)) != SSP_SSP0SR_TNF_NOTFULL);
-    SSP_SSP0DR = data;
-  
-    /* Wait until the busy bit is cleared and receive buffer is not empty */
-    while ((SSP_SSP0SR & (SSP_SSP0SR_BSY_MASK | SSP_SSP0SR_RNE_MASK)) != SSP_SSP0SR_RNE_NOTEMPTY);
-
-    // Read the queue
-    return SSP_SSP0DR;
-}
diff --git a/drivers/chibi/chb_spi.h b/drivers/chibi/chb_spi.h
deleted file mode 100644 (file)
index 220feb7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-
-*******************************************************************/
-/*!
-    \file 
-    \ingroup
-
-
-*/
-/**************************************************************************/
-
-#ifndef CHB_SPI_H
-#define CHB_SPI_H
-
-#include "projectconfig.h"
-#include "core/gpio/gpio.h"
-
-#define CHB_SSPORT          (0) // P0.2 = SSEL
-#define CHB_SSPIN           (2)
-
-#define CHB_SPI_ENABLE()    do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 0);} while (0)  // Drive SSEL low
-#define CHB_SPI_DISABLE()   do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 1);} while (0)  // Drive SSEL high
-
-#define CHB_SPIPORT     0
-#define CHB_SCK         1                 // PB.1 - Output: SPI Serial Clock (SCLK)
-#define CHB_MOSI        2                 // PB.2 - Output: SPI Master out - slave in (MOSI)
-#define CHB_MISO        3                 // PB.3 - Input:  SPI Master in - slave out (MISO)
-
-void chb_spi_init();
-U8 chb_xfer_byte(U8 data);
-
-#endif
diff --git a/drivers/chibi/types.h b/drivers/chibi/types.h
deleted file mode 100644 (file)
index c551bbc..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************
-    Copyright (C) 2009 FreakLabs
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    1. Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-       notice, this list of conditions and the following disclaimer in the
-       documentation and/or other materials provided with the distribution.
-    3. Neither the name of the the copyright holder nor the names of its contributors
-       may be used to endorse or promote products derived from this software
-       without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
-    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
-    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-    SUCH DAMAGE.
-
-    Originally written by Christopher Wang aka Akiba.
-    Please post support questions to the FreakLabs forum.
-*******************************************************************/
-/*!
-    \file types.h
-    \ingroup usb
-*/
-/*******************************************************************/
-#ifndef TYPES_H
-#define TYPES_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-// Standard data types
-typedef uint8_t     U8;     /// Generic 8 bit unsigned data type
-typedef uint16_t    U16;    /// Generic 16 bit unsigned data type
-typedef uint32_t    U32;    /// Generic 32 bit unsigned data type
-typedef uint64_t    U64;    /// Generic 64 bit unsigned data type
-
-typedef int8_t     S8;     /// Generic 8 bit signed data type
-typedef int16_t    S16;    /// Generic 16 bit signed data type
-typedef int32_t    S32;    /// Generic 32 bit signed data type
-
-#endif
diff --git a/drivers/rf/chibi/chb.c b/drivers/rf/chibi/chb.c
new file mode 100644 (file)
index 0000000..2c02f1a
--- /dev/null
@@ -0,0 +1,231 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+    
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "chb.h"
+#include "chb_drvr.h"
+#include "chb_buf.h"
+
+static chb_pcb_t pcb;
+// these are for the duplicate checking and rejection
+static U8 prev_seq = 0xFF;
+static U16 prev_src_addr = 0xFFFE;
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_init()
+{
+    memset(&pcb, 0, sizeof(chb_pcb_t));
+    pcb.src_addr = chb_get_short_addr();
+    chb_drvr_init();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+chb_pcb_t *chb_get_pcb()
+{
+    return &pcb;
+}
+
+/**************************************************************************/
+/*! 
+    Requires the dest addr, location to store data, and len of payload.
+    Returns the length of the hdr. 
+*/
+/**************************************************************************/
+static U8 chb_gen_hdr(U8 *hdr, U16 addr, U8 len)
+{
+    U8 *hdr_ptr = hdr;
+
+    // calc frame size and put in 0 position of array
+    // frame size = hdr sz + payload len + fcs len
+    *hdr_ptr++ = CHB_HDR_SZ + len + CHB_FCS_LEN;
+
+    // use default fcf byte 0 val but test for ack request. we won't request
+    // ack if broadcast. all other cases we will.
+    *hdr_ptr++ = CHB_FCF_BYTE_0 | ((addr != 0xFFFF) << CHB_ACK_REQ_POS);
+    *hdr_ptr++ = CHB_FCF_BYTE_1;
+
+    *hdr_ptr++ = pcb.seq++;
+
+    // fill out dest pan ID, dest addr, src addr
+    *(U16 *)hdr_ptr = CFG_CHIBI_PANID;
+    hdr_ptr += sizeof(U16);
+    *(U16 *)hdr_ptr = addr;
+    hdr_ptr += sizeof(U16);
+    *(U16 *)hdr_ptr = pcb.src_addr;
+    hdr_ptr += sizeof(U16);
+    
+    // return the len of the header
+    return hdr_ptr - hdr;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_write(U16 addr, U8 *data, U8 len)
+{
+    // U8 status, frm_len, hdr_len, hdr[CHB_HDR_SZ + 1];
+    U8 status, frm_len, hdr[CHB_HDR_SZ + 1];
+    
+    while (len > 0)
+    {
+        // calculate which frame len to use. if greater than max payload, split
+        // up operation.
+        frm_len = (len > CHB_MAX_PAYLOAD) ? CHB_MAX_PAYLOAD : len;
+
+        // gen frame header
+        // hdr_len = chb_gen_hdr(hdr, addr, frm_len);
+        chb_gen_hdr(hdr, addr, frm_len);
+
+        // send data to chip
+        status = chb_tx(hdr, data, frm_len);
+    
+        if (status != CHB_SUCCESS)
+        {
+            switch (status)
+            {
+            case RADIO_SUCCESS:
+                // fall through
+            case CHB_SUCCESS_DATA_PENDING:
+                pcb.txd_success++;
+                break;
+
+            case CHB_NO_ACK:
+                pcb.txd_noack++;
+                break;
+
+            case CHB_CHANNEL_ACCESS_FAILURE:
+                pcb.txd_channel_fail++;
+                break;
+
+            default:
+                break;
+            }
+            return status;
+        }
+
+        // adjust len and restart
+        len = len - frm_len;
+    }
+    return CHB_SUCCESS;
+}
+
+/**************************************************************************/
+/*!
+    Read data from the buffer. Need to pass in a buffer of at leasts max frame
+    size and two 16-bit containers for the src and dest addresses.
+    The read function will automatically populate the addresses and the data with
+    the frm payload. It will then return the len of the payload.
+*/
+/**************************************************************************/
+U8 chb_read(chb_rx_data_t *rx)
+{
+    U8 i, len, seq, *data_ptr;
+
+    data_ptr = rx->data;
+
+    // first byte is always len. check it to make sure 
+    // we have a valid len byte.
+    if ((len = chb_buf_read()) > CHB_MAX_FRAME_LENGTH)
+    {
+        return 0;
+    }
+    *data_ptr++ = len;
+
+    // load the rest of the data into buffer
+    for (i=0; i<len; i++)
+    {
+        *data_ptr++ = chb_buf_read();
+    }
+
+    // we're using the buffer that's fed in as an argument as a temp
+    // buffer as well to save resources.
+    // we'll use it as temp storage to parse the frame. then move the frame
+    // down so that only the payload will be in the buffer.
+
+    // extract the sequence number
+    data_ptr = rx->data + 3;    // location of sequence number
+    seq = *data_ptr;
+
+    // parse the buffer and extract the dest and src addresses
+    data_ptr = rx->data + 6;                // location of dest addr
+    rx->dest_addr = *(U16 *)data_ptr;
+    data_ptr += sizeof(U16);
+    rx->src_addr = *(U16 *)data_ptr;
+    data_ptr += sizeof(U16);
+
+    // if the data in the rx buf is 0, then clear the rx_flag. otherwise, keep it raised
+    if (!chb_buf_get_len())
+    {
+        pcb.data_rcv = false;
+    }
+
+#if (CFG_CHIBI_PROMISCUOUS == 1)
+    // if we're in promiscuous mode, we don't want to do any duplicate rejection and we don't want to move the payload
+    // to the front of the buffer. We want to capture the full frame so just keep the frame intact and return the length.
+    return len;
+#else
+    // duplicate frame check (dupe check). we want to remove frames that have been already been received since they 
+    // are just retries. 
+    // note: this dupe check only removes duplicate frames from the previous transfer. if another frame from a different
+    // node comes in between the dupes, then the dupe will show up as a received frame.
+    if ((seq == prev_seq) && (rx->src_addr == prev_src_addr))
+    {
+        // this is a duplicate frame from a retry. the remote node thinks we didn't receive 
+        // it properly. discard.
+        return 0;
+    }
+    else
+    {
+        prev_seq = seq;
+        prev_src_addr = rx->src_addr;
+    }
+
+    // move the payload down to the beginning of the data buffer
+    memmove(rx->data, data_ptr, len - CHB_HDR_SZ);
+    // finally, return the len of the payload
+    return len - CHB_HDR_SZ - CHB_FCS_LEN;
+#endif
+}
+
diff --git a/drivers/rf/chibi/chb.h b/drivers/rf/chibi/chb.h
new file mode 100644 (file)
index 0000000..6fb7827
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHIBI_H
+#define CHIBI_H
+
+#include "types.h"
+
+#define CHB_HDR_SZ        9    // FCF + seq + pan_id + dest_addr + src_addr (2 + 1 + 2 + 2 + 2)
+#define CHB_FCS_LEN       2
+#define CHB_MAX_PAYLOAD   100
+
+
+// frame_type = data
+// security enabled = false
+// frame pending = false
+// ack request = false
+// pan ID compression = true
+#define CHB_FCF_BYTE_0    0x41    
+
+// dest addr = 16-bit
+// frame version = 802.15.4 (not 2003)
+// src addr = 16-bit
+#define CHB_FCF_BYTE_1    0x98
+
+#define CHB_ACK_REQ_POS   5
+
+enum
+{
+    CHB_SUCCESS                 = 0,
+    CHB_SUCCESS_DATA_PENDING    = 1,
+    CHB_CHANNEL_ACCESS_FAILURE  = 3,
+    CHB_NO_ACK                  = 5,
+    CHB_INVALID                 = 7
+};
+
+// Chibi Protocol control block
+typedef struct
+{
+    U16 src_addr;
+    U8 seq;
+    volatile bool data_rcv;
+    volatile bool tx_end;
+
+    // stats
+    U16 rcvd_xfers;
+    U16 txd_success;
+    U16 txd_noack;
+    U16 txd_channel_fail;
+    U16 overflow;
+    U16 underrun;
+    U8 battlow;
+    U8 ed;
+    U8 crc;
+} chb_pcb_t;
+
+typedef struct
+{
+    U8 len;
+    U16 src_addr;
+    U16 dest_addr;
+    U8 data[CHB_MAX_PAYLOAD];
+} chb_rx_data_t;
+
+void chb_init();
+chb_pcb_t *chb_get_pcb();
+U8 chb_write(U16 addr, U8 *data, U8 len);
+U8 chb_read(chb_rx_data_t *rx);
+
+#endif
diff --git a/drivers/rf/chibi/chb_buf.c b/drivers/rf/chibi/chb_buf.c
new file mode 100644 (file)
index 0000000..a08c856
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include <stdio.h>
+#include "chb_buf.h"
+#include "projectconfig.h"
+
+static U8 chb_buf[CFG_CHIBI_BUFFERSIZE];
+static volatile U32 rd_ptr, wr_ptr;
+static volatile U32 len;
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_buf_init()
+{
+    rd_ptr = 0;
+    wr_ptr = 0;
+    len = 0;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_buf_write(U8 data)
+{
+    chb_buf[wr_ptr] = data;
+    wr_ptr = (wr_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
+    len++;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_buf_read()
+{
+    U8 data;
+
+    data = chb_buf[rd_ptr];
+    rd_ptr = (rd_ptr + 1) % CFG_CHIBI_BUFFERSIZE;
+    len--;
+    return data;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U32 chb_buf_get_len()
+{
+    return len;
+}
diff --git a/drivers/rf/chibi/chb_buf.h b/drivers/rf/chibi/chb_buf.h
new file mode 100644 (file)
index 0000000..ec75812
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHB_BUF_H
+#define CHB_BUF_H
+
+#include "types.h"
+
+void chb_buf_init();
+void chb_buf_write(U8 data);
+U8 chb_buf_read();
+U32 chb_buf_get_len();
+
+#endif
diff --git a/drivers/rf/chibi/chb_drvr.c b/drivers/rf/chibi/chb_drvr.c
new file mode 100644 (file)
index 0000000..fb78918
--- /dev/null
@@ -0,0 +1,925 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#include <stdio.h>
+#include "chb.h"
+#include "chb_drvr.h"
+#include "chb_buf.h"
+#include "chb_spi.h"
+#include "chb_eeprom.h"
+
+#include "core/systick/systick.h"
+#include "core/timer16/timer16.h"
+
+// store string messages in flash rather than RAM
+const char chb_err_overflow[] = "BUFFER FULL. TOSSING INCOMING DATA\r\n";
+const char chb_err_init[] = "RADIO NOT INITIALIZED PROPERLY\r\n";
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static U8 chb_get_state()
+{
+    return chb_reg_read(TRX_STATUS) & 0x1f;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static U8 chb_get_status()
+{
+    return chb_reg_read(TRX_STATE) >> CHB_TRAC_STATUS_POS;
+}
+
+/**************************************************************************/
+/*!
+    Cause a blocking delay for x microseconds
+*/
+/**************************************************************************/
+static void chb_delay_us(U16 usec)
+{
+  // Determine maximum delay using a 16 bit timer
+  // ToDo: Move this to a macro or fixed value!
+  uint32_t maxus = 0xFFFF / (CFG_CPU_CCLK / 1000000);
+
+  // Check if delay can be done in one operation
+  if (usec <= maxus)
+  {
+    timer16DelayUS(0, usec);
+    return;
+  }
+
+  // Split delay into several steps (to stay within limit of 16-bit timer)
+  do
+  {
+    if (usec >= maxus)
+    {
+      timer16DelayUS(0, maxus);
+      usec -= maxus;
+    }
+    else
+    {
+      timer16DelayUS(0, usec);
+      usec = 0;
+    }
+  } while (usec > 0);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reset()
+{
+    CHB_RST_DISABLE();
+    CHB_SLPTR_DISABLE();
+
+    // wait a bit while transceiver wakes up
+    chb_delay_us(TIME_P_ON_TO_CLKM_AVAIL);
+
+    // reset the device
+    CHB_RST_ENABLE();
+    chb_delay_us(TIME_RST_PULSE_WIDTH);
+    CHB_RST_DISABLE();
+
+    // check that we have the part number that we're expecting
+    while (1)
+    {
+        // if you're stuck in this loop, that means that you're not reading
+        // the version and part number register correctly. possible that version number
+        // changes. if so, update version num in header file
+        if ((chb_reg_read(VERSION_NUM) == CHB_AT86RF212_VER_NUM) && (chb_reg_read(PART_NUM) == CHB_AT86RF212_PART_NUM)) 
+        {
+            break;
+        }
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_reg_read(U8 addr)
+{
+    U8 val = 0;
+
+    /* Add the register read command to the register address. */
+    addr |= 0x80;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send Register address and read register content.*/
+    val = chb_xfer_byte(addr);
+    val = chb_xfer_byte(val);
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+
+    return val;
+}
+
+/**************************************************************************/
+/*! 
+*/
+/**************************************************************************/
+U16 chb_reg_read16(U8 addr)
+{
+    U8 i;
+    U16 val = 0;
+
+    for (i=0; i<2; i++)
+    {
+        addr |= chb_reg_read(addr + i) << (8 * i);
+    }
+    return val;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write(U8 addr, U8 val)
+{
+    // U8 dummy; 
+
+    /* Add the Register Write command to the address. */
+    addr |= 0xC0;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send Register address and write register content.*/
+    // dummy = chb_xfer_byte(addr);
+    // dummy = chb_xfer_byte(val);
+    chb_xfer_byte(addr);
+    chb_xfer_byte(val);
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write16(U8 addr, U16 val)
+{
+    U8 i;
+
+    for (i=0; i<2; i++)
+    {
+        chb_reg_write(addr + i, val >> (8 * i));
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_write64(U8 addr, U8 *val)
+{
+    U8 i;
+
+    for (i=0; i<8; i++)
+    {
+        chb_reg_write(addr + i, *(val + i));
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask)
+{
+    U8 tmp;
+
+    tmp = chb_reg_read(addr);
+    val &= mask;                // mask off stray bits from val
+    tmp &= ~mask;               // mask off bits in reg val
+    tmp |= val;                 // copy val into reg val
+    chb_reg_write(addr, tmp);   // write back to reg
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len)
+{
+    //U8 i, dummy;
+    U8 i;
+
+    // dont allow transmission longer than max frame size
+    if ((hdr_len + data_len) > 127)
+    {
+        return;
+    }
+
+    // initiate spi transaction
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE(); 
+
+    // send fifo write command
+    // dummy = chb_xfer_byte(CHB_SPI_CMD_FW);
+    chb_xfer_byte(CHB_SPI_CMD_FW);
+
+    // write hdr contents to fifo
+    for (i=0; i<hdr_len; i++)
+    {
+        // dummy = chb_xfer_byte(*hdr++);
+        chb_xfer_byte(*hdr++);
+    }
+
+    // write data contents to fifo
+    for (i=0; i<data_len; i++)
+    {
+        // dummy = chb_xfer_byte(*data++);
+        chb_xfer_byte(*data++);
+    }
+
+    // terminate spi transaction
+    CHB_SPI_DISABLE(); 
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static void chb_frame_read()
+{
+    U8 i, len, data;
+
+    // CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send frame read command and read the length.*/
+    chb_xfer_byte(CHB_SPI_CMD_FR);
+    len = chb_xfer_byte(0);
+
+    /*Check for correct frame length.*/
+    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
+    {
+        // check to see if there is room to write the frame in the buffer. if not, then drop it
+        if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len()))
+        {
+            chb_buf_write(len);
+            
+            for (i=0; i<len; i++)
+            {
+                data = chb_xfer_byte(0);
+                chb_buf_write(data);
+            }
+        }
+        else
+        {
+            // we've overflowed the buffer. toss the data and do some housekeeping
+            chb_pcb_t *pcb = chb_get_pcb();
+
+            // read out the data and throw it away
+            for (i=0; i<len; i++)
+            {
+                data = chb_xfer_byte(0);
+            }
+
+            // Increment the overflow stat
+            pcb->overflow++;
+
+            // print the error message
+            printf(chb_err_overflow);
+        }
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+    Read directly from the SRAM on the radio. This is only used for debugging
+    purposes.
+*/
+/**************************************************************************/
+#ifdef CHB_DEBUG
+void chb_sram_read(U8 addr, U8 len, U8 *data)
+{
+    U8 i, dummy;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send SRAM read command.*/
+    dummy = chb_xfer_byte(CHB_SPI_CMD_SR);
+
+    /*Send address where to start reading.*/
+    dummy = chb_xfer_byte(addr);
+
+    for (i=0; i<len; i++)
+    {
+        *data++ = chb_xfer_byte(0);
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_sram_write(U8 addr, U8 len, U8 *data)
+{    
+    U8 i, dummy;
+
+    CHB_ENTER_CRIT();
+    CHB_SPI_ENABLE();
+
+    /*Send SRAM write command.*/
+    dummy = chb_xfer_byte(CHB_SPI_CMD_SW);
+
+    /*Send address where to start writing to.*/
+    dummy = chb_xfer_byte(addr);
+
+    for (i=0; i<len; i++)
+    {
+        dummy = chb_xfer_byte(*data++);
+    }
+
+    CHB_SPI_DISABLE();
+    CHB_LEAVE_CRIT();
+}
+#endif
+
+/**************************************************************************/
+/*!
+    Set the channel mode, BPSK, OQPSK, etc...
+*/
+/**************************************************************************/
+void chb_set_mode(U8 mode)
+{
+    switch (mode)
+    {
+    case OQPSK_868MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);                 // 802.15.4-2006, channel page 2, channel 0 (868 MHz, Europe)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case OQPSK_915MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);                 // 802.15.4-2006, channel page 2, channels 1-10 (915 MHz, US)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case OQPSK_780MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x1c, 0x3f);                 // 802.15.4-2006, channel page 5, channel 0-3 (780 MHz, China)
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_OQPSK_TX_OFFSET, 0x3);    // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case BPSK40_915MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 40 kbps
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    case BPSK20_868MHZ:
+        chb_reg_read_mod_write(TRX_CTRL_2, 0x00, 0x3f);                 // 802.15.4-2006, BPSK, 20 kbps
+        chb_reg_read_mod_write(RF_CTRL_0, CHB_BPSK_TX_OFFSET, 0x3);     // this is according to table 7-16 in at86rf212 datasheet
+        break;
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U8 chb_set_channel(U8 channel)
+{
+    U8 state;
+    
+#if (CHB_CHINA == 1)
+
+    // this if for China only which uses a 780 MHz frequency band
+    if ((chb_reg_read(TRX_CTRL2) & 0x3f) != 0x1c)
+    {
+        chb_reg_read_mod_write(TRX_CTRL2, 0x1c, 0x3f);
+    }
+    
+    if (channel > 3)
+    {
+        channel = 0;
+    }
+
+    channel = (channel << 1) + 11;      
+
+    chb_reg_read_mod_write(CC_CTRL_1, 0x4, 0x7);                // set 769 MHz base frequency for China
+    chb_reg_write(CC_CTRL_0, channel);                          // set the center frequency for the channel
+
+#else
+    //if (channel == 0)
+    //{
+    //    // Channel 0 is for European use only. make sure we are using channel page 2,
+    //    // channel 0 settings for 100 kbps
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x08)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x08, 0x3f);
+    //    }
+    //}
+    //else if (channel > 10)
+    //{
+    //    // if the channel is out of bounds for page 2, then default to channel 1 and 
+    //    // assume we're on the US frequency of 915 MHz
+    //    channel = 1;
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
+    //    }
+    //}
+    //else
+    //{
+    //    // Channels 1-10 are for US frequencies of 915 MHz
+    //    if ((chb_reg_read(TRX_CTRL_2) & 0x3f) != 0x0c)
+    //    {
+    //        chb_reg_read_mod_write(TRX_CTRL_2, 0x0c, 0x3f);
+    //    }
+    //}
+        
+    chb_reg_read_mod_write(PHY_CC_CCA, channel, 0x1f); 
+#endif
+
+    // add a delay to allow the PLL to lock if in active mode.
+    state = chb_get_state();
+    if ((state == RX_ON) || (state == PLL_ON))
+    {
+        chb_delay_us(TIME_PLL_LOCK_TIME);
+    }
+
+    return ((chb_reg_read(PHY_CC_CCA) & 0x1f) == channel) ? RADIO_SUCCESS : RADIO_TIMED_OUT;
+}
+
+/**************************************************************************/
+/*!
+    Set the power level
+*/
+/**************************************************************************/
+void chb_set_pwr(U8 val)
+{
+    chb_reg_write(PHY_TX_PWR, val);
+}
+
+/**************************************************************************/
+/*!
+    Set the TX/RX state machine state. Some manual manipulation is required 
+    for certain operations. Check the datasheet for more details on the state 
+    machine and manipulations.
+*/
+/**************************************************************************/
+U8 chb_set_state(U8 state)
+{
+    U8 curr_state, delay;
+
+    // if we're sleeping then don't allow transition
+    if (gpioGetValue(CHB_SLPTRPORT, CHB_SLPTRPIN))
+    {
+        return RADIO_WRONG_STATE;
+    }
+
+    // if we're in a transition state, wait for the state to become stable
+    curr_state = chb_get_state();
+    if ((curr_state == BUSY_TX_ARET) || (curr_state == BUSY_RX_AACK) || (curr_state == BUSY_RX) || (curr_state == BUSY_TX))
+    {
+        while (chb_get_state() == curr_state);
+    }
+
+    // At this point it is clear that the requested new_state is:
+    // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON.
+    // we need to handle some special cases before we transition to the new state
+    switch (state)
+    {
+    case TRX_OFF:
+        /* Go to TRX_OFF from any state. */
+        CHB_SLPTR_DISABLE();
+        chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1f);
+        chb_delay_us(TIME_ALL_STATES_TRX_OFF);
+        break;
+
+    case TX_ARET_ON:
+        if (curr_state == RX_AACK_ON)
+        {
+            /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */
+            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
+            chb_delay_us(TIME_RX_ON_PLL_ON);
+        }
+        break;
+
+    case RX_AACK_ON:
+        if (curr_state == TX_ARET_ON)
+        {
+            /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */
+            chb_reg_read_mod_write(TRX_STATE, CMD_PLL_ON, 0x1f);
+            chb_delay_us(TIME_RX_ON_PLL_ON);
+        }
+        break;
+    }
+
+    /* Now we're okay to transition to any new state. */
+    chb_reg_read_mod_write(TRX_STATE, state, 0x1f);
+
+    /* When the PLL is active most states can be reached in 1us. However, from */
+    /* TRX_OFF the PLL needs time to activate. */
+    delay = (curr_state == TRX_OFF) ? TIME_TRX_OFF_PLL_ON : TIME_RX_ON_PLL_ON;
+    chb_delay_us(delay);
+
+    if (chb_get_state() == state)
+    {
+        return RADIO_SUCCESS;
+    }
+    return RADIO_TIMED_OUT;
+}
+
+/**************************************************************************/
+/*! 
+*/
+/**************************************************************************/
+void chb_set_ieee_addr(U8 *addr)
+{
+    chb_eeprom_write(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8); 
+    chb_reg_write64(IEEE_ADDR_0, addr); 
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_get_ieee_addr(U8 *addr)
+{
+    chb_eeprom_read(CFG_EEPROM_CHIBI_IEEEADDR, addr, 8);
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_set_short_addr(U16 addr)
+{
+    U8 *addr_ptr = (U8 *)&addr;
+    chb_pcb_t *pcb = chb_get_pcb();
+
+    chb_eeprom_write(CFG_EEPROM_CHIBI_SHORTADDR, addr_ptr, 2);
+    chb_reg_write16(SHORT_ADDR_0, addr);
+    pcb->src_addr = addr;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+U16 chb_get_short_addr()
+{
+    int16_t addr;
+
+    chb_eeprom_read(CFG_EEPROM_CHIBI_SHORTADDR, (uint8_t*)&addr, 2);
+    return addr;       
+}
+/**************************************************************************/
+/*!
+    Set the high gain mode pin for the CC1190
+*/
+/**************************************************************************/
+#if (CHB_CC1190_PRESENT)
+void chb_set_hgm(U8 enb)
+{
+    if (enb)
+    {
+        gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 1);
+    }
+    else
+    {
+        gpioSetValue(CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 0);
+    }
+}
+#endif
+
+/**************************************************************************/
+/*!
+    Load the data into the fifo, initiate a transmission attempt,
+    and return the status of the transmission attempt.
+*/
+/**************************************************************************/
+U8 chb_tx(U8 *hdr, U8 *data, U8 len)
+{
+    U8 state = chb_get_state();
+    chb_pcb_t *pcb = chb_get_pcb();
+
+    if ((state == BUSY_TX) || (state == BUSY_TX_ARET))
+    {
+        return RADIO_WRONG_STATE;
+    }
+
+    // TODO: check why we need to transition to the off state before we go to tx_aret_on
+    chb_set_state(TRX_OFF);
+    chb_set_state(TX_ARET_ON);
+
+    // TODO: try and start the frame transmission by writing TX_START command instead of toggling
+    // sleep pin...i just feel like it's kind of weird...
+
+    // write frame to buffer. first write header into buffer (add 1 for len byte), then data. 
+    chb_frame_write(hdr, CHB_HDR_SZ + 1, data, len);
+
+    //Do frame transmission
+    chb_reg_read_mod_write(TRX_STATE, CMD_TX_START, 0x1F);
+
+    // wait for the transmission to end, signalled by the TRX END flag
+    while (!pcb->tx_end);
+    pcb->tx_end = false;
+
+    // check the status of the transmission
+    return chb_get_status();
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+static void chb_radio_init()
+{
+    U8 ieee_addr[8];
+
+    // reset chip
+    chb_reset();
+
+    // disable intps while we config the radio
+    chb_reg_write(IRQ_MASK, 0);
+
+    // force transceiver off while we configure the intps
+    chb_reg_read_mod_write(TRX_STATE, CMD_FORCE_TRX_OFF, 0x1F);
+
+    // make sure the transceiver is in the off state before proceeding
+    while ((chb_reg_read(TRX_STATUS) & 0x1f) != TRX_OFF);
+
+    // set radio cfg parameters
+    // **note** uncomment if these will be set to something other than default
+    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_FRAME_RETRIES << CHB_MAX_FRAME_RETRIES_POS, 0xF << CHB_MAX_FRAME_RETRIES_POS);
+    //chb_reg_read_mod_write(XAH_CTRL_0, CHB_MAX_CSMA_RETRIES << CHB_MAX_CSMA_RETIRES_POS, 0x7 << CHB_MAX_CSMA_RETIRES_POS);
+    //chb_reg_read_mod_write(CSMA_SEED_1, CHB_CSMA_SEED1 << CHB_CSMA_SEED1_POS, 0x7 << CHB_CSMA_SEED1_POS);
+    //chb_ret_write(CSMA_SEED0, CHB_CSMA_SEED0);     
+    //chb_reg_read_mod_write(PHY_CC_CCA, CHB_CCA_MODE << CHB_CCA_MODE_POS,0x3 << CHB_CCA_MODE_POS);
+    //chb_reg_write(CCA_THRES, CHB_CCA_ED_THRES);
+
+    // set frame version that we'll accept
+    chb_reg_read_mod_write(CSMA_SEED_1, CHB_FRM_VER << CHB_FVN_POS, 3 << CHB_FVN_POS);
+
+    // set interrupt mask
+    // re-enable intps while we config the radio
+    chb_reg_write(IRQ_MASK, (1<<IRQ_RX_START) | (1<<IRQ_TRX_END));
+
+    #if (CFG_CHIBI_PROMISCUOUS == 0)
+      // set autocrc mode
+      chb_reg_read_mod_write(TRX_CTRL_1, 1 << CHB_AUTO_CRC_POS, 1 << CHB_AUTO_CRC_POS);
+    #endif
+    // set up default phy modulation, data rate and power (Ex. OQPSK, 100 kbps, 868 MHz, 3dBm)
+    chb_set_mode(CFG_CHIBI_MODE);       // Defined in projectconfig.h
+    chb_set_pwr(CFG_CHIBI_POWER);       // Defined in projectconfig.h
+    chb_set_channel(CFG_CHIBI_CHANNEL); // Defined in projectconfig.h
+
+    // set fsm state
+    // put trx in rx auto ack mode
+    chb_set_state(RX_STATE);
+
+    // set pan ID
+    chb_reg_write16(PAN_ID_0, CFG_CHIBI_PANID); // Defined in projectconfig.h
+
+    // set short addr
+    // NOTE: Possibly get this from EEPROM
+    chb_reg_write16(SHORT_ADDR_0, chb_get_short_addr());
+
+    // set long addr
+    // NOTE: Possibly get this from EEPROM
+    chb_get_ieee_addr(ieee_addr);
+    chb_reg_write64(IEEE_ADDR_0, ieee_addr);
+
+#if (CHB_CC1190_PRESENT)
+    // set high gain mode pin to output and init to zero
+    gpioSetDir (CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 1);
+    gpioSetPullup (&CHB_CC1190_HGM_IOCONREG, gpioPullupMode_Inactive);
+    gpioSetValue (CHB_CC1190_HGM_PORT, CHB_CC1190_HGM_PIN, 0);
+
+    // set external power amp on AT86RF212
+    chb_reg_read_mod_write(TRX_CTRL_1, 1<<CHB_PA_EXT_EN_POS, 1<<CHB_PA_EXT_EN_POS);
+
+    // set power to lowest level possible
+    chb_set_pwr(0xd);   // set to -11 dBm
+#endif
+
+    // set interrupt/gpio pin to input
+    gpioSetDir (CHB_EINTPORT, CHB_EINTPIN, 0);
+
+    // set internal resistor on EINT pin to inactive
+    gpioSetPullup (&CHB_EINTPIN_IOCONREG, gpioPullupMode_Inactive);
+
+    // configure pin for interrupt
+    gpioSetInterrupt (CHB_EINTPORT,
+                      CHB_EINTPIN,
+                      gpioInterruptSense_Edge,        // Edge-sensitive
+                      gpioInterruptEdge_Single,       // Single edge
+                      gpioInterruptEvent_ActiveLow);  // High triggers interrupt
+
+    // enable interrupt
+    gpioIntEnable (CHB_EINTPORT,
+                   CHB_EINTPIN); 
+
+    if (chb_get_state() != RX_STATE)
+    {
+        // ERROR occurred initializing the radio. Print out error message.
+        printf(chb_err_init);
+    }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_drvr_init()
+{
+    // ToDo: Make sure gpioInit has been called
+    // ToDo: Make sure CT32B0 has been initialised and enabled
+
+    // config SPI for at86rf230 access
+    chb_spi_init();
+
+    // Setup 16-bit timer 0 (used for us delays)
+    timer16Init(0, 0xFFFF);
+    timer16Enable(0);
+
+    // Set sleep and reset as output
+    gpioSetDir(CHB_SLPTRPORT, CHB_SLPTRPIN, 1);
+    gpioSetDir(CHB_RSTPORT, CHB_RSTPIN, 1);
+
+    // configure IOs
+    gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1);  // Set sleep high
+    gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1);      // Set reset high
+
+    // Set internal resistors
+    gpioSetPullup (&CHB_SLPTRPIN_IOCONREG, gpioPullupMode_Inactive);
+    gpioSetPullup (&CHB_RSTPIN_IOCONREG, gpioPullupMode_Inactive);
+
+    // config radio
+    chb_radio_init();
+}
+
+/**************************************************************************/
+/*!
+    Enable or disable the radio's sleep mode.
+*/
+/**************************************************************************/
+void chb_sleep(U8 enb)
+{
+  if (enb)
+  {
+    // first we need to go to TRX OFF state
+    chb_set_state(TRX_OFF);
+
+    // set the SLPTR pin
+    // CHB_SLPTR_PORT |= _BV(CHB_SLPTR_PIN);
+    CHB_SLPTR_ENABLE();
+  }
+  else
+  {
+    // make sure the SLPTR pin is low first
+    // CHB_SLPTR_PORT &= ~(_BV(CHB_SLPTR_PIN));
+    CHB_SLPTR_DISABLE();
+
+    // we need to allow some time for the PLL to lock
+    chb_delay_us(TIME_SLEEP_TO_TRX_OFF);
+
+    // Turn the transceiver back on
+    chb_set_state(RX_STATE);
+  }
+}
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_ISR_Handler (void)
+{
+    // U8 dummy, state, intp_src = 0;
+    U8 state, intp_src = 0;
+    chb_pcb_t *pcb = chb_get_pcb();
+
+    CHB_ENTER_CRIT();
+
+    /*Read Interrupt source.*/
+    CHB_SPI_ENABLE();   
+
+    /*Send Register address and read register content.*/
+    // dummy = chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
+    chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
+    intp_src = chb_xfer_byte(0);
+
+    CHB_SPI_DISABLE();
+
+    while (intp_src)
+    {
+        /*Handle the incomming interrupt. Prioritized.*/
+        if ((intp_src & CHB_IRQ_RX_START_MASK))
+        {
+            intp_src &= ~CHB_IRQ_RX_START_MASK;
+        }
+        else if (intp_src & CHB_IRQ_TRX_END_MASK)
+        {
+            state = chb_get_state();
+
+            if ((state == RX_ON) || (state == RX_AACK_ON) || (state == BUSY_RX_AACK))
+            {
+                // get the ed measurement
+                pcb->ed = chb_reg_read(PHY_ED_LEVEL);
+
+                // get the crc
+                pcb->crc = (chb_reg_read(PHY_RSSI) & (1<<7)) ? 1 : 0;
+
+                // if the crc is not valid, then do not read the frame and set the rx flag
+                if (pcb->crc)
+                {
+                    // get the data
+                    chb_frame_read();
+                    pcb->rcvd_xfers++;
+                    pcb->data_rcv = true;
+                }
+            }
+            else
+            {
+                pcb->tx_end = true;
+            }
+            intp_src &= ~CHB_IRQ_TRX_END_MASK;
+            while (chb_set_state(RX_STATE) != RADIO_SUCCESS);
+        }
+        else if (intp_src & CHB_IRQ_TRX_UR_MASK)
+        {
+            intp_src &= ~CHB_IRQ_TRX_UR_MASK;
+            pcb->underrun++;
+        }
+        else if (intp_src & CHB_IRQ_PLL_UNLOCK_MASK)
+        {
+            intp_src &= ~CHB_IRQ_PLL_UNLOCK_MASK;
+        }
+        else if (intp_src & CHB_IRQ_PLL_LOCK_MASK)
+        {
+            intp_src &= ~CHB_IRQ_PLL_LOCK_MASK;
+        }
+        else if (intp_src & CHB_IRQ_BAT_LOW_MASK)
+        {
+            intp_src &= ~CHB_IRQ_BAT_LOW_MASK;
+            pcb->battlow++;
+        }
+        else
+        {
+        }
+    }
+    CHB_LEAVE_CRIT();
+}
diff --git a/drivers/rf/chibi/chb_drvr.h b/drivers/rf/chibi/chb_drvr.h
new file mode 100644 (file)
index 0000000..48990bb
--- /dev/null
@@ -0,0 +1,374 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+#ifndef CHIBI_DRVR_H
+#define CHIBI_DRVR_H
+
+#include "types.h"
+#include "projectconfig.h"
+#include "core/gpio/gpio.h"
+
+#define CHB_CC1190_PRESENT      0       /// Set to 1 if CC1190 is being used
+#define CHB_CHINA               0
+#define CHB_EEPROM_IEEE_ADDR    CFG_CHIBI_EEPROM_IEEEADDR
+#define CHB_EEPROM_SHORT_ADDR   CFG_CHIBI_EEPROM_SHORTADDR
+#define CHB_AT86RF212_VER_NUM   0x01
+#define CHB_AT86RF212_PART_NUM  0x07
+// #define CHB_BPSK                0       // set to 1 if want to use BPSK rather than OQPSK
+
+#define CHB_SPI_CMD_RW      0xC0    /**<  Register Write (short mode). */
+#define CHB_SPI_CMD_RR      0x80    /**<  Register Read (short mode). */
+#define CHB_SPI_CMD_FW      0x60    /**<  Frame Transmit Mode (long mode). */
+#define CHB_SPI_CMD_FR      0x20    /**<  Frame Receive Mode (long mode). */
+#define CHB_SPI_CMD_SW      0x40    /**<  SRAM Write. */
+#define CHB_SPI_CMD_SR      0x00    /**<  SRAM Read. */
+#define CHB_SPI_CMD_RADDRM  0x7F    /**<  Register Address Mask. */
+
+#define CHB_IRQ_BAT_LOW_MASK        0x80  /**< Mask for the BAT_LOW interrupt. */
+#define CHB_IRQ_TRX_UR_MASK         0x40  /**< Mask for the TRX_UR interrupt. */
+#define CHB_IRQ_TRX_END_MASK        0x08  /**< Mask for the TRX_END interrupt. */
+#define CHB_IRQ_RX_START_MASK       0x04  /**< Mask for the RX_START interrupt. */
+#define CHB_IRQ_PLL_UNLOCK_MASK     0x02  /**< Mask for the PLL_UNLOCK interrupt. */
+#define CHB_IRQ_PLL_LOCK_MASK       0x01  /**< Mask for the PLL_LOCK interrupt. */
+
+#define CHB_EINTPORT          1
+#define CHB_EINTPIN           8
+#define CHB_EINTPIN_IOCONREG  IOCON_PIO1_8
+#define CHB_RSTPORT           1
+#define CHB_RSTPIN            9
+#define CHB_RSTPIN_IOCONREG   IOCON_PIO1_9
+#define CHB_SLPTRPORT         1
+#define CHB_SLPTRPIN          10
+#define CHB_SLPTRPIN_IOCONREG IOCON_PIO1_10
+
+// if CC1190 present, set up the ports and pins for high gain mode control
+#if (CHB_CC1190_PRESENT)
+    #define CHB_CC1190_HGM_PORT     1
+    #define CHB_CC1190_HGM_PIN      11
+    #define CHB_CC1190_HGM_IOCONREG IOCON_PIO1_11
+#endif
+
+//#define CHB_DDR_SLPTR       DDRF
+//#define CHB_DDR_RST         DDRF
+//#define CHB_RADIO_IRQ       INT6_vect
+//#define CHB_RADIO_IRQ_PIN   INT6
+    
+#define CHB_ENTER_CRIT()    __disable_irq()
+#define CHB_LEAVE_CRIT()    __enable_irq()
+#define CHB_RST_ENABLE()    do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 0); } while (0)
+#define CHB_RST_DISABLE()   do {gpioSetValue(CHB_RSTPORT, CHB_RSTPIN, 1); } while (0)
+#define CHB_SLPTR_ENABLE()  do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 1); } while (0)
+#define CHB_SLPTR_DISABLE() do {gpioSetValue(CHB_SLPTRPORT, CHB_SLPTRPIN, 0); } while (0)
+
+// CCA constants
+enum
+{
+    CCA_ED                    = 1,    /**< Use energy detection above threshold mode. */
+    CCA_CARRIER_SENSE         = 2,    /**< Use carrier sense mode. */
+    CCA_CARRIER_SENSE_WITH_ED = 3     /**< Use a combination of both energy detection and carrier sense. */
+};
+
+// configuration parameters
+enum
+{
+    CHB_CHANNEL             = 1,        // Replaced in projectconfig.h with CFG_CHIBI_CHANNEL
+    CHB_PAN_ID              = 0x1234,   // Replaced in projectconfig.h with CFG_CHIBI_PANID
+    CHB_TX_PWR              = 0x0,
+    CHB_SHORT_ADDR          = 0x0,
+    CHB_IEEE_ADDR           = 0x0,
+    CHB_MAX_FRAME_RETRIES   = 3,
+    CHB_MAX_CSMA_RETRIES    = 4,
+    CHB_CCA_MODE            = CCA_ED,
+    CHB_MIN_BE              = 3,
+    CHB_MAX_BE              = 5,
+    CHB_CCA_ED_THRES        = 0x7,
+    CHB_CSMA_SEED0          = 0,
+    CHB_CSMA_SEED1          = 0,
+    CHB_FRM_VER             = 1         // accept 802.15.4 ver 0 or 1 frames
+};
+
+// register addresses
+enum
+{
+    TRX_STATUS              = 0x01,
+    TRX_STATE               = 0x02,
+    TRX_CTRL_0              = 0x03,
+    TRX_CTRL_1              = 0x04,
+    PHY_TX_PWR              = 0x05,
+    PHY_RSSI                = 0x06,
+    PHY_ED_LEVEL            = 0x07,
+    PHY_CC_CCA              = 0x08,
+    CCA_THRES               = 0x09,
+    RX_CTRL                 = 0x0a,
+    SFD_VALUE               = 0x0b,
+    TRX_CTRL_2              = 0x0c,
+    ANT_DIV                 = 0x0d,
+    IRQ_MASK                = 0x0e,
+    IRQ_STATUS              = 0x0f,
+    VREG_CTRL               = 0x10,
+    BATMON                  = 0x11,
+    XOSC_CTRL               = 0x12,
+    CC_CTRL_0               = 0x13,
+    CC_CTRL_1               = 0x14,
+    RX_SYN                  = 0x15,
+    RF_CTRL_0               = 0x16,
+    XAH_CTRL_1              = 0x17,
+    FTN_CTRL                = 0x18,
+    RF_CTRL_1               = 0x19,
+    PLL_CF                  = 0x1a,
+    PLL_DCU                 = 0x1b,
+    PART_NUM                = 0x1c,
+    VERSION_NUM             = 0x1d,
+    MAN_ID_0                = 0x1e,
+    MAN_ID_1                = 0x1f,
+    SHORT_ADDR_0            = 0x20,
+    SHORT_ADDR_1            = 0x21,
+    PAN_ID_0                = 0x22,
+    PAN_ID_1                = 0x23,
+    IEEE_ADDR_0             = 0x24,
+    IEEE_ADDR_1             = 0x25,
+    IEEE_ADDR_2             = 0x26,
+    IEEE_ADDR_3             = 0x27,
+    IEEE_ADDR_4             = 0x28,
+    IEEE_ADDR_5             = 0x29,
+    IEEE_ADDR_6             = 0x2a,
+    IEEE_ADDR_7             = 0x2b,
+    XAH_CTRL_0              = 0x2c,
+    CSMA_SEED_0             = 0x2d,
+    CSMA_SEED_1             = 0x2e,
+    CSMA_BE                 = 0x2f
+};
+
+// random defines
+enum
+{
+    CHB_MAX_FRAME_RETRIES_POS   = 4,
+    CHB_MAX_CSMA_RETIRES_POS    = 1,
+    CHB_CSMA_SEED1_POS          = 0,
+    CHB_CCA_MODE_POS            = 5,
+    CHB_AUTO_CRC_POS            = 5,
+    CHB_TRX_END_POS             = 3,
+    CHB_TRAC_STATUS_POS         = 5,
+    CHB_FVN_POS                 = 6,
+    CHB_OQPSK_TX_OFFSET         = 2,
+    CHB_BPSK_TX_OFFSET          = 3,
+    CHB_MIN_FRAME_LENGTH        = 3,
+    CHB_MAX_FRAME_LENGTH        = 0x7f,
+    CHB_PA_EXT_EN_POS           = 7
+};
+
+// transceiver timing
+enum{
+    TIME_RST_PULSE_WIDTH        = 1, 
+    TIME_P_ON_TO_CLKM_AVAIL     = 380,
+    TIME_SLEEP_TO_TRX_OFF       = 240,
+    TIME_TRX_OFF_TO_SLEEP       = 35,
+    TIME_PLL_ON_TRX_OFF         = 1,
+    TIME_TRX_OFF_RX_ON          = 110,
+    TIME_RX_ON_TRX_OFF          = 1,
+    TIME_PLL_ON_RX_ON           = 1,
+    TIME_RX_ON_PLL_ON           = 1,
+    TIME_PLL_LOCK_TIME          = 110,
+    TIME_BUSY_TX_PLL_ON         = 32,
+    TIME_ALL_STATES_TRX_OFF     = 1,
+    TIME_RESET_TRX_OFF          = 26,
+    TIME_TRX_IRQ_DELAY          = 9,
+    TIME_TRX_OFF_PLL_ON         = 110,
+    TIME_IRQ_PROCESSING_DLY     = 32
+};
+
+// trac status
+enum{
+    TRAC_SUCCESS               = 0,
+    TRAC_SUCCESS_DATA_PENDING  = 1,
+    TRAC_WAIT_FOR_ACK          = 2,
+    TRAC_CHANNEL_ACCESS_FAIL   = 3,
+    TRAC_NO_ACK                = 5,
+    TRAC_INVALID               = 7
+};
+
+// radio statuses
+enum{
+    RADIO_SUCCESS = 0x40,                       /**< The requested service was performed successfully. */
+    RADIO_UNSUPPORTED_DEVICE,                   /**< The connected device is not an Atmel AT86RF212. */
+    RADIO_INVALID_ARGUMENT,                     /**< One or more of the supplied function arguments are invalid. */
+    RADIO_TIMED_OUT,                            /**< The requested service timed out. */
+    RADIO_WRONG_STATE,                          /**< The end-user tried to do an invalid state transition. */
+    RADIO_BUSY_STATE,                           /**< The radio transceiver is busy receiving or transmitting. */
+    RADIO_STATE_TRANSITION_FAILED,              /**< The requested state transition could not be completed. */
+    RADIO_CCA_IDLE,                             /**< Channel is clear, available to transmit a new frame. */
+    RADIO_CCA_BUSY,                             /**< Channel busy. */
+    RADIO_TRX_BUSY,                             /**< Transceiver is busy receiving or transmitting data. */
+    RADIO_BAT_LOW,                              /**< Measured battery voltage is lower than voltage threshold. */
+    RADIO_BAT_OK,                               /**< Measured battery voltage is above the voltage threshold. */
+    RADIO_CRC_FAILED,                           /**< The CRC failed for the actual frame. */
+    RADIO_CHANNEL_ACCESS_FAILURE,               /**< The channel access failed during the auto mode. */
+    RADIO_NO_ACK,                               /**< No acknowledge frame was received. */
+};
+
+// transceiver commands
+enum
+{
+    CMD_NOP                 = 0,
+    CMD_TX_START            = 2,
+    CMD_FORCE_TRX_OFF       = 3,
+    CMD_FORCE_PLL_ON        = 4,
+    CMD_RX_ON               = 6,
+    CMD_TRX_OFF             = 8,
+    CMD_PLL_ON              = 9,
+    CMD_RX_AACK_ON          = 22,
+    CMD_TX_ARET_ON          = 25
+};
+
+// transceiver states
+enum
+{
+    P_ON               = 0,
+    BUSY_RX            = 1,
+    BUSY_TX            = 2,
+    RX_ON              = 6,
+    TRX_OFF            = 8,
+    PLL_ON             = 9,
+    SLEEP              = 15,
+    BUSY_RX_AACK       = 17,
+    BUSY_TX_ARET       = 18,
+    RX_AACK_ON         = 22,
+    TX_ARET_ON         = 25,
+    RX_ON_NOCLK        = 28,
+    RX_AACK_ON_NOCLK   = 29,
+    BUSY_RX_AACK_NOCLK = 30,
+    TRANS_IN_PROG      = 31
+};
+
+// transceiver interrupt register
+enum 
+{
+    IRQ_PLL_LOCK                = 0,
+    IRQ_PLL_UNLOCK              = 1,
+    IRQ_RX_START                = 2,
+    IRQ_TRX_END                 = 3,
+    IRQ_CCA_ED_READY            = 4,
+    IRQ_AMI                     = 5,
+    IRQ_TRX_UR                  = 6,
+    IRQ_BAT_LOW                 = 7 
+}; 
+
+// transceiver modes
+enum
+{
+    OQPSK_868MHZ    = 0,
+    OQPSK_915MHZ    = 1,
+    OQPSK_780MHZ    = 2,
+    BPSK40_915MHZ   = 3,
+    BPSK20_868MHZ   = 4
+};
+
+// See Table 7-15 for details
+enum
+{
+  CHB_PWR_EU1_2DBM   = 0x63,    // EU (868MHz) Linearized PA mode
+  CHB_PWR_EU1_1DBM   = 0x64,    // Note: BPSK 20kbit/s only!
+  CHB_PWR_EU1_0DBM   = 0x65,
+  CHB_PWR_EU2_5DBM   = 0xE7,    // EU (868MHz) Boost mode (but > supply current)
+  CHB_PWR_EU2_4DBM   = 0xE8,    // 4-5dBM BPSK 20 kbit/s only!
+  CHB_PWR_EU2_3DBM   = 0xE9,    // 0-3dBM O-QPSK 100/200/400 kbit/s or BPSK
+  CHB_PWR_EU2_2DBM   = 0xEA,
+  CHB_PWR_EU2_1DBM   = 0xCB,
+  CHB_PWR_EU2_0DBM   = 0xAB,
+  CHB_PWR_NA_10DBM   = 0xC0,    // North America (915MHz)
+  CHB_PWR_NA_9DBM    = 0xA1,
+  CHB_PWR_NA_8DBM    = 0x81,
+  CHB_PWR_NA_7DBM    = 0x82,
+  CHB_PWR_NA_6DBM    = 0x83,
+  CHB_PWR_NA_5DBM    = 0x60,
+  CHB_PWR_NA_4DBM    = 0x61,
+  CHB_PWR_NA_3DBM    = 0x41,
+  CHB_PWR_NA_2DBM    = 0x42,
+  CHB_PWR_NA_1DBM    = 0x22,
+  CHB_PWR_NA_0DBM    = 0x23,
+  CHB_PWR_CHINA_5DBM = 0xE7,    // China (780MHz)
+  CHB_PWR_CHINA_4DBM = 0xE8,
+  CHB_PWR_CHINA_3DBM = 0xE9,
+  CHB_PWR_CHINA_2DBM = 0xEA,
+  CHB_PWR_CHINA_1DBM = 0xCA,
+  CHB_PWR_CHINA_0DBM = 0xAA
+};
+
+// define receive state based on promiscuous mode setting
+#if (CFG_CHIBI_PROMISCUOUS == 1)
+    #define RX_STATE RX_ON
+#else
+    #define RX_STATE RX_AACK_ON
+#endif
+// init 
+void chb_drvr_init();
+
+// data access
+U8 chb_reg_read(U8 addr);
+U16 chb_reg_read16(U8 addr);
+void chb_reg_write(U8 addr, U8 val);
+void chb_reg_write16(U8 addr, U16 val);
+void chb_reg_write64(U8 addr, U8 *val);
+void chb_reg_read_mod_write(U8 addr, U8 val, U8 mask);
+void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len);
+
+// general configuration
+void chb_set_mode(U8 mode);
+U8 chb_set_channel(U8 channel);
+void chb_set_pwr(U8 val);
+void chb_set_ieee_addr(U8 *addr);
+void chb_get_ieee_addr(U8 *addr);
+void chb_set_short_addr(U16 addr);
+U16 chb_get_short_addr();
+U8 chb_set_state(U8 state);
+
+// Power management
+void chb_sleep(U8 enb);
+
+// data transmit
+U8 chb_tx(U8 *hdr, U8 *data, U8 len);
+
+#if (CHB_CC1190_PRESENT)
+    void chb_set_hgm(U8 enb);
+#endif
+
+#ifdef CHB_DEBUG
+// sram access
+void chb_sram_read(U8 addr, U8 len, U8 *data);
+void chb_sram_write(U8 addr, U8 len, U8 *data);
+#endif
+
+void chb_ISR_Handler (void);
+
+#endif
+
diff --git a/drivers/rf/chibi/chb_eeprom.c b/drivers/rf/chibi/chb_eeprom.c
new file mode 100644 (file)
index 0000000..4849928
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file 
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#include "chb_eeprom.h"
+#include "drivers/storage/eeprom/eeprom.h"
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_eeprom_write(uint16_t addr, uint8_t *buf, uint16_t size)
+{
+  // Write the address one byte at a time
+  uint16_t a = 0;
+  while (a < size)
+  {
+    eepromWriteU8(addr + a, buf[a]);
+    a++;
+  }
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_eeprom_read(uint16_t addr, uint8_t *buf, uint16_t size)
+{
+  // Read the contents at address
+  eepromReadBuffer(addr, buf, size);
+}
+
diff --git a/drivers/rf/chibi/chb_eeprom.h b/drivers/rf/chibi/chb_eeprom.h
new file mode 100644 (file)
index 0000000..3c3df71
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file 
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#ifndef CHB_EEPROM_H
+#define CHB_EEPROM_H
+
+#include "projectconfig.h"
+#include "types.h"
+
+void chb_eeprom_write(U16 addr, U8 *buf, U16 size);
+void chb_eeprom_read(U16 addr, U8 *buf, U16 size);
+
+#endif
diff --git a/drivers/rf/chibi/chb_spi.c b/drivers/rf/chibi/chb_spi.c
new file mode 100644 (file)
index 0000000..e552184
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file 
+    \ingroup
+
+
+*/
+/**************************************************************************/
+#include "chb.h"
+#include "chb_spi.h"
+#include "core/ssp/ssp.h"
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+void chb_spi_init()
+{
+    // initialise spi, high between frames and transition on trailing edge
+    sspInit(0, sspClockPolarity_High, sspClockPhase_FallingEdge);
+
+    // set the slave select to idle
+    CHB_SPI_DISABLE();
+}
+
+/**************************************************************************/
+/*!
+    This function both reads and writes data. For write operations, include data
+    to be written as argument. For read ops, use dummy data as arg. Returned
+    data is read byte val.
+*/
+/**************************************************************************/
+U8 chb_xfer_byte(U8 data)
+{
+    /* Move on only if NOT busy and TX FIFO not full */
+    while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_MASK | SSP_SSP0SR_BSY_MASK)) != SSP_SSP0SR_TNF_NOTFULL);
+    SSP_SSP0DR = data;
+  
+    /* Wait until the busy bit is cleared and receive buffer is not empty */
+    while ((SSP_SSP0SR & (SSP_SSP0SR_BSY_MASK | SSP_SSP0SR_RNE_MASK)) != SSP_SSP0SR_RNE_NOTEMPTY);
+
+    // Read the queue
+    return SSP_SSP0DR;
+}
diff --git a/drivers/rf/chibi/chb_spi.h b/drivers/rf/chibi/chb_spi.h
new file mode 100644 (file)
index 0000000..220feb7
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+
+*******************************************************************/
+/*!
+    \file 
+    \ingroup
+
+
+*/
+/**************************************************************************/
+
+#ifndef CHB_SPI_H
+#define CHB_SPI_H
+
+#include "projectconfig.h"
+#include "core/gpio/gpio.h"
+
+#define CHB_SSPORT          (0) // P0.2 = SSEL
+#define CHB_SSPIN           (2)
+
+#define CHB_SPI_ENABLE()    do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 0);} while (0)  // Drive SSEL low
+#define CHB_SPI_DISABLE()   do {gpioSetValue(CHB_SSPORT, CHB_SSPIN, 1);} while (0)  // Drive SSEL high
+
+#define CHB_SPIPORT     0
+#define CHB_SCK         1                 // PB.1 - Output: SPI Serial Clock (SCLK)
+#define CHB_MOSI        2                 // PB.2 - Output: SPI Master out - slave in (MOSI)
+#define CHB_MISO        3                 // PB.3 - Input:  SPI Master in - slave out (MISO)
+
+void chb_spi_init();
+U8 chb_xfer_byte(U8 data);
+
+#endif
diff --git a/drivers/rf/chibi/types.h b/drivers/rf/chibi/types.h
new file mode 100644 (file)
index 0000000..c551bbc
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************
+    Copyright (C) 2009 FreakLabs
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name of the the copyright holder nor the names of its contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    Originally written by Christopher Wang aka Akiba.
+    Please post support questions to the FreakLabs forum.
+*******************************************************************/
+/*!
+    \file types.h
+    \ingroup usb
+*/
+/*******************************************************************/
+#ifndef TYPES_H
+#define TYPES_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+// Standard data types
+typedef uint8_t     U8;     /// Generic 8 bit unsigned data type
+typedef uint16_t    U16;    /// Generic 16 bit unsigned data type
+typedef uint32_t    U32;    /// Generic 32 bit unsigned data type
+typedef uint64_t    U64;    /// Generic 64 bit unsigned data type
+
+typedef int8_t     S8;     /// Generic 8 bit signed data type
+typedef int16_t    S16;    /// Generic 16 bit signed data type
+typedef int32_t    S32;    /// Generic 32 bit signed data type
+
+#endif
diff --git a/drivers/rf/pn532/helpers/pn532_mifare.h b/drivers/rf/pn532/helpers/pn532_mifare.h
new file mode 100644 (file)
index 0000000..94d2c2e
--- /dev/null
@@ -0,0 +1,29 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_mifare.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_MIFARE_H__
+#define __PN532_MIFARE_H__
+
+#include "projectconfig.h"
+
+// These may need to be enlarged for multi card support
+#define PN532_RESPONSELEN_INLISTPASSIVETARGET (64)
+#define PN532_RESPONSELEN_INDATAEXCHANGE      (64)  
+
+typedef enum pn532_mifare_cmd_e
+{
+  PN532_MIFARE_CMD_AUTH_A     = 0x60,
+  PN532_MIFARE_CMD_AUTH_B     = 0x61,
+  PN532_MIFARE_CMD_READ       = 0x30,
+  PN532_MIFARE_CMD_WRITE      = 0xA0,
+  PN532_MIFARE_CMD_TRANSFER   = 0xB0,
+  PN532_MIFARE_CMD_DECREMENT  = 0xC0,
+  PN532_MIFARE_CMD_INCREMENT  = 0xC1,
+  PN532_MIFARE_CMD_STORE      = 0xC2
+} 
+pn532_mifare_cmd_t;
+
+#endif
diff --git a/drivers/rf/pn532/helpers/pn532_mifare_classic.c b/drivers/rf/pn532/helpers/pn532_mifare_classic.c
new file mode 100644 (file)
index 0000000..debf834
--- /dev/null
@@ -0,0 +1,458 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_mifare_classic.c
+*/
+/**************************************************************************/
+
+/*  MIFARE CLASSIC DESCRIPTION
+    ==========================
+
+    MIFARE Classic cards come in 1K and 4K varieties.  While several
+    varieties of chips exist, the two main chipsets used are described
+    in the following publicly accessible documents:
+
+        MF1S503x Mifare Classic 1K data sheet:
+        http://www.nxp.com/documents/data_sheet/MF1S503x.pdf
+            
+        MF1S70yyX MIFARE Classic 4K data sheet:
+        http://www.nxp.com/documents/data_sheet/MF1S70YYX.pdf
+
+    Mifare Classic cards typically have a a 4-byte NUID, though you may
+    find cards with 7 byte IDs as well
+        
+    EEPROM MEMORY
+    =============
+    Mifare Classic cards have either 1K or 4K of EEPROM memory. Each
+    memory block can be configured with different access conditions,
+    with two seperate authentication keys present in each block.
+
+    The two main Mifare Classic card types are organised as follows:
+
+        1K Cards: 16 sectors of 4 blocks (0..15)
+        4K Cards: 32 sectors of 4 blocks (0..31) and
+                  8 sectors of 16 blocks (32..39)
+
+    4 block sectors
+    ===============
+    Sector  Block   Bytes                                                           Description
+    ------  -----   -----                                                           -----------
+                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+
+    1       3       [-------KEY A-------]   [Access Bits]   [-------KEY A-------]   Sector Trailer 1
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                            Data                           ]   Data
+
+    0       3       [-------KEY A-------]   [Access Bits]   [-------KEY A-------]   Sector Trailer 1
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                     Manufacturer Data                     ]   Manufacturer Block
+
+    Sector Trailer (Block 3)
+    ------------------------
+    The sector trailer block contains the two secret keys (Key A and Key B), as well
+    as the access conditions for the four blocks.  It has the following structure:
+
+        Sector Trailer Bytes
+        --------------------------------------------------------------
+        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+        [       Key A       ]   [Access Bits]   [       Key B       ]
+
+    For more information in using Keys to access the clock contents, see
+    Accessing Data Blocks further below.
+
+    Data Blocks (Blocks 0..2)
+    -------------------------
+    Data blocks are 16 bytes wide and, depending on the permissions set in the
+    access bits, can be read from and written to. You are free to use the 16 data
+    bytes in any way you wish.  You can easily store text input, store four 32-bit
+    integer values, a 16 character uri, etc.
+
+    Data Blocks as "Value Blocks"
+    -----------------------------
+    An alternative to storing random data in the 16 byte-wide blocks is to
+    configure them as "Value Blocks".  Value blocks allow performing electronic
+    purse functions (valid commands are: read, write, increment, decrement,
+    restore, transfer).
+    
+    Each Value block contains a single signed 32-bit value, and this value is
+    stored 3 times for data integrity and security reasons.  It is stored twice
+    non-inverted, and once inverted.  The last 4 bytes are used for a 1-byte
+    address, which is stored 4 times (twice non-inverted, and twice inverted).
+    
+    Data blocks configured as "Value Blocks" have the following structure:
+
+        Value Block Bytes
+        --------------------------------------------------------------
+        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+        [   Value   ]   [   ~Value  ]   [   Value   ]   [A  ~A  A   ~A]
+
+    Manufacturer Block (Sector 0, Block 0)
+    --------------------------------------
+    Sector 0 is special since it contains the Manufacturer Block. This block
+    contains the manufacturer data, and is read-only.  It should be avoided
+    unless you know what you are doing.
+
+    16 block sectors
+    ================
+    16 block sectors are identical to 4 block sectors, but with more data blocks.  The same
+    structure described in the 4 block sectors above applies.
+
+    Sector  Block   Bytes                                                           Description
+    ------  -----   -----                                                           ----------
+                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
+
+    32      15      [-------KEY A-------]   [Access Bits]   [-------KEY B-------]   Sector Trailer 32
+            14      [                            Data                           ]   Data
+            13      [                            Data                           ]   Data
+            ...
+            2       [                            Data                           ]   Data
+            1       [                            Data                           ]   Data
+            0       [                            Data                           ]   Data
+
+    ACCESSING DATA BLOCKS
+    =====================
+
+    Before you can access the cards, you must following two steps:
+
+    1.) You must retrieve the 7 byte UID or the 4-byte NUID of the card.
+        This can be done using pn532_mifareclassic_WaitForPassiveTarget()
+        below, which will return the appropriate ID.
+
+    2.) You must authenticate the sector you wish to access according to the
+        access rules defined in the Sector Trailer block for that sector.
+        This can be done using pn532_mifareclassic_AuthenticateBlock(),
+        passing in the appropriate key value.
+          
+        Most new cards have a default Key A of 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF,
+        but some common values worth trying are:
+
+            0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
+            0XD3 0XF7 0XD3 0XF7 0XD3 0XF7
+            0XA0 0XA1 0XA2 0XA3 0XA4 0XA5
+            0XB0 0XB1 0XB2 0XB3 0XB4 0XB5
+            0X4D 0X3A 0X99 0XC3 0X51 0XDD
+            0X1A 0X98 0X2C 0X7E 0X45 0X9A
+            0XAA 0XBB 0XCC 0XDD 0XEE 0XFF
+            0X00 0X00 0X00 0X00 0X00 0X00
+            0XAB 0XCD 0XEF 0X12 0X34 0X56
+
+    3.) Once authenication has succeeded, and depending on the sector
+        permissions, you can then read/write/increment/decrement the
+        contents of the specific block, using one of the helper functions
+        included in this module.
+
+*/
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_mifare.h"
+#include "pn532_mifare_classic.h"
+
+#include "core/systick/systick.h"
+
+/**************************************************************************/
+/*! 
+      Indicates whether the specified block number is the first block
+      in the sector (block 0 relative to the current sector)
+*/
+/**************************************************************************/
+bool is_first_block (uint32_t uiBlock)
+{
+  // Test if we are in the small or big sectors
+  if (uiBlock < 128)
+    return ((uiBlock) % 4 == 0);
+  else
+    return ((uiBlock) % 16 == 0);
+}
+
+/**************************************************************************/
+/*! 
+      Indicates whether the specified block number is the sector trailer
+*/
+/**************************************************************************/
+bool is_trailer_block (uint32_t uiBlock)
+{
+  // Test if we are in the small or big sectors
+  if (uiBlock < 128)
+    return ((uiBlock + 1) % 4 == 0);
+  else
+    return ((uiBlock + 1) % 16 == 0);
+}
+
+/**************************************************************************/
+/*! 
+    Tries to detect MIFARE targets in passive mode.  This needs to be done
+    before anything useful can be accomplished with a tag since you need
+    the tag's unique UID to communicate with it.
+
+    @param  pbtCUID     Pointer to the byte array where the card's UID
+                        will be stored once a card is detected
+    @param  pszUIDLen   Pointer to the size of the card UID in bytes
+
+    Response for a valid ISO14443A 106KBPS (Mifare Classic, etc.)
+    should be in the following format.  See UM0701-02 section
+    7.3.5 for more information
+    
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              Tags Found
+    b8              Tag Number (only one used in this example)
+    b9..10          SENS_RES
+    b11             SEL_RES
+    b12             NFCID Length
+    b13..NFCIDLen   NFCID                                      
+    
+    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
+    --------   -------     -----------------------   ---------
+    00 04      08          NXP Mifare Classic 1K     4 bytes   
+    00 02      18          NXP Mifare Classic 4K     4 bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_WRONGCARDTYPE
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
+{
+  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
+  pn532_error_t error;
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
+  /* Note:  To wait for a card with a known UID, append the four byte     */
+  /*        UID to the end of the command.                                */ 
+  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error) 
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    systickDelay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error) 
+    return error;
+
+  /* Check SENSE_RES to make sure this is a Mifare Classic card           */
+  /*          Classic 1K       = 00 04                                    */
+  /*          Classic 4K       = 00 02                                    */
+  /*          Classic Emulated = 00 08                                    */
+  if ((abtResponse[10] == 0x02) || 
+      (abtResponse[10] == 0x04) || 
+      (abtResponse[10] == 0x08))
+  {
+    /* Card appears to be Mifare Classic */
+    *szCUIDLen = abtResponse[12];
+    uint8_t i;
+    for (i=0; i < *szCUIDLen; i++) 
+    {
+      pbtCUID[i] = abtResponse[13+i];
+    }
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      ATQA: ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      UID: ");
+      pn532PrintHex(pbtCUID, *szCUIDLen);
+    #endif
+  }
+  else
+  {
+    /* Card is ISO14443A but doesn't appear to be Mifare Classic          */
+    /*    Mifare Ultralight    = 0x0044                                   */
+    /*    Mifare DESFire       = 0x0344                                   */
+    /*    Innovision Jewel     = 0x0C00                                   */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 02, 00 04 or 00 08) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  ATQA       : ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID        : ");
+      size_t pos;
+      for (pos=0; pos < abtResponse[12]; pos++) 
+      {
+        printf("%02x ", abtResponse[13 + pos]);
+      }
+      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_WRONGCARDTYPE;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+
+/**************************************************************************/
+/*! 
+    Tries to authenticate a block of memory on a MIFARE card using the
+    INDATAEXCHANGE command.  See section 7.3.8 of the PN532 User Manual
+    for more information on sending MIFARE and other commands.
+
+    @param  pbtCUID       Pointer to a byte array containing the card UID
+    @param  szCUIDLen     The length (in bytes) of the card's UID (Should
+                          be 4 for MIFARE Classic)
+    @param  uiBlockNumber The block number to authenticate.  (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  uiKeyType     Which key type to use during authentication
+                          (PN532_MIFARE_CMD_AUTH_A or PN532_MIFARE_CMD_AUTH_B)
+    @param  pbtKeys       Pointer to a byte array containing the 6 byte
+                          key value
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys)
+{
+  pn532_error_t error;
+  byte_t abtCommand[17];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Trying to authenticate card ");
+  pn532PrintHex(pbtCUID, szCUIDLen);
+  #endif
+
+  /* Prepare the authentication command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;   /* Data Exchange Header */
+  abtCommand[1] = 1;                              /* Max card numbers */
+  abtCommand[2] = (uiKeyType) ? PN532_MIFARE_CMD_AUTH_A : PN532_MIFARE_CMD_AUTH_B;
+  abtCommand[3] = uiBlockNumber;                  /* Block Number (1K = 0..63, 4K = 0..255 */
+  memcpy (abtCommand+4, pbtKeys, 6);
+  uint8_t i;
+  for (i = 0; i < szCUIDLen; i++)
+  {
+    abtCommand[10+i] = pbtCUID[i];                /* 4 byte card ID */
+  }
+  
+  /* Send the command */
+  error = pn532Write(abtCommand, 10+szCUIDLen);
+  if (error)
+  {
+    /* Problem with the serial bus, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the authentication response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    systickDelay(25);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  // ToDo: How to check if authentification really worked (bad key, etc.)?
+
+  /* Output the authentification data */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Authenticated block %d %s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    Tries to read an entire 16-byte data block at the specified block
+    address.
+
+    @param  uiBlockNumber The block number to authenticate.  (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  pbtData       Pointer to the byte array that will hold the
+                          retrieved data (if any)
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BLOCKREADFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData)
+{
+  pn532_error_t error;
+  byte_t abtCommand[4];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Reading 16 bytes at block %03d%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Prepare the command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
+  abtCommand[1] = 1;                            /* Card number */
+  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
+  abtCommand[3] = uiBlockNumber;                /* Block Number (0..63 for 1K, 0..255 for 4K) */
+  
+  /* Send the commands */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+  {
+    /* Bus error, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    systickDelay(50);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Make sure we have a valid response (should be 26 bytes long) */
+  if (szLen == 26)
+  {
+    /* Copy the 16 data bytes to the output buffer        */
+    /* Block content starts at byte 9 of a valid response */
+    memcpy (pbtData, abtResponse+8, 16);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_BLOCKREADFAILED;
+  }
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Block %03d: ", uiBlockNumber, CFG_PRINTF_NEWLINE);
+    pn532PrintHexVerbose(pbtData, 16);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
diff --git a/drivers/rf/pn532/helpers/pn532_mifare_classic.h b/drivers/rf/pn532/helpers/pn532_mifare_classic.h
new file mode 100644 (file)
index 0000000..81177e9
--- /dev/null
@@ -0,0 +1,17 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_mifare_classic.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_MIFARE_CLASSIC_H__
+#define __PN532_MIFARE_CLASSIC_H__
+
+#include "projectconfig.h"
+#include "pn532_mifare.h"
+
+pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
+pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys);
+pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData);
+
+#endif
diff --git a/drivers/rf/pn532/helpers/pn532_mifare_ultralight.c b/drivers/rf/pn532/helpers/pn532_mifare_ultralight.c
new file mode 100644 (file)
index 0000000..0876101
--- /dev/null
@@ -0,0 +1,286 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_mifare_ultralight.c
+*/
+/**************************************************************************/
+
+/*  MIFARE ULTRALIGHT DESCRIPTION
+    =============================
+
+    MIFARE Ultralight cards typically contain 512 bits (64 bytes) of
+    memory, including 4 bytes (32-bits) of OTP (One Time Programmable)
+    memory where the individual bits can be written but not erased.
+
+        MF0ICU1 Mifare Ultralight Functional Specification:
+        http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
+            
+
+    Mifare Ultralight cards have a 7-byte UID
+    
+    EEPROM MEMORY
+    =============
+    Mifare Ultralight cards have 512 bits (64 bytes) of EEPROM memory,
+    including 4 byte (32 bits) of OTP memory.  Unlike Mifare Classic cards,
+    there is no authentication on a per block level, although the blocks
+    can be set to "read-only" mode using Lock Bytes (described below).
+
+    EEPROM memory is organised into 16 pages of four bytes eachs, in
+    the following order
+
+    Page   Description
+    ----   ------------
+    0      Serial Number (4 bytes)
+    1      Serial Number (4 bytes)
+    2      Byte 0:    Serial Number
+           Byte 1:    Internal Memory
+           Byte 2..3: lock bytes
+    3      One-time programmable memory (4 bytes)
+    4..15  User memory (4 bytes)
+
+    Lock Bytes (Page 2)
+    -------------------
+    Bytes 2 and 3 of page 2 are referred to as "Lock Bytes".  Each
+    page from 0x03 and higher can individually locked by setting the
+    corresponding locking bit to "1" to prevent further write access,
+    effectively making the memory read only.
+
+    For information on the lock byte mechanism, refer to section 8.5.2 of
+    the datasheet (referenced above).
+
+    OTP Bytes (Page 3)
+    ------------------
+    Page 3 is the OTP memory, and by default all bits on this page are
+    set to 0.  These bits can be bitwise modified using the Mifare WRITE
+    command, and individual bits can be set to 1, but can not be changed
+    back to 0.
+
+    Data Pages (Pages 4..15)
+    ------------------------
+    Pages 4 to 15 are can be freely read from and written to, 
+    provided there is no conflict with the Lock Bytes described above.
+
+    After production, the bytes have the following default values:
+
+    Page    Byte Values
+    ----    ----------------------
+            0     1     2     3
+    4       0xFF  0xFF  0xFF  0xFF
+    5..15   0x00  0x00  0x00  0x00
+
+    ACCESSING DATA BLOCKS
+    =====================
+
+    Before you can access the cards, you must following two steps:
+
+    1.) 'Connect' to a Mifare Ultralight card and retrieve the 7 byte
+        UID of the card.
+
+    2.) Memory can be read and written directly once a passive mode
+        connection has been made.  No authentication is required for
+        Mifare Ultralight cards.
+
+*/
+
+#include <string.h>
+
+#include "../pn532.h"
+#include "../pn532_bus.h"
+#include "pn532_mifare_ultralight.h"
+
+#include "core/systick/systick.h"
+
+/**************************************************************************/
+/*! 
+    Tries to detect MIFARE targets in passive mode.
+
+    @param  pbtCUID     Pointer to the byte array where the card's 7 byte
+                        UID will be stored once a card is detected
+    @param  pszUIDLen   Pointer to the size of the card UID in bytes
+
+    Response for a valid ISO14443A 106KBPS (Mifare Ultralight, etc.)
+    should be in the following format.  See UM0701-02 section
+    7.3.5 for more information
+    
+    byte            Description
+    -------------   ------------------------------------------
+    b0..6           Frame header and preamble
+    b7              Tags Found
+    b8              Tag Number (only one used in this example)
+    b9..10          SENS_RES
+    b11             SEL_RES
+    b12             NFCID Length
+    b13..NFCIDLen   NFCID                                      
+    
+    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
+    --------   -------     -----------------------   ---------
+    00 44      00          NXP Mifare Ultralight     7 bytes   
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_WRONGCARDTYPE
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
+{
+  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
+  pn532_error_t error;
+  size_t szLen;
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
+  /* Note:  To wait for a card with a known UID, append the four byte     */
+  /*        UID to the end of the command.                                */ 
+  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error) 
+    return error;
+
+  /* Wait until we get a valid response or a timeout                      */
+  do
+  {
+    systickDelay(25);
+    error = pn532Read(abtResponse, &szLen);
+  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error) 
+    return error;
+
+  /* Check SENS_RES to make sure this is a Mifare Ultralight card         */
+  /*          Mifare Ultralight = 00 44                                   */
+  if (abtResponse[10] == 0x44)
+  {
+    /* Card appears to be Mifare Ultralight */
+    *szCUIDLen = abtResponse[12];
+    uint8_t i;
+    for (i=0; i < *szCUIDLen; i++) 
+    {
+      pbtCUID[i] = abtResponse[13+i];
+    }
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      ATQA: ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("      UID: ");
+      pn532PrintHex(pbtCUID, *szCUIDLen);
+    #endif
+  }
+  else
+  {
+    /* Card is ISO14443A but doesn't appear to be Mifare Ultralight       */
+    /*    Mifare Classic       = 0x0002, 0x0004, 0x0008                   */
+    /*    Mifare DESFire       = 0x0344                                   */
+    /*    Innovision Jewel     = 0x0C00                                   */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 44) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  ATQA       : ");
+      pn532PrintHex(abtResponse+9, 2);
+      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
+      PN532_DEBUG("  UID        : ");
+      size_t pos;
+      for (pos=0; pos < abtResponse[12]; pos++) 
+      {
+        printf("%02x ", abtResponse[13 + pos]);
+      }
+      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_WRONGCARDTYPE;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    Tries to read an entire 4-byte page at the specified address.
+
+    @param  page        The page number (0..63 in most cases)
+    @param  pbtBuffer   Pointer to the byte array that will hold the
+                        retrieved data (if any)
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_ADDRESSOUTOFRANGE
+            - PN532_ERROR_BLOCKREADFAILED
+*/
+/**************************************************************************/
+pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer)
+{
+  pn532_error_t error;
+  byte_t abtCommand[4];
+  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
+  size_t szLen;
+
+  if (page >= 64)
+  {
+    return PN532_ERROR_ADDRESSOUTOFRANGE;
+  }
+
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Reading page %03d%s", page, CFG_PRINTF_NEWLINE);
+  #endif
+
+  /* Prepare the command */
+  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
+  abtCommand[1] = 1;                            /* Card number */
+  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
+  abtCommand[3] = page;                         /* Page Number (0..63 in most cases) */
+  
+  /* Send the commands */
+  error = pn532Write(abtCommand, sizeof(abtCommand));
+  if (error)
+  {
+    /* Bus error, etc. */
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }
+
+  /* Read the response */
+  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
+  do
+  {
+    systickDelay(50);
+    error = pn532Read(abtResponse, &szLen);
+  }
+  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
+  if (error)
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return error;
+  }  
+
+  /* Make sure we have a valid response (should be 26 bytes long) */
+  if (szLen == 26)
+  {
+    /* Copy the 4 data bytes to the output buffer         */
+    /* Block content starts at byte 9 of a valid response */
+    /* Note that the command actually reads 16 byte or 4  */
+    /* pages at a time ... we simply discard the last 12  */
+    /* bytes                                              */
+    memcpy (pbtBuffer, abtResponse+8, 4);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", page, CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_BLOCKREADFAILED;
+  }
+
+  /* Display data for debug if requested */
+  #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Page %02d: ", page, CFG_PRINTF_NEWLINE);
+    pn532PrintHexVerbose(pbtBuffer, 4);
+  #endif
+
+  // Return OK signal
+  return PN532_ERROR_NONE;
+}
+
diff --git a/drivers/rf/pn532/helpers/pn532_mifare_ultralight.h b/drivers/rf/pn532/helpers/pn532_mifare_ultralight.h
new file mode 100644 (file)
index 0000000..78239c9
--- /dev/null
@@ -0,0 +1,16 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_mifare_ultralight.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_MIFARE_ULTRALIGHT_H__
+#define __PN532_MIFARE_ULTRALIGHT_H__
+
+#include "projectconfig.h"
+#include "pn532_mifare.h"
+
+pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
+pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer);
+
+#endif
diff --git a/drivers/rf/pn532/pn532.c b/drivers/rf/pn532/pn532.c
new file mode 100644 (file)
index 0000000..78eae7f
--- /dev/null
@@ -0,0 +1,163 @@
+/**************************************************************************/
+/*! 
+    @file     pn532.c
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "pn532.h"
+#include "pn532_bus.h"
+#include "core/systick/systick.h"
+#include "core/uart/uart.h"
+
+static pn532_pcb_t pcb;
+
+/**************************************************************************/
+/*! 
+    @brief  Prints a hexadecimal value in plain characters
+
+    @param  pbtData   Pointer to the byte data
+    @param  szBytes   Data length in bytes
+*/
+/**************************************************************************/
+void pn532PrintHex(const byte_t * pbtData, const size_t szBytes)
+{
+  size_t szPos;
+  for (szPos=0; szPos < szBytes; szPos++) 
+  {
+    printf("%02x ", pbtData[szPos]);
+  }
+  printf(CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Prints a hexadecimal value in plain characters, along with
+            the char equivalents in the following format
+
+            AA BB CC DD EE FF  ......
+
+    @param  pbtData   Pointer to the byte data
+    @param  szBytes   Data length in bytes
+*/
+/**************************************************************************/
+void pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes)
+{
+  size_t szPos;
+  for (szPos=0; szPos < szBytes; szPos++) 
+  {
+    printf("%02x", pbtData[szPos]);
+  }
+  printf("  ");
+  for (szPos=0; szPos < szBytes; szPos++) 
+  {
+    printf("%c", pbtData[szPos] <= 0x1F ? '.' : pbtData[szPos]);
+  }
+  printf(CFG_PRINTF_NEWLINE);
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Gets a reference to the PN532 peripheral control block,
+                which can be used to determine that state of the PN532
+                IC, buffers, etc.
+*/
+/**************************************************************************/
+pn532_pcb_t * pn532GetPCB()
+{
+  return &pcb;
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Initialises the appropriate serial bus (UART, etc.),and
+                sets up any buffers or peripherals required by the PN532.
+*/
+/**************************************************************************/
+void pn532Init(void)
+{
+  // Clear protocol control blocks
+  memset(&pcb, 0, sizeof(pn532_pcb_t));
+
+  // Initialise the underlying HW
+  pn532_bus_HWInit();
+
+  // Set the PCB flags to an appropriate state
+  pcb.initialised = TRUE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Reads the response buffer from the PN532
+
+    @param      pbtResponse
+                The byte array that will hold the response data
+    @param      pszLen
+                Pointer to the number of bytes in pbtCommand
+*/
+/**************************************************************************/
+pn532_error_t pn532Read(byte_t * pbtResponse, size_t * pszLen)
+{
+  if (!pcb.initialised) pn532Init();  
+
+  // Try to wake the device up if it's in sleep mode
+  if (pcb.state == PN532_STATE_SLEEP)
+  {
+    pn532_error_t wakeupError = pn532_bus_Wakeup();
+    if (wakeupError)
+      return wakeupError;
+  }
+
+  // Read the response if the device is in an appropriate state
+  if (pcb.state == PN532_STATE_READY)
+  {
+    return pn532_bus_ReadResponse(pbtResponse, pszLen);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_UNABLETOINIT;
+  }
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Sends a byte array of command and parameter data to the
+                PN532, starting with the command byte.  The frame's
+                preamble, checksums, postamble and frame identifier (0xD4)
+                will all be automatically added.
+
+    @param      abtCommand
+                The byte array containg the command and any
+                optional parameters
+    @param      szLen
+                The number of bytes in abtCommand
+*/
+/**************************************************************************/
+pn532_error_t pn532Write(byte_t * abtCommand, size_t szLen)
+{
+  if (!pcb.initialised) pn532Init();
+
+  // Try to wake the device up if it's in sleep mode
+  if (pcb.state == PN532_STATE_SLEEP)
+  {
+    pn532_error_t wakeupError = pn532_bus_Wakeup();
+    if (wakeupError)
+      return wakeupError;
+  }
+
+  // Send the command if the device is in an appropriate state
+  if (pcb.state == PN532_STATE_READY)
+  {
+    return pn532_bus_SendCommand(abtCommand, szLen);
+  }
+  else
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_UNABLETOINIT;
+  }
+}
diff --git a/drivers/rf/pn532/pn532.h b/drivers/rf/pn532/pn532.h
new file mode 100644 (file)
index 0000000..4ddf19a
--- /dev/null
@@ -0,0 +1,144 @@
+/**************************************************************************/
+/*! 
+    @file     pn532.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_H__
+#define __PN532_H__
+
+#include "projectconfig.h"
+
+// Comment out this line to disable debug output
+// #define PN532_DEBUGMODE
+#define PN532_DEBUG(fmt, args...)             printf(fmt, ##args) 
+
+/* Error messages generated by the stack */
+/* Not to be confused with app level errors from the PN532 */
+/* These are the errors that are returned by the PN532 driver */
+typedef enum pn532_error_e
+{
+  PN532_ERROR_NONE                    = 0x00,
+  PN532_ERROR_UNABLETOINIT            = 0x01,   // Unable to initialise or wakeup the device
+  PN532_ERROR_APPLEVELERROR           = 0x02,   // Application level error detected
+  PN532_ERROR_BUSY                    = 0x03,   // Busy executing a previous command
+  PN532_ERROR_NOACK                   = 0x04,   // No ack message received
+  PN532_ERROR_INVALIDACK              = 0x05,   // Ack != 00 00 FF 00 FF 00
+  PN532_ERROR_PREAMBLEMISMATCH        = 0x06,   // Frame preamble + start code mismatch
+  PN532_ERROR_EXTENDEDFRAME           = 0x07,   // Extended frames currently unsupported
+  PN532_ERROR_LENCHECKSUMMISMATCH     = 0x08,
+  PN532_ERROR_RESPONSEBUFFEREMPTY     = 0x09,   // No response data received
+  PN532_ERROR_READYSTATUSTIMEOUT      = 0x0A,   // Timeout waiting for 'ready' status (SPI/I2C only)
+  PN532_ERROR_TIMEOUTWAITINGFORCARD   = 0x0B,   // No card detected in field with the specified timeout
+  PN532_ERROR_BLOCKREADFAILED         = 0x0C,   // Unexpected response to block read request
+  PN532_ERROR_WRONGCARDTYPE           = 0x0D,   // Card is not the expected format (based on SENS_RES/ATQA value)
+  PN532_ERROR_ADDRESSOUTOFRANGE       = 0x0E,   // Specified block and page is out of range
+  PN532_ERROR_I2C_NACK                = 0x0F    // I2C Bus - No ACK was received for master to slave data transfer
+} pn532_error_t;
+
+typedef enum pn532_modulation_e
+{
+  PN532_MODULATION_ISO14443A_106KBPS  = 0x00,
+  PN532_MODULATION_FELICA_212KBPS     = 0x01,
+  PN532_MODULATION_FELICA_424KBPS     = 0x02,
+  PN532_MODULATION_ISO14443B_106KBPS  = 0x03,
+  PN532_MODULATION_JEWEL_106KBPS      = 0x04
+} pn532_modulation_t;
+
+/* HW Commands for the PN532.  */
+/* See UM0701-02 - PN532 User Manual */
+enum
+{
+  PN532_COMMAND_DIAGNOSE              = 0x00,
+  PN532_COMMAND_GETFIRMWAREVERSION    = 0x02,
+  PN532_COMMAND_GETGENERALSTATUS      = 0x04,
+  PN532_COMMAND_READREGISTER          = 0x06,
+  PN532_COMMAND_WRITEREGISTER         = 0x08,
+  PN532_COMMAND_READGPIO              = 0x0C,
+  PN532_COMMAND_WRITEGPIO             = 0x0E,
+  PN532_COMMAND_SETSERIALBAUDRATE     = 0x10,
+  PN532_COMMAND_SETPARAMETERS         = 0x12,
+  PN532_COMMAND_SAMCONFIGURATION      = 0x14,
+  PN532_COMMAND_POWERDOWN             = 0x16,
+  PN532_COMMAND_RFCONFIGURATION       = 0x32,
+  PN532_COMMAND_RFREGULATIONTEST      = 0x58,
+  PN532_COMMAND_INJUMPFORDEP          = 0x56,
+  PN532_COMMAND_INJUMPFORPSL          = 0x46,
+  PN532_COMMAND_INLISTPASSIVETARGET   = 0x4A,
+  PN532_COMMAND_INATR                 = 0x50,
+  PN532_COMMAND_INPSL                 = 0x4E,
+  PN532_COMMAND_INDATAEXCHANGE        = 0x40,
+  PN532_COMMAND_INCOMMUNICATETHRU     = 0x42,
+  PN532_COMMAND_INDESELECT            = 0x44,
+  PN532_COMMAND_INRELEASE             = 0x52,
+  PN532_COMMAND_INSELECT              = 0x54,
+  PN532_COMMAND_INAUTOPOLL            = 0x60,
+  PN532_COMMAND_TGINITASTARGET        = 0x8C,
+  PN532_COMMAND_TGSETGENERALBYTES     = 0x92,
+  PN532_COMMAND_TGGETDATA             = 0x86,
+  PN532_COMMAND_TGSETDATA             = 0x8E,
+  PN532_COMMAND_TGSETMETADATA         = 0x94,
+  PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88,
+  PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90,
+  PN532_COMMAND_TGGETTARGETSTATUS     = 0x8A
+};
+
+/* Application level errors generated by the PN532 chip */
+/* See UM0701-02 - PN532 User Manual */
+enum 
+{
+  PN532_APPERROR_NONE                 = 0x00,
+  PN532_APPERROR_TIMEOUT              = 0x01,
+  PN532_APPERROR_CRCERROR             = 0x02,
+  PN532_APPERROR_PARITYERROR          = 0x04,
+  PN532_APPERROR_FRAMINGERROR         = 0x05,
+  PN532_APPERROR_BITCOLLISION         = 0x06,
+  PN532_APPERROR_INSUFFICIENTBUFFER   = 0x07,
+  PN532_APPERROR_RFBUFFEROVERFLOW     = 0x09,
+  PN532_APPERROR_RFFIELDTIMEOUT       = 0x0A,
+  PN532_APPERROR_RFPROTOCOLERROR      = 0x0B,
+  PN532_APPERROR_TEMPERROR            = 0x0D,
+  PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E,
+  PN532_APPERROR_INVALIDPARAMETER     = 0x10,
+  PN532_APPERROR_DEP_UNSUPPORTEDCMD   = 0x12,
+  PN532_APPERROR_DEP_INVALIDOFORMAT   = 0x13,
+  PN532_APPERROR_AUTHENTERR           = 0x14,
+  PN532_APPERROR_UIDCCHECKERROR       = 0x23,
+  PN532_APPERROR_DEP_INVALIDDEVSTATE  = 0x25,
+  PN532_APPERROR_OPERATIONNOTALLOWED  = 0x26,
+  PN532_APPERROR_CMDNOTACCEPTABLE     = 0x27,
+  PN532_APPERROR_TARGETRELEASED       = 0x29,
+  PN532_APPERROR_IDMISMATCH           = 0x2A,
+  PN532_APPERROR_CARDDISAPPEARED      = 0x2B,
+  PN532_APPERROR_NFCID3MISMATCH       = 0x2C,
+  PN532_APPERROR_OVERCURRENTEVENT     = 0x2D,
+  PN532_APPERROR_NADMISSINGINDEP      = 0x2E
+};
+
+/* Possible states for the PN532 SW Stack */
+typedef enum pn532_state_e
+{
+  PN532_STATE_SLEEP,
+  PN532_STATE_READY,
+  PN532_STATE_BUSY
+}
+pn532_state_t;
+
+/* PN532 Protocol control block */
+typedef struct
+{
+  BOOL                initialised;
+  pn532_state_t       state;
+  pn532_modulation_t  modulation;
+  uint32_t            lastCommand;
+  uint32_t            appError;
+} pn532_pcb_t;
+
+void          pn532PrintHex(const byte_t * pbtData, const size_t szBytes);
+void          pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes);
+pn532_pcb_t * pn532GetPCB();
+void          pn532Init();
+pn532_error_t pn532Read(byte_t *pbtResponse, size_t * pszLen);
+pn532_error_t pn532Write(byte_t *abtCommand, size_t szLen);
+
+#endif
diff --git a/drivers/rf/pn532/pn532_bus.h b/drivers/rf/pn532/pn532_bus.h
new file mode 100644 (file)
index 0000000..9a509b9
--- /dev/null
@@ -0,0 +1,39 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_bus.h
+*/
+/**************************************************************************/
+
+#ifndef __PN532_BUS_H__
+#define __PN532_BUS_H__
+
+#include "projectconfig.h"
+#include "pn532.h"
+
+// #define PN532_BUS_UART
+#define PN532_BUS_I2C
+
+#define PN532_RSTPD_PORT                      (3)
+#define PN532_RSTPD_PIN                       (1)
+#define PN532_I2C_IRQPORT                     (3)
+#define PN532_I2C_IRQPIN                      (2)
+
+#define PN532_NORMAL_FRAME__DATA_MAX_LEN      (254)
+#define PN532_NORMAL_FRAME__OVERHEAD          (8)
+#define PN532_EXTENDED_FRAME__DATA_MAX_LEN    (264)
+#define PN532_EXTENDED_FRAME__OVERHEAD        (11)
+#define PN532_BUFFER_LEN                      (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD)
+
+#define PN532_UART_BAUDRATE                   (115200)
+
+#define PN532_I2C_ADDRESS                     (0x48)
+#define PN532_I2C_READBIT                     (0x01)
+#define PN532_I2C_READYTIMEOUT                (20)    // Max number of attempts to read Ready bit (see UM 5-Nov-2007 Section 6.2.4)
+
+// Generic interface for the different serial buses available on the PN532
+void          pn532_bus_HWInit(void);
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData);
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen);
+pn532_error_t pn532_bus_Wakeup(void);
+
+#endif
diff --git a/drivers/rf/pn532/pn532_bus_i2c.c b/drivers/rf/pn532/pn532_bus_i2c.c
new file mode 100644 (file)
index 0000000..bbcff7c
--- /dev/null
@@ -0,0 +1,490 @@
+/**************************************************************************/
+/*! 
+    @file     pn532_bus_i2c.c
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, microBuilder SARL
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "pn532.h"
+#include "pn532_bus.h"
+
+#ifdef PN532_BUS_I2C
+
+#include "core/systick/systick.h"
+#include "core/gpio/gpio.h"
+#include "core/i2c/i2c.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+/* ======================================================================
+   PRIVATE FUNCTIONS                                                      
+   ====================================================================== */
+
+/**************************************************************************/
+/*! 
+    @brief  Writes an 8 bit value over I2C
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_I2C_NACK
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_i2c_WriteData (const byte_t * pbtData, const size_t szData)
+{
+  uint32_t i2cState;
+
+  // Clear write buffers
+  uint32_t i;
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+
+  // Send the specified bytes
+  I2CWriteLength = szData+1;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS;         // I2C device address
+  for ( i = 0; i < szData; i++ )
+  {
+    I2CMasterBuffer[i+1] = pbtData[i];
+  }
+  i2cState = i2cEngine();
+
+  // Check if we got an ACK
+  if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK))
+  {
+    // I2C slave didn't acknowledge the master transfer
+    // The PN532 probably isn't connected properly or the
+    // bus select pins are in the wrong state
+    return PN532_ERROR_I2C_NACK;
+  }
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief    Checks the 'IRQ' pin to know if the PN532 is ready to send
+              a response or not
+    
+    @note     The IRQ bit may stay high intentionally, and this isn't
+              always an error condition.  When PN532_COMMAND_INLISTPASSIVETARGET
+              is sent, for example, the PN532 will wait until a card
+              enters the magnetic field, and IRQ will remain high since
+              there is no response ready yet.  The IRQ pin will go low
+              as soon as a card enters the magentic field and the data
+              has been retrieved from it.
+
+    @returns  1 if a response is ready, 0 if the PN532 is still busy or a
+              timeout occurred
+*/
+/**************************************************************************/
+uint8_t pn532_bus_i2c_WaitForReady(void) 
+{
+  uint8_t busy = 1;
+  // uint8_t busyTimeout = 0;
+
+  while (busy)
+  {
+    // For now, we wait forever until a command is ready
+    // ToDo: Add user-specified timeout
+    busy = gpioGetValue(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN);
+    systickDelay(1);
+    // busyTimeout++;
+    // if (busyTimeout == PN532_I2C_READYTIMEOUT)
+    // {
+    //   return false;
+    // }
+  }
+
+  return true;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Builds a standard PN532 frame using the supplied data
+
+    @param  pbtFrame  Pointer to the field that will hold the frame data
+    @param  pszFrame  Pointer to the field that will hold the frame length
+    @param  pbtData   Pointer to the data to insert in a frame
+    @param  swData    Length of the data to insert in bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_i2c_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
+{
+  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN) 
+  {
+    // Extended frames currently unsupported
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+
+  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
+  pbtFrame[3] = szData + 1;
+  // LCS - Packet length checksum
+  pbtFrame[4] = 256 - (szData + 1);
+  // TFI
+  pbtFrame[5] = 0xD4;
+  // DATA - Copy the PN53X command into the packet buffer
+  memcpy (pbtFrame + 6, pbtData, szData);
+
+  // DCS - Calculate data payload checksum
+  byte_t btDCS = (256 - 0xD4);
+  size_t szPos;
+  for (szPos = 0; szPos < szData; szPos++) 
+  {
+    btDCS -= pbtData[szPos];
+  }
+  pbtFrame[6 + szData] = btDCS;
+
+  // 0x00 - End of stream marker
+  pbtFrame[szData + 7] = 0x00;
+
+  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
+
+  return PN532_ERROR_NONE;
+}
+
+/* ======================================================================
+   PUBLIC FUNCTIONS                                                      
+   ====================================================================== */
+
+/**************************************************************************/
+/*! 
+    @brief  Initialises I2C and configures the PN532 HW
+*/
+/**************************************************************************/
+void pn532_bus_HWInit(void)
+{
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Initialising I2C %s", CFG_PRINTF_NEWLINE);
+  #endif
+  i2cInit(I2CMASTER);
+
+  // Set IRQ pin to input
+  gpioSetDir(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN, gpioDirection_Input);
+
+  // Set reset pin as output and reset device
+  gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Resetting the PN532...\r\n");
+  #endif
+  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
+  systickDelay(400);
+  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
+
+  // Wait for the PN532 to finish booting
+  systickDelay(100);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends the specified command to the PN532, automatically
+            creating an appropriate frame for it
+
+    @param  pdbData   Pointer to the byte data to send
+    @param  szData    Length in bytes of the data to send
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME       // Extended frames not supported
+            - PN532_ERROR_BUSY                // Already busy with a command
+            - PN532_ERROR_I2C_NACK            // No ACK on I2C
+            - PN532_ERROR_READYSTATUSTIMEOUT  // Timeout waiting for ready bit
+            - PN532_ERROR_INVALIDACK          // No ACK frame received
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
+{
+  pn532_error_t error = PN532_ERROR_NONE;
+  pn532_pcb_t *pn532 = pn532GetPCB();
+    
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // --------------------------------------------------------------------
+  // Send the command frame
+  // --------------------------------------------------------------------
+  byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
+  size_t szFrame = 0;
+
+  // Build the frame
+  pn532_bus_i2c_BuildFrame (abtFrame, &szFrame, pbtData, szData);
+
+  // Keep track of the last command that was sent
+  pn532->lastCommand = pbtData[0];
+
+  // Output the frame data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending  (%02d): ", szFrame);
+  pn532PrintHex(abtFrame, szFrame);
+  #endif
+
+  // Send data to the PN532
+  error = pn532_bus_i2c_WriteData(abtFrame, szFrame);
+
+  if (error == PN532_ERROR_I2C_NACK)
+  {
+    // Most likely error is PN532_ERROR_I2C_NACK
+    // meaning no I2C ACK received from the PN532
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("No ACK received on I2C bus%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return error;
+  }
+
+  // --------------------------------------------------------------------
+  // Wait for the IRQ/Ready flag
+  // --------------------------------------------------------------------
+  if (!(pn532_bus_i2c_WaitForReady()))
+  {
+    pn532->state = PN532_STATE_READY;
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  // --------------------------------------------------------------------
+  // Read the ACK frame
+  // --------------------------------------------------------------------
+  uint32_t i;
+  // Clear buffer
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+  I2CWriteLength = 0;
+  I2CReadLength = 7;  // ACK + Ready bit = 7
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+
+  // Make sure the received ACK matches the prototype
+  const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
+  byte_t abtRxBuf[6];
+  // memcpy(abtRxBuf, I2CSlaveBuffer+1, 6);
+  for ( i = 0; i < 6; i++ )
+  {
+    abtRxBuf[i] = I2CSlaveBuffer[i+1];
+  }
+  if (0 != (memcmp (abtRxBuf, abtAck, 6))) 
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Invalid ACK: ");
+    pn532PrintHex(abtRxBuf, 6);
+    PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_INVALIDACK;
+  }
+
+  // --------------------------------------------------------------------
+  // Wait for the post-ACK IRQ/Ready flag
+  // --------------------------------------------------------------------
+  if (!(pn532_bus_i2c_WaitForReady()))
+  {
+    pn532->state = PN532_STATE_READY;
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
+    #endif
+    return PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads a response from the PN532
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_RESPONSEBUFFEREMPTY
+            - PN532_ERROR_PREAMBLEMISMATCH
+            - PN532_ERROR_APPLEVELERROR
+            - PN532_ERROR_EXTENDEDFRAME
+            - PN532_ERROR_LENCHECKSUMMISMATCH
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
+{
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Reset the app error flag
+  pn532->appError = PN532_APPERROR_NONE;
+
+  uint32_t i;
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+  I2CWriteLength = 0;
+  I2CReadLength = I2C_BUFSIZE;
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+
+  // Display the raw response data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Received (%02d): ", I2C_BUFSIZE-1);
+  pn532PrintHex(pbtResponse, I2C_BUFSIZE-1);
+  #endif
+
+  // Use the full I2C buffer size for now (until we're sure we have a good frame)
+  *pszRxLen = I2C_BUFSIZE - 1;
+
+  // Fill the response buffer from I2C (skipping the leading 'ready' bit when using I2C)
+  // memcpy(pbtResponse, I2CSlaveBuffer+1, I2C_BUFSIZE-1);
+  for ( i = 0; i < I2C_BUFSIZE-1; i++ )
+  {
+    pbtResponse[i] = I2CSlaveBuffer[i+1];
+  }
+
+  // Check the frame type
+  if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) 
+  {
+    // Error frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
+    #endif
+    // Set application error message ID
+    pn532->appError = pbtResponse[5];
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_APPLEVELERROR;
+  } 
+  else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) 
+  {
+    // Extended frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_EXTENDEDFRAME;
+  } 
+  else 
+  {
+    // Normal frame
+    if (256 != (pbtResponse[3] + pbtResponse[4])) 
+    {
+      // TODO: Retry
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
+      #endif
+      pn532->state = PN532_STATE_READY;
+      return PN532_ERROR_LENCHECKSUMMISMATCH;
+    }
+  }
+
+  // Figure out how large the response really is
+  // Response Frame Len = pbtResponse[3] + 7 (00 00 FF LEN LCS TFI [DATA] DCS)
+  *pszRxLen = pbtResponse[3] + 7;
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Sends the wakeup sequence to the PN532.
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_I2C_NACK            // No I2C ACK
+            - PN532_ERROR_READYSTATUSTIMEOUT  // Timed out waiting for ready bit
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_Wakeup(void)
+{
+  pn532_error_t error = PN532_ERROR_NONE;
+  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
+  uint32_t i;
+
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
+  #endif
+  error = pn532_bus_i2c_WriteData(abtWakeUp,sizeof(abtWakeUp));
+  systickDelay(100);
+
+  // Wait for the IRQ/Ready flag to indicate a response is ready
+  if (!(pn532_bus_i2c_WaitForReady()))
+  {
+    error = PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  // Read and discard the ACK frame
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+  I2CWriteLength = 0;
+  I2CReadLength = 7;  // ACK + Ready bit = 7
+  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
+  i2cEngine();
+  systickDelay(1);
+
+  // Wait for the IRQ/Ready flag to indicate a response is ready
+  if (!(pn532_bus_i2c_WaitForReady()))
+  {
+    error = PN532_ERROR_READYSTATUSTIMEOUT;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return error;
+}
+
+#endif  // #ifdef PN532_BUS_I2C
\ No newline at end of file
diff --git a/drivers/rf/pn532/pn532_bus_uart.c b/drivers/rf/pn532/pn532_bus_uart.c
new file mode 100644 (file)
index 0000000..981df74
--- /dev/null
@@ -0,0 +1,298 @@
+/**************************************************************************/
+/*! 
+    @file   pn532_bus_uart.c
+*/
+/**************************************************************************/
+#include <string.h>
+
+#include "pn532.h"
+#include "pn532_bus.h"
+
+#ifdef PN532_BUS_UART
+
+#include "core/systick/systick.h"
+#include "core/gpio/gpio.h"
+#include "core/uart/uart.h"
+
+/**************************************************************************/
+/*! 
+    @brief  Builds a standard PN532 frame using the supplied data
+
+    @param  pbtFrame  Pointer to the field that will hold the frame data
+    @param  pszFrame  Pointer to the field that will hold the frame length
+    @param  pbtData   Pointer to the data to insert in a frame
+    @param  swData    Length of the data to insert in bytes
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_EXTENDEDFRAME
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
+{
+  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN) 
+  {
+    // Extended frames currently unsupported
+    return PN532_ERROR_EXTENDEDFRAME;
+  }
+
+  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
+  pbtFrame[3] = szData + 1;
+  // LCS - Packet length checksum
+  pbtFrame[4] = 256 - (szData + 1);
+  // TFI
+  pbtFrame[5] = 0xD4;
+  // DATA - Copy the PN53X command into the packet buffer
+  memcpy (pbtFrame + 6, pbtData, szData);
+
+  // DCS - Calculate data payload checksum
+  byte_t btDCS = (256 - 0xD4);
+  size_t szPos;
+  for (szPos = 0; szPos < szData; szPos++) 
+  {
+    btDCS -= pbtData[szPos];
+  }
+  pbtFrame[6 + szData] = btDCS;
+
+  // 0x00 - End of stream marker
+  pbtFrame[szData + 7] = 0x00;
+
+  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
+
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Initialises UART and configures the PN532
+*/
+/**************************************************************************/
+void pn532_bus_HWInit(void)
+{
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Initialising UART (%d)%s", PN532_UART_BAUDRATE, CFG_PRINTF_NEWLINE);
+  #endif
+  uartInit(PN532_UART_BAUDRATE);
+
+  // Set reset pin as output and reset device
+  gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Resetting the PN532...\r\n");
+  #endif
+  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
+  systickDelay(400);
+  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
+
+  // Wait for the PN532 to finish booting
+  systickDelay(100);
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Sends the specified command to the PN532, automatically
+            creating an appropriate frame for it
+
+    @param  pdbData   Pointer to the byte data to send
+    @param  szData    Length in bytes of the data to send
+
+    @note   Possible error messages are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_NOACK
+            - PN532_ERROR_INVALIDACK
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
+{
+  pn532_pcb_t *pn532 = pn532GetPCB();
+    
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Every packet must start with "00 00 ff"
+  byte_t  abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
+  size_t szFrame = 0;
+
+  // Build the frame
+  pn532_bus_BuildFrame (abtFrame, &szFrame, pbtData, szData);
+
+  // Keep track of the last command that was sent
+  pn532->lastCommand = pbtData[0];
+
+  // Output the frame data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending  (%02d): ", szFrame);
+  pn532PrintHex(abtFrame, szFrame);
+  #endif
+
+  // Send data to the PN532
+  uartSend (abtFrame, szFrame);
+
+  // Wait for ACK
+  byte_t abtRxBuf[6];
+  uart_pcb_t *uart = uartGetPCB();
+  systickDelay(10);   // FIXME: How long should we wait for ACK?
+  if (uart->rxfifo.len < 6) 
+  {
+    // Unable to read ACK
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Unable to read ACK%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_NOACK;
+  }
+
+  // Read ACK ... this will also remove it from the buffer
+  const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
+  abtRxBuf[0] = uartRxBufferRead();
+  abtRxBuf[1] = uartRxBufferRead();
+  abtRxBuf[2] = uartRxBufferRead();
+  abtRxBuf[3] = uartRxBufferRead();
+  abtRxBuf[4] = uartRxBufferRead();
+  abtRxBuf[5] = uartRxBufferRead();
+
+  // Make sure the received ACK matches the prototype
+  if (0 != (memcmp (abtRxBuf, abtAck, 6))) 
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG ("Invalid ACK: ");
+    pn532PrintHex(abtRxBuf, 6);
+    PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_INVALIDACK;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads a response from the PN532
+
+    @note   Possible error message are:
+
+            - PN532_ERROR_BUSY
+            - PN532_ERROR_RESPONSEBUFFEREMPTY
+            - PN532_ERROR_PREAMBLEMISMATCH
+            - PN532_ERROR_APPLEVELERROR
+            - PN532_ERROR_EXTENDEDFRAME
+            - PN532_ERROR_LENCHECKSUMMISMATCH
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
+{
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  // Check if we're busy
+  if (pn532->state == PN532_STATE_BUSY)
+  {
+    return PN532_ERROR_BUSY;
+  }
+
+  // Flag the stack as busy
+  pn532->state = PN532_STATE_BUSY;
+
+  // Reset the app error flag
+  pn532->appError = PN532_APPERROR_NONE;
+
+  // Read response from uart
+  if (!uartRxBufferReadArray(pbtResponse, pszRxLen)) 
+  {
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_RESPONSEBUFFEREMPTY;
+  }
+
+  // Display the raw response data for debugging if requested
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Received (%02d): ", *pszRxLen);
+  pn532PrintHex(pbtResponse, *pszRxLen);
+  #endif
+  
+  // Check preamble
+  const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
+  if (0 != (memcmp (pbtResponse, pn53x_preamble, 3))) 
+  {
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_PREAMBLEMISMATCH;
+  }
+
+  // Check the frame type
+  if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) 
+  {
+    // Error frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
+    #endif
+    // Set application error message ID
+    pn532->appError = pbtResponse[5];
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_APPLEVELERROR;
+  } 
+  else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) 
+  {
+    // Extended frame
+    #ifdef PN532_DEBUGMODE
+    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
+    #endif
+    pn532->state = PN532_STATE_READY;
+    return PN532_ERROR_EXTENDEDFRAME;
+  } 
+  else 
+  {
+    // Normal frame
+    if (256 != (pbtResponse[3] + pbtResponse[4])) 
+    {
+      // TODO: Retry
+      #ifdef PN532_DEBUGMODE
+      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
+      #endif
+      pn532->state = PN532_STATE_READY;
+      return PN532_ERROR_LENCHECKSUMMISMATCH;
+    }
+    // size_t szPayloadLen = abtRx[3] - 2;
+  }
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*! 
+    @brief      Sends the wakeup sequence to the PN532.
+*/
+/**************************************************************************/
+pn532_error_t pn532_bus_Wakeup(void)
+{
+  size_t szLen;
+  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
+
+  pn532_pcb_t *pn532 = pn532GetPCB();
+
+  #ifdef PN532_DEBUGMODE
+  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
+  #endif
+  uartSend(abtWakeUp,sizeof(abtWakeUp));
+  systickDelay(100);
+
+  byte_t response[32];
+  pn532_bus_ReadResponse(response, &szLen);
+
+  // Todo: Check for error ... currently throws a checksum error
+  // that isn't really an error
+
+  pn532->state = PN532_STATE_READY;
+  return PN532_ERROR_NONE;
+}
+
+#endif  // #ifdef PN532_BUS_UART
\ No newline at end of file
diff --git a/drivers/sensors/pn532/helpers/pn532_mifare.h b/drivers/sensors/pn532/helpers/pn532_mifare.h
deleted file mode 100644 (file)
index 94d2c2e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_mifare.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_MIFARE_H__
-#define __PN532_MIFARE_H__
-
-#include "projectconfig.h"
-
-// These may need to be enlarged for multi card support
-#define PN532_RESPONSELEN_INLISTPASSIVETARGET (64)
-#define PN532_RESPONSELEN_INDATAEXCHANGE      (64)  
-
-typedef enum pn532_mifare_cmd_e
-{
-  PN532_MIFARE_CMD_AUTH_A     = 0x60,
-  PN532_MIFARE_CMD_AUTH_B     = 0x61,
-  PN532_MIFARE_CMD_READ       = 0x30,
-  PN532_MIFARE_CMD_WRITE      = 0xA0,
-  PN532_MIFARE_CMD_TRANSFER   = 0xB0,
-  PN532_MIFARE_CMD_DECREMENT  = 0xC0,
-  PN532_MIFARE_CMD_INCREMENT  = 0xC1,
-  PN532_MIFARE_CMD_STORE      = 0xC2
-} 
-pn532_mifare_cmd_t;
-
-#endif
diff --git a/drivers/sensors/pn532/helpers/pn532_mifare_classic.c b/drivers/sensors/pn532/helpers/pn532_mifare_classic.c
deleted file mode 100644 (file)
index debf834..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_mifare_classic.c
-*/
-/**************************************************************************/
-
-/*  MIFARE CLASSIC DESCRIPTION
-    ==========================
-
-    MIFARE Classic cards come in 1K and 4K varieties.  While several
-    varieties of chips exist, the two main chipsets used are described
-    in the following publicly accessible documents:
-
-        MF1S503x Mifare Classic 1K data sheet:
-        http://www.nxp.com/documents/data_sheet/MF1S503x.pdf
-            
-        MF1S70yyX MIFARE Classic 4K data sheet:
-        http://www.nxp.com/documents/data_sheet/MF1S70YYX.pdf
-
-    Mifare Classic cards typically have a a 4-byte NUID, though you may
-    find cards with 7 byte IDs as well
-        
-    EEPROM MEMORY
-    =============
-    Mifare Classic cards have either 1K or 4K of EEPROM memory. Each
-    memory block can be configured with different access conditions,
-    with two seperate authentication keys present in each block.
-
-    The two main Mifare Classic card types are organised as follows:
-
-        1K Cards: 16 sectors of 4 blocks (0..15)
-        4K Cards: 32 sectors of 4 blocks (0..31) and
-                  8 sectors of 16 blocks (32..39)
-
-    4 block sectors
-    ===============
-    Sector  Block   Bytes                                                           Description
-    ------  -----   -----                                                           -----------
-                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
-
-    1       3       [-------KEY A-------]   [Access Bits]   [-------KEY A-------]   Sector Trailer 1
-            2       [                            Data                           ]   Data
-            1       [                            Data                           ]   Data
-            0       [                            Data                           ]   Data
-
-    0       3       [-------KEY A-------]   [Access Bits]   [-------KEY A-------]   Sector Trailer 1
-            2       [                            Data                           ]   Data
-            1       [                            Data                           ]   Data
-            0       [                     Manufacturer Data                     ]   Manufacturer Block
-
-    Sector Trailer (Block 3)
-    ------------------------
-    The sector trailer block contains the two secret keys (Key A and Key B), as well
-    as the access conditions for the four blocks.  It has the following structure:
-
-        Sector Trailer Bytes
-        --------------------------------------------------------------
-        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
-        [       Key A       ]   [Access Bits]   [       Key B       ]
-
-    For more information in using Keys to access the clock contents, see
-    Accessing Data Blocks further below.
-
-    Data Blocks (Blocks 0..2)
-    -------------------------
-    Data blocks are 16 bytes wide and, depending on the permissions set in the
-    access bits, can be read from and written to. You are free to use the 16 data
-    bytes in any way you wish.  You can easily store text input, store four 32-bit
-    integer values, a 16 character uri, etc.
-
-    Data Blocks as "Value Blocks"
-    -----------------------------
-    An alternative to storing random data in the 16 byte-wide blocks is to
-    configure them as "Value Blocks".  Value blocks allow performing electronic
-    purse functions (valid commands are: read, write, increment, decrement,
-    restore, transfer).
-    
-    Each Value block contains a single signed 32-bit value, and this value is
-    stored 3 times for data integrity and security reasons.  It is stored twice
-    non-inverted, and once inverted.  The last 4 bytes are used for a 1-byte
-    address, which is stored 4 times (twice non-inverted, and twice inverted).
-    
-    Data blocks configured as "Value Blocks" have the following structure:
-
-        Value Block Bytes
-        --------------------------------------------------------------
-        0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
-        [   Value   ]   [   ~Value  ]   [   Value   ]   [A  ~A  A   ~A]
-
-    Manufacturer Block (Sector 0, Block 0)
-    --------------------------------------
-    Sector 0 is special since it contains the Manufacturer Block. This block
-    contains the manufacturer data, and is read-only.  It should be avoided
-    unless you know what you are doing.
-
-    16 block sectors
-    ================
-    16 block sectors are identical to 4 block sectors, but with more data blocks.  The same
-    structure described in the 4 block sectors above applies.
-
-    Sector  Block   Bytes                                                           Description
-    ------  -----   -----                                                           ----------
-                    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
-
-    32      15      [-------KEY A-------]   [Access Bits]   [-------KEY B-------]   Sector Trailer 32
-            14      [                            Data                           ]   Data
-            13      [                            Data                           ]   Data
-            ...
-            2       [                            Data                           ]   Data
-            1       [                            Data                           ]   Data
-            0       [                            Data                           ]   Data
-
-    ACCESSING DATA BLOCKS
-    =====================
-
-    Before you can access the cards, you must following two steps:
-
-    1.) You must retrieve the 7 byte UID or the 4-byte NUID of the card.
-        This can be done using pn532_mifareclassic_WaitForPassiveTarget()
-        below, which will return the appropriate ID.
-
-    2.) You must authenticate the sector you wish to access according to the
-        access rules defined in the Sector Trailer block for that sector.
-        This can be done using pn532_mifareclassic_AuthenticateBlock(),
-        passing in the appropriate key value.
-          
-        Most new cards have a default Key A of 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF,
-        but some common values worth trying are:
-
-            0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
-            0XD3 0XF7 0XD3 0XF7 0XD3 0XF7
-            0XA0 0XA1 0XA2 0XA3 0XA4 0XA5
-            0XB0 0XB1 0XB2 0XB3 0XB4 0XB5
-            0X4D 0X3A 0X99 0XC3 0X51 0XDD
-            0X1A 0X98 0X2C 0X7E 0X45 0X9A
-            0XAA 0XBB 0XCC 0XDD 0XEE 0XFF
-            0X00 0X00 0X00 0X00 0X00 0X00
-            0XAB 0XCD 0XEF 0X12 0X34 0X56
-
-    3.) Once authenication has succeeded, and depending on the sector
-        permissions, you can then read/write/increment/decrement the
-        contents of the specific block, using one of the helper functions
-        included in this module.
-
-*/
-
-#include <string.h>
-
-#include "../pn532.h"
-#include "../pn532_bus.h"
-#include "pn532_mifare.h"
-#include "pn532_mifare_classic.h"
-
-#include "core/systick/systick.h"
-
-/**************************************************************************/
-/*! 
-      Indicates whether the specified block number is the first block
-      in the sector (block 0 relative to the current sector)
-*/
-/**************************************************************************/
-bool is_first_block (uint32_t uiBlock)
-{
-  // Test if we are in the small or big sectors
-  if (uiBlock < 128)
-    return ((uiBlock) % 4 == 0);
-  else
-    return ((uiBlock) % 16 == 0);
-}
-
-/**************************************************************************/
-/*! 
-      Indicates whether the specified block number is the sector trailer
-*/
-/**************************************************************************/
-bool is_trailer_block (uint32_t uiBlock)
-{
-  // Test if we are in the small or big sectors
-  if (uiBlock < 128)
-    return ((uiBlock + 1) % 4 == 0);
-  else
-    return ((uiBlock + 1) % 16 == 0);
-}
-
-/**************************************************************************/
-/*! 
-    Tries to detect MIFARE targets in passive mode.  This needs to be done
-    before anything useful can be accomplished with a tag since you need
-    the tag's unique UID to communicate with it.
-
-    @param  pbtCUID     Pointer to the byte array where the card's UID
-                        will be stored once a card is detected
-    @param  pszUIDLen   Pointer to the size of the card UID in bytes
-
-    Response for a valid ISO14443A 106KBPS (Mifare Classic, etc.)
-    should be in the following format.  See UM0701-02 section
-    7.3.5 for more information
-    
-    byte            Description
-    -------------   ------------------------------------------
-    b0..6           Frame header and preamble
-    b7              Tags Found
-    b8              Tag Number (only one used in this example)
-    b9..10          SENS_RES
-    b11             SEL_RES
-    b12             NFCID Length
-    b13..NFCIDLen   NFCID                                      
-    
-    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
-    --------   -------     -----------------------   ---------
-    00 04      08          NXP Mifare Classic 1K     4 bytes   
-    00 02      18          NXP Mifare Classic 4K     4 bytes
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_WRONGCARDTYPE
-*/
-/**************************************************************************/
-pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
-{
-  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
-  pn532_error_t error;
-  size_t szLen;
-
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
-  #endif
-
-  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
-  /* Note:  To wait for a card with a known UID, append the four byte     */
-  /*        UID to the end of the command.                                */ 
-  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
-  error = pn532Write(abtCommand, sizeof(abtCommand));
-  if (error) 
-    return error;
-
-  /* Wait until we get a valid response or a timeout                      */
-  do
-  {
-    systickDelay(25);
-    error = pn532Read(abtResponse, &szLen);
-  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
-  if (error) 
-    return error;
-
-  /* Check SENSE_RES to make sure this is a Mifare Classic card           */
-  /*          Classic 1K       = 00 04                                    */
-  /*          Classic 4K       = 00 02                                    */
-  /*          Classic Emulated = 00 08                                    */
-  if ((abtResponse[10] == 0x02) || 
-      (abtResponse[10] == 0x04) || 
-      (abtResponse[10] == 0x08))
-  {
-    /* Card appears to be Mifare Classic */
-    *szCUIDLen = abtResponse[12];
-    uint8_t i;
-    for (i=0; i < *szCUIDLen; i++) 
-    {
-      pbtCUID[i] = abtResponse[13+i];
-    }
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("      ATQA: ");
-      pn532PrintHex(abtResponse+9, 2);
-      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("      UID: ");
-      pn532PrintHex(pbtCUID, *szCUIDLen);
-    #endif
-  }
-  else
-  {
-    /* Card is ISO14443A but doesn't appear to be Mifare Classic          */
-    /*    Mifare Ultralight    = 0x0044                                   */
-    /*    Mifare DESFire       = 0x0344                                   */
-    /*    Innovision Jewel     = 0x0C00                                   */
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 02, 00 04 or 00 08) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  ATQA       : ");
-      pn532PrintHex(abtResponse+9, 2);
-      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  UID        : ");
-      size_t pos;
-      for (pos=0; pos < abtResponse[12]; pos++) 
-      {
-        printf("%02x ", abtResponse[13 + pos]);
-      }
-      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_WRONGCARDTYPE;
-  }
-
-  return PN532_ERROR_NONE;
-}
-
-
-/**************************************************************************/
-/*! 
-    Tries to authenticate a block of memory on a MIFARE card using the
-    INDATAEXCHANGE command.  See section 7.3.8 of the PN532 User Manual
-    for more information on sending MIFARE and other commands.
-
-    @param  pbtCUID       Pointer to a byte array containing the card UID
-    @param  szCUIDLen     The length (in bytes) of the card's UID (Should
-                          be 4 for MIFARE Classic)
-    @param  uiBlockNumber The block number to authenticate.  (0..63 for
-                          1KB cards, and 0..255 for 4KB cards).
-    @param  uiKeyType     Which key type to use during authentication
-                          (PN532_MIFARE_CMD_AUTH_A or PN532_MIFARE_CMD_AUTH_B)
-    @param  pbtKeys       Pointer to a byte array containing the 6 byte
-                          key value
-*/
-/**************************************************************************/
-pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys)
-{
-  pn532_error_t error;
-  byte_t abtCommand[17];
-  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
-  size_t szLen;
-
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Trying to authenticate card ");
-  pn532PrintHex(pbtCUID, szCUIDLen);
-  #endif
-
-  /* Prepare the authentication command */
-  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;   /* Data Exchange Header */
-  abtCommand[1] = 1;                              /* Max card numbers */
-  abtCommand[2] = (uiKeyType) ? PN532_MIFARE_CMD_AUTH_A : PN532_MIFARE_CMD_AUTH_B;
-  abtCommand[3] = uiBlockNumber;                  /* Block Number (1K = 0..63, 4K = 0..255 */
-  memcpy (abtCommand+4, pbtKeys, 6);
-  uint8_t i;
-  for (i = 0; i < szCUIDLen; i++)
-  {
-    abtCommand[10+i] = pbtCUID[i];                /* 4 byte card ID */
-  }
-  
-  /* Send the command */
-  error = pn532Write(abtCommand, 10+szCUIDLen);
-  if (error)
-  {
-    /* Problem with the serial bus, etc. */
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }
-
-  /* Read the authentication response */
-  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
-  do
-  {
-    systickDelay(25);
-    error = pn532Read(abtResponse, &szLen);
-  }
-  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
-  if (error)
-  {
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }
-
-  // ToDo: How to check if authentification really worked (bad key, etc.)?
-
-  /* Output the authentification data */
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Authenticated block %d %s", uiBlockNumber, CFG_PRINTF_NEWLINE);
-  #endif
-
-  // Return OK signal
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    Tries to read an entire 16-byte data block at the specified block
-    address.
-
-    @param  uiBlockNumber The block number to authenticate.  (0..63 for
-                          1KB cards, and 0..255 for 4KB cards).
-    @param  pbtData       Pointer to the byte array that will hold the
-                          retrieved data (if any)
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_BLOCKREADFAILED
-*/
-/**************************************************************************/
-pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData)
-{
-  pn532_error_t error;
-  byte_t abtCommand[4];
-  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
-  size_t szLen;
-
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Reading 16 bytes at block %03d%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
-  #endif
-
-  /* Prepare the command */
-  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
-  abtCommand[1] = 1;                            /* Card number */
-  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
-  abtCommand[3] = uiBlockNumber;                /* Block Number (0..63 for 1K, 0..255 for 4K) */
-  
-  /* Send the commands */
-  error = pn532Write(abtCommand, sizeof(abtCommand));
-  if (error)
-  {
-    /* Bus error, etc. */
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }
-
-  /* Read the response */
-  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
-  do
-  {
-    systickDelay(50);
-    error = pn532Read(abtResponse, &szLen);
-  }
-  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
-  if (error)
-  {
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }
-
-  /* Make sure we have a valid response (should be 26 bytes long) */
-  if (szLen == 26)
-  {
-    /* Copy the 16 data bytes to the output buffer        */
-    /* Block content starts at byte 9 of a valid response */
-    memcpy (pbtData, abtResponse+8, 16);
-  }
-  else
-  {
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_BLOCKREADFAILED;
-  }
-
-  /* Display data for debug if requested */
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Block %03d: ", uiBlockNumber, CFG_PRINTF_NEWLINE);
-    pn532PrintHexVerbose(pbtData, 16);
-  #endif
-
-  // Return OK signal
-  return PN532_ERROR_NONE;
-}
diff --git a/drivers/sensors/pn532/helpers/pn532_mifare_classic.h b/drivers/sensors/pn532/helpers/pn532_mifare_classic.h
deleted file mode 100644 (file)
index 81177e9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_mifare_classic.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_MIFARE_CLASSIC_H__
-#define __PN532_MIFARE_CLASSIC_H__
-
-#include "projectconfig.h"
-#include "pn532_mifare.h"
-
-pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
-pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys);
-pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData);
-
-#endif
diff --git a/drivers/sensors/pn532/helpers/pn532_mifare_ultralight.c b/drivers/sensors/pn532/helpers/pn532_mifare_ultralight.c
deleted file mode 100644 (file)
index 0876101..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_mifare_ultralight.c
-*/
-/**************************************************************************/
-
-/*  MIFARE ULTRALIGHT DESCRIPTION
-    =============================
-
-    MIFARE Ultralight cards typically contain 512 bits (64 bytes) of
-    memory, including 4 bytes (32-bits) of OTP (One Time Programmable)
-    memory where the individual bits can be written but not erased.
-
-        MF0ICU1 Mifare Ultralight Functional Specification:
-        http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
-            
-
-    Mifare Ultralight cards have a 7-byte UID
-    
-    EEPROM MEMORY
-    =============
-    Mifare Ultralight cards have 512 bits (64 bytes) of EEPROM memory,
-    including 4 byte (32 bits) of OTP memory.  Unlike Mifare Classic cards,
-    there is no authentication on a per block level, although the blocks
-    can be set to "read-only" mode using Lock Bytes (described below).
-
-    EEPROM memory is organised into 16 pages of four bytes eachs, in
-    the following order
-
-    Page   Description
-    ----   ------------
-    0      Serial Number (4 bytes)
-    1      Serial Number (4 bytes)
-    2      Byte 0:    Serial Number
-           Byte 1:    Internal Memory
-           Byte 2..3: lock bytes
-    3      One-time programmable memory (4 bytes)
-    4..15  User memory (4 bytes)
-
-    Lock Bytes (Page 2)
-    -------------------
-    Bytes 2 and 3 of page 2 are referred to as "Lock Bytes".  Each
-    page from 0x03 and higher can individually locked by setting the
-    corresponding locking bit to "1" to prevent further write access,
-    effectively making the memory read only.
-
-    For information on the lock byte mechanism, refer to section 8.5.2 of
-    the datasheet (referenced above).
-
-    OTP Bytes (Page 3)
-    ------------------
-    Page 3 is the OTP memory, and by default all bits on this page are
-    set to 0.  These bits can be bitwise modified using the Mifare WRITE
-    command, and individual bits can be set to 1, but can not be changed
-    back to 0.
-
-    Data Pages (Pages 4..15)
-    ------------------------
-    Pages 4 to 15 are can be freely read from and written to, 
-    provided there is no conflict with the Lock Bytes described above.
-
-    After production, the bytes have the following default values:
-
-    Page    Byte Values
-    ----    ----------------------
-            0     1     2     3
-    4       0xFF  0xFF  0xFF  0xFF
-    5..15   0x00  0x00  0x00  0x00
-
-    ACCESSING DATA BLOCKS
-    =====================
-
-    Before you can access the cards, you must following two steps:
-
-    1.) 'Connect' to a Mifare Ultralight card and retrieve the 7 byte
-        UID of the card.
-
-    2.) Memory can be read and written directly once a passive mode
-        connection has been made.  No authentication is required for
-        Mifare Ultralight cards.
-
-*/
-
-#include <string.h>
-
-#include "../pn532.h"
-#include "../pn532_bus.h"
-#include "pn532_mifare_ultralight.h"
-
-#include "core/systick/systick.h"
-
-/**************************************************************************/
-/*! 
-    Tries to detect MIFARE targets in passive mode.
-
-    @param  pbtCUID     Pointer to the byte array where the card's 7 byte
-                        UID will be stored once a card is detected
-    @param  pszUIDLen   Pointer to the size of the card UID in bytes
-
-    Response for a valid ISO14443A 106KBPS (Mifare Ultralight, etc.)
-    should be in the following format.  See UM0701-02 section
-    7.3.5 for more information
-    
-    byte            Description
-    -------------   ------------------------------------------
-    b0..6           Frame header and preamble
-    b7              Tags Found
-    b8              Tag Number (only one used in this example)
-    b9..10          SENS_RES
-    b11             SEL_RES
-    b12             NFCID Length
-    b13..NFCIDLen   NFCID                                      
-    
-    SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
-    --------   -------     -----------------------   ---------
-    00 44      00          NXP Mifare Ultralight     7 bytes   
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_WRONGCARDTYPE
-*/
-/**************************************************************************/
-pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
-{
-  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
-  pn532_error_t error;
-  size_t szLen;
-
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
-  #endif
-
-  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
-  /* Note:  To wait for a card with a known UID, append the four byte     */
-  /*        UID to the end of the command.                                */ 
-  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
-  error = pn532Write(abtCommand, sizeof(abtCommand));
-  if (error) 
-    return error;
-
-  /* Wait until we get a valid response or a timeout                      */
-  do
-  {
-    systickDelay(25);
-    error = pn532Read(abtResponse, &szLen);
-  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
-  if (error) 
-    return error;
-
-  /* Check SENS_RES to make sure this is a Mifare Ultralight card         */
-  /*          Mifare Ultralight = 00 44                                   */
-  if (abtResponse[10] == 0x44)
-  {
-    /* Card appears to be Mifare Ultralight */
-    *szCUIDLen = abtResponse[12];
-    uint8_t i;
-    for (i=0; i < *szCUIDLen; i++) 
-    {
-      pbtCUID[i] = abtResponse[13+i];
-    }
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("      ATQA: ");
-      pn532PrintHex(abtResponse+9, 2);
-      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("      UID: ");
-      pn532PrintHex(pbtCUID, *szCUIDLen);
-    #endif
-  }
-  else
-  {
-    /* Card is ISO14443A but doesn't appear to be Mifare Ultralight       */
-    /*    Mifare Classic       = 0x0002, 0x0004, 0x0008                   */
-    /*    Mifare DESFire       = 0x0344                                   */
-    /*    Innovision Jewel     = 0x0C00                                   */
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 44) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  ATQA       : ");
-      pn532PrintHex(abtResponse+9, 2);
-      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
-      PN532_DEBUG("  UID        : ");
-      size_t pos;
-      for (pos=0; pos < abtResponse[12]; pos++) 
-      {
-        printf("%02x ", abtResponse[13 + pos]);
-      }
-      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_WRONGCARDTYPE;
-  }
-
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    Tries to read an entire 4-byte page at the specified address.
-
-    @param  page        The page number (0..63 in most cases)
-    @param  pbtBuffer   Pointer to the byte array that will hold the
-                        retrieved data (if any)
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_ADDRESSOUTOFRANGE
-            - PN532_ERROR_BLOCKREADFAILED
-*/
-/**************************************************************************/
-pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer)
-{
-  pn532_error_t error;
-  byte_t abtCommand[4];
-  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
-  size_t szLen;
-
-  if (page >= 64)
-  {
-    return PN532_ERROR_ADDRESSOUTOFRANGE;
-  }
-
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Reading page %03d%s", page, CFG_PRINTF_NEWLINE);
-  #endif
-
-  /* Prepare the command */
-  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
-  abtCommand[1] = 1;                            /* Card number */
-  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
-  abtCommand[3] = page;                         /* Page Number (0..63 in most cases) */
-  
-  /* Send the commands */
-  error = pn532Write(abtCommand, sizeof(abtCommand));
-  if (error)
-  {
-    /* Bus error, etc. */
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }
-
-  /* Read the response */
-  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
-  do
-  {
-    systickDelay(50);
-    error = pn532Read(abtResponse, &szLen);
-  }
-  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
-  if (error)
-  {
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return error;
-  }  
-
-  /* Make sure we have a valid response (should be 26 bytes long) */
-  if (szLen == 26)
-  {
-    /* Copy the 4 data bytes to the output buffer         */
-    /* Block content starts at byte 9 of a valid response */
-    /* Note that the command actually reads 16 byte or 4  */
-    /* pages at a time ... we simply discard the last 12  */
-    /* bytes                                              */
-    memcpy (pbtBuffer, abtResponse+8, 4);
-  }
-  else
-  {
-    #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", page, CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_BLOCKREADFAILED;
-  }
-
-  /* Display data for debug if requested */
-  #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Page %02d: ", page, CFG_PRINTF_NEWLINE);
-    pn532PrintHexVerbose(pbtBuffer, 4);
-  #endif
-
-  // Return OK signal
-  return PN532_ERROR_NONE;
-}
-
diff --git a/drivers/sensors/pn532/helpers/pn532_mifare_ultralight.h b/drivers/sensors/pn532/helpers/pn532_mifare_ultralight.h
deleted file mode 100644 (file)
index 78239c9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_mifare_ultralight.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_MIFARE_ULTRALIGHT_H__
-#define __PN532_MIFARE_ULTRALIGHT_H__
-
-#include "projectconfig.h"
-#include "pn532_mifare.h"
-
-pn532_error_t pn532_mifareultralight_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen);
-pn532_error_t pn532_mifareultralight_ReadPage (uint8_t page, byte_t * pbtBuffer);
-
-#endif
diff --git a/drivers/sensors/pn532/pn532.c b/drivers/sensors/pn532/pn532.c
deleted file mode 100644 (file)
index 78eae7f..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532.c
-*/
-/**************************************************************************/
-#include <string.h>
-
-#include "pn532.h"
-#include "pn532_bus.h"
-#include "core/systick/systick.h"
-#include "core/uart/uart.h"
-
-static pn532_pcb_t pcb;
-
-/**************************************************************************/
-/*! 
-    @brief  Prints a hexadecimal value in plain characters
-
-    @param  pbtData   Pointer to the byte data
-    @param  szBytes   Data length in bytes
-*/
-/**************************************************************************/
-void pn532PrintHex(const byte_t * pbtData, const size_t szBytes)
-{
-  size_t szPos;
-  for (szPos=0; szPos < szBytes; szPos++) 
-  {
-    printf("%02x ", pbtData[szPos]);
-  }
-  printf(CFG_PRINTF_NEWLINE);
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Prints a hexadecimal value in plain characters, along with
-            the char equivalents in the following format
-
-            AA BB CC DD EE FF  ......
-
-    @param  pbtData   Pointer to the byte data
-    @param  szBytes   Data length in bytes
-*/
-/**************************************************************************/
-void pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes)
-{
-  size_t szPos;
-  for (szPos=0; szPos < szBytes; szPos++) 
-  {
-    printf("%02x", pbtData[szPos]);
-  }
-  printf("  ");
-  for (szPos=0; szPos < szBytes; szPos++) 
-  {
-    printf("%c", pbtData[szPos] <= 0x1F ? '.' : pbtData[szPos]);
-  }
-  printf(CFG_PRINTF_NEWLINE);
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Gets a reference to the PN532 peripheral control block,
-                which can be used to determine that state of the PN532
-                IC, buffers, etc.
-*/
-/**************************************************************************/
-pn532_pcb_t * pn532GetPCB()
-{
-  return &pcb;
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Initialises the appropriate serial bus (UART, etc.),and
-                sets up any buffers or peripherals required by the PN532.
-*/
-/**************************************************************************/
-void pn532Init(void)
-{
-  // Clear protocol control blocks
-  memset(&pcb, 0, sizeof(pn532_pcb_t));
-
-  // Initialise the underlying HW
-  pn532_bus_HWInit();
-
-  // Set the PCB flags to an appropriate state
-  pcb.initialised = TRUE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Reads the response buffer from the PN532
-
-    @param      pbtResponse
-                The byte array that will hold the response data
-    @param      pszLen
-                Pointer to the number of bytes in pbtCommand
-*/
-/**************************************************************************/
-pn532_error_t pn532Read(byte_t * pbtResponse, size_t * pszLen)
-{
-  if (!pcb.initialised) pn532Init();  
-
-  // Try to wake the device up if it's in sleep mode
-  if (pcb.state == PN532_STATE_SLEEP)
-  {
-    pn532_error_t wakeupError = pn532_bus_Wakeup();
-    if (wakeupError)
-      return wakeupError;
-  }
-
-  // Read the response if the device is in an appropriate state
-  if (pcb.state == PN532_STATE_READY)
-  {
-    return pn532_bus_ReadResponse(pbtResponse, pszLen);
-  }
-  else
-  {
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_UNABLETOINIT;
-  }
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Sends a byte array of command and parameter data to the
-                PN532, starting with the command byte.  The frame's
-                preamble, checksums, postamble and frame identifier (0xD4)
-                will all be automatically added.
-
-    @param      abtCommand
-                The byte array containg the command and any
-                optional parameters
-    @param      szLen
-                The number of bytes in abtCommand
-*/
-/**************************************************************************/
-pn532_error_t pn532Write(byte_t * abtCommand, size_t szLen)
-{
-  if (!pcb.initialised) pn532Init();
-
-  // Try to wake the device up if it's in sleep mode
-  if (pcb.state == PN532_STATE_SLEEP)
-  {
-    pn532_error_t wakeupError = pn532_bus_Wakeup();
-    if (wakeupError)
-      return wakeupError;
-  }
-
-  // Send the command if the device is in an appropriate state
-  if (pcb.state == PN532_STATE_READY)
-  {
-    return pn532_bus_SendCommand(abtCommand, szLen);
-  }
-  else
-  {
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Init Failed%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_UNABLETOINIT;
-  }
-}
diff --git a/drivers/sensors/pn532/pn532.h b/drivers/sensors/pn532/pn532.h
deleted file mode 100644 (file)
index 4ddf19a..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_H__
-#define __PN532_H__
-
-#include "projectconfig.h"
-
-// Comment out this line to disable debug output
-// #define PN532_DEBUGMODE
-#define PN532_DEBUG(fmt, args...)             printf(fmt, ##args) 
-
-/* Error messages generated by the stack */
-/* Not to be confused with app level errors from the PN532 */
-/* These are the errors that are returned by the PN532 driver */
-typedef enum pn532_error_e
-{
-  PN532_ERROR_NONE                    = 0x00,
-  PN532_ERROR_UNABLETOINIT            = 0x01,   // Unable to initialise or wakeup the device
-  PN532_ERROR_APPLEVELERROR           = 0x02,   // Application level error detected
-  PN532_ERROR_BUSY                    = 0x03,   // Busy executing a previous command
-  PN532_ERROR_NOACK                   = 0x04,   // No ack message received
-  PN532_ERROR_INVALIDACK              = 0x05,   // Ack != 00 00 FF 00 FF 00
-  PN532_ERROR_PREAMBLEMISMATCH        = 0x06,   // Frame preamble + start code mismatch
-  PN532_ERROR_EXTENDEDFRAME           = 0x07,   // Extended frames currently unsupported
-  PN532_ERROR_LENCHECKSUMMISMATCH     = 0x08,
-  PN532_ERROR_RESPONSEBUFFEREMPTY     = 0x09,   // No response data received
-  PN532_ERROR_READYSTATUSTIMEOUT      = 0x0A,   // Timeout waiting for 'ready' status (SPI/I2C only)
-  PN532_ERROR_TIMEOUTWAITINGFORCARD   = 0x0B,   // No card detected in field with the specified timeout
-  PN532_ERROR_BLOCKREADFAILED         = 0x0C,   // Unexpected response to block read request
-  PN532_ERROR_WRONGCARDTYPE           = 0x0D,   // Card is not the expected format (based on SENS_RES/ATQA value)
-  PN532_ERROR_ADDRESSOUTOFRANGE       = 0x0E,   // Specified block and page is out of range
-  PN532_ERROR_I2C_NACK                = 0x0F    // I2C Bus - No ACK was received for master to slave data transfer
-} pn532_error_t;
-
-typedef enum pn532_modulation_e
-{
-  PN532_MODULATION_ISO14443A_106KBPS  = 0x00,
-  PN532_MODULATION_FELICA_212KBPS     = 0x01,
-  PN532_MODULATION_FELICA_424KBPS     = 0x02,
-  PN532_MODULATION_ISO14443B_106KBPS  = 0x03,
-  PN532_MODULATION_JEWEL_106KBPS      = 0x04
-} pn532_modulation_t;
-
-/* HW Commands for the PN532.  */
-/* See UM0701-02 - PN532 User Manual */
-enum
-{
-  PN532_COMMAND_DIAGNOSE              = 0x00,
-  PN532_COMMAND_GETFIRMWAREVERSION    = 0x02,
-  PN532_COMMAND_GETGENERALSTATUS      = 0x04,
-  PN532_COMMAND_READREGISTER          = 0x06,
-  PN532_COMMAND_WRITEREGISTER         = 0x08,
-  PN532_COMMAND_READGPIO              = 0x0C,
-  PN532_COMMAND_WRITEGPIO             = 0x0E,
-  PN532_COMMAND_SETSERIALBAUDRATE     = 0x10,
-  PN532_COMMAND_SETPARAMETERS         = 0x12,
-  PN532_COMMAND_SAMCONFIGURATION      = 0x14,
-  PN532_COMMAND_POWERDOWN             = 0x16,
-  PN532_COMMAND_RFCONFIGURATION       = 0x32,
-  PN532_COMMAND_RFREGULATIONTEST      = 0x58,
-  PN532_COMMAND_INJUMPFORDEP          = 0x56,
-  PN532_COMMAND_INJUMPFORPSL          = 0x46,
-  PN532_COMMAND_INLISTPASSIVETARGET   = 0x4A,
-  PN532_COMMAND_INATR                 = 0x50,
-  PN532_COMMAND_INPSL                 = 0x4E,
-  PN532_COMMAND_INDATAEXCHANGE        = 0x40,
-  PN532_COMMAND_INCOMMUNICATETHRU     = 0x42,
-  PN532_COMMAND_INDESELECT            = 0x44,
-  PN532_COMMAND_INRELEASE             = 0x52,
-  PN532_COMMAND_INSELECT              = 0x54,
-  PN532_COMMAND_INAUTOPOLL            = 0x60,
-  PN532_COMMAND_TGINITASTARGET        = 0x8C,
-  PN532_COMMAND_TGSETGENERALBYTES     = 0x92,
-  PN532_COMMAND_TGGETDATA             = 0x86,
-  PN532_COMMAND_TGSETDATA             = 0x8E,
-  PN532_COMMAND_TGSETMETADATA         = 0x94,
-  PN532_COMMAND_TGGETINITIATORCOMMAND = 0x88,
-  PN532_COMMAND_TGRESPONSETOINITIATOR = 0x90,
-  PN532_COMMAND_TGGETTARGETSTATUS     = 0x8A
-};
-
-/* Application level errors generated by the PN532 chip */
-/* See UM0701-02 - PN532 User Manual */
-enum 
-{
-  PN532_APPERROR_NONE                 = 0x00,
-  PN532_APPERROR_TIMEOUT              = 0x01,
-  PN532_APPERROR_CRCERROR             = 0x02,
-  PN532_APPERROR_PARITYERROR          = 0x04,
-  PN532_APPERROR_FRAMINGERROR         = 0x05,
-  PN532_APPERROR_BITCOLLISION         = 0x06,
-  PN532_APPERROR_INSUFFICIENTBUFFER   = 0x07,
-  PN532_APPERROR_RFBUFFEROVERFLOW     = 0x09,
-  PN532_APPERROR_RFFIELDTIMEOUT       = 0x0A,
-  PN532_APPERROR_RFPROTOCOLERROR      = 0x0B,
-  PN532_APPERROR_TEMPERROR            = 0x0D,
-  PN532_APPERROR_INTERNBUFFEROVERFLOW = 0x0E,
-  PN532_APPERROR_INVALIDPARAMETER     = 0x10,
-  PN532_APPERROR_DEP_UNSUPPORTEDCMD   = 0x12,
-  PN532_APPERROR_DEP_INVALIDOFORMAT   = 0x13,
-  PN532_APPERROR_AUTHENTERR           = 0x14,
-  PN532_APPERROR_UIDCCHECKERROR       = 0x23,
-  PN532_APPERROR_DEP_INVALIDDEVSTATE  = 0x25,
-  PN532_APPERROR_OPERATIONNOTALLOWED  = 0x26,
-  PN532_APPERROR_CMDNOTACCEPTABLE     = 0x27,
-  PN532_APPERROR_TARGETRELEASED       = 0x29,
-  PN532_APPERROR_IDMISMATCH           = 0x2A,
-  PN532_APPERROR_CARDDISAPPEARED      = 0x2B,
-  PN532_APPERROR_NFCID3MISMATCH       = 0x2C,
-  PN532_APPERROR_OVERCURRENTEVENT     = 0x2D,
-  PN532_APPERROR_NADMISSINGINDEP      = 0x2E
-};
-
-/* Possible states for the PN532 SW Stack */
-typedef enum pn532_state_e
-{
-  PN532_STATE_SLEEP,
-  PN532_STATE_READY,
-  PN532_STATE_BUSY
-}
-pn532_state_t;
-
-/* PN532 Protocol control block */
-typedef struct
-{
-  BOOL                initialised;
-  pn532_state_t       state;
-  pn532_modulation_t  modulation;
-  uint32_t            lastCommand;
-  uint32_t            appError;
-} pn532_pcb_t;
-
-void          pn532PrintHex(const byte_t * pbtData, const size_t szBytes);
-void          pn532PrintHexChar(const byte_t * pbtData, const size_t szBytes);
-pn532_pcb_t * pn532GetPCB();
-void          pn532Init();
-pn532_error_t pn532Read(byte_t *pbtResponse, size_t * pszLen);
-pn532_error_t pn532Write(byte_t *abtCommand, size_t szLen);
-
-#endif
diff --git a/drivers/sensors/pn532/pn532_bus.h b/drivers/sensors/pn532/pn532_bus.h
deleted file mode 100644 (file)
index 9a509b9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_bus.h
-*/
-/**************************************************************************/
-
-#ifndef __PN532_BUS_H__
-#define __PN532_BUS_H__
-
-#include "projectconfig.h"
-#include "pn532.h"
-
-// #define PN532_BUS_UART
-#define PN532_BUS_I2C
-
-#define PN532_RSTPD_PORT                      (3)
-#define PN532_RSTPD_PIN                       (1)
-#define PN532_I2C_IRQPORT                     (3)
-#define PN532_I2C_IRQPIN                      (2)
-
-#define PN532_NORMAL_FRAME__DATA_MAX_LEN      (254)
-#define PN532_NORMAL_FRAME__OVERHEAD          (8)
-#define PN532_EXTENDED_FRAME__DATA_MAX_LEN    (264)
-#define PN532_EXTENDED_FRAME__OVERHEAD        (11)
-#define PN532_BUFFER_LEN                      (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD)
-
-#define PN532_UART_BAUDRATE                   (115200)
-
-#define PN532_I2C_ADDRESS                     (0x48)
-#define PN532_I2C_READBIT                     (0x01)
-#define PN532_I2C_READYTIMEOUT                (20)    // Max number of attempts to read Ready bit (see UM 5-Nov-2007 Section 6.2.4)
-
-// Generic interface for the different serial buses available on the PN532
-void          pn532_bus_HWInit(void);
-pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData);
-pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen);
-pn532_error_t pn532_bus_Wakeup(void);
-
-#endif
diff --git a/drivers/sensors/pn532/pn532_bus_i2c.c b/drivers/sensors/pn532/pn532_bus_i2c.c
deleted file mode 100644 (file)
index bbcff7c..0000000
+++ /dev/null
@@ -1,490 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file     pn532_bus_i2c.c
-    @author   K. Townsend (microBuilder.eu)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2012, microBuilder SARL
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/**************************************************************************/
-#include <string.h>
-
-#include "pn532.h"
-#include "pn532_bus.h"
-
-#ifdef PN532_BUS_I2C
-
-#include "core/systick/systick.h"
-#include "core/gpio/gpio.h"
-#include "core/i2c/i2c.h"
-
-extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
-extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
-extern volatile uint32_t  I2CReadLength, I2CWriteLength;
-
-/* ======================================================================
-   PRIVATE FUNCTIONS                                                      
-   ====================================================================== */
-
-/**************************************************************************/
-/*! 
-    @brief  Writes an 8 bit value over I2C
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_I2C_NACK
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_i2c_WriteData (const byte_t * pbtData, const size_t szData)
-{
-  uint32_t i2cState;
-
-  // Clear write buffers
-  uint32_t i;
-  for ( i = 0; i < I2C_BUFSIZE; i++ )
-  {
-    I2CMasterBuffer[i] = 0x00;
-  }
-
-  // Send the specified bytes
-  I2CWriteLength = szData+1;
-  I2CReadLength = 0;
-  I2CMasterBuffer[0] = PN532_I2C_ADDRESS;         // I2C device address
-  for ( i = 0; i < szData; i++ )
-  {
-    I2CMasterBuffer[i+1] = pbtData[i];
-  }
-  i2cState = i2cEngine();
-
-  // Check if we got an ACK
-  if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK))
-  {
-    // I2C slave didn't acknowledge the master transfer
-    // The PN532 probably isn't connected properly or the
-    // bus select pins are in the wrong state
-    return PN532_ERROR_I2C_NACK;
-  }
-
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief    Checks the 'IRQ' pin to know if the PN532 is ready to send
-              a response or not
-    
-    @note     The IRQ bit may stay high intentionally, and this isn't
-              always an error condition.  When PN532_COMMAND_INLISTPASSIVETARGET
-              is sent, for example, the PN532 will wait until a card
-              enters the magnetic field, and IRQ will remain high since
-              there is no response ready yet.  The IRQ pin will go low
-              as soon as a card enters the magentic field and the data
-              has been retrieved from it.
-
-    @returns  1 if a response is ready, 0 if the PN532 is still busy or a
-              timeout occurred
-*/
-/**************************************************************************/
-uint8_t pn532_bus_i2c_WaitForReady(void) 
-{
-  uint8_t busy = 1;
-  // uint8_t busyTimeout = 0;
-
-  while (busy)
-  {
-    // For now, we wait forever until a command is ready
-    // ToDo: Add user-specified timeout
-    busy = gpioGetValue(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN);
-    systickDelay(1);
-    // busyTimeout++;
-    // if (busyTimeout == PN532_I2C_READYTIMEOUT)
-    // {
-    //   return false;
-    // }
-  }
-
-  return true;
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Builds a standard PN532 frame using the supplied data
-
-    @param  pbtFrame  Pointer to the field that will hold the frame data
-    @param  pszFrame  Pointer to the field that will hold the frame length
-    @param  pbtData   Pointer to the data to insert in a frame
-    @param  swData    Length of the data to insert in bytes
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_EXTENDEDFRAME
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_i2c_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
-{
-  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN) 
-  {
-    // Extended frames currently unsupported
-    return PN532_ERROR_EXTENDEDFRAME;
-  }
-
-  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
-  pbtFrame[3] = szData + 1;
-  // LCS - Packet length checksum
-  pbtFrame[4] = 256 - (szData + 1);
-  // TFI
-  pbtFrame[5] = 0xD4;
-  // DATA - Copy the PN53X command into the packet buffer
-  memcpy (pbtFrame + 6, pbtData, szData);
-
-  // DCS - Calculate data payload checksum
-  byte_t btDCS = (256 - 0xD4);
-  size_t szPos;
-  for (szPos = 0; szPos < szData; szPos++) 
-  {
-    btDCS -= pbtData[szPos];
-  }
-  pbtFrame[6 + szData] = btDCS;
-
-  // 0x00 - End of stream marker
-  pbtFrame[szData + 7] = 0x00;
-
-  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
-
-  return PN532_ERROR_NONE;
-}
-
-/* ======================================================================
-   PUBLIC FUNCTIONS                                                      
-   ====================================================================== */
-
-/**************************************************************************/
-/*! 
-    @brief  Initialises I2C and configures the PN532 HW
-*/
-/**************************************************************************/
-void pn532_bus_HWInit(void)
-{
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Initialising I2C %s", CFG_PRINTF_NEWLINE);
-  #endif
-  i2cInit(I2CMASTER);
-
-  // Set IRQ pin to input
-  gpioSetDir(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN, gpioDirection_Input);
-
-  // Set reset pin as output and reset device
-  gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Resetting the PN532...\r\n");
-  #endif
-  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
-  systickDelay(400);
-  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
-
-  // Wait for the PN532 to finish booting
-  systickDelay(100);
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Sends the specified command to the PN532, automatically
-            creating an appropriate frame for it
-
-    @param  pdbData   Pointer to the byte data to send
-    @param  szData    Length in bytes of the data to send
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_EXTENDEDFRAME       // Extended frames not supported
-            - PN532_ERROR_BUSY                // Already busy with a command
-            - PN532_ERROR_I2C_NACK            // No ACK on I2C
-            - PN532_ERROR_READYSTATUSTIMEOUT  // Timeout waiting for ready bit
-            - PN532_ERROR_INVALIDACK          // No ACK frame received
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
-{
-  pn532_error_t error = PN532_ERROR_NONE;
-  pn532_pcb_t *pn532 = pn532GetPCB();
-    
-  // Check if we're busy
-  if (pn532->state == PN532_STATE_BUSY)
-  {
-    return PN532_ERROR_BUSY;
-  }
-
-  // Flag the stack as busy
-  pn532->state = PN532_STATE_BUSY;
-
-  // --------------------------------------------------------------------
-  // Send the command frame
-  // --------------------------------------------------------------------
-  byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
-  size_t szFrame = 0;
-
-  // Build the frame
-  pn532_bus_i2c_BuildFrame (abtFrame, &szFrame, pbtData, szData);
-
-  // Keep track of the last command that was sent
-  pn532->lastCommand = pbtData[0];
-
-  // Output the frame data for debugging if requested
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Sending  (%02d): ", szFrame);
-  pn532PrintHex(abtFrame, szFrame);
-  #endif
-
-  // Send data to the PN532
-  error = pn532_bus_i2c_WriteData(abtFrame, szFrame);
-
-  if (error == PN532_ERROR_I2C_NACK)
-  {
-    // Most likely error is PN532_ERROR_I2C_NACK
-    // meaning no I2C ACK received from the PN532
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("No ACK received on I2C bus%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return error;
-  }
-
-  // --------------------------------------------------------------------
-  // Wait for the IRQ/Ready flag
-  // --------------------------------------------------------------------
-  if (!(pn532_bus_i2c_WaitForReady()))
-  {
-    pn532->state = PN532_STATE_READY;
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_READYSTATUSTIMEOUT;
-  }
-
-  // --------------------------------------------------------------------
-  // Read the ACK frame
-  // --------------------------------------------------------------------
-  uint32_t i;
-  // Clear buffer
-  for ( i = 0; i < I2C_BUFSIZE; i++ )
-  {
-    I2CMasterBuffer[i] = 0x00;
-  }
-  I2CWriteLength = 0;
-  I2CReadLength = 7;  // ACK + Ready bit = 7
-  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
-  i2cEngine();
-
-  // Make sure the received ACK matches the prototype
-  const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
-  byte_t abtRxBuf[6];
-  // memcpy(abtRxBuf, I2CSlaveBuffer+1, 6);
-  for ( i = 0; i < 6; i++ )
-  {
-    abtRxBuf[i] = I2CSlaveBuffer[i+1];
-  }
-  if (0 != (memcmp (abtRxBuf, abtAck, 6))) 
-  {
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("Invalid ACK: ");
-    pn532PrintHex(abtRxBuf, 6);
-    PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_INVALIDACK;
-  }
-
-  // --------------------------------------------------------------------
-  // Wait for the post-ACK IRQ/Ready flag
-  // --------------------------------------------------------------------
-  if (!(pn532_bus_i2c_WaitForReady()))
-  {
-    pn532->state = PN532_STATE_READY;
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
-    #endif
-    return PN532_ERROR_READYSTATUSTIMEOUT;
-  }
-
-  pn532->state = PN532_STATE_READY;
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Reads a response from the PN532
-
-    @note   Possible error message are:
-
-            - PN532_ERROR_BUSY
-            - PN532_ERROR_RESPONSEBUFFEREMPTY
-            - PN532_ERROR_PREAMBLEMISMATCH
-            - PN532_ERROR_APPLEVELERROR
-            - PN532_ERROR_EXTENDEDFRAME
-            - PN532_ERROR_LENCHECKSUMMISMATCH
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
-{
-  pn532_pcb_t *pn532 = pn532GetPCB();
-
-  // Check if we're busy
-  if (pn532->state == PN532_STATE_BUSY)
-  {
-    return PN532_ERROR_BUSY;
-  }
-
-  // Flag the stack as busy
-  pn532->state = PN532_STATE_BUSY;
-
-  // Reset the app error flag
-  pn532->appError = PN532_APPERROR_NONE;
-
-  uint32_t i;
-  for ( i = 0; i < I2C_BUFSIZE; i++ )
-  {
-    I2CMasterBuffer[i] = 0x00;
-  }
-  I2CWriteLength = 0;
-  I2CReadLength = I2C_BUFSIZE;
-  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
-  i2cEngine();
-
-  // Display the raw response data for debugging if requested
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Received (%02d): ", I2C_BUFSIZE-1);
-  pn532PrintHex(pbtResponse, I2C_BUFSIZE-1);
-  #endif
-
-  // Use the full I2C buffer size for now (until we're sure we have a good frame)
-  *pszRxLen = I2C_BUFSIZE - 1;
-
-  // Fill the response buffer from I2C (skipping the leading 'ready' bit when using I2C)
-  // memcpy(pbtResponse, I2CSlaveBuffer+1, I2C_BUFSIZE-1);
-  for ( i = 0; i < I2C_BUFSIZE-1; i++ )
-  {
-    pbtResponse[i] = I2CSlaveBuffer[i+1];
-  }
-
-  // Check the frame type
-  if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) 
-  {
-    // Error frame
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
-    #endif
-    // Set application error message ID
-    pn532->appError = pbtResponse[5];
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_APPLEVELERROR;
-  } 
-  else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) 
-  {
-    // Extended frame
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_EXTENDEDFRAME;
-  } 
-  else 
-  {
-    // Normal frame
-    if (256 != (pbtResponse[3] + pbtResponse[4])) 
-    {
-      // TODO: Retry
-      #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
-      #endif
-      pn532->state = PN532_STATE_READY;
-      return PN532_ERROR_LENCHECKSUMMISMATCH;
-    }
-  }
-
-  // Figure out how large the response really is
-  // Response Frame Len = pbtResponse[3] + 7 (00 00 FF LEN LCS TFI [DATA] DCS)
-  *pszRxLen = pbtResponse[3] + 7;
-
-  pn532->state = PN532_STATE_READY;
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Sends the wakeup sequence to the PN532.
-
-    @note   Possible error message are:
-
-            - PN532_ERROR_BUSY
-            - PN532_ERROR_I2C_NACK            // No I2C ACK
-            - PN532_ERROR_READYSTATUSTIMEOUT  // Timed out waiting for ready bit
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_Wakeup(void)
-{
-  pn532_error_t error = PN532_ERROR_NONE;
-  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
-  uint32_t i;
-
-  pn532_pcb_t *pn532 = pn532GetPCB();
-
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
-  #endif
-  error = pn532_bus_i2c_WriteData(abtWakeUp,sizeof(abtWakeUp));
-  systickDelay(100);
-
-  // Wait for the IRQ/Ready flag to indicate a response is ready
-  if (!(pn532_bus_i2c_WaitForReady()))
-  {
-    error = PN532_ERROR_READYSTATUSTIMEOUT;
-  }
-
-  // Read and discard the ACK frame
-  for ( i = 0; i < I2C_BUFSIZE; i++ )
-  {
-    I2CMasterBuffer[i] = 0x00;
-  }
-  I2CWriteLength = 0;
-  I2CReadLength = 7;  // ACK + Ready bit = 7
-  I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
-  i2cEngine();
-  systickDelay(1);
-
-  // Wait for the IRQ/Ready flag to indicate a response is ready
-  if (!(pn532_bus_i2c_WaitForReady()))
-  {
-    error = PN532_ERROR_READYSTATUSTIMEOUT;
-  }
-
-  pn532->state = PN532_STATE_READY;
-  return error;
-}
-
-#endif  // #ifdef PN532_BUS_I2C
\ No newline at end of file
diff --git a/drivers/sensors/pn532/pn532_bus_uart.c b/drivers/sensors/pn532/pn532_bus_uart.c
deleted file mode 100644 (file)
index 981df74..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/**************************************************************************/
-/*! 
-    @file   pn532_bus_uart.c
-*/
-/**************************************************************************/
-#include <string.h>
-
-#include "pn532.h"
-#include "pn532_bus.h"
-
-#ifdef PN532_BUS_UART
-
-#include "core/systick/systick.h"
-#include "core/gpio/gpio.h"
-#include "core/uart/uart.h"
-
-/**************************************************************************/
-/*! 
-    @brief  Builds a standard PN532 frame using the supplied data
-
-    @param  pbtFrame  Pointer to the field that will hold the frame data
-    @param  pszFrame  Pointer to the field that will hold the frame length
-    @param  pbtData   Pointer to the data to insert in a frame
-    @param  swData    Length of the data to insert in bytes
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_EXTENDEDFRAME
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
-{
-  if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN) 
-  {
-    // Extended frames currently unsupported
-    return PN532_ERROR_EXTENDEDFRAME;
-  }
-
-  // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
-  pbtFrame[3] = szData + 1;
-  // LCS - Packet length checksum
-  pbtFrame[4] = 256 - (szData + 1);
-  // TFI
-  pbtFrame[5] = 0xD4;
-  // DATA - Copy the PN53X command into the packet buffer
-  memcpy (pbtFrame + 6, pbtData, szData);
-
-  // DCS - Calculate data payload checksum
-  byte_t btDCS = (256 - 0xD4);
-  size_t szPos;
-  for (szPos = 0; szPos < szData; szPos++) 
-  {
-    btDCS -= pbtData[szPos];
-  }
-  pbtFrame[6 + szData] = btDCS;
-
-  // 0x00 - End of stream marker
-  pbtFrame[szData + 7] = 0x00;
-
-  (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
-
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Initialises UART and configures the PN532
-*/
-/**************************************************************************/
-void pn532_bus_HWInit(void)
-{
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Initialising UART (%d)%s", PN532_UART_BAUDRATE, CFG_PRINTF_NEWLINE);
-  #endif
-  uartInit(PN532_UART_BAUDRATE);
-
-  // Set reset pin as output and reset device
-  gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Resetting the PN532...\r\n");
-  #endif
-  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
-  systickDelay(400);
-  gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
-
-  // Wait for the PN532 to finish booting
-  systickDelay(100);
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Sends the specified command to the PN532, automatically
-            creating an appropriate frame for it
-
-    @param  pdbData   Pointer to the byte data to send
-    @param  szData    Length in bytes of the data to send
-
-    @note   Possible error messages are:
-
-            - PN532_ERROR_BUSY
-            - PN532_ERROR_NOACK
-            - PN532_ERROR_INVALIDACK
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
-{
-  pn532_pcb_t *pn532 = pn532GetPCB();
-    
-  // Check if we're busy
-  if (pn532->state == PN532_STATE_BUSY)
-  {
-    return PN532_ERROR_BUSY;
-  }
-
-  // Flag the stack as busy
-  pn532->state = PN532_STATE_BUSY;
-
-  // Every packet must start with "00 00 ff"
-  byte_t  abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
-  size_t szFrame = 0;
-
-  // Build the frame
-  pn532_bus_BuildFrame (abtFrame, &szFrame, pbtData, szData);
-
-  // Keep track of the last command that was sent
-  pn532->lastCommand = pbtData[0];
-
-  // Output the frame data for debugging if requested
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Sending  (%02d): ", szFrame);
-  pn532PrintHex(abtFrame, szFrame);
-  #endif
-
-  // Send data to the PN532
-  uartSend (abtFrame, szFrame);
-
-  // Wait for ACK
-  byte_t abtRxBuf[6];
-  uart_pcb_t *uart = uartGetPCB();
-  systickDelay(10);   // FIXME: How long should we wait for ACK?
-  if (uart->rxfifo.len < 6) 
-  {
-    // Unable to read ACK
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("Unable to read ACK%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_NOACK;
-  }
-
-  // Read ACK ... this will also remove it from the buffer
-  const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
-  abtRxBuf[0] = uartRxBufferRead();
-  abtRxBuf[1] = uartRxBufferRead();
-  abtRxBuf[2] = uartRxBufferRead();
-  abtRxBuf[3] = uartRxBufferRead();
-  abtRxBuf[4] = uartRxBufferRead();
-  abtRxBuf[5] = uartRxBufferRead();
-
-  // Make sure the received ACK matches the prototype
-  if (0 != (memcmp (abtRxBuf, abtAck, 6))) 
-  {
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG ("Invalid ACK: ");
-    pn532PrintHex(abtRxBuf, 6);
-    PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_INVALIDACK;
-  }
-
-  pn532->state = PN532_STATE_READY;
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief  Reads a response from the PN532
-
-    @note   Possible error message are:
-
-            - PN532_ERROR_BUSY
-            - PN532_ERROR_RESPONSEBUFFEREMPTY
-            - PN532_ERROR_PREAMBLEMISMATCH
-            - PN532_ERROR_APPLEVELERROR
-            - PN532_ERROR_EXTENDEDFRAME
-            - PN532_ERROR_LENCHECKSUMMISMATCH
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
-{
-  pn532_pcb_t *pn532 = pn532GetPCB();
-
-  // Check if we're busy
-  if (pn532->state == PN532_STATE_BUSY)
-  {
-    return PN532_ERROR_BUSY;
-  }
-
-  // Flag the stack as busy
-  pn532->state = PN532_STATE_BUSY;
-
-  // Reset the app error flag
-  pn532->appError = PN532_APPERROR_NONE;
-
-  // Read response from uart
-  if (!uartRxBufferReadArray(pbtResponse, pszRxLen)) 
-  {
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_RESPONSEBUFFEREMPTY;
-  }
-
-  // Display the raw response data for debugging if requested
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Received (%02d): ", *pszRxLen);
-  pn532PrintHex(pbtResponse, *pszRxLen);
-  #endif
-  
-  // Check preamble
-  const byte_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
-  if (0 != (memcmp (pbtResponse, pn53x_preamble, 3))) 
-  {
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Frame preamble + start code mismatch%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_PREAMBLEMISMATCH;
-  }
-
-  // Check the frame type
-  if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4])) 
-  {
-    // Error frame
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
-    #endif
-    // Set application error message ID
-    pn532->appError = pbtResponse[5];
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_APPLEVELERROR;
-  } 
-  else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4])) 
-  {
-    // Extended frame
-    #ifdef PN532_DEBUGMODE
-    PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
-    #endif
-    pn532->state = PN532_STATE_READY;
-    return PN532_ERROR_EXTENDEDFRAME;
-  } 
-  else 
-  {
-    // Normal frame
-    if (256 != (pbtResponse[3] + pbtResponse[4])) 
-    {
-      // TODO: Retry
-      #ifdef PN532_DEBUGMODE
-      PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
-      #endif
-      pn532->state = PN532_STATE_READY;
-      return PN532_ERROR_LENCHECKSUMMISMATCH;
-    }
-    // size_t szPayloadLen = abtRx[3] - 2;
-  }
-
-  pn532->state = PN532_STATE_READY;
-  return PN532_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*! 
-    @brief      Sends the wakeup sequence to the PN532.
-*/
-/**************************************************************************/
-pn532_error_t pn532_bus_Wakeup(void)
-{
-  size_t szLen;
-  byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
-
-  pn532_pcb_t *pn532 = pn532GetPCB();
-
-  #ifdef PN532_DEBUGMODE
-  PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
-  #endif
-  uartSend(abtWakeUp,sizeof(abtWakeUp));
-  systickDelay(100);
-
-  byte_t response[32];
-  pn532_bus_ReadResponse(response, &szLen);
-
-  // Todo: Check for error ... currently throws a checksum error
-  // that isn't really an error
-
-  pn532->state = PN532_STATE_READY;
-  return PN532_ERROR_NONE;
-}
-
-#endif  // #ifdef PN532_BUS_UART
\ No newline at end of file
This page took 0.161582 seconds and 4 git commands to generate.