Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8RF24examplesrf24_ATTinytimingSearch3pintimingSearch3pin.ino

207 lines · 6.5 KB

1/**
2 * See documentation at https://nRF24.github.io/RF24
3 * See License information at root directory of this library
4 * written by tong67 (https://github.com/tong67)
5 * edited by 2bndy5 (http://github.com/2bndy5) for compatibility with SpenceKonde's ATTinyCore
6 */
7
8/*
9 * This sketch can determine the best settle time values to use for
10 * macros, defined as RF24_CSN_SETTLE_HIGH_DELAY and RF24_CSN_SETTLE_LOW_DELAY,
11 * in RF24::csn().
12 * The settle time values used here are 100/20. However, these values depend
13 * on the actual used RC combination and voltage drop by LED. The
14 * intermediate results are written to TX (PB3, pin 2 -- using Serial).
15 *
16 * For schematic details, see introductory comment block in the
17 * examples/rf24_ATTiny/rf24ping85/rf24ping85.ino sketch.
18 */
19
20#include <stdio.h>
21#include <SPI.h>
22#include <Arduino.h>
23#include <nRF24L01.h>
24
25
26#if defined(ARDUINO) && !defined(__arm__)
27#if defined(__AVR_ATtinyX5__) || defined(__AVR_ATtinyX4__)
28#define RF24_TINY
29#endif
30#endif
31
32/****************************************************************************/
33
34#if defined(RF24_TINY)
35
36// when Attiny84 or Attiny85 is detected
37#define CE_PIN 3 /** "Chip Enable" pin, activates the RX or TX role */
38#define CSN_PIN 3 /** SPI Chip Select Not */
39
40#else
41// when not running on an ATTiny84 or ATTiny85
42#define CE_PIN 7 /** "Chip Enable" pin, activates the RX or TX role */
43#define CSN_PIN 8 /** SPI Chip Select Not */
44
45#endif
46
47#define MAX_HIGH 100
48#define MAX_LOW 100
49#define MINIMAL 8
50
51// Use these adjustable variables to test for best configuration to be used on
52// the ATTiny chips. These variables are defined as macros in the library's
53// RF24/utility/ATTiny/RF24_arch_config.h file. To change them, simply define
54// the corresponding macro(s) before #include <RF24> in your sketch.
55uint8_t csnHighSettle = MAX_HIGH; // defined as RF24_CSN_SETTLE_HIGH_DELAY
56uint8_t csnLowSettle = MAX_LOW; // defined as RF24_CSN_SETTLE_LOW_DELAY
57
58/****************************************************************************/
59void ce(bool level) {
60 if (CE_PIN != CSN_PIN) digitalWrite(CE_PIN, level);
61}
62
63/****************************************************************************/
64void csn(bool mode) {
65 if (CE_PIN != CSN_PIN) {
66 digitalWrite(CSN_PIN, mode);
67 } else {
68 // digitalWrite(SCK, mode);
69 if (mode == HIGH) {
70 PORTB |= (1 << PINB2); // SCK->CSN HIGH
71 delayMicroseconds(csnHighSettle); // allow csn to settle
72 } else {
73 PORTB &= ~(1 << PINB2); // SCK->CSN LOW
74 delayMicroseconds(csnLowSettle); // allow csn to settle
75 }
76 }
77}
78
79/****************************************************************************/
80uint8_t read_register(uint8_t reg) {
81 csn(LOW);
82 SPI.transfer(reg);
83 uint8_t result = SPI.transfer(0xff);
84 csn(HIGH);
85 return result;
86}
87
88/****************************************************************************/
89void write_register(uint8_t reg, uint8_t value) {
90 csn(LOW);
91 SPI.transfer(W_REGISTER | reg);
92 SPI.transfer(value);
93 csn(HIGH);
94}
95
96/****************************************************************************/
97void setup(void) {
98
99#ifndef __AVR_ATtinyX313__
100 // not enough memory on ATTiny4313 or ATTint2313(a) to use Serial I/O for this sketch
101
102 // start serial port and SPI
103 Serial.begin(115200);
104 SPI.begin();
105 // configure CE and CSN as output when used
106 pinMode(CE_PIN, OUTPUT);
107 if (CSN_PIN != CE_PIN)
108 pinMode(CSN_PIN, OUTPUT);
109
110 // csn is used in SPI transfers. Set to LOW at start and HIGH after transfer. Set to HIGH to reflect no transfer active
111 // SPI command are accepted in Power Down state.
112 // CE pin represent PRX (LOW) or PTX (HIGH) mode apart from register settings. Start in PRX mode.
113 ce(LOW);
114 csn(HIGH);
115
116 // nRF24L01 goes from to Power Down state 100ms after Power on Reset ( Vdd > 1.9V) or when PWR_UP is 0 in config register
117 // Goto Power Down state (Powerup or force) and set in transmit mode
118 write_register(NRF_CONFIG, read_register(NRF_CONFIG) & ~_BV(PWR_UP) & ~_BV(PRIM_RX));
119 delay(100);
120
121 // Goto Standby-I
122 // Technically we require 4.5ms Tpd2stby+ 14us as a worst case. We'll just call it 5ms for good measure.
123 // WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
124 write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PWR_UP));
125 delay(5);
126
127 // Goto Standby-II
128 ce(HIGH);
129 Serial.print("Scanning for optimal setting time for csn");
130
131
132 /************************** Main program *********************************/
133
134 uint8_t result; // used to compare read/write results with read/write cmds
135 bool success = true;
136 uint8_t bottom_success;
137 bool bottom_found;
138 uint8_t value[] = { 5, 10 };
139 uint8_t limit[] = { MAX_HIGH, MAX_LOW };
140 uint8_t advice[] = { MAX_HIGH, MAX_LOW };
141
142 // check max values give correct behavior
143 for (uint8_t k = 0; k < 2; k++) {
144 bottom_found = false;
145 bottom_success = 0;
146 while (bottom_success < 255) {
147 csnHighSettle = limit[0];
148 csnLowSettle = limit[1];
149 // check current values
150 uint8_t i = 0;
151 while (i < 255 && success) {
152 for (uint8_t j = 0; j < 2; j++) {
153 write_register(EN_AA, value[j]);
154 result = read_register(EN_AA);
155 if (value[j] != result) {
156 success = false;
157 }
158 }
159 i++;
160 }
161 // process result of current values
162 if (!success) {
163 Serial.print("Settle Not OK. csnHigh=");
164 Serial.print(limit[0], DEC);
165 Serial.print(" csnLow=");
166 Serial.println(limit[1], DEC);
167 limit[k]++;
168 bottom_found = true;
169 bottom_success = 0;
170 success = true;
171 } else {
172 Serial.print("Settle OK. csnHigh=");
173 Serial.print(limit[0], DEC);
174 Serial.print(" csnLow=");
175 Serial.println(limit[1], DEC);
176 if (!bottom_found) {
177 limit[k]--;
178 if (limit[k] == MINIMAL) {
179 bottom_found = true;
180 bottom_success = 0;
181 success = true;
182 }
183 } else {
184 bottom_success++;
185 }
186 }
187 } // while (bottom_success < 255)
188 Serial.print("Settle value found for ");
189 if (k == 0) {
190 Serial.print("csnHigh: ");
191 } else {
192 Serial.print("csnLow: ");
193 }
194 Serial.println(limit[k], DEC);
195 advice[k] = limit[k] + (limit[k] / 10);
196 limit[k] = 100;
197 } // for (uint8_t k = 0; k < 2; k++)
198 Serial.print("Advised Settle times are: csnHigh=");
199 Serial.print(advice[0], DEC);
200 Serial.print(" csnLow=");
201 Serial.println(advice[1], DEC);
202
203#endif // not defined __AVR_ATtinyX313__
204}
205
206
207void loop(void) {} // this program runs only once, thus it resides in setup()