Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
deltaflight
deltaflight
Commits
72050604
Commit
72050604
authored
Jun 14, 2016
by
Martin Budden
Committed by
GitHub
Jun 14, 2016
Browse files
Merge pull request #283 from martinbudden/inav_nrf24
Support for Crazepony MINI flight controller and NRF24L01 transceiver
parents
c2dcfea3
7af74cbf
Changes
45
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
72050604
...
...
@@ -376,8 +376,11 @@ COMMON_SRC = \
drivers/buf_writer.c
\
drivers/bus_i2c_soft.c
\
drivers/bus_spi.c
\
drivers/bus_spi_soft.c
\
drivers/gps_i2cnav.c
\
drivers/gyro_sync.c
\
drivers/rx_nrf24l01.c
\
drivers/rx_xn297.c
\
drivers/pwm_mapping.c
\
drivers/pwm_output.c
\
drivers/pwm_rx.c
\
...
...
@@ -403,6 +406,12 @@ COMMON_SRC = \
io/statusindicator.c
\
rx/ibus.c
\
rx/msp.c
\
rx/nrf24.c
\
rx/nrf24_cx10.c
\
rx/nrf24_syma.c
\
rx/nrf24_v202.c
\
rx/nrf24_h8_3d.c
\
rx/nrf24_ref.c
\
rx/pwm.c
\
rx/rx.c
\
rx/sbus.c
\
...
...
src/main/common/maths.c
View file @
72050604
...
...
@@ -439,3 +439,17 @@ void sensorCalibrationSolveForScale(sensorCalibrationState_t * state, float resu
result
[
i
]
=
sqrtf
(
beta
[
i
]);
}
}
uint16_t
crc16_ccitt
(
uint16_t
crc
,
unsigned
char
a
)
{
crc
^=
a
<<
8
;
for
(
int
ii
=
0
;
ii
<
8
;
++
ii
)
{
if
(
crc
&
0x8000
)
{
crc
=
(
crc
<<
1
)
^
0x1021
;
}
else
{
crc
=
crc
<<
1
;
}
}
return
crc
;
}
src/main/common/maths.h
View file @
72050604
...
...
@@ -168,3 +168,4 @@ float acos_approx(float x);
#endif
void
arraySubInt32
(
int32_t
*
dest
,
int32_t
*
array1
,
int32_t
*
array2
,
int
count
);
uint16_t
crc16_ccitt
(
uint16_t
crc
,
unsigned
char
a
);
src/main/config/config.c
View file @
72050604
...
...
@@ -35,6 +35,7 @@
#include "drivers/gpio.h"
#include "drivers/timer.h"
#include "drivers/pwm_rx.h"
#include "drivers/rx_nrf24l01.h"
#include "drivers/serial.h"
#include "sensors/sensors.h"
...
...
@@ -55,6 +56,7 @@
#include "io/gps.h"
#include "rx/rx.h"
#include "rx/nrf24.h"
#include "blackbox/blackbox_io.h"
...
...
@@ -81,6 +83,13 @@
void
useRcControlsConfig
(
modeActivationCondition_t
*
modeActivationConditions
,
escAndServoConfig_t
*
escAndServoConfigToUse
,
pidProfile_t
*
pidProfileToUse
);
#ifndef DEFAULT_RX_FEATURE
#define DEFAULT_RX_FEATURE FEATURE_RX_PARALLEL_PWM
#endif
#ifndef NRF24_DEFAULT_PROTOCOL
#define NRF24_DEFAULT_PROTOCOL 0
#endif
#if !defined(FLASH_SIZE)
#error "Flash size not defined for target. (specify in KB)"
#endif
...
...
@@ -465,6 +474,7 @@ static void resetConf(void)
resetTelemetryConfig
(
&
masterConfig
.
telemetryConfig
);
masterConfig
.
rxConfig
.
serialrx_provider
=
0
;
masterConfig
.
rxConfig
.
nrf24rx_protocol
=
NRF24_DEFAULT_PROTOCOL
;
masterConfig
.
rxConfig
.
spektrum_sat_bind
=
0
;
masterConfig
.
rxConfig
.
midrc
=
1500
;
masterConfig
.
rxConfig
.
mincheck
=
1100
;
...
...
@@ -792,33 +802,48 @@ void activateConfig(void)
#endif
}
void
validateAndFixConfig
(
void
)
static
void
validateAndFixConfig
(
void
)
{
if
(
!
(
featureConfigured
(
FEATURE_RX_PARALLEL_PWM
)
||
featureConfigured
(
FEATURE_RX_PPM
)
||
featureConfigured
(
FEATURE_RX_SERIAL
)
||
featureConfigured
(
FEATURE_RX_MSP
)))
{
featureSet
(
FEATURE_RX_PARALLEL_PWM
);
// Consider changing the default to PPM
}
if
(
!
(
featureConfigured
(
FEATURE_RX_PARALLEL_PWM
)
||
featureConfigured
(
FEATURE_RX_PPM
)
||
featureConfigured
(
FEATURE_RX_SERIAL
)
||
featureConfigured
(
FEATURE_RX_MSP
)
||
featureConfigured
(
FEATURE_RX_NRF24
)
))
{
featureSet
(
DEFAULT_RX_FEATURE
);
}
if
(
featureConfigured
(
FEATURE_RX_PPM
))
{
featureClear
(
FEATURE_RX_
PARALLEL_PWM
);
}
if
(
featureConfigured
(
FEATURE_RX_PPM
))
{
featureClear
(
FEATURE_RX_
SERIAL
|
FEATURE_RX_PARALLEL_PWM
|
FEATURE_RX_MSP
|
FEATURE_RX_NRF24
);
}
if
(
featureConfigured
(
FEATURE_RX_MSP
))
{
featureClear
(
FEATURE_RX_SERIAL
);
featureClear
(
FEATURE_RX_PARALLEL_PWM
);
featureClear
(
FEATURE_RX_PPM
);
}
if
(
featureConfigured
(
FEATURE_RX_MSP
))
{
featureClear
(
FEATURE_RX_SERIAL
|
FEATURE_RX_PARALLEL_PWM
|
FEATURE_RX_PPM
|
FEATURE_RX_NRF24
);
}
if
(
featureConfigured
(
FEATURE_RX_SERIAL
))
{
featureClear
(
FEATURE_RX_PARALLEL_PWM
);
featureClear
(
FEATURE_RX_PPM
);
}
if
(
featureConfigured
(
FEATURE_RX_SERIAL
))
{
featureClear
(
FEATURE_RX_PARALLEL_PWM
|
FEATURE_RX_MSP
|
FEATURE_RX_PPM
|
FEATURE_RX_NRF24
);
}
if
(
featureConfigured
(
FEATURE_RX_NRF24
))
{
featureClear
(
FEATURE_RX_SERIAL
|
FEATURE_RX_PARALLEL_PWM
|
FEATURE_RX_PPM
|
FEATURE_RX_MSP
);
}
#if defined(NAV)
// Ensure sane values of navConfig settings
validateNavConfig
(
&
masterConfig
.
navConfig
);
#endif
if
(
featureConfigured
(
FEATURE_SOFTSPI
))
{
featureClear
(
FEATURE_RX_PPM
|
FEATURE_RX_PARALLEL_PWM
|
FEATURE_SOFTSERIAL
|
FEATURE_VBAT
);
#if defined(STM32F10X)
featureClear
(
FEATURE_LED_STRIP
);
// rssi adc needs the same ports
featureClear
(
FEATURE_RSSI_ADC
);
// current meter needs the same ports
if
(
masterConfig
.
batteryConfig
.
currentMeterType
==
CURRENT_SENSOR_ADC
)
{
featureClear
(
FEATURE_CURRENT_METER
);
}
#endif
}
if
(
featureConfigured
(
FEATURE_RX_PARALLEL_PWM
))
{
featureClear
(
FEATURE_RX_SERIAL
|
FEATURE_RX_MSP
|
FEATURE_RX_PPM
|
FEATURE_RX_NRF24
);
#if defined(STM32F10X)
// rssi adc needs the same ports
featureClear
(
FEATURE_RSSI_ADC
);
...
...
src/main/config/config.h
View file @
72050604
...
...
@@ -43,7 +43,9 @@ typedef enum {
FEATURE_DISPLAY
=
1
<<
17
,
FEATURE_ONESHOT125
=
1
<<
18
,
FEATURE_BLACKBOX
=
1
<<
19
,
FEATURE_CHANNEL_FORWARDING
=
1
<<
20
FEATURE_CHANNEL_FORWARDING
=
1
<<
20
,
FEATURE_RX_NRF24
=
1
<<
21
,
FEATURE_SOFTSPI
=
1
<<
22
,
}
features_e
;
void
handleOneshotFeatureChangeOnRestart
(
void
);
...
...
src/main/drivers/bus_spi_soft.c
0 → 100644
View file @
72050604
/*
* This file is part of Cleanflight.
*
* Cleanflight 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, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdint.h>
#include <platform.h>
#include "build_config.h"
#ifdef USE_SOFTSPI
#include "gpio.h"
#include "bus_spi_soft.h"
void
softSpiInit
(
const
softSPIDevice_t
*
dev
)
{
GPIO_InitTypeDef
GPIO_InitStructure
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
// SCK as output
GPIO_InitStructure
.
GPIO_Pin
=
dev
->
sck_pin
;
GPIO_Init
(
dev
->
sck_gpio
,
&
GPIO_InitStructure
);
// MOSI as output
GPIO_InitStructure
.
GPIO_Pin
=
dev
->
mosi_pin
;
GPIO_Init
(
dev
->
mosi_gpio
,
&
GPIO_InitStructure
);
// MISO as input
GPIO_InitStructure
.
GPIO_Pin
=
dev
->
miso_pin
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_Init
(
dev
->
miso_gpio
,
&
GPIO_InitStructure
);
#ifdef SOFTSPI_NSS_PIN
// NSS as output
GPIO_InitStructure
.
GPIO_Pin
=
dev
->
nss_pin
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_Init
(
dev
->
nss_gpio
,
&
GPIO_InitStructure
);
#endif
}
uint8_t
softSpiTransferByte
(
const
softSPIDevice_t
*
dev
,
uint8_t
byte
)
{
for
(
int
ii
=
0
;
ii
<
8
;
++
ii
)
{
if
(
byte
&
0x80
)
{
GPIO_SetBits
(
dev
->
mosi_gpio
,
dev
->
mosi_pin
);
}
else
{
GPIO_ResetBits
(
dev
->
mosi_gpio
,
dev
->
mosi_pin
);
}
GPIO_SetBits
(
dev
->
sck_gpio
,
dev
->
sck_pin
);
byte
<<=
1
;
if
(
GPIO_ReadInputDataBit
(
dev
->
miso_gpio
,
dev
->
miso_pin
)
==
1
)
{
byte
|=
1
;
}
GPIO_ResetBits
(
dev
->
sck_gpio
,
dev
->
sck_pin
);
}
return
byte
;
}
#endif
src/main/drivers/bus_spi_soft.h
0 → 100644
View file @
72050604
/*
* This file is part of Cleanflight.
*
* Cleanflight 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, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
typedef
struct
softSPIDevice_s
{
GPIO_TypeDef
*
sck_gpio
;
uint16_t
sck_pin
;
GPIO_TypeDef
*
mosi_gpio
;
uint16_t
mosi_pin
;
GPIO_TypeDef
*
miso_gpio
;
uint16_t
miso_pin
;
#ifdef SOFTSPI_NSS_PIN
GPIO_TypeDef
*
nss_gpio
;
uint16_t
nss_pin
;
#endif
}
softSPIDevice_t
;
void
softSpiInit
(
const
softSPIDevice_t
*
dev
);
uint8_t
softSpiTransferByte
(
const
softSPIDevice_t
*
dev
,
uint8_t
data
);
src/main/drivers/pwm_mapping.c
View file @
72050604
...
...
@@ -84,21 +84,20 @@ pwmIOConfiguration_t *pwmGetOutputConfiguration(void){
pwmIOConfiguration_t
*
pwmInit
(
drv_pwm_config_t
*
init
)
{
int
i
=
0
;
const
uint16_t
*
setup
;
#ifndef SKIP_RX_PWM_PPM
int
channelIndex
=
0
;
#endif
memset
(
&
pwmIOConfiguration
,
0
,
sizeof
(
pwmIOConfiguration
));
// this is pretty hacky shit, but it will do for now. array of 4 config maps, [ multiPWM multiPPM airPWM airPPM ]
int
i
=
0
;
if
(
init
->
airplane
)
i
=
2
;
// switch to air hardware config
if
(
init
->
usePPM
||
init
->
useSerialRx
)
i
++
;
// next index is for PPM
setup
=
hardwareMaps
[
i
];
const
uint16_t
*
setup
=
hardwareMaps
[
i
];
for
(
i
=
0
;
i
<
USABLE_TIMER_CHANNEL_COUNT
&&
setup
[
i
]
!=
0xFFFF
;
i
++
)
{
uint8_t
timerIndex
=
setup
[
i
]
&
0x00FF
;
...
...
@@ -265,6 +264,7 @@ pwmIOConfiguration_t *pwmInit(drv_pwm_config_t *init)
#endif
if
(
type
==
MAP_TO_PPM_INPUT
)
{
#ifndef SKIP_RX_PWM_PPM
#ifdef CC3D_PPM1
if
(
init
->
useOneshot
||
isMotorBrushed
(
init
->
motorPwmRate
))
{
ppmAvoidPWMTimerClash
(
timerHardwarePtr
,
TIM4
);
...
...
@@ -278,11 +278,14 @@ pwmIOConfiguration_t *pwmInit(drv_pwm_config_t *init)
ppmInConfig
(
timerHardwarePtr
);
pwmIOConfiguration
.
ioConfigurations
[
pwmIOConfiguration
.
ioCount
].
flags
=
PWM_PF_PPM
;
pwmIOConfiguration
.
ppmInputCount
++
;
#endif
}
else
if
(
type
==
MAP_TO_PWM_INPUT
)
{
#ifndef SKIP_RX_PWM_PPM
pwmInConfig
(
timerHardwarePtr
,
channelIndex
);
pwmIOConfiguration
.
ioConfigurations
[
pwmIOConfiguration
.
ioCount
].
flags
=
PWM_PF_PWM
;
pwmIOConfiguration
.
pwmInputCount
++
;
channelIndex
++
;
#endif
}
else
if
(
type
==
MAP_TO_MOTOR_OUTPUT
)
{
#if defined(CC3D) && !defined(CC3D_PPM1)
...
...
src/main/drivers/pwm_rx.c
View file @
72050604
...
...
@@ -22,6 +22,9 @@
#include "platform.h"
#include "build_config.h"
#ifndef SKIP_RX_PWM_PPM
#include "debug.h"
#include "common/utils.h"
...
...
@@ -424,3 +427,4 @@ uint16_t pwmRead(uint8_t channel)
{
return
captures
[
channel
];
}
#endif
src/main/drivers/rx_nrf24l01.c
0 → 100644
View file @
72050604
/*
* This file is part of Cleanflight.
*
* Cleanflight 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, either version 3 of the License, or
* (at your option) any later version.
*
* Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
// This file is copied with modifications from project Deviation,
// see http://deviationtx.com
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <platform.h>
#ifdef USE_RX_NRF24
#include "system.h"
#include "gpio.h"
#include "rx_nrf24l01.h"
#ifdef UNIT_TEST
#define NRF24_CE_HI() {}
#define NRF24_CE_LO() {}
void
NRF24L01_SpiInit
(
void
)
{}
#else
#include "bus_spi.h"
#include "bus_spi_soft.h"
#define DISABLE_NRF24() {GPIO_SetBits(NRF24_CSN_GPIO, NRF24_CSN_PIN);}
#define ENABLE_NRF24() {GPIO_ResetBits(NRF24_CSN_GPIO, NRF24_CSN_PIN);}
#define NRF24_CE_HI() {GPIO_SetBits(NRF24_CE_GPIO, NRF24_CE_PIN);}
#define NRF24_CE_LO() {GPIO_ResetBits(NRF24_CE_GPIO, NRF24_CE_PIN);}
#ifdef USE_NRF24_SOFTSPI
static
const
softSPIDevice_t
softSPIDevice
=
{
.
sck_gpio
=
NRF24_SCK_GPIO
,
.
mosi_gpio
=
NRF24_MOSI_GPIO
,
.
miso_gpio
=
NRF24_MISO_GPIO
,
.
sck_pin
=
NRF24_SCK_PIN
,
.
mosi_pin
=
NRF24_MOSI_PIN
,
.
miso_pin
=
NRF24_MISO_PIN
,
#ifdef SOFTSPI_NSS_PIN
.
nss_pin
=
NRF24_CSN_PIN
,
.
nss_gpio
=
NRF24_CSN_GPIO
#endif
};
#endif
#ifdef USE_NRF24_SOFTSPI
static
bool
useSoftSPI
=
false
;
#endif
void
NRF24L01_SpiInit
(
nfr24l01_spi_type_e
spiType
)
{
static
bool
hardwareInitialised
=
false
;
if
(
hardwareInitialised
)
{
return
;
}
if
(
spiType
==
NFR24L01_SOFTSPI
)
{
#ifdef USE_NRF24_SOFTSPI
useSoftSPI
=
true
;
softSpiInit
(
&
softSPIDevice
);
#endif
}
// Note: Nordic Semiconductor uses 'CSN', STM uses 'NSS'
GPIO_InitTypeDef
GPIO_InitStructure
;
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
#if defined(STM32F10X)
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
#endif
#ifdef STM32F303xC
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_OUT
;
GPIO_InitStructure
.
GPIO_OType
=
GPIO_OType_PP
;
GPIO_InitStructure
.
GPIO_PuPd
=
GPIO_PuPd_NOPULL
;
#endif
#ifndef SOFTSPI_NSS_PIN
// CSN as output
RCC_AHBPeriphClockCmd
(
NRF24_CSN_GPIO_CLK_PERIPHERAL
,
ENABLE
);
GPIO_InitStructure
.
GPIO_Pin
=
NRF24_CSN_PIN
;
GPIO_Init
(
NRF24_CSN_GPIO
,
&
GPIO_InitStructure
);
#endif
// CE as OUTPUT
RCC_AHBPeriphClockCmd
(
NRF24_CE_GPIO_CLK_PERIPHERAL
,
ENABLE
);
GPIO_InitStructure
.
GPIO_Pin
=
NRF24_CE_PIN
;
GPIO_Init
(
NRF24_CE_GPIO
,
&
GPIO_InitStructure
);
DISABLE_NRF24
();
NRF24_CE_LO
();
#ifdef NRF24_SPI_INSTANCE
spiSetDivisor
(
NRF24_SPI_INSTANCE
,
SPI_9MHZ_CLOCK_DIVIDER
);
#endif
hardwareInitialised
=
true
;
}
uint8_t
nrf24TransferByte
(
uint8_t
data
)
{
#ifdef USE_NRF24_SOFTSPI
if
(
useSoftSPI
)
{
return
softSpiTransferByte
(
&
softSPIDevice
,
data
);
}
else
#endif
{
#ifdef NRF24_SPI_INSTANCE
return
spiTransferByte
(
NRF24_SPI_INSTANCE
,
data
);
#else
return
0
;
#endif
}
}
// Instruction Mnemonics
// nRF24L01: Table 16. Command set for the nRF24L01 SPI. Product Specification, p46
// nRF24L01+: Table 20. Command set for the nRF24L01+ SPI. Product Specification, p51
#define R_REGISTER 0x00
#define W_REGISTER 0x20
#define REGISTER_MASK 0x1F
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define W_ACK_PAYLOAD 0xA8
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
uint8_t
NRF24L01_WriteReg
(
uint8_t
reg
,
uint8_t
data
)
{
ENABLE_NRF24
();
nrf24TransferByte
(
W_REGISTER
|
(
REGISTER_MASK
&
reg
));
nrf24TransferByte
(
data
);
DISABLE_NRF24
();
return
true
;
}
uint8_t
NRF24L01_WriteRegisterMulti
(
uint8_t
reg
,
const
uint8_t
*
data
,
uint8_t
length
)
{
ENABLE_NRF24
();
const
uint8_t
ret
=
nrf24TransferByte
(
W_REGISTER
|
(
REGISTER_MASK
&
reg
));
for
(
uint8_t
i
=
0
;
i
<
length
;
i
++
)
{
nrf24TransferByte
(
data
[
i
]);
}
DISABLE_NRF24
();
return
ret
;
}
/*
* Transfer the payload to the nRF24L01 TX FIFO
* Packets in the TX FIFO are transmitted when the
* nRF24L01 next enters TX mode
*/
uint8_t
NRF24L01_WritePayload
(
const
uint8_t
*
data
,
uint8_t
length
)
{
ENABLE_NRF24
();
const
uint8_t
ret
=
nrf24TransferByte
(
W_TX_PAYLOAD
);
for
(
uint8_t
i
=
0
;
i
<
length
;
i
++
)
{
nrf24TransferByte
(
data
[
i
]);
}
DISABLE_NRF24
();
return
ret
;
}
uint8_t
NRF24L01_ReadReg
(
uint8_t
reg
)
{
ENABLE_NRF24
();
nrf24TransferByte
(
R_REGISTER
|
(
REGISTER_MASK
&
reg
));
const
uint8_t
ret
=
nrf24TransferByte
(
NOP
);
DISABLE_NRF24
();
return
ret
;
}
uint8_t
NRF24L01_ReadRegisterMulti
(
uint8_t
reg
,
uint8_t
*
data
,
uint8_t
length
)
{
ENABLE_NRF24
();
const
uint8_t
ret
=
nrf24TransferByte
(
R_REGISTER
|
(
REGISTER_MASK
&
reg
));
for
(
uint8_t
i
=
0
;
i
<
length
;
i
++
)
{
data
[
i
]
=
nrf24TransferByte
(
NOP
);
}
DISABLE_NRF24
();
return
ret
;
}
/*
* Read a packet from the nRF24L01 RX FIFO.
*/
uint8_t
NRF24L01_ReadPayload
(
uint8_t
*
data
,
uint8_t
length
)
{
ENABLE_NRF24
();
const
uint8_t
ret
=
nrf24TransferByte
(
R_RX_PAYLOAD
);
for
(
uint8_t
i
=
0
;
i
<
length
;
i
++
)
{
data
[
i
]
=
nrf24TransferByte
(
NOP
);
}
DISABLE_NRF24
();
return
ret
;
}
/*
* Empty the transmit FIFO buffer.
*/
void
NRF24L01_FlushTx
()
{
ENABLE_NRF24
();
nrf24TransferByte
(
FLUSH_TX
);
DISABLE_NRF24
();
}
/*
* Empty the receive FIFO buffer.
*/
void
NRF24L01_FlushRx
()
{
ENABLE_NRF24
();
nrf24TransferByte
(
FLUSH_RX
);
DISABLE_NRF24
();
}
#endif // UNIT_TEST
// standby configuration, used to simplify switching between RX, TX, and Standby modes
static
uint8_t
standbyConfig
;
void
NRF24L01_Initialize
(
uint8_t
baseConfig
)
{
standbyConfig
=
BV
(
NRF24L01_00_CONFIG_PWR_UP
)
|
baseConfig
;
NRF24_CE_LO
();
// nRF24L01+ needs 100 milliseconds settling time from PowerOnReset to PowerDown mode
static
const
uint32_t
settlingTimeUs
=
100000
;
const
uint32_t
currentTimeUs
=
micros
();
if
(
currentTimeUs
<
settlingTimeUs
)
{
delayMicroseconds
(
settlingTimeUs
-
currentTimeUs
);
}
// now in PowerDown mode
NRF24L01_WriteReg
(
NRF24L01_00_CONFIG
,
standbyConfig
);
// set PWR_UP to enter Standby mode
// nRF24L01+ needs 4500 microseconds from PowerDown mode to Standby mode, for crystal oscillator startup
delayMicroseconds
(
4500
);
// now in Standby mode
}
/*
* Enter standby mode
*/
void
NRF24L01_SetStandbyMode
(
void
)
{
// set CE low and clear the PRIM_RX bit to enter standby mode
NRF24_CE_LO
();
NRF24L01_WriteReg
(
NRF24L01_00_CONFIG
,
standbyConfig
);
}
/*
* Enter receive mode
*/
void
NRF24L01_SetRxMode
(
void
)
{
NRF24_CE_LO
();
// drop into standby mode
// set the PRIM_RX bit
NRF24L01_WriteReg
(
NRF24L01_00_CONFIG
,
standbyConfig
|
BV
(
NRF24L01_00_CONFIG_PRIM_RX
));
NRF24L01_ClearAllInterrupts
();
// finally set CE high to start enter RX mode
NRF24_CE_HI
();
// nRF24L01+ will now transition from Standby mode to RX mode after 130 microseconds settling time
}
/*
* Enter transmit mode. Anything in the transmit FIFO will be transmitted.
*/
void
NRF24L01_SetTxMode
(
void
)
{
// Ensure in standby mode, since can only enter TX mode from standby mode
NRF24L01_SetStandbyMode
();
NRF24L01_ClearAllInterrupts
();