1
+ #include "esp32-hal.h"
2
+ #include "esp8266-compat.h"
3
+ #include "soc/gpio_reg.h"
4
+ #include "soc/gpio_reg.h"
5
+
6
+ #include "esp32-hal-rmt.h"
7
+ #include "driver/periph_ctrl.h"
8
+
9
+ #include "soc/rmt_struct.h"
10
+ #include "esp_intr_alloc.h"
11
+
12
+
13
+ #define MAX_CHANNELS 8
14
+ #define ABS (a ) (a>0?a:-a)
15
+
16
+
17
+ struct rmt_obj_s
18
+ {
19
+ bool allocated ;
20
+ intr_handle_t intr_handle ;
21
+ int pin ;
22
+ int channel ;
23
+ bool tx_not_rx ;
24
+ int buffers ;
25
+ };
26
+
27
+ static rmt_obj_t g_rmt_objects [MAX_CHANNELS ] = {
28
+ { false, NULL , 0 , 0 , 0 , 0 },
29
+ { false, NULL , 0 , 0 , 0 , 0 },
30
+ };
31
+
32
+ static intr_handle_t intr_handle ;
33
+
34
+ static bool periph_enabled = false;
35
+
36
+ static void _initPin (int pin , int channel );
37
+
38
+
39
+ bool rmtDeinit (rmt_obj_t * rmt )
40
+ {
41
+ if (!rmt ) {
42
+ return false;
43
+ }
44
+
45
+ // sanity check
46
+ if (rmt != & (g_rmt_objects [rmt -> channel ])) {
47
+ return false;
48
+ }
49
+
50
+ size_t from = rmt -> channel ;
51
+ size_t to = rmt -> buffers + rmt -> channel ;
52
+ size_t i ;
53
+
54
+ for (i = from ; i < to ; i ++ ) {
55
+ g_rmt_objects [i ].allocated = false;
56
+ }
57
+ return true;
58
+ g_rmt_objects [from ].channel = 0 ;
59
+ g_rmt_objects [from ].buffers = 0 ;
60
+ }
61
+
62
+ bool rmtSend (uint32_t * data , size_t size , rmt_obj_t * rmt )
63
+ {
64
+ if (!rmt ) {
65
+ return false;
66
+ }
67
+ int channel = rmt -> channel ;
68
+ RMT .apb_conf .fifo_mask = 1 ;
69
+ size_t i ;
70
+ for (i = 0 ; i < size ; i ++ ) {
71
+ RMTMEM .chan [channel ].data32 [i ].val = data [i ];
72
+ }
73
+
74
+ RMT .conf_ch [channel ].conf1 .mem_rd_rst = 1 ;
75
+
76
+ RMT .conf_ch [channel ].conf1 .tx_start = 1 ;
77
+
78
+ return true;
79
+ }
80
+
81
+ rmt_obj_t * _rmtAllocate (int pin , int from , int size )
82
+ {
83
+ size_t i ;
84
+ // setup how many buffers shall we use
85
+ g_rmt_objects [from ].buffers = size ;
86
+
87
+ for (i = 0 ; i < size ; i ++ ) {
88
+ // mark the block of channels as used
89
+ g_rmt_objects [i + from ].allocated = true;
90
+ }
91
+ return & (g_rmt_objects [from ]);
92
+ }
93
+
94
+
95
+ float rmtSetTick (rmt_obj_t * rmt , float tick )
96
+ {
97
+ if (!rmt ) {
98
+ return false;
99
+ }
100
+
101
+ int apb_div = 0xFF & (int )(tick /12.5 );
102
+ int ref_div = 0xFF & (int )(tick /1000 );
103
+
104
+ float apb_tick = 12.5 * apb_div ;
105
+ float ref_tick = 1000.0 * ref_div ;
106
+
107
+ size_t channel = rmt -> channel ;
108
+ if (ABS (apb_tick - tick ) < ABS (ref_tick - tick )) {
109
+ RMT .conf_ch [channel ].conf0 .div_cnt = apb_div ;
110
+ RMT .conf_ch [channel ].conf1 .ref_always_on = 1 ;
111
+ return apb_tick ;
112
+ } else {
113
+ RMT .conf_ch [channel ].conf0 .div_cnt = ref_div ;
114
+ RMT .conf_ch [channel ].conf1 .ref_always_on = 0 ;
115
+ return ref_tick ;
116
+ }
117
+ }
118
+
119
+ rmt_obj_t * rmtInit (int pin , bool tx_not_rx , int entries , int period )
120
+ {
121
+ int buffers = 1 + entries /64 ;
122
+ rmt_obj_t * rmt ;
123
+ size_t i ;
124
+ size_t j ;
125
+ for (i = 0 ; i < MAX_CHANNELS ; i ++ ) {
126
+ for (j = 0 ; j < buffers && i + j < MAX_CHANNELS ; j ++ ) {
127
+ // if the space is ocupied break and continue on other channel
128
+ if (g_rmt_objects [i + j ].allocated ) {
129
+ i += j ; // continue searching from latter channel
130
+ break ;
131
+ }
132
+ }
133
+ if (j == buffers ) {
134
+ // found a space in channel descriptors
135
+ break ;
136
+ }
137
+ }
138
+ if (i == MAX_CHANNELS ) {
139
+ return NULL ;
140
+ }
141
+ rmt = _rmtAllocate (pin , i , buffers );
142
+
143
+ size_t channel = i ;
144
+ rmt -> pin = pin ;
145
+ rmt -> tx_not_rx = tx_not_rx ;
146
+ rmt -> buffers = buffers ;
147
+ rmt -> channel = channel ;
148
+ _initPin (pin , channel );
149
+
150
+ // rmt tick from 1/80M -> 12.5ns (1x)
151
+ // 3.2 us (FFx 00 is more)
152
+ // rmt tick for 1 MHz -> 1us (1x)
153
+ // 256us (00x)
154
+
155
+ // default config (period of 1us)
156
+ RMT .conf_ch [channel ].conf0 .div_cnt = 1 ;
157
+ RMT .conf_ch [channel ].conf0 .mem_size = buffers ;
158
+ RMT .conf_ch [channel ].conf0 .carrier_en = 0 ;
159
+ RMT .conf_ch [channel ].conf0 .carrier_out_lv = 0 ;
160
+ RMT .conf_ch [channel ].conf0 .mem_pd = 0 ;
161
+
162
+ RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
163
+ RMT .conf_ch [channel ].conf1 .tx_conti_mode = 0 ;
164
+ RMT .conf_ch [channel ].conf1 .ref_cnt_rst = 0 ;
165
+ RMT .conf_ch [channel ].conf1 .rx_filter_en = 0 ;
166
+ RMT .conf_ch [channel ].conf1 .rx_filter_thres = 0 ;
167
+ RMT .conf_ch [channel ].conf1 .idle_out_lv = 0 ; // signal level for idle
168
+ RMT .conf_ch [channel ].conf1 .idle_out_en = 1 ; // enable idle
169
+ RMT .conf_ch [channel ].conf1 .ref_always_on = 0 ; // base clock
170
+
171
+ if (tx_not_rx ) {
172
+ RMT .conf_ch [channel ].conf1 .rx_en = 0 ;
173
+ RMT .conf_ch [channel ].conf1 .mem_owner = 0 ;
174
+ } else {
175
+ RMT .conf_ch [channel ].conf1 .rx_en = 1 ;
176
+ RMT .conf_ch [channel ].conf1 .mem_owner = 1 ;
177
+ }
178
+ // RMT.conf_ch[channel].conf0.val = ((uint32_t*)config)[0];
179
+ // RMT.conf_ch[channel].conf1.val = ((uint32_t*)config)[1];
180
+
181
+ return rmt ;
182
+ }
183
+
184
+
185
+
186
+ static void _initPin (int pin , int channel )
187
+ // rmt_driver_config_t* config)
188
+ {
189
+ if (!periph_enabled ) {
190
+ periph_enabled = true;
191
+ periph_module_enable ( PERIPH_RMT_MODULE );
192
+ }
193
+ pinMode (pin , OUTPUT );
194
+ pinMatrixOutAttach (pin , RMT_SIG_OUT0_IDX + channel , 0 , 0 );
195
+
196
+ // memcpy( (uint8_t*)&RMT.conf_ch[channel].conf0.val, (uint8_t*)config, 8);
197
+ // memcpy( (uint8_t*)&RMT.conf_ch[channel].conf1.val, ((uint8_t*)config) + 4, sizeof(uint32_t));
198
+ }
199
+
200
+ void initMemory (int offset , uint32_t * data , size_t size )
201
+ {
202
+ RMT .apb_conf .fifo_mask = 1 ;
203
+ size_t i ;
204
+ // uint16_t * ptr = (uint16_t*)&(RMTMEM.chan[offset].data16[0]);
205
+ // uint16_t * ptr = (uint16_t*)(0x3ff56800);
206
+ // // uint16_t ptr[32];
207
+ // memset(ptr, 0, 32);
208
+ // for (i = 0; i < size; i++) {
209
+ // printf(">> %x\n", ptr[i]);
210
+ // }
211
+
212
+ for (i = 0 ; i < size ; i ++ ) {
213
+ RMTMEM .chan [offset ].data32 [i ].val = data [i ];
214
+ // printf(">> %x\n", data[i]);
215
+ // RMTMEM.chan[offset].data16[i]
216
+ // RMTMEM.chan[offset].data32[i].val = data[i];
217
+ // printf(" %x\n", RMTMEM.chan[offset].data16[i].val);
218
+ // RMTMEM.chan[offset].data16[i] = data[i];
219
+ // *ptr++ = i;
220
+ // ptr[i] = i;
221
+ // RMTMEM.chan[i].data1 = 0x11+ i;
222
+ // RMTMEM.chan[i].data2 = 0x22+ i;
223
+
224
+ // printf(" %x\n", RMTMEM.chan[offset].data16[i].val);
225
+ // printf(" %x\n", RMTMEM.chan[offset].data32[i/2].val);
226
+ // printf("--------\n");
227
+
228
+ // printf(" %x\n", RMTMEM.chan[offset].xx.data16[i]);
229
+ // RMTMEM.chan[offset].xx.data16[i] = data[i];
230
+ // printf(" %x\n", RMTMEM.chan[offset].xx.data16[i]);
231
+ // printf(" %x\n", RMTMEM.chan[offset].xx.data32[i/2]);
232
+ // printf("--------\n");
233
+
234
+ }
235
+
236
+ }
237
+
238
+ // 00000000
239
+ // 00010000
240
+
241
+
242
+
243
+ void startTx (int channel )
244
+ {
245
+ // reset rd value
246
+ RMT .conf_ch [channel ].conf1 .mem_rd_rst = 1 ;
247
+
248
+ RMT .conf_ch [channel ].conf1 .tx_start = 1 ;
249
+ }
250
+
251
+ // struct rmt_struct_t {
252
+ // uart_dev_t * dev;
253
+ // #if !CONFIG_DISABLE_HAL_LOCKS
254
+ // xSemaphoreHandle lock;
255
+ // #endif
256
+ // uint8_t num;
257
+ // xQueueHandle queue;
258
+ // intr_handle_t intr_handle;
259
+ // };
260
+
261
+ static int state = 0 ;
262
+
263
+ static void IRAM_ATTR _rmt_isr (void * arg )
264
+ {
265
+ RMT .int_clr .val = 1 ;
266
+ // printf("test");
267
+ state ^= 1 ;
268
+ digitalWrite (4 , state );
269
+ }
270
+
271
+ int config ();
272
+
273
+ int setpin (int pin )
274
+ {
275
+ int channel = 0 ;
276
+ pinMode (pin , OUTPUT );
277
+ // *((uint32_t*)0x3FF49070) = 0x002A0000;
278
+ pinMatrixOutAttach (pin , RMT_SIG_OUT0_IDX + channel , 0 , 0 );
279
+ periph_module_enable ( PERIPH_RMT_MODULE );
280
+
281
+ // 0x3ff49000 : 0x3FF49000 <Hex>
282
+ // Address 0 - 3 4 - 7 8 - B C - F
283
+ // 3FF49000 FF030000 00080000 00080000 00080000
284
+ // 3FF49010 00080000 00080000 00080000 00080000
285
+ // 3FF49020 00080000 00080000 00080000 000A0000
286
+ // 3FF49030 000A0000 800A0000 000A0000 000B0000
287
+ // 3FF49040 800A0000 000B0000 800A0000 000A0000
288
+ // 3FF49050 000A0000 002B0000 002B0000 002B0000
289
+ // 3FF49060 001B0000 002B0000 002B0000 000B0000
290
+ // 3FF49070 002A0000 000A0000 000A0000 000A0000
291
+ // 3FF49080 000A0000 000B0000 000A0000 000A0000
292
+ // 3FF49090 00080000 00080000 00080000 00080000
293
+ // 3FF490A0 00080000 00080000 00080000 00080000
294
+
295
+ * ((unsigned int * )(0x3FF560F0 )) = 1 ;
296
+ // SET(RMT_DATA_REG, 0x8010020);
297
+ * ((uint32_t * )0x3ff56800 ) = 0x8FFF0FFF ;
298
+ * ((uint32_t * )0x3ff56804 ) = 0x9FFF0FFF ;
299
+ * ((uint32_t * )0x3ff56808 ) = 0 ;
300
+ * ((uint32_t * )0x3ff5680C ) = 0 ;
301
+ * ((uint32_t * )0x3ff56810 ) = 0 ;
302
+ * ((uint32_t * )0x3FF560D0 ) = 0 ;
303
+ // uint32_t test = 0x8010;
304
+ // uint32_t zero = 0;
305
+ // memcpy((uint8_t*)0x3ff56800, &test, 4);
306
+ // memcpy((uint8_t*)0x3ff56804, &zero, 4);
307
+
308
+ RMT .conf_ch [0 ].conf0 .val = 0x01000001 ;
309
+ RMT .conf_ch [0 ].conf1 .val = 0x20000 ;
310
+
311
+ esp_intr_alloc (ETS_RMT_INTR_SOURCE , (int )ESP_INTR_FLAG_IRAM , _rmt_isr , NULL , & intr_handle );
312
+ RMT .int_ena .val = 1 ;
313
+
314
+ // RMT[0].conf0 = 0x01000001;
315
+ // // SET(RMT_CHnCONF0_REG(0), 0x31000001);
316
+ // // SET(RMT_CHnCONF1_REG(0), 0x20000);
317
+ // RMT[1].conf1 = 0x20000;
318
+
319
+
320
+ // 0x311000ff
321
+ //-- 0x01000ff
322
+
323
+ // 0xa0f00
324
+ return 1 ;
325
+ }
326
+
327
+ int run ()
328
+ {
329
+ // SET(RMT_CHnCONF0_REG(0), 0x1000001);
330
+
331
+ // *((unsigned int*)(0x3FF560F0)) = 1;
332
+ // // SET(RMT_DATA_REG, 0x8010020);
333
+ // *((uint32_t*)0x3ff56800) = 0x8010;
334
+ // *((uint32_t*)0x3ff56804) = 0;
335
+
336
+ // SET(RMT_CHnCONF1_REG(0), 0x20009);
337
+
338
+ return 0 ;
339
+
340
+ }
0 commit comments