239 lines
5.0 KiB
C
239 lines
5.0 KiB
C
|
/***************************************************************
|
||
|
*
|
||
|
* OpenBeacon.org - midlevel access functions for
|
||
|
* issuing raw commands to the nRF24L01 2.4Ghz frontend
|
||
|
*
|
||
|
* Copyright 2007 Milosch Meriac <meriac@openbeacon.de>
|
||
|
*
|
||
|
* provides generic register level access functions
|
||
|
* for accessing nRF24L01 registers at a generic level
|
||
|
*
|
||
|
***************************************************************
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; version 2.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License along
|
||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
|
||
|
*/
|
||
|
#include <openbeacon.h>
|
||
|
#include "pmu.h"
|
||
|
#include "nRF_API.h"
|
||
|
#include "nRF_HW.h"
|
||
|
#include "nRF_CMD.h"
|
||
|
#include "spi.h"
|
||
|
|
||
|
/* IO definitions */
|
||
|
#define RF_IRQ_CPU_PORT 1
|
||
|
#define RF_IRQ_CPU_PIN 9
|
||
|
#define CPU_CE_RF_PORT 0
|
||
|
#define CPU_CE_RF_PIN 11
|
||
|
#define CPU_SWITCH_RF_PORT 0
|
||
|
#define CPU_SWITCH_RF_PIN 2
|
||
|
|
||
|
#define SPI_MAX_XFER_LEN 33
|
||
|
#define NRFCMD_MACRO_READ 0x80
|
||
|
|
||
|
#define SPI_MAX_XFER_LEN 33
|
||
|
#define NRFCMD_MACRO_READ 0x80
|
||
|
static uint8_t spi_outbuf[SPI_MAX_XFER_LEN];
|
||
|
static uint8_t spi_inbuf[SPI_MAX_XFER_LEN];
|
||
|
|
||
|
void
|
||
|
nRFCMD_CE (uint8_t enable)
|
||
|
{
|
||
|
GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, enable ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_Power (uint8_t enable)
|
||
|
{
|
||
|
GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, enable ? 0 : 1);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_ReadWriteBuffer (const uint8_t * tx_data, uint8_t * rx_data,
|
||
|
uint32_t len)
|
||
|
{
|
||
|
spi_txrx (SPI_CS_NRF, tx_data, len, rx_data, len);
|
||
|
}
|
||
|
|
||
|
static uint8_t
|
||
|
nRFCMD_ReadWriteByte (uint8_t reg)
|
||
|
{
|
||
|
uint8_t res;
|
||
|
|
||
|
nRFCMD_ReadWriteBuffer (®, &res, 1);
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_CmdExec (uint8_t cmd)
|
||
|
{
|
||
|
uint8_t res;
|
||
|
|
||
|
res = nRFCMD_ReadWriteByte (cmd);
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_RegRead (uint8_t reg)
|
||
|
{
|
||
|
spi_outbuf[0] = reg;
|
||
|
spi_outbuf[1] = 0;
|
||
|
|
||
|
nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2);
|
||
|
|
||
|
return spi_inbuf[1];
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_RegWriteStatusRead (uint8_t reg, uint8_t value)
|
||
|
{
|
||
|
spi_outbuf[0] = reg;
|
||
|
spi_outbuf[1] = value;
|
||
|
|
||
|
nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, 2);
|
||
|
|
||
|
return spi_inbuf[0];
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_RegWriteBuf (uint8_t reg, const uint8_t * buf, uint8_t count)
|
||
|
{
|
||
|
spi_outbuf[0] = reg;
|
||
|
memcpy (spi_outbuf + 1, buf, count);
|
||
|
nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 1);
|
||
|
|
||
|
return spi_inbuf[0];
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_RegReadBuf (uint8_t reg, uint8_t * buf, uint8_t count)
|
||
|
{
|
||
|
spi_outbuf[0] = reg;
|
||
|
nRFCMD_ReadWriteBuffer (spi_outbuf, spi_inbuf, count + 2);
|
||
|
memcpy (buf, spi_inbuf + 1, count);
|
||
|
|
||
|
return spi_inbuf[0];
|
||
|
}
|
||
|
|
||
|
uint8_t
|
||
|
nRFCMD_GetRegSize (uint8_t reg)
|
||
|
{
|
||
|
uint8_t res;
|
||
|
|
||
|
if (reg > 0x17)
|
||
|
res = 0;
|
||
|
else
|
||
|
switch (reg)
|
||
|
{
|
||
|
case RX_ADDR_P0:
|
||
|
case RX_ADDR_P1:
|
||
|
case TX_ADDR:
|
||
|
res = NRF_MAX_MAC_SIZE;
|
||
|
break;
|
||
|
default:
|
||
|
res = 1;
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_ExecMacro (const uint8_t * macro)
|
||
|
{
|
||
|
unsigned char size;
|
||
|
|
||
|
while ((size = *macro++) != 0)
|
||
|
{
|
||
|
nRFCMD_ReadWriteBuffer (macro, NULL, size - 1);
|
||
|
macro += size;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_RegisterDump (void)
|
||
|
{
|
||
|
uint8_t t, size, reg, buf[32];
|
||
|
|
||
|
reg = 0;
|
||
|
debug_printf ("\nnRFCMD_RegisterDump:\n");
|
||
|
while (((size = nRFCMD_GetRegSize (reg)) > 0) && (reg < 0xFF))
|
||
|
{
|
||
|
nRFCMD_RegReadBuf (reg, buf, size);
|
||
|
|
||
|
debug_printf ("\treg[0x%02X]:", reg);
|
||
|
for (t = 0; t < size; t++)
|
||
|
debug_printf (" 0x%02X", buf[t]);
|
||
|
debug_printf ("\n");
|
||
|
|
||
|
reg++;
|
||
|
}
|
||
|
debug_printf ("\n");
|
||
|
}
|
||
|
|
||
|
void
|
||
|
WAKEUP_IRQHandlerPIO1_9 (void)
|
||
|
{
|
||
|
/* Clear pending IRQ */
|
||
|
LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9;
|
||
|
|
||
|
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||
|
__NOP ();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_Shutdown (void)
|
||
|
{
|
||
|
/* disable RX mode */
|
||
|
nRFCMD_CE (0);
|
||
|
|
||
|
/* wait 5ms */
|
||
|
pmu_sleep_ms (5);
|
||
|
|
||
|
/* switch to TX mode */
|
||
|
nRFAPI_SetRxMode (0);
|
||
|
|
||
|
/* powering down */
|
||
|
nRFAPI_PowerDown ();
|
||
|
|
||
|
/* set pins to lowest power */
|
||
|
GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 1);
|
||
|
GPIOSetValue (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0);
|
||
|
GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0);
|
||
|
GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nRFCMD_Init (void)
|
||
|
{
|
||
|
/* setup SPI chipselect pin */
|
||
|
spi_init_pin (SPI_CS_NRF);
|
||
|
|
||
|
/* setup IOs */
|
||
|
LPC_IOCON->PIO1_9 = 0;
|
||
|
GPIOSetDir (RF_IRQ_CPU_PORT, RF_IRQ_CPU_PIN, 0);
|
||
|
NVIC_EnableIRQ (WAKEUP_PIO1_9_IRQn);
|
||
|
LPC_SYSCON->STARTAPRP0 = (LPC_SYSCON->STARTAPRP0 & ~STARTxPRP0_PIO1_9);
|
||
|
LPC_SYSCON->STARTRSRP0CLR = STARTxPRP0_PIO1_9;
|
||
|
LPC_SYSCON->STARTERP0 |= STARTxPRP0_PIO1_9;
|
||
|
|
||
|
LPC_IOCON->JTAG_TDI_PIO0_11 = 0x81;
|
||
|
GPIOSetDir (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 1);
|
||
|
GPIOSetValue (CPU_CE_RF_PORT, CPU_CE_RF_PIN, 0);
|
||
|
|
||
|
LPC_IOCON->PIO0_2 = 0;
|
||
|
GPIOSetDir (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 1);
|
||
|
GPIOSetValue (CPU_SWITCH_RF_PORT, CPU_SWITCH_RF_PIN, 0);
|
||
|
}
|