nrf control, stub of sending data
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by MightyPork on 2018/04/03.
|
||||
//
|
||||
|
||||
#ifndef GEX_NRF_CRC32_H
|
||||
#define GEX_NRF_CRC32_H
|
||||
|
||||
uint32_t CRC32_Start(void);
|
||||
|
||||
uint32_t CRC32_Add(uint32_t cksum, uint8_t byte);
|
||||
|
||||
uint32_t CRC32_End(uint32_t cksum);
|
||||
|
||||
|
||||
#endif //GEX_NRF_CRC32_H
|
||||
+2
-1
@@ -6,7 +6,8 @@
|
||||
#define GEX_NRF_GEX_GATEWAY_H
|
||||
|
||||
#include "main.h"
|
||||
void gw_process(void);
|
||||
void gw_handle_usb_out(uint8_t *buffer);
|
||||
|
||||
void gw_setup_radio(void);
|
||||
|
||||
#endif //GEX_NRF_GEX_GATEWAY_H
|
||||
|
||||
+1
-2
@@ -21,8 +21,7 @@ typedef struct {
|
||||
volatile uint32_t nw;
|
||||
} MQueue;
|
||||
|
||||
extern MQueue usb_rxq;
|
||||
extern MQueue usb_txq;
|
||||
extern MQueue usb_inq;
|
||||
|
||||
void mq_init(MQueue *mq);
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
//
|
||||
// Created by MightyPork on 2018/04/02.
|
||||
//
|
||||
|
||||
#ifndef GEX_NRF_NRF_H
|
||||
#define GEX_NRF_NRF_H
|
||||
|
||||
/*
|
||||
* nordic.h
|
||||
*
|
||||
* Created:12/16/2013 3:36:04 PM
|
||||
* Author: Tom
|
||||
*
|
||||
* NRF24L01+ Library II
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NORDIC_H_
|
||||
#define NORDIC_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
// Initialize SPI and the Nordic
|
||||
|
||||
/**
|
||||
* Initialize the NRF module
|
||||
*
|
||||
* @param pSpeed
|
||||
*/
|
||||
void NRF_Init(uint8_t pSpeed);
|
||||
|
||||
#define NRF_SPEED_500k 0b00100110
|
||||
#define NRF_SPEED_2M 0b00001110
|
||||
#define NRF_SPEED_1M 0b00000110
|
||||
|
||||
/**
|
||||
* Set reception address
|
||||
* @param pipenum - pipe to set
|
||||
* @param AddrByte - byte 0
|
||||
*/
|
||||
void NRF_SetRxAddress(uint8_t pipenum, uint8_t AddrByte);
|
||||
|
||||
/**
|
||||
* Set communication channel
|
||||
*/
|
||||
void NRF_SetChannel(uint8_t Ch) ; // 0 through 83 only!
|
||||
|
||||
/**
|
||||
* Power down the transceiver
|
||||
*/
|
||||
void NRF_PowerDown(void);
|
||||
|
||||
/**
|
||||
* Selecr RX mode
|
||||
*/
|
||||
void NRF_ModeRX(void);
|
||||
|
||||
/**
|
||||
* Select TX mode
|
||||
*/
|
||||
void NRF_ModeTX(void);
|
||||
|
||||
/**
|
||||
* @return NRF is power down
|
||||
*/
|
||||
uint8_t NRF_IsModePowerDown(void);
|
||||
|
||||
/**
|
||||
* @return NRF in TX mode
|
||||
*/
|
||||
uint8_t NRF_IsModeTX(void);
|
||||
|
||||
/**
|
||||
* @return NRF in RX mode
|
||||
*/
|
||||
uint8_t NRF_IsModeRx(void);
|
||||
|
||||
/**
|
||||
* Add a pipe to the next free slot
|
||||
*
|
||||
* @param AddrByte - address byte of the peer
|
||||
* @param[out] PipeNum - pipe number is written here
|
||||
* @return success
|
||||
*/
|
||||
bool NRF_AddPipe(uint8_t AddrByte, uint8_t *PipeNum);
|
||||
|
||||
/**
|
||||
* Convert pipe number to address byte
|
||||
*
|
||||
* @param pipe_num - pipe number
|
||||
* @return address byte
|
||||
*/
|
||||
uint8_t NRF_PipeNum2Addr(uint8_t pipe_num);
|
||||
|
||||
/**
|
||||
* Convert address to a pipe number
|
||||
*
|
||||
* @param addr
|
||||
* @return
|
||||
*/
|
||||
uint8_t NRF_Addr2PipeNum(uint8_t addr);
|
||||
|
||||
/**
|
||||
* Reset as much as possible (incl. removing pipes)
|
||||
*/
|
||||
void NRF_Reset(void);
|
||||
|
||||
/**
|
||||
* Send a packet (takes care of mode switching etc)
|
||||
*
|
||||
* @param PipeNum - pipe number
|
||||
* @param Packet - packet bytes
|
||||
* @param Length - packet length
|
||||
* @return success (ACK'd)
|
||||
*/
|
||||
bool NRF_SendPacket(uint8_t PipeNum, const uint8_t *Packet, uint8_t Length);
|
||||
|
||||
/**
|
||||
* Receive a packet
|
||||
*
|
||||
* @param[out] Packet - the receiuved packet - buffer that is written
|
||||
* @param[out] PipeNum - pipe number that was received from
|
||||
* @return packet size, 0 on failure
|
||||
*/
|
||||
uint8_t NRF_ReceivePacket(uint8_t *Packet, uint8_t *PipeNum);
|
||||
|
||||
/**
|
||||
* Set base address
|
||||
* @param Bytes4
|
||||
*/
|
||||
void NRF_SetBaseAddress(const uint8_t *Bytes4);
|
||||
|
||||
/**
|
||||
* Check if there's a packet to be read
|
||||
*
|
||||
* @return 1 if any to read
|
||||
*/
|
||||
bool NRF_IsRxPacket(void);
|
||||
|
||||
/**
|
||||
* Enable a pipe
|
||||
*
|
||||
* @param pipenum - pipe number 0-5
|
||||
*/
|
||||
void NRF_EnablePipe(uint8_t pipenum);
|
||||
|
||||
/**
|
||||
* Disable a pipe
|
||||
*
|
||||
* @param pipenum - pipe number 0-5
|
||||
*/
|
||||
void NRF_DisablePipe(uint8_t pipenum);
|
||||
|
||||
#endif /* NORDIC_H_ */
|
||||
|
||||
#endif //GEX_NRF_NRF_H
|
||||
@@ -67,6 +67,8 @@ Src/msg_queue.c \
|
||||
Src/gex_gateway.c \
|
||||
Src/payload_builder.c \
|
||||
Src/payload_parser.c \
|
||||
Src/nrf.c \
|
||||
Src/crc32.c \
|
||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
|
||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
|
||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// Created by MightyPork on 2018/04/03.
|
||||
//
|
||||
|
||||
#include "main.h"
|
||||
#include "crc32.h"
|
||||
|
||||
static const uint32_t crc32_table[] = { /* CRC polynomial 0xedb88320 */
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
uint32_t CRC32_Start(void)
|
||||
{
|
||||
return (uint32_t) 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32_t CRC32_Add(uint32_t cksum, uint8_t byte)
|
||||
{
|
||||
return crc32_table[((cksum) ^ ((uint8_t) byte)) & 0xff] ^ ((cksum) >> 8);
|
||||
}
|
||||
|
||||
uint32_t CRC32_End(uint32_t cksum)
|
||||
{
|
||||
return (uint32_t) ~cksum;
|
||||
}
|
||||
+114
-36
@@ -9,49 +9,61 @@
|
||||
#include "main.h"
|
||||
#include "minmax.h"
|
||||
#include "payload_parser.h"
|
||||
#include "nrf.h"
|
||||
#include "crc32.h"
|
||||
#include "payload_builder.h"
|
||||
|
||||
static uint8_t gex_network[4];
|
||||
|
||||
// USB RX
|
||||
enum URX_STATE {
|
||||
URXS_IDLE = 0,
|
||||
URXS_MSG4SLAVE = 1,
|
||||
enum USB_RX_STATE {
|
||||
CMD_STATE_IDLE = 0,
|
||||
CMD_STATE_TXMSG = 1,
|
||||
};
|
||||
|
||||
#define MAX_FRAME_LEN 512
|
||||
|
||||
static enum URX_STATE urx_state = URXS_IDLE;
|
||||
static uint32_t msg4slave_len = 0; // total len to be collected
|
||||
static uint32_t msg4slave_already = 0; // already collected len
|
||||
static uint8_t msg4slave[MAX_FRAME_LEN]; // equal buffer size in GEX
|
||||
static uint8_t msg4slave_addr = 0;
|
||||
static uint8_t msg4slave_cksum = 0;
|
||||
static enum USB_RX_STATE cmd_state = CMD_STATE_IDLE;
|
||||
|
||||
static uint32_t txmsg_len = 0; // total len to be collected
|
||||
static uint32_t txmsg_collected = 0; // already collected len
|
||||
static uint8_t txmsg_payload[MAX_FRAME_LEN]; // equal buffer size in GEX
|
||||
static uint8_t txmsg_addr = 0;
|
||||
static uint8_t txmsg_cksum = 0;
|
||||
|
||||
#define MAGIC_GW_COMMAND 0x47U // 'G'
|
||||
|
||||
enum GW_CMD {
|
||||
CMD_GET_ID = 'i', // 105
|
||||
CMD_MSG4SLAVE = 'm', // 109
|
||||
CMD_GET_ID = 'i', // 105 - get network ID
|
||||
CMD_RESET = 'r', // reset the radio and network
|
||||
CMD_ADD_NODE = 'n', // add a node by address byte
|
||||
CMD_TXMSG = 'm', // 109 - send a message
|
||||
};
|
||||
|
||||
void respond_gw_id() {} // TODO impl
|
||||
void respond_gw_id(void);
|
||||
|
||||
void handle_cmd_addnode(PayloadParser *pp);
|
||||
|
||||
void handle_cmd_reset(void);
|
||||
|
||||
void start_slave_cmd(uint8_t slave_addr, uint16_t frame_len, uint8_t cksum)
|
||||
{
|
||||
msg4slave_len = frame_len;
|
||||
msg4slave_already = 0;
|
||||
msg4slave_addr = slave_addr;
|
||||
msg4slave_cksum = cksum;
|
||||
txmsg_len = frame_len;
|
||||
txmsg_collected = 0;
|
||||
txmsg_addr = slave_addr;
|
||||
txmsg_cksum = cksum;
|
||||
}
|
||||
|
||||
void gw_handle_usb_out(uint8_t *buffer)
|
||||
{
|
||||
if (urx_state == URXS_IDLE) {
|
||||
if (cmd_state == CMD_STATE_IDLE) {
|
||||
PayloadParser pp = pp_start(buffer, MQ_SLOT_LEN, NULL);
|
||||
|
||||
// handle binary commands for the gateway
|
||||
|
||||
// magic twice, one inverted - denotes a gateway command
|
||||
uint16_t magic1 = pp_u8(&pp);
|
||||
uint16_t magic2 = pp_u8(&pp);
|
||||
const uint16_t magic1 = pp_u8(&pp);
|
||||
const uint16_t magic2 = pp_u8(&pp);
|
||||
if (magic1 == MAGIC_GW_COMMAND && magic2 == (0xFFU & (~MAGIC_GW_COMMAND))) {
|
||||
// third byte is the command code
|
||||
switch (pp_u8(&pp)) {
|
||||
@@ -59,7 +71,15 @@ void gw_handle_usb_out(uint8_t *buffer)
|
||||
respond_gw_id();
|
||||
break;
|
||||
|
||||
case CMD_MSG4SLAVE:;
|
||||
case CMD_RESET:
|
||||
handle_cmd_reset();
|
||||
break;
|
||||
|
||||
case CMD_ADD_NODE:
|
||||
handle_cmd_addnode(&pp);
|
||||
break;
|
||||
|
||||
case CMD_TXMSG:;
|
||||
uint8_t slave_addr = pp_u8(&pp);
|
||||
uint16_t frame_len = pp_u16(&pp);
|
||||
uint8_t cksum = pp_u8(&pp);
|
||||
@@ -71,7 +91,7 @@ void gw_handle_usb_out(uint8_t *buffer)
|
||||
|
||||
start_slave_cmd(slave_addr, frame_len, cksum);
|
||||
dbg("Collecting frame for slave %02x: %d bytes", (int)slave_addr, (int)frame_len);
|
||||
urx_state = URXS_MSG4SLAVE;
|
||||
cmd_state = CMD_STATE_TXMSG;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -82,38 +102,96 @@ void gw_handle_usb_out(uint8_t *buffer)
|
||||
dbg("Bad USB frame, starts %x,%x", buffer[0],buffer[1]);
|
||||
}
|
||||
}
|
||||
else if (urx_state == URXS_MSG4SLAVE) {
|
||||
uint32_t wanted = MIN(msg4slave_len-msg4slave_already, MQ_SLOT_LEN);
|
||||
memcpy(&msg4slave[msg4slave_already], buffer, wanted);
|
||||
msg4slave_already += wanted;
|
||||
else if (cmd_state == CMD_STATE_TXMSG) {
|
||||
uint32_t wanted = MIN(txmsg_len - txmsg_collected, MQ_SLOT_LEN);
|
||||
memcpy(&txmsg_payload[txmsg_collected], buffer, wanted);
|
||||
txmsg_collected += wanted;
|
||||
|
||||
if (wanted < MQ_SLOT_LEN) {
|
||||
// this was the end
|
||||
uint8_t ck = 0;
|
||||
for (int i = 0; i < msg4slave_len; i++) {
|
||||
ck ^= msg4slave[i];
|
||||
for (int i = 0; i < txmsg_len; i++) {
|
||||
ck ^= txmsg_payload[i];
|
||||
}
|
||||
ck = ~ck;
|
||||
|
||||
if (ck != msg4slave_cksum) {
|
||||
if (ck != txmsg_cksum) {
|
||||
dbg("Checksum mismatch!");
|
||||
}
|
||||
else {
|
||||
dbg("Verified, sending a %d B frame to slave.", (int) msg4slave_len);
|
||||
dbg("Verified, sending a %d B frame to slave.", (int) txmsg_len);
|
||||
// TODO send to slave
|
||||
}
|
||||
|
||||
urx_state = URXS_IDLE;
|
||||
cmd_state = CMD_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** called from the main loop, periodically */
|
||||
void gw_process(void)
|
||||
void handle_cmd_reset(void)
|
||||
{
|
||||
// static uint8_t buffer[MQ_SLOT_LEN];
|
||||
// while (mq_read(&usb_rxq, buffer)) { // greedy - handle as many as possible
|
||||
// gw_handle_usb_out(buffer);
|
||||
// }
|
||||
NRF_Reset();
|
||||
// TODO also clear queues?
|
||||
}
|
||||
|
||||
void handle_cmd_addnode(PayloadParser *pp)
|
||||
{
|
||||
uint8_t node = pp_u8(pp);
|
||||
uint8_t pipenum;
|
||||
bool suc = NRF_AddPipe(node, &pipenum);
|
||||
if (!suc) dbg("Failed to add node.");
|
||||
// TODO response
|
||||
}
|
||||
|
||||
void respond_gw_id(void)
|
||||
{
|
||||
// TODO implement (after response system is added)
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the GEX network ID based on the gateway MCU unique ID.
|
||||
* The ID is a 4-byte code that must be entered in each node to join the network.
|
||||
*/
|
||||
static void compute_network_id(void)
|
||||
{
|
||||
uint8_t uid[12];
|
||||
PayloadBuilder pb = pb_start(uid, 12, NULL);
|
||||
pb_u32(&pb, LL_GetUID_Word0());
|
||||
pb_u32(&pb, LL_GetUID_Word1());
|
||||
pb_u32(&pb, LL_GetUID_Word2());
|
||||
|
||||
uint32_t ck = CRC32_Start();
|
||||
for (int i = 0; i < 12; i++) {
|
||||
ck = CRC32_Add(ck, uid[i]);
|
||||
}
|
||||
ck = CRC32_End(ck);
|
||||
|
||||
pb = pb_start(gex_network, 4, NULL);
|
||||
pb_u32(&pb, ck);
|
||||
|
||||
dbg("Dongle network ID: %02X-%02X-%02X-%02X",
|
||||
gex_network[0], gex_network[1], gex_network[2], gex_network[3]);
|
||||
}
|
||||
|
||||
void gw_setup_radio(void)
|
||||
{
|
||||
bool suc;
|
||||
dbg("Init NRF");
|
||||
|
||||
NRF_Init(NRF_SPEED_2M);
|
||||
|
||||
compute_network_id();
|
||||
NRF_SetBaseAddress(gex_network);
|
||||
|
||||
// TODO by config
|
||||
uint8_t pipenum;
|
||||
suc = NRF_AddPipe(0x01, &pipenum);
|
||||
dbg("Pipe added? %d, num %d", (int)suc, (int)pipenum);
|
||||
|
||||
NRF_ModeRX(); // base state is RX
|
||||
|
||||
dbg("Send a packet");
|
||||
|
||||
suc = NRF_SendPacket(pipenum, (uint8_t *) "AHOJ", 5);
|
||||
dbg("Suc? %d", (int)suc);
|
||||
}
|
||||
|
||||
+3
-1
@@ -82,7 +82,7 @@ void MX_GPIO_Init(void)
|
||||
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin);
|
||||
|
||||
/**/
|
||||
LL_GPIO_ResetOutputPin(GPIOA, NRF_CE_Pin|NRF_NSS_Pin);
|
||||
// LL_GPIO_ResetOutputPin(GPIOA, NRF_CE_Pin|NRF_NSS_Pin);
|
||||
|
||||
/**/
|
||||
GPIO_InitStruct.Pin = LED_Pin;
|
||||
@@ -98,6 +98,7 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
#if 0
|
||||
/**/
|
||||
LL_GPIO_AF_SetEXTISource(LL_GPIO_AF_EXTI_PORTA, LL_GPIO_AF_EXTI_LINE2);
|
||||
|
||||
@@ -110,6 +111,7 @@ void MX_GPIO_Init(void)
|
||||
|
||||
/**/
|
||||
LL_GPIO_SetPinMode(NRF_IRQ_GPIO_Port, NRF_IRQ_Pin, LL_GPIO_MODE_FLOATING);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
+12
-14
@@ -47,8 +47,6 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <gex_gateway.h>
|
||||
#include <msg_queue.h>
|
||||
#include "main.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "dma.h"
|
||||
@@ -57,6 +55,8 @@
|
||||
#include "usb_device.h"
|
||||
#include "gpio.h"
|
||||
#include "debug.h"
|
||||
#include "gex_gateway.h"
|
||||
#include "msg_queue.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
@@ -121,23 +121,21 @@ int main(void)
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
gw_setup_radio();
|
||||
mq_init(&usb_inq);
|
||||
|
||||
dbg("Main loop starts.");
|
||||
|
||||
mq_init(&usb_rxq);
|
||||
mq_init(&usb_txq);
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
int cnt = 0;
|
||||
while (1)
|
||||
{
|
||||
if (cnt++ > 100000) {
|
||||
GPIOC->ODR ^= (1 << 13);
|
||||
cnt = 0;
|
||||
while (1) {
|
||||
if (cnt++ > 4000000) {
|
||||
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||
// GPIOC->ODR ^= (1 << 13);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gw_process();
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -9,8 +9,7 @@
|
||||
#include "msg_queue.h"
|
||||
|
||||
// the two USB messaging queues
|
||||
MQueue usb_rxq;
|
||||
MQueue usb_txq;
|
||||
MQueue usb_inq;
|
||||
|
||||
void mq_init(MQueue *mq)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,470 @@
|
||||
//
|
||||
// Created by MightyPork on 2018/04/02.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "nrf.h"
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* Read a register
|
||||
*
|
||||
* @param reg - register number (max 83)
|
||||
* @return register value
|
||||
*/
|
||||
static uint8_t NRF_ReadRegister(uint8_t reg);
|
||||
|
||||
/**
|
||||
* Write a register
|
||||
*
|
||||
* @param reg - register number (max 83)
|
||||
* @param value - register value
|
||||
* @return status register value
|
||||
*/
|
||||
static uint8_t NRF_WriteRegister(uint8_t reg, uint8_t value);
|
||||
|
||||
// Internal use
|
||||
static uint8_t NRF_WriteBuffer(uint8_t reg, const uint8_t *pBuf, uint8_t bytes);
|
||||
|
||||
static uint8_t NRF_ReadBuffer(uint8_t reg, uint8_t *pBuf, uint8_t bytes);
|
||||
|
||||
/**
|
||||
* Set TX address for next frame
|
||||
*
|
||||
* @param SendTo - addr
|
||||
*/
|
||||
static void NRF_SetTxAddress(uint8_t ToAddr);
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
/** Tight asm loop */
|
||||
#define __asm_loop(cycles) \
|
||||
do { \
|
||||
register uint32_t _count asm ("r4") = cycles; \
|
||||
asm volatile( \
|
||||
".syntax unified\n" \
|
||||
".thumb\n" \
|
||||
"0:" \
|
||||
"subs %0, #1\n" \
|
||||
"bne 0b\n" \
|
||||
: "+r" (_count)); \
|
||||
} while(0)
|
||||
|
||||
// inaccurate!
|
||||
#define _delay_us(n) __asm_loop((n)*12)
|
||||
|
||||
static inline void CE(bool level) {
|
||||
if (level) LL_GPIO_SetOutputPin(NRF_CE_GPIO_Port, NRF_CE_Pin);
|
||||
else LL_GPIO_ResetOutputPin(NRF_CE_GPIO_Port, NRF_CE_Pin);
|
||||
}
|
||||
|
||||
static inline void NSS(bool level) {
|
||||
if (level) LL_GPIO_SetOutputPin(NRF_NSS_GPIO_Port, NRF_NSS_Pin);
|
||||
else LL_GPIO_ResetOutputPin(NRF_NSS_GPIO_Port, NRF_NSS_Pin);
|
||||
}
|
||||
|
||||
static uint8_t spi(uint8_t tx) {
|
||||
while (! LL_SPI_IsActiveFlag_TXE(SPI1));
|
||||
LL_SPI_TransmitData8(SPI1, tx);
|
||||
|
||||
while (! LL_SPI_IsActiveFlag_RXNE(SPI1));
|
||||
return LL_SPI_ReceiveData8(SPI1);
|
||||
}
|
||||
|
||||
//-------
|
||||
|
||||
/*
|
||||
* from: http://barefootelectronics.com/NRF24L01.aspx
|
||||
*/
|
||||
|
||||
#define CMD_READ_REG 0x00 // Read command to register
|
||||
#define CMD_WRITE_REG 0x20 // Write command to register
|
||||
#define CMD_RD_RX_PLD 0x61 // Read RX payload register address
|
||||
#define CMD_WR_TX_PLD 0xA0 // Write TX payload register address
|
||||
#define CMD_FLUSH_TX 0xE1 // Flush TX register command
|
||||
#define CMD_FLUSH_RX 0xE2 // Flush RX register command
|
||||
#define CMD_REUSE_TX_PL 0xE3 // Reuse TX payload register command
|
||||
#define CMD_RD_RX_PL_WIDTH 0x60 // Read RX Payload Width
|
||||
#define CMD_WR_ACK_PLD 0xA8 // Write ACK payload for Pipe (Add pipe number 0-6)
|
||||
#define CMD_WR_TX_PLD_NK 0xB0 // Write ACK payload for not ack
|
||||
#define CMD_NOP 0xFF // No Operation, might be used to read status register
|
||||
|
||||
// SPI(nRF24L01) registers(addresses)
|
||||
#define RG_CONFIG 0x00 // 'Config' register address
|
||||
#define RG_EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
|
||||
#define RG_EN_RXADDR 0x02 // 'Enabled RX addresses' register address
|
||||
#define RG_SETUP_AW 0x03 // 'Setup address width' register address
|
||||
#define RG_SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
|
||||
#define RG_RF_CH 0x05 // 'RF channel' register address
|
||||
#define RG_RF_SETUP 0x06 // 'RF setup' register address
|
||||
#define RG_STATUS 0x07 // 'Status' register address
|
||||
#define RG_OBSERVE_TX 0x08 // 'Observe TX' register address
|
||||
#define RG_CD 0x09 // 'Carrier Detect' register address
|
||||
#define RG_RX_ADDR_P0 0x0A // 'RX address pipe0' register address
|
||||
#define RG_RX_ADDR_P1 0x0B // 'RX address pipe1' register address
|
||||
#define RG_RX_ADDR_P2 0x0C // 'RX address pipe2' register address
|
||||
#define RG_RX_ADDR_P3 0x0D // 'RX address pipe3' register address
|
||||
#define RG_RX_ADDR_P4 0x0E // 'RX address pipe4' register address
|
||||
#define RG_RX_ADDR_P5 0x0F // 'RX address pipe5' register address
|
||||
#define RG_TX_ADDR 0x10 // 'TX address' register address
|
||||
#define RG_RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
|
||||
#define RG_RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
|
||||
#define RG_RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
|
||||
#define RG_RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
|
||||
#define RG_RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
|
||||
#define RG_RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
|
||||
#define RG_FIFO_STATUS 0x17 // 'FIFO Status Register' register address
|
||||
#define RG_DYNPD 0x1C // 'Enable dynamic payload length
|
||||
#define RG_FEATURE 0x1D // 'Feature register
|
||||
|
||||
#define RD_STATUS_TX_FULL 0x01 // tx queue full
|
||||
#define RD_STATUS_RX_PNO 0x0E // pipe number of the received payload
|
||||
#define RD_STATUS_MAX_RT 0x10 // max retransmissions
|
||||
#define RD_STATUS_TX_DS 0x20 // data sent
|
||||
#define RD_STATUS_RX_DR 0x40 // data ready
|
||||
|
||||
#define RD_CONFIG_PRIM_RX 0x01 // is primary receiver
|
||||
#define RD_CONFIG_PWR_UP 0x02 // power up
|
||||
#define RD_CONFIG_CRCO 0x04 // 2-byte CRC
|
||||
#define RD_CONFIG_EN_CRC 0x08 // enable CRC
|
||||
#define RD_CONFIG_DISABLE_IRQ_MAX_RT 0x10
|
||||
#define RD_CONFIG_DISABLE_IRQ_TX_DS 0x20
|
||||
#define RD_CONFIG_DISABLE_IRQ_RX_DR 0x40
|
||||
|
||||
// Config register bits (excluding the bottom two that are changed dynamically)
|
||||
// enable only Rx IRQ
|
||||
#define ModeBits (RD_CONFIG_DISABLE_IRQ_MAX_RT | \
|
||||
RD_CONFIG_DISABLE_IRQ_TX_DS | \
|
||||
RD_CONFIG_EN_CRC | \
|
||||
RD_CONFIG_CRCO)
|
||||
|
||||
#define CEHIGH CE(1)
|
||||
#define CELOW CE(0)
|
||||
|
||||
static inline uint8_t CS(uint8_t hl)
|
||||
{
|
||||
if (hl == 1) {
|
||||
NSS(0);
|
||||
}
|
||||
else {
|
||||
NSS(1);
|
||||
}
|
||||
return hl;
|
||||
}
|
||||
|
||||
#define CHIPSELECT for (uint8_t cs = CS(1); cs==1; cs = CS(0))
|
||||
|
||||
// Base NRF address - byte 4 may be modified before writing to a pipe register,
|
||||
// the first 4 bytes are shared in the network. Master is always code 0.
|
||||
static uint8_t nrf_base_address[5];
|
||||
|
||||
static uint8_t nrf_pipe_addr[6];
|
||||
static bool nrf_pipe_enabled[6];
|
||||
|
||||
static uint8_t NRF_WriteRegister(uint8_t reg, uint8_t value)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
CHIPSELECT {
|
||||
status = spi(CMD_WRITE_REG | reg);
|
||||
spi(value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint8_t NRF_ReadRegister(uint8_t reg)
|
||||
{
|
||||
uint8_t reg_val = 0;
|
||||
CHIPSELECT {
|
||||
spi(CMD_READ_REG | reg);
|
||||
reg_val = spi(0);
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
static uint8_t NRF_ReadStatus(void)
|
||||
{
|
||||
uint8_t reg_val = 0;
|
||||
CHIPSELECT {
|
||||
reg_val = spi(CMD_NOP);
|
||||
}
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
static uint8_t NRF_WriteBuffer(uint8_t reg, const uint8_t *pBuf, uint8_t bytes)
|
||||
{
|
||||
uint8_t status = 0, i = 0;
|
||||
CHIPSELECT {
|
||||
status = spi(CMD_WRITE_REG | reg);
|
||||
for (i = 0; i < bytes; i++) {
|
||||
spi(*pBuf++);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint8_t NRF_ReadBuffer(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
|
||||
{
|
||||
uint8_t status = 0, i;
|
||||
CHIPSELECT {
|
||||
status = spi(CMD_READ_REG | reg);
|
||||
for (i = 0; i < bytes; i++) {
|
||||
pBuf[i] = spi(0);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void NRF_SetBaseAddress(const uint8_t *Bytes4)
|
||||
{
|
||||
memcpy(nrf_base_address, Bytes4, 4);
|
||||
nrf_base_address[4] = 0;
|
||||
}
|
||||
|
||||
void NRF_SetRxAddress(uint8_t pipenum, uint8_t AddrByte)
|
||||
{
|
||||
if (pipenum > 5) {
|
||||
dbg("!! bad pipe %d", pipenum);
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_base_address[4] = AddrByte;
|
||||
|
||||
nrf_pipe_addr[pipenum] = AddrByte;
|
||||
|
||||
if (pipenum == 0) {
|
||||
NRF_WriteBuffer(RG_RX_ADDR_P0, nrf_base_address, 5);
|
||||
}
|
||||
else if (pipenum == 1) {
|
||||
NRF_WriteBuffer(RG_RX_ADDR_P1, nrf_base_address, 5);
|
||||
}
|
||||
else {
|
||||
NRF_WriteRegister(RG_RX_ADDR_P2 + (pipenum - 2), AddrByte);
|
||||
}
|
||||
}
|
||||
|
||||
bool NRF_AddPipe(uint8_t AddrByte, uint8_t *PipeNum)
|
||||
{
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if(!nrf_pipe_enabled[i]) {
|
||||
NRF_SetRxAddress(i, AddrByte);
|
||||
*PipeNum = i;
|
||||
NRF_EnablePipe(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t NRF_PipeNum2Addr(uint8_t pipe_num)
|
||||
{
|
||||
if (pipe_num > 5) return 0; // fail
|
||||
return nrf_pipe_addr[pipe_num];
|
||||
}
|
||||
|
||||
uint8_t NRF_Addr2PipeNum(uint8_t addr)
|
||||
{
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (nrf_pipe_addr[i] == addr) return (uint8_t) i;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void NRF_EnablePipe(uint8_t pipenum)
|
||||
{
|
||||
uint8_t enabled = NRF_ReadRegister(RG_EN_RXADDR);
|
||||
enabled |= 1 << pipenum;
|
||||
NRF_WriteRegister(RG_EN_RXADDR, enabled);
|
||||
|
||||
nrf_pipe_enabled[pipenum] = 1;
|
||||
}
|
||||
|
||||
void NRF_DisablePipe(uint8_t pipenum)
|
||||
{
|
||||
uint8_t enabled = NRF_ReadRegister(RG_EN_RXADDR);
|
||||
enabled &= ~(1 << pipenum);
|
||||
NRF_WriteRegister(RG_EN_RXADDR, enabled);
|
||||
|
||||
nrf_pipe_enabled[pipenum] = 0;
|
||||
}
|
||||
|
||||
static void NRF_SetTxAddress(uint8_t SendTo)
|
||||
{
|
||||
nrf_base_address[4] = SendTo;
|
||||
NRF_WriteBuffer(RG_TX_ADDR, nrf_base_address, 5);
|
||||
NRF_WriteBuffer(RG_RX_ADDR_P0, nrf_base_address, 5); // the ACK will come to pipe 0
|
||||
}
|
||||
|
||||
void NRF_PowerDown(void)
|
||||
{
|
||||
CELOW;
|
||||
NRF_WriteRegister(RG_CONFIG, ModeBits);
|
||||
}
|
||||
|
||||
void NRF_ModeTX(void)
|
||||
{
|
||||
CELOW;
|
||||
uint8_t m = NRF_ReadRegister(RG_CONFIG);
|
||||
NRF_WriteRegister(RG_CONFIG, ModeBits | RD_CONFIG_PWR_UP);
|
||||
if ((m & RD_CONFIG_PWR_UP) == 0) LL_mDelay(5);
|
||||
}
|
||||
|
||||
void NRF_ModeRX(void)
|
||||
{
|
||||
NRF_WriteRegister(RG_CONFIG, ModeBits | RD_CONFIG_PWR_UP | RD_CONFIG_PRIM_RX);
|
||||
NRF_SetRxAddress(0, nrf_pipe_addr[0]); // set the P0 address - it was changed during Rx for ACK reception
|
||||
CEHIGH;
|
||||
|
||||
//if ((m&2)==0) LL_mDelay()(5); You don't need to wait. Just nothing will come for 5ms or more
|
||||
}
|
||||
|
||||
uint8_t NRF_IsModePowerDown(void)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
if ((NRF_ReadRegister(RG_CONFIG) & RD_CONFIG_PWR_UP) == 0) ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t NRF_IsModeTX(void)
|
||||
{
|
||||
uint8_t m = NRF_ReadRegister(RG_CONFIG);
|
||||
if ((m & RD_CONFIG_PWR_UP) == 0) return 0; // OFF
|
||||
if ((m & RD_CONFIG_PRIM_RX) == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t NRF_IsModeRx(void)
|
||||
{
|
||||
uint8_t m = NRF_ReadRegister(RG_CONFIG);
|
||||
if ((m & RD_CONFIG_PWR_UP) == 0) return 0; // OFF
|
||||
if ((m & RD_CONFIG_PRIM_RX) == 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NRF_SetChannel(uint8_t Ch)
|
||||
{
|
||||
NRF_WriteRegister(RG_RF_CH, Ch);
|
||||
}
|
||||
|
||||
uint8_t NRF_ReceivePacket(uint8_t *Packet, uint8_t *PipeNum)
|
||||
{
|
||||
uint8_t pw = 0, status;
|
||||
if (!NRF_IsRxPacket()) return 0;
|
||||
|
||||
CELOW;
|
||||
CHIPSELECT {
|
||||
status = spi(CMD_RD_RX_PL_WIDTH);
|
||||
pw = spi(0);
|
||||
}
|
||||
|
||||
if (pw > 32) {
|
||||
CHIPSELECT {
|
||||
spi(CMD_FLUSH_RX);
|
||||
}
|
||||
NRF_WriteRegister(RG_STATUS, RD_STATUS_RX_DR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the reception pipe number
|
||||
*PipeNum = (status & RD_STATUS_RX_PNO) >> 1;
|
||||
|
||||
CHIPSELECT {
|
||||
spi(CMD_RD_RX_PLD);
|
||||
for (uint8_t i = 0; i < pw; i++) Packet[i] = spi(0);
|
||||
}
|
||||
NRF_WriteRegister(RG_STATUS, RD_STATUS_RX_DR); // Clear the RX_DR interrupt
|
||||
CEHIGH;
|
||||
return pw;
|
||||
}
|
||||
|
||||
bool NRF_IsRxPacket(void)
|
||||
{
|
||||
uint8_t ret = NRF_ReadRegister(RG_STATUS) & RD_STATUS_RX_DR;
|
||||
return 0 != ret;
|
||||
}
|
||||
|
||||
bool NRF_SendPacket(uint8_t PipeNum, const uint8_t *Packet, uint8_t Length)
|
||||
{
|
||||
if (!nrf_pipe_enabled[PipeNum]) {
|
||||
dbg("!! Pipe %d not enabled", PipeNum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t orig_conf = NRF_ReadRegister(RG_CONFIG);
|
||||
CELOW;
|
||||
NRF_ModeTX(); // Make sure in TX mode
|
||||
NRF_SetTxAddress(nrf_pipe_addr[PipeNum]);
|
||||
|
||||
CHIPSELECT {
|
||||
spi(CMD_FLUSH_TX);
|
||||
};
|
||||
|
||||
CHIPSELECT {
|
||||
spi(CMD_WR_TX_PLD);
|
||||
for (uint8_t i = 0; i < Length; i++) spi(Packet[i]);
|
||||
};
|
||||
|
||||
CEHIGH;
|
||||
_delay_us(15); // At least 10 us
|
||||
CELOW;
|
||||
|
||||
uint8_t st = 0;
|
||||
while ((st & (RD_STATUS_MAX_RT|RD_STATUS_TX_DS)) == 0) {
|
||||
st = NRF_ReadStatus(); // Packet acked or timed out
|
||||
}
|
||||
|
||||
NRF_WriteRegister(RG_STATUS, st & (RD_STATUS_MAX_RT|RD_STATUS_TX_DS)); // Clear the bit
|
||||
|
||||
if ((orig_conf & RD_CONFIG_PWR_UP) == 0) {
|
||||
NRF_PowerDown();
|
||||
}
|
||||
else if ((orig_conf & RD_CONFIG_PRIM_RX) == RD_CONFIG_PRIM_RX) {
|
||||
NRF_ModeRX();
|
||||
}
|
||||
|
||||
return 0 != (st & RD_STATUS_TX_DS); // success
|
||||
}
|
||||
|
||||
void NRF_Reset(void)
|
||||
{
|
||||
NSS(1);
|
||||
CELOW;
|
||||
NRF_PowerDown();
|
||||
|
||||
NRF_WriteRegister(RG_EN_RXADDR, 0); // disable all pipes
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
nrf_pipe_addr[i] = 0;
|
||||
nrf_pipe_enabled[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NRF_Init(uint8_t pSpeed)
|
||||
{
|
||||
// Set the required output pins
|
||||
NSS(1);
|
||||
CELOW;
|
||||
|
||||
LL_mDelay(200);
|
||||
|
||||
NRF_WriteRegister(RG_CONFIG, ModeBits);
|
||||
NRF_WriteRegister(RG_SETUP_AW, 0b11); // 5 byte addresses
|
||||
|
||||
// default
|
||||
// NRF_EnablePipe(0);
|
||||
|
||||
NRF_WriteRegister(RG_SETUP_RETR, 0x18); // 8 retries
|
||||
NRF_WriteRegister(RG_RF_CH, 2); // channel 2 NO HIGHER THAN 83 in USA!
|
||||
|
||||
NRF_WriteRegister(RG_RF_SETUP, pSpeed);
|
||||
|
||||
NRF_WriteRegister(RG_DYNPD, 0b111111); // Dynamic packet length
|
||||
NRF_WriteRegister(RG_FEATURE, 0b100); // Enable dynamic payload, and no payload in the ack.
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
NRF_WriteRegister(RG_RX_PW_P0+i, 32); // Receive 32 byte packets - XXX this is probably not needed with dynamic length
|
||||
}
|
||||
|
||||
//NRFModePowerDown(); // Already in power down mode, dummy
|
||||
}
|
||||
@@ -82,7 +82,8 @@ void MX_SPI1_Init(void)
|
||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* SPI1 DMA Init */
|
||||
|
||||
|
||||
#if 0
|
||||
/* SPI1_RX Init */
|
||||
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
|
||||
|
||||
@@ -112,6 +113,7 @@ void MX_SPI1_Init(void)
|
||||
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE);
|
||||
|
||||
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE);
|
||||
#endif
|
||||
|
||||
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
|
||||
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
|
||||
@@ -125,6 +127,7 @@ void MX_SPI1_Init(void)
|
||||
SPI_InitStruct.CRCPoly = 10;
|
||||
LL_SPI_Init(SPI1, &SPI_InitStruct);
|
||||
|
||||
LL_SPI_Enable(SPI1);
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
Reference in New Issue
Block a user