Files
player/Project/Src/MyApp/nrf.c

385 lines
8.7 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#include "nrf.h"
#include "24l01.h"
2025-06-27 00:32:57 +08:00
#include "buff.h"
#include "rthw.h"
#include "stdio.h"
#include "string.h"
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
// <20>ӿں<D3BF><DABA><EFBFBD>
static void nrf_dalay_us(int us) { rt_hw_us_delay(us); }
2025-06-27 00:32:57 +08:00
static int nrf_get_random(void) {
static int d = 0;
d++;
return d;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
/* -------------------------- ͨ<><CDA8>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---------------------------- */
2025-06-27 00:32:57 +08:00
typedef struct {
// <20><><EFBFBD><EFBFBD>״̬
int connect_state;
// <20><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD>״̬
int interaction_err;
// <20><><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD>Ӧ
int no_respond;
// <20><><EFBFBD>ݷ<EFBFBD><DDB7>ͳɹ<CDB3>
int send_ok;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1>䣬us
int interaction_time_out;
// <20><><EFBFBD>ӳ<EFBFBD>ʱʱ<CAB1>䣬ms
int connect_time_out;
// <20><><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD>
int retry_itmes;
// <20>ŵ<EFBFBD>Ƶ<EFBFBD><C6B5>
int channel_frequency;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
int send_packet_all;
// <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
int send_packet_failed;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
uint8_t addr_myself[5];
// Ŀ<><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
uint8_t addr_dst[5];
2025-06-27 00:32:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>ħ<EFBFBD><C4A7>
uint8_t magic_number_send;
2025-06-27 00:32:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>ħ<EFBFBD><C4A7>
uint8_t magic_number_recv;
} nrf_env_struct;
static nrf_env_struct g_nrf_env = {0};
static data_buff g_buff = {0};
static const uint8_t g_dst_addr[TX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10,
0x01}; // <20><><EFBFBD>͵<EFBFBD>ַ
static const uint8_t g_my_addr[RX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10,
0x01}; // <20><><EFBFBD>͵<EFBFBD>ַ
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
int nrf_set_connect_state(int s) {
g_nrf_env.connect_state = s;
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>״̬
int nrf_get_connect_state(void) { return g_nrf_env.connect_state; }
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ŵ<EFBFBD>ַ
int nrf_set_addr(const uint8_t *my, const uint8_t *dst) {
if (my)
memcpy(g_nrf_env.addr_myself, my, 5);
if (dst)
memcpy(g_nrf_env.addr_dst, dst, 5);
nrf24l01_set_addr(g_nrf_env.addr_myself, g_nrf_env.addr_dst);
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD>
int nrf_set_retry_times(int times) {
g_nrf_env.retry_itmes = times;
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD>
int nrf_set_chan(uint8_t chan) {
if (chan >= 64)
return NRF_ERR;
if (g_nrf_env.channel_frequency != chan) {
g_nrf_env.channel_frequency = chan;
nrf24l01_set_chan(g_nrf_env.channel_frequency);
}
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ŵ<EFBFBD>
int nrf_get_chan(void) { return g_nrf_env.channel_frequency; }
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD>ó<EFBFBD>ʱʱ<CAB1><CAB1>
int nrf_set_time_out(int connect_time_ms, int interaction_time_us) {
g_nrf_env.connect_time_out = connect_time_ms;
g_nrf_env.interaction_time_out = interaction_time_us;
return 0;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD>
int nrf_get_packet_num(int *all, int *failed) {
if (all)
*all = g_nrf_env.send_packet_all;
if (failed)
*failed = g_nrf_env.send_packet_failed;
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ͼ<EFBFBD>¼
int nrf_clear_packet_num(void) {
g_nrf_env.send_packet_all = 0;
g_nrf_env.send_packet_failed = 0;
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻص<DDBB>
2025-06-27 00:32:57 +08:00
void nrf_send_cb(void *t);
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݻص<DDBB>
2025-06-27 00:32:57 +08:00
void nrf_recv_cb(void *t);
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ų<EFBFBD>ʼ<EFBFBD><CABC>
int nrf_init(void) {
memset(&g_nrf_env, 0, sizeof(nrf_env_struct));
2025-06-27 00:32:57 +08:00
buff_init(&g_buff, 4096 * 16, 0, 0, 0);
2025-06-27 00:32:57 +08:00
nrf24l01_set_recv_cb(nrf_recv_cb, 0);
nrf24l01_set_send_cb(nrf_send_cb, 0);
2025-06-27 00:32:57 +08:00
nrf24l01_init();
g_nrf_env.channel_frequency = -1;
nrf_set_connect_state(1);
nrf_set_addr(g_my_addr, g_dst_addr);
nrf_set_chan(20);
nrf_set_time_out(1000, 5000);
nrf_set_retry_times(1000);
2025-06-27 00:32:57 +08:00
if (nrf24l01_check() == 0)
return NRF_OK;
else {
buff_deinit(&g_buff);
return NRF_ERR;
}
2025-06-27 00:32:57 +08:00
}
// ȥ<><C8A5>ʼ<EFBFBD><CABC>
int nrf_deinit(void) {
buff_deinit(&g_buff);
nrf24l01_deinit();
return NRF_OK;
}
2025-06-27 00:32:57 +08:00
// <20><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݣ<EFBFBD>NRF_OK<4F>ɹ<EFBFBD>
int nrf_read_byte(uint8_t *data) {
if (buff_read_byte(&g_buff, data) == 0)
2025-06-27 00:32:57 +08:00
return NRF_OK;
else
return NRF_ERR;
2025-06-27 00:32:57 +08:00
}
// <20><><EFBFBD>ս<EFBFBD><D5BD><EFBFBD><EFBFBD><EFBFBD>
int nrf_clear(void) {
buff_clear(&g_buff);
return NRF_OK;
}
2025-06-27 00:32:57 +08:00
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>NRF_OK
int nrf_send(void *data, int size, int *rs) {
int ret = NRF_OK;
int len = 0;
uint8_t *ptr = data;
nrf_load_struct load;
while (size > 0) {
if (size > 29)
len = 29;
else
len = size;
nrf_packet_pack(&load, NRF_TYPE_DATA, ptr, len);
if (ret = nrf_send_load(&load), ret != NRF_OK) {
return ret;
} else {
if (rs)
(*rs) += len;
size -= len;
ptr += len;
2025-06-27 00:32:57 +08:00
}
}
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// ͬ<><CDAC>ͨ<EFBFBD><CDA8><EFBFBD>ŵ<EFBFBD>
int nrf_ctrl_chan(uint8_t chan) {
if (nrf_get_connect_state() == 0)
return NRF_ERR;
nrf_load_struct load = {0};
nrf_chan_struct c = {0};
c.chan = chan;
c.times = 0;
uint8_t chan_old = g_nrf_env.channel_frequency;
// <20><>һ<EFBFBD>η<EFBFBD><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ղ<EFBFBD><D5B2><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>Ϊ<EFBFBD>ӻ<EFBFBD><D3BB>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD>
nrf_packet_pack(&load, NRF_TYPE_CHAN, &c, sizeof(nrf_chan_struct));
nrf_send_load(&load);
// <20><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><DEB8>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵ڶ<CDB5><DAB6><EFBFBD>
nrf_set_chan(c.chan);
c.times++;
// <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD>dzɹ<C7B3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ɹ<EFBFBD>
nrf_packet_pack(&load, NRF_TYPE_CHAN, &c, sizeof(nrf_chan_struct));
if (nrf_send_load(&load) == NRF_OK) {
return NRF_OK;
} else {
// <20><><EFBFBD>û<EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD>ŵ<EFBFBD>
nrf_set_chan(chan_old);
return NRF_ERR;
}
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// ͨ<><CDA8>Э<EFBFBD><EFBFBD>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD> NRF_OK
int nrf_send_load(nrf_load_struct *load) {
int ret = 0;
int time_out = 0;
int retry_times = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>ΪNRF_ERR<52><52><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5>Է<EFBFBD><D4B7><EFBFBD><EFBFBD>غ<EFBFBD><D8BA>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
g_nrf_env.interaction_err = NRF_ERR;
// <20>ڷ<EFBFBD><DAB7>͵<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ħ<EFBFBD><C4A7>
do {
load->magic_number = nrf_get_random();
} while (load->magic_number == g_nrf_env.magic_number_send);
g_nrf_env.magic_number_send = load->magic_number;
// TODO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݻص<DDBB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽ<EFBFBD><DABD>նԷ<D5B6><D4B7>Ļ<EFBFBD>Ӧ
retry:
nrf24l01_send(load);
g_nrf_env.send_packet_all++;
while (time_out < g_nrf_env.interaction_time_out) {
if (g_nrf_env.interaction_err == NRF_OK)
return NRF_OK;
if (g_nrf_env.interaction_err != NRF_ERR)
return g_nrf_env.interaction_err;
nrf_dalay_us(1);
time_out++;
}
if (retry_times < g_nrf_env.retry_itmes) {
g_nrf_env.send_packet_failed++;
retry_times++;
time_out = 0;
goto retry;
}
return NRF_TIMEOUT;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20>ڽ<EFBFBD><DABD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD>ظ<EFBFBD><D8B8>Է<EFBFBD>
int nrf_respond(nrf_load_struct *load) {
if (g_nrf_env.no_respond)
2025-06-27 00:32:57 +08:00
return NRF_OK;
int ret = 0;
int time_out = 0;
int retry_times = 0;
// <20><><EFBFBD>ͳɹ<CDB3><C9B9><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA>Զ<EFBFBD><D4B6><EFBFBD>1
g_nrf_env.send_ok = 0;
// <20><>ħ<EFBFBD><C4A7><EFBFBD><EFBFBD><EFBFBD>óɺͽ<C9BA><CDBD><EFBFBD>ʱ<EFBFBD><CAB1>ͬ
load->magic_number = g_nrf_env.magic_number_recv;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>е<EFBFBD><D0B5>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϷ<D0B6><CFB7>ͳɹ<CDB3><C9B9><EFBFBD>
// <20>ȼ<EFBFBD><C8BC><EFBFBD>ÿ<EFBFBD>ζ<EFBFBD><CEB6><EFBFBD><EFBFBD>ͳɹ<CDB3><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>
nrf24l01_send(load);
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ӧ,1,<2C><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>0<EFBFBD><30><EFBFBD><EFBFBD>Ӧ
int nrf_set_no_respond(int power) {
g_nrf_env.no_respond = power;
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD>֡,<2C><><EFBFBD><EFBFBD>NRF_OK<4F>ɹ<EFBFBD>
int nrf_packet_pack(nrf_load_struct *load, uint8_t type, void *data,
int data_len) {
if (data_len > 29)
return NRF_ERR;
if (load == 0)
return NRF_ERR;
load->len = data_len;
load->type = type;
memcpy(load->load, data, data_len);
return NRF_OK;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>1
int nrf_addr_cmp(uint8_t addr1[5], uint8_t addr2[5]) {
for (int i = 0; i < 5; i++) {
if (addr1[i] != addr2[i])
return 0;
}
return 1;
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݻص<DDBB>
void nrf_recv_cb(void *t) {
nrf_load_struct r = {0};
nrf24l01_read(&r);
// TODO <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1>
uint8_t magic_number_old = g_nrf_env.magic_number_recv;
g_nrf_env.magic_number_recv = r.magic_number;
switch (r.type) {
case NRF_TYPE_NULL:
// TODO <20>ǿղ<C7BF><D5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>
nrf_packet_pack(&r, NRF_TYPE_ANSWER, NRF_ANSWER_OK);
nrf_respond(&r);
break;
case NRF_TYPE_CONN: {
nrf_conn_struct *c = (nrf_conn_struct *)r.load;
if (nrf_addr_cmp(c->addr_dst, g_nrf_env.addr_myself)) {
nrf_packet_pack(&r, NRF_TYPE_ANSWER, NRF_ANSWER_OK);
nrf_respond(&r);
// TODO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD>ŵ<EFBFBD>
nrf_set_addr(0, c->addr_src);
nrf_set_chan(c->chan);
}
} break;
case NRF_TYPE_CHAN: {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB>ŵ<EFBFBD>
nrf_chan_struct *c = (nrf_chan_struct *)r.load;
if (nrf_get_connect_state()) {
if (c->times == 0) {
// <20><>һ<EFBFBD>ν<EFBFBD><CEBD><EFBFBD>ֱ<EFBFBD>Ӹ<EFBFBD><D3B8>ŵ<EFBFBD><C5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ
nrf_set_chan(c->chan);
} else if (c->times == 1) {
// <20>ڶ<EFBFBD><DAB6>λ<EFBFBD>Ӧ<EFBFBD>ɹ<EFBFBD>
nrf_packet_pack(&r, NRF_TYPE_ANSWER, NRF_ANSWER_OK);
nrf_respond(&r);
}
}
} break;
case NRF_TYPE_ANSWER: {
// TODO <20><><EFBFBD>ݷ<EFBFBD><DDB7>صĴ<D8B5><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>״̬
if (g_nrf_env.magic_number_send == r.magic_number) {
uint8_t err = r.load[0];
g_nrf_env.interaction_err = err;
} else {
g_nrf_env.interaction_err = NRF_MISMATCH;
}
} break;
case NRF_TYPE_DATA: {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (magic_number_old != r.magic_number) {
for (int i = 0; i < r.len; i++) {
if (buff_save_byte(&g_buff, r.load[i]) != 0) {
printf("%s:buff overflow\r\n", __func__);
2025-06-27 00:32:57 +08:00
}
}
} else {
printf("%s:resave\r\n", __func__);
2025-06-27 00:32:57 +08:00
}
nrf_packet_pack(&r, NRF_TYPE_ANSWER, NRF_ANSWER_OK);
nrf_respond(&r);
} break;
default:
break;
}
2025-06-27 00:32:57 +08:00
}
2025-07-05 19:47:28 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻص<DDBB>
void nrf_send_cb(void *t) { g_nrf_env.send_ok = 1; }