/*************************************************************** * * OpenBeacon.org - midlevel access functions for * issuing raw commands to the nRF24L01 2.4Ghz frontend * * Copyright 2007 Milosch Meriac * * 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 #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); }