Mikrocontroller und Digitale Elektronik
›
Thread
ATxmega128a1 und RFM70 Problem.
DS
Daniel S.
(sany)
OP
15.03.2013 17:46
#3087806
Hallo,
Habe hier ein Problem, ich krieg von dem RFM70 die ChipID nicht zurück,
habe den Code ursprünglich auf den Atxmega umgebaut... aber irgendwo
steckt da wohl noch ein Fehler?
Der ATxmega128a1 läuft mit internem 32MHZ takt.. :-)
Aktuell der Code:
1 /*
2 Diese Library bassiert auf der Arduino RFM70 Library, ich habe sie lediglich so
3 angepasst, dass man sie auf einem AVR und ohne zusätzliche Libs von Arduino
4 verwenden kann.
5
6 Es sind nur die wichtigstens Funktionen implementiert!
7 Bei Fragen oder Anregungen:
8 Mein Blog: http:://projects.web4clans.com
9 Meine Email: daniel.weber@web4clans.com
10
11 */
12
13 #include "rfm70.h"
14 #include "display/Graphics.h"
15 #include "display/display_lib.h"
16 ///////////////////////////////////////////////////////////////////////////////
17 // Register initialization values and command macros //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 //************ Address definition commands
21 const uint8_t PROGMEM RFM70_cmd_adrRX0[] = { (0x20|0x0A), 0x34,0x43,0x10,0x10,0x01};
22 const uint8_t PROGMEM RFM70_cmd_adrTX[] = { (0x20|0x10), 0x34,0x43,0x10,0x10,0x01};
23 const uint8_t PROGMEM RFM70_cmd_adrRX1[] = { (0x20|0x0B), 0x35,0x43,0x10,0x10,0x02};
24
25 //************ Bank0 register initialization commands
26 const uint8_t PROGMEM RFM70_bank0Init[][2] = {
27 // address data
28 { (0x20|0x00), 0x0F }, //Disable CRC ,CRC=1byte, POWER UP, TX
29 { (0x20|0x01), 0x3F }, //Enable auto acknowledgement data pipe0-5
30 { (0x20|0x02), 0x3F }, //Enable RX Addresses pipe0-5
31 { (0x20|0x03), 0x03 }, //RX/TX address field width 5byte
32 { (0x20|0x04), 0x08 }, //x = 250 ms = 4000ms, y = 15 tries
33 { (0x20|0x05), 0x17 }, //channel = 0x17
34 { (0x20|0x06), 0x3F }, //air data rate-2M,out power 5dbm,setup LNA gain high (0dBM)
35 { (0x20|0x07), 0x07 }, //
36 { (0x20|0x08), 0x00 }, //
37 { (0x20|0x09), 0x00 }, //
38 { (0x20|0x0C), 0xc3 }, //LSB Addr pipe 2
39 { (0x20|0x0D), 0xc4 }, //LSB Addr pipe 3
40 { (0x20|0x0E), 0xc5 }, //LSB Addr pipe 4
41 { (0x20|0x0F), 0xc6 }, //LSB Addr pipe 5
42 { (0x20|0x11), 0x20 }, //Payload len pipe0
43 { (0x20|0x12), 0x20 }, //Payload len pipe0
44 { (0x20|0x13), 0x20 }, //Payload len pipe0
45 { (0x20|0x14), 0x20 }, //Payload len pipe0
46 { (0x20|0x15), 0x20 }, //Payload len pipe0
47 { (0x20|0x16), 0x20 }, //Payload len pipe0
48 { (0x20|0x17), 0x20 }, //Payload len pipe0
49 { (0x20|0x1C), 0x3F }, //Enable dynamic payload legth data pipe0-5
50 { (0x20|0x1D), 0x07 } //Enables Dynamic Payload Length,Enables Payload with ACK
51 };
52
53 //************ Bank1 register initialization commands
54 const uint8_t PROGMEM RFM70_bank1Init[][5] = {
55 // address data
56 { (0x20|0x00), 0x40, 0x4B, 0x01, 0xE2 },
57 { (0x20|0x01), 0xC0, 0x4B, 0x00, 0x00 },
58 { (0x20|0x02), 0xD0, 0xFC, 0x8C, 0x02 },
59 { (0x20|0x03), 0x99, 0x00, 0x39, 0x41 },
60 { (0x20|0x04), 0xb9, 0x9E, 0x86, 0x0B }, // b9? f9?
61 { (0x20|0x05), 0x24, 0x06, 0x7F, 0xA6 },
62 { (0x20|0x06), 0x00, 0x00, 0x00, 0x00 },
63 { (0x20|0x07), 0x00, 0x00, 0x00, 0x00 },
64 { (0x20|0x08), 0x00, 0x00, 0x00, 0x00 },
65 { (0x20|0x09), 0x00, 0x00, 0x00, 0x00 },
66 { (0x20|0x0a), 0x00, 0x00, 0x00, 0x00 },
67 { (0x20|0x0b), 0x00, 0x00, 0x00, 0x00 },
68 { (0x20|0x0C), 0x00, 0x12, 0x73, 0x00 },
69 { (0x20|0x0D), 0x36, 0xb4, 0x80, 0x00 }
70 };
71
72 //************ Bank1 register 14 initialization commands
73 const uint8_t PROGMEM RFM70_bank1R0EInit[] = {
74 // address Data...
75 (0x20|0x0E), 0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
76 };
77
78
79 //************ other commands: { <command>, <data>, ... }
80 const uint8_t PROGMEM RFM70_cmd_switch_cfg[] = { 0x50, 0x53 }; // switch Register Bank
81 const uint8_t PROGMEM RFM70_cmd_flush_rx[] = { 0xe2, 0x00 }; // flush RX FIFO
82 const uint8_t PROGMEM RFM70_cmd_flush_tx[] = { 0xe1, 0x00 }; // flush TX FIFO
83 const uint8_t PROGMEM RFM70_cmd_activate[] = { 0x50, 0x73 }; // Activation command
84 const uint8_t PROGMEM RFM70_cmd_tog1[]={ (0x20|0x04), 0xd9 | 0x06, 0x9e, 0x86, 0x0b }; //assosciated with set1[4]!
85 const uint8_t PROGMEM RFM70_cmd_tog2[]={ (0x20|0x04), 0xd9 & ~0x06, 0x9e, 0x86, 0x0b}; //assosciated with set1[4]!
86
87
88
89 void initSPI(uint8_t clk_div)
90 {
91 // set the pin direction to output
92 PORTC.DIRSET = (1<<SCK) | (1<<MOSI) | (1<<CSN); // Ausgang
93 PORTC.OUTCLR = (1<<MOSI)|(1<<SCK); // Set to Low
94
95
96 // chip select to high
97 PORTC.OUTSET = (1<<CSN);
98
99 SPIC.CTRL = SPI_PRESCALER_DIV4_gc | SPI_MODE_0_gc | SPI_MODE_1_gc| (1<<SPI_ENABLE_bp) | (1<<SPI_MASTER_bp);
100 SPIC.INTCTRL = SPI_INTLVL_OFF_gc;
101 // other to low
102
103 _delay_ms(RFM70_BEGIN_INIT_WAIT_MS);
104 initRegisters();
105 }
106
107 void initHardware(uint8_t irq)
108 {
109 // set the CE ddr to output
110 PORTC.DIRSET = (1<<CE);
111
112 //DDR_SPI |= CE;
113 // and set it to low
114 //PORT_SPI &=~CE;
115 PORTC.OUTCLR = (1<<CE);
116
117 if (irq != -1)
118 PORTC.DIR &=~ (1<<IRQ);
119
120
121 }
122
123 void initRegisters(void)
124 {
125 // init bank 0 registers
126 selectBank(0);
127
128 for (int i = 0; i < 20; i++)
129 writeRegVal(pgm_read_byte(&RFM70_bank0Init[i][0]), pgm_read_byte(&RFM70_bank0Init[i][1]));
130
131
132 // init address registers in bank 0
133 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrRX0, sizeof(RFM70_cmd_adrRX0));
134 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrRX1, sizeof(RFM70_cmd_adrRX1));
135 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrTX, sizeof(RFM70_cmd_adrTX));
136
137 // activate Feature register
138 if(!readRegVal(RFM70_REG_FEATURE))
139 writeRegPgmBuf((uint8_t *)RFM70_cmd_activate, sizeof(RFM70_cmd_activate));
140
141 // now set Registers 1D and 1C
142 writeRegVal(pgm_read_byte(&RFM70_bank0Init[22][0]), pgm_read_byte(&RFM70_bank0Init[22][1]));
143 writeRegVal(pgm_read_byte(&RFM70_bank0Init[21][0]), pgm_read_byte(&RFM70_bank0Init[21][1]));
144
145 // init bank 1 registers
146 selectBank(1);
147
148 for (int i=0; i < 14; i++)
149 writeRegPgmBuf((uint8_t *)RFM70_bank1Init[i], sizeof(RFM70_bank1Init[i]));
150
151 // set ramp curve
152 writeRegPgmBuf((uint8_t *)RFM70_bank1R0EInit, sizeof(RFM70_bank1R0EInit));
153
154
155 // do we have to toggle some bits here like in the example code?
156 writeRegPgmBuf((uint8_t *)RFM70_cmd_tog1, sizeof(RFM70_cmd_tog1));
157 writeRegPgmBuf((uint8_t *)RFM70_cmd_tog2, sizeof(RFM70_cmd_tog2));
158
159 _delay_ms(RFM70_END_INIT_WAIT_MS);
160
161 //Check the ChipID
162 if (readRegVal(0x08) != 0x63)
163 debug(RFM70_DEBUG_WRONG_CHIP_ID);
164 else
165 ScrollText("load rfm70 register successful\n", to_rgb565(255,255,255));
166
167 selectBank(0);
168 setModeRX();
169 }
170
171 void Begin(void)
172 {
173 setBegin(-1, RFM77_DEFAULT_SPI_CLOCK_DIV);
174 }
175
176
177 void setBegin(uint8_t irq, uint8_t clk_div)
178 {
179 initHardware(irq);
180 initSPI(clk_div);
181 //_delay_ms(RFM70_BEGIN_INIT_WAIT_MS);
182 //initRegisters();
183 }
184
185
186
187 uint8_t transmitSPI(uint8_t val)
188 {
189 SPIC.DATA = val;
190 while (!(SPIC.STATUS & (1<<SPI_IF_bp)))
191 ;
192 return SPIC.DATA;
193 }
194
195 void selectBank(uint8_t bank)
196 {
197 uint8_t tmp = readRegVal(0x07) & 0x80;
198 if(bank)
199 {
200 if(!tmp)
201 writeRegPgmBuf((uint8_t *)RFM70_cmd_switch_cfg, sizeof(RFM70_cmd_switch_cfg));
202 }
203 else
204 {
205 if(tmp)
206 writeRegPgmBuf((uint8_t *)RFM70_cmd_switch_cfg, sizeof(RFM70_cmd_switch_cfg));
207 }
208 }
209
210 void setMode(uint8_t mode)
211 {
212 if (mode == 1)
213 setModeRX();
214 else
215 setModeTX();
216 }
217
218
219 void setModeRX(void)
220 {
221 uint8_t val;
222
223 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Flush RX FIFO
224 val = readRegVal(RFM70_REG_STATUS); // Read Status
225 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, val); // Reset IRQ bits
226 PORT_SPI &=~ (1<<CE); // RFM chip disable
227 // set PRIM_RX bit to 1
228 val=readRegVal(RFM70_REG_CONFIG);
229 val |= RFM70_PIN_PRIM_RX;
230 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val);
231 PORT_SPI |= (1<<CE); // RFM chip enable
232 }
233
234
235 void setModeTX(void)
236 {
237 uint8_t val;
238
239 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_tx, sizeof(RFM70_cmd_flush_tx)); // Flush TX FIFO
240 PORT_SPI &=~ (1<<CE); // disable rfm70
241 // set PRIM_RX bit to 0
242 val=readRegVal(RFM70_REG_CONFIG);
243 val &= ~RFM70_PIN_PRIM_RX;
244 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val);
245 PORT_SPI |= (1<<CE); // RFM chip enable
246 }
247
248 uint8_t getMode(void)
249 {
250 return readRegVal(RFM70_REG_CONFIG) & RFM70_PIN_PRIM_RX;
251 }
252
253
254 void setChannel(uint8_t cnum)
255 {
256 writeRegVal( RFM70_CMD_WRITE_REG | RFM70_REG_RF_CH, cnum);
257 }
258
259 uint8_t getChannel(void)
260 {
261 return readRegVal(RFM70_REG_RF_CH);
262 }
263
264
265 uint8_t configRxPipe(uint8_t pipe_nr, uint8_t * adr, uint8_t plLen, uint8_t en_aa)
266 {
267
268 uint8_t tmp;
269 uint8_t nr = pipe_nr -1;
270
271 if(plLen > 32 || nr > 5 || en_aa > 1)
272 return 0;
273
274 // write address
275 if(nr<2) // full length for rx pipe 0 an 1
276 writeRegCmdBuf(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr, sizeof(adr));
277 else // only LSB for pipes 2..5
278 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr[0]); //ODO:check this
279
280 // static
281 if (plLen) {
282 // set payload len
283 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), plLen);
284 // set EN_AA bit
285 tmp = readRegVal(RFM70_REG_EN_AA);
286 if (en_aa)
287 tmp |= 1 << nr;
288 else
289 tmp &= ~(1 << nr);
290 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp);
291 // clear DPL bit
292 tmp = readRegVal(RFM70_REG_DYNPD);
293 tmp &= ~(1 << nr);
294 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
295 // set Enable pipe bit
296 enableRxPipe(nr);
297 }
298 // dynamic
299 else
300 {
301 // set payload len to default
302 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), 0x20);
303 // set EN_AA bit
304 tmp = readRegVal(RFM70_REG_EN_AA);
305 tmp |= 1 << nr;
306 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp);
307 // set DPL bit
308 tmp = readRegVal(RFM70_REG_DYNPD);
309 tmp |= 1 << nr;
310 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
311 // set Enable pipe bit
312 enableRxPipe(nr);
313 }
314 return 1;
315 }
316
317 void enableRxPipe(uint8_t pipe_nr)
318 {
319 uint8_t nr = pipe_nr - 1;
320 if (nr > 5) return;
321 uint8_t tmp;
322 // set Enable pipe bit
323 tmp = readRegVal(RFM70_REG_EN_RXADDR);
324 tmp |= 1 << nr;
325 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_RXADDR, tmp);
326 }
327
328 void disableRxPipe(uint8_t pipe_nr)
329 {
330 uint8_t nr = pipe_nr - 1;
331 if (nr > 5) return;
332 uint8_t tmp;
333 // set Enable pipe bit
334 tmp = readRegVal(RFM70_REG_EN_RXADDR);
335 tmp &= ~(1 << nr);
336 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_RXADDR, tmp);
337
338 }
339
340 void configTxPipe(uint8_t * adr, uint8_t pltype)
341 {
342 // write TX address
343 writeRegCmdBuf(RFM70_CMD_WRITE_REG | RFM70_REG_TX_ADDR, adr, sizeof(adr));
344 // write RX0 address
345 writeRegCmdBuf(RFM70_CMD_WRITE_REG | RFM70_REG_RX_ADDR_P0, adr, sizeof(adr));
346 // set static or dynamic payload
347 uint8_t tmp;
348 tmp = readRegVal(RFM70_REG_DYNPD);
349 if(pltype == TX_DPL) // dynamic
350 tmp |= 1;
351 else
352 tmp &= ~(1 << 0);
353 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
354 }
355
356 uint8_t sendPayload(uint8_t * payload, uint8_t len, uint8_t toAck) // choose 0=nAck, 1=AckRequest
357 {
358
359 // check TX_FIFO
360 uint8_t status;
361 status = readRegVal(RFM70_REG_FIFO_STATUS);
362 if (status & RFM70_FIFO_STATUS_TX_FULL)
363 {
364 debug(RFM70_DEBUG_FIFO_FULL);
365 return 0;
366 }
367
368 // send payload
369 PORTC.DIRSET &=~ (1<<CSN);
370 _delay_ms(RFM70_CS_DELAY);
371 if(toAck == -1)
372 transmitSPI(RFM70_CMD_W_ACK_PAYLOAD);
373 else if (toAck == 0)
374 transmitSPI(RFM70_CMD_W_TX_PAYLOAD_NOACK);
375 else
376 transmitSPI(RFM70_CMD_WR_TX_PLOAD);
377 while(len--)
378 {
379 transmitSPI(*(payload++));
380 //ScrollText(*payload, to_rgb565(255,255,255));
381 }
382 PORTC.OUTSET = (1<<CSN);
383 _delay_ms(RFM70_CS_DELAY);
384 //PORTA ^= (1<<PA4);
385 return 1;
386 }
387
388 uint8_t receivePayload(uint8_t *payload)
389 {
390 uint8_t len;
391 // check RX_FIFO
392 uint8_t status;
393 status = readRegVal(RFM70_REG_STATUS);
394 if (status & RFM70_IRQ_STATUS_RX_DR) { // RX_DR
395 //PORTA ^= (1<<PA4);
396 //while(1) {
397 uint8_t fifo_sta;
398 len = readRegVal(RFM70_CMD_RX_PL_WID); // Payload width
399 readRegBuf(RFM70_CMD_RD_RX_PLOAD, payload, len);
400 fifo_sta = readRegVal(RFM70_REG_FIFO_STATUS);
401 //if (fifo_sta & RFM70_FIFO_STATUS_RX_EMPTY) break; // read until RX_FIFO empty
402 //}
403
404 if (fifo_sta & RFM70_FIFO_STATUS_RX_EMPTY) {
405 status|= 0x40 & 0xCF; // clear status bit rx_dr
406 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, status);
407 }
408 return len;
409 }
410 else
411 {
412
413 return 0;
414 }
415 }
416
417
418 void flushTxFIFO()
419 {
420 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_tx, sizeof(RFM70_cmd_flush_tx)); // Flush TX FIFO
421 }
422
423 void flushRxFIFO()
424 {
425 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Flush RX FIFO
426 }
427
428
429
430
431
432 uint8_t readRegVal(uint8_t cmd)
433 {
434 uint8_t res;
435 PORTC.DIRSET &=~ (1<<CSN);
436 _delay_ms(RFM70_CS_DELAY);
437
438 transmitSPI(cmd);
439
440 res=transmitSPI(0);
441 PORTC.OUTSET = (1<<CSN);
442 _delay_ms(RFM70_CS_DELAY);
443 return res;
444 }
445
446 uint8_t writeRegVal(uint8_t cmd, uint8_t val)
447 {
448 PORTC.DIRSET &=~ (1<<CSN);
449 _delay_ms(RFM70_CS_DELAY);
450 transmitSPI(cmd);
451 transmitSPI(val);
452 PORTC.OUTSET = (1<<CSN);
453 _delay_ms(RFM70_CS_DELAY);
454 return 1;
455 }
456
457 void readRegBuf(uint8_t reg, uint8_t * buf, uint8_t len)
458 {
459 uint8_t status, byte_ctr;
460 PORTC.DIRSET &=~ (1<<CSN);
461 _delay_ms(RFM70_CS_DELAY);
462 status = transmitSPI(reg); // Select register to write, and read status UINT8
463 for(byte_ctr = 0; byte_ctr < len; byte_ctr++)
464 buf[byte_ctr] = transmitSPI(0); // Perform SPI_RW to read UINT8 from RFM70
465 PORTC.OUTSET = (1<<CSN);
466 _delay_ms(RFM70_CS_DELAY);
467 }
468
469
470
471 uint8_t writeRegPgmBuf(uint8_t * cmdbuf, uint8_t len)
472 {
473 PORTC.DIRSET &=~ (1<<CSN);
474 _delay_ms(RFM70_CS_DELAY);
475 while(len--) {
476 transmitSPI(pgm_read_byte(cmdbuf++));
477 }
478 PORTC.OUTSET = (1<<CSN);
479 _delay_ms(RFM70_CS_DELAY);
480 return 1;
481 }
482
483 uint8_t writeRegCmdBuf(uint8_t cmd, uint8_t * buf, uint8_t len)
484 {
485 PORTC.DIRSET &=~ (1<<CSN);
486 _delay_ms(RFM70_CS_DELAY);
487 transmitSPI(cmd);
488 while(len--)
489 {
490 transmitSPI(*(buf++));
491 }
492 PORTC.OUTSET = (1<<CSN);
493 _delay_ms(RFM70_CS_DELAY);
494 return 1;
495 }
496
497 void configRfPower(uint8_t pwr)
498 {
499 if (pwr > 3) return;
500 uint8_t tmp = readRegVal(RFM70_REG_RF_SETUP);
501 tmp &= 0xF9;
502 tmp |= pwr << 1;
503 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_RF_SETUP, tmp);
504 }
505
506
507
508
509 void debug(uint8_t token)
510 {
511 switch(token)
512 {
513 case 0x01:
514 ScrollText("rfm error: the reseive chip id is invalid!\n", to_rgb565(255,255,255));
515 break;
516
517 case 0x02:
518 ScrollText("rfm error: the fifo is full!\n", to_rgb565(255,255,255));
519 break;
520 }
521 }
522
523 void spiSetClockDivider(uint8_t rate)
524 {
525 //SPIC.CTRL = (SPIC.CTRL & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
526 //SPIC.STATUS = (SPIC.STATUS & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
527 }
in diesem Falle kriege ich leider nur chip id is invalid..
Wäre um hilfe dankbar :-)
Grüße,
daniel
Also ich arbeite mit dem RFM70 und NRF24L01 mit folgendem mode:
SPIC.CTRL = (1<<SPI_MASTER_bp) | (1<<SPI_ENABLE_bp) |
(1<<SPI_PRESCALER1_bp);
Also nicht MODE[1:0] = 11
DS
Daniel S.
(sany)
OP
15.03.2013 18:23
#3087881
Hallo,
Also auch mit deinem SPI Init, bleibt die Chip ID falsch :/
Gruß,
Daniel
Falsch heisst du liest zumindest etwas aus was !=0xFF oder so ist?
Achja und was soll das hier: ( PORTC.DIRSET &=~ (1<<CSN);)
Damit setzt du natürlich alle PORT-Pins außer CSN auf Output. Du setzt
ihn aber nie den CSN wieder auf output. Das kann so also nicht gehen.
Ich mache das immer so:
#define CSN_ON() PORTC.OUTCLR = (1<<PIN4)
#define CSN_OFF() PORTC.OUTSET = (1<<PIN4)
Wobei der CSN natürlich Output bleibt, aber du setzt ihn nicht wie
eigentlich gewollt auf low.
DS
Daniel S.
(sany)
OP
16.03.2013 21:07
#3089388
Hallo,
Sorry war mein Fehler, hatte das bereits umprogrammiert ;-)
Nun aber der aktuelle Sourcecode, aktuell funktioniert die
Initialisierung per SPI und die ChipID ist auch korrekt... nun habe ich
das Problem das er mir keine Daten empfängt, kann das am Interupt evtl.
liegen?
Die Ports nach der Initialisierung habe ich als Screenshot beigefügt.
Hier der aktuelle Code, bei dem die Initialisierung durchläuft und mir
die ChipID zurück gibt:
1 #include "rfm70.h"
2 #include "display/Graphics.h"
3 #include "display/display_lib.h"
4 ///////////////////////////////////////////////////////////////////////////////
5 // Register initialization values and command macros //
6 ///////////////////////////////////////////////////////////////////////////////
7
8 //************ Address definition commands
9 const uint8_t PROGMEM RFM70_cmd_adrRX0[] = { (0x20|0x0A), 0x34,0x43,0x10,0x10,0x01};
10 const uint8_t PROGMEM RFM70_cmd_adrTX[] = { (0x20|0x10), 0x34,0x43,0x10,0x10,0x01};
11 const uint8_t PROGMEM RFM70_cmd_adrRX1[] = { (0x20|0x0B), 0x35,0x43,0x10,0x10,0x02};
12
13 //************ Bank0 register initialization commands
14 const uint8_t PROGMEM RFM70_bank0Init[][2] = {
15 // address data
16 { (0x20|0x00), 0x0F }, //Disable CRC ,CRC=1byte, POWER UP, TX
17 { (0x20|0x01), 0x3F }, //Enable auto acknowledgement data pipe0-5
18 { (0x20|0x02), 0x3F }, //Enable RX Addresses pipe0-5
19 { (0x20|0x03), 0x03 }, //RX/TX address field width 5byte
20 { (0x20|0x04), 0x08 }, //x = 250 ms = 4000ms, y = 15 tries
21 { (0x20|0x05), 0x17 }, //channel = 0x17
22 { (0x20|0x06), 0x3F }, //air data rate-2M,out power 5dbm,setup LNA gain high (0dBM)
23 { (0x20|0x07), 0x07 }, //
24 { (0x20|0x08), 0x00 }, //
25 { (0x20|0x09), 0x00 }, //
26 { (0x20|0x0C), 0xc3 }, //LSB Addr pipe 2
27 { (0x20|0x0D), 0xc4 }, //LSB Addr pipe 3
28 { (0x20|0x0E), 0xc5 }, //LSB Addr pipe 4
29 { (0x20|0x0F), 0xc6 }, //LSB Addr pipe 5
30 { (0x20|0x11), 0x20 }, //Payload len pipe0
31 { (0x20|0x12), 0x20 }, //Payload len pipe0
32 { (0x20|0x13), 0x20 }, //Payload len pipe0
33 { (0x20|0x14), 0x20 }, //Payload len pipe0
34 { (0x20|0x15), 0x20 }, //Payload len pipe0
35 { (0x20|0x16), 0x20 }, //Payload len pipe0
36 { (0x20|0x17), 0x20 }, //Payload len pipe0
37 { (0x20|0x1C), 0x3F }, //Enable dynamic payload legth data pipe0-5
38 { (0x20|0x1D), 0x07 } //Enables Dynamic Payload Length,Enables Payload with ACK
39 };
40
41 //************ Bank1 register initialization commands
42 const uint8_t PROGMEM RFM70_bank1Init[][5] = {
43 // address data
44 { (0x20|0x00), 0x40, 0x4B, 0x01, 0xE2 },
45 { (0x20|0x01), 0xC0, 0x4B, 0x00, 0x00 },
46 { (0x20|0x02), 0xD0, 0xFC, 0x8C, 0x02 },
47 { (0x20|0x03), 0x99, 0x00, 0x39, 0x41 },
48 { (0x20|0x04), 0xb9, 0x9E, 0x86, 0x0B }, // b9? f9?
49 { (0x20|0x05), 0x24, 0x06, 0x7F, 0xA6 },
50 { (0x20|0x06), 0x00, 0x00, 0x00, 0x00 },
51 { (0x20|0x07), 0x00, 0x00, 0x00, 0x00 },
52 { (0x20|0x08), 0x00, 0x00, 0x00, 0x00 },
53 { (0x20|0x09), 0x00, 0x00, 0x00, 0x00 },
54 { (0x20|0x0a), 0x00, 0x00, 0x00, 0x00 },
55 { (0x20|0x0b), 0x00, 0x00, 0x00, 0x00 },
56 { (0x20|0x0C), 0x00, 0x12, 0x73, 0x00 },
57 { (0x20|0x0D), 0x36, 0xb4, 0x80, 0x00 }
58 };
59
60 //************ Bank1 register 14 initialization commands
61 const uint8_t PROGMEM RFM70_bank1R0EInit[] = {
62 // address Data...
63 (0x20|0x0E), 0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
64 };
65
66
67 //************ other commands: { <command>, <data>, ... }
68 const uint8_t PROGMEM RFM70_cmd_switch_cfg[] = { 0x50, 0x53 }; // switch Register Bank
69 const uint8_t PROGMEM RFM70_cmd_flush_rx[] = { 0xe2, 0x00 }; // flush RX FIFO
70 const uint8_t PROGMEM RFM70_cmd_flush_tx[] = { 0xe1, 0x00 }; // flush TX FIFO
71 const uint8_t PROGMEM RFM70_cmd_activate[] = { 0x50, 0x73 }; // Activation command
72 const uint8_t PROGMEM RFM70_cmd_tog1[]={ (0x20|0x04), 0xd9 | 0x06, 0x9e, 0x86, 0x0b }; //assosciated with set1[4]!
73 const uint8_t PROGMEM RFM70_cmd_tog2[]={ (0x20|0x04), 0xd9 & ~0x06, 0x9e, 0x86, 0x0b}; //assosciated with set1[4]!
74
75 #define CSN_OFF() PORTC.OUTCLR = (1<<PIN4)
76 #define CSN_ON() PORTC.OUTSET = (1<<PIN4)
77
78 void initSPI(uint8_t clk_div)
79 {
80 // set the pin direction to output
81
82 PORTC.DIR = (1<<SCK) | (1<<MOSI) | (1<<CSN); // Ausgang
83 PORTC.OUTCLR = (1<<MOSI)|(1<<SCK); // Set to Low
84
85
86 // chip select to high
87 CSN_ON();
88
89 SPIC.CTRL = (1<<SPI_ENABLE_bp) | (1<<SPI_MASTER_bp) | (1<< SPI_CLK2X_bp) | (1<<SPI_PRESCALER1_bp);
90 SPIC.INTCTRL = SPI_INTLVL_OFF_gc;
91 SPIC.STATUS = 0;
92
93 // other to low
94
95 _delay_ms(RFM70_BEGIN_INIT_WAIT_MS);
96 initRegisters();
97 }
98
99 void initHardware(uint8_t irq)
100 {
101 // set the CE ddr to output
102 PORTC.DIRSET = (1<<CE);
103
104 //DDR_SPI |= CE;
105 // and set it to low
106 //PORT_SPI &=~CE;
107 PORTC.OUTCLR = (1<<CE);
108
109 if (irq != -1)
110 PORTC.OUTCLR &=~ (1<<IRQ);
111
112
113 }
114
115 void initRegisters(void)
116 {
117 // init bank 0 registers
118 selectBank(0);
119
120 for (int i = 0; i < 20; i++)
121 writeRegVal(pgm_read_byte(&RFM70_bank0Init[i][0]), pgm_read_byte(&RFM70_bank0Init[i][1]));
122
123
124 // init address registers in bank 0
125 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrRX0, sizeof(RFM70_cmd_adrRX0));
126 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrRX1, sizeof(RFM70_cmd_adrRX1));
127 writeRegPgmBuf((uint8_t *)RFM70_cmd_adrTX, sizeof(RFM70_cmd_adrTX));
128
129 // activate Feature register
130 if(!readRegVal(RFM70_REG_FEATURE))
131 writeRegPgmBuf((uint8_t *)RFM70_cmd_activate, sizeof(RFM70_cmd_activate));
132
133 // now set Registers 1D and 1C
134 writeRegVal(pgm_read_byte(&RFM70_bank0Init[22][0]), pgm_read_byte(&RFM70_bank0Init[22][1]));
135 writeRegVal(pgm_read_byte(&RFM70_bank0Init[21][0]), pgm_read_byte(&RFM70_bank0Init[21][1]));
136
137 // init bank 1 registers
138 selectBank(1);
139
140 for (int i=0; i < 14; i++)
141 writeRegPgmBuf((uint8_t *)RFM70_bank1Init[i], sizeof(RFM70_bank1Init[i]));
142
143 // set ramp curve
144 writeRegPgmBuf((uint8_t *)RFM70_bank1R0EInit, sizeof(RFM70_bank1R0EInit));
145
146
147 // do we have to toggle some bits here like in the example code?
148 writeRegPgmBuf((uint8_t *)RFM70_cmd_tog1, sizeof(RFM70_cmd_tog1));
149 writeRegPgmBuf((uint8_t *)RFM70_cmd_tog2, sizeof(RFM70_cmd_tog2));
150
151 _delay_ms(RFM70_END_INIT_WAIT_MS);
152
153 //Check the ChipID
154 if (readRegVal(0x08) != 0x63)
155 debug(RFM70_DEBUG_WRONG_CHIP_ID);
156 else
157 ScrollText("load rfm70 register successful\n", to_rgb565(255,255,255));
158
159 selectBank(0);
160 setModeRX();
161 }
162
163 void Begin(void)
164 {
165 setBegin(-1, RFM77_DEFAULT_SPI_CLOCK_DIV);
166 }
167
168
169 void setBegin(uint8_t irq, uint8_t clk_div)
170 {
171 initHardware(irq);
172 initSPI(clk_div);
173 //_delay_ms(RFM70_BEGIN_INIT_WAIT_MS);
174 //initRegisters();
175 }
176
177
178
179 uint8_t transmitSPI(uint8_t val)
180 {
181 SPIC.DATA = val;
182 while (!(SPIC.STATUS & (1<<SPI_IF_bp)))
183 ;
184 return SPIC.DATA;
185 }
186
187 void selectBank(uint8_t bank)
188 {
189 uint8_t tmp = readRegVal(0x07) & 0x80;
190 if(bank)
191 {
192 if(!tmp)
193 writeRegPgmBuf((uint8_t *)RFM70_cmd_switch_cfg, sizeof(RFM70_cmd_switch_cfg));
194 }
195 else
196 {
197 if(tmp)
198 writeRegPgmBuf((uint8_t *)RFM70_cmd_switch_cfg, sizeof(RFM70_cmd_switch_cfg));
199 }
200 }
201
202 void setMode(uint8_t mode)
203 {
204 if (mode == 1)
205 setModeRX();
206 else
207 setModeTX();
208 }
209
210
211 void setModeRX(void)
212 {
213 uint8_t val;
214
215 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Flush RX FIFO
216 val = readRegVal(RFM70_REG_STATUS); // Read Status
217 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, val); // Reset IRQ bits
218 PORTC.OUTCLR &=~ (1<<CE); // RFM chip disable
219 // set PRIM_RX bit to 1
220 val=readRegVal(RFM70_REG_CONFIG);
221 val |= RFM70_PIN_PRIM_RX;
222 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val);
223 PORTC.OUTSET |= (1<<CE); // RFM chip enable
224 }
225
226
227 void setModeTX(void)
228 {
229 uint8_t val;
230
231 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_tx, sizeof(RFM70_cmd_flush_tx)); // Flush TX FIFO
232 PORTC.OUTCLR &=~ (1<<CE); // disable rfm70
233 // set PRIM_RX bit to 0
234 val=readRegVal(RFM70_REG_CONFIG);
235 val &= ~RFM70_PIN_PRIM_RX;
236 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val);
237 PORTC.OUTSET |= (1<<CE); // RFM chip enable
238 }
239
240 uint8_t getMode(void)
241 {
242 return readRegVal(RFM70_REG_CONFIG) & RFM70_PIN_PRIM_RX;
243 }
244
245
246 void setChannel(uint8_t cnum)
247 {
248 writeRegVal( RFM70_CMD_WRITE_REG | RFM70_REG_RF_CH, cnum);
249 }
250
251 uint8_t getChannel(void)
252 {
253 return readRegVal(RFM70_REG_RF_CH);
254 }
255
256
257 uint8_t configRxPipe(uint8_t pipe_nr, uint8_t * adr, uint8_t plLen, uint8_t en_aa)
258 {
259
260 uint8_t tmp;
261 uint8_t nr = pipe_nr -1;
262
263 if(plLen > 32 || nr > 5 || en_aa > 1)
264 return 0;
265
266 // write address
267 if(nr<2) // full length for rx pipe 0 an 1
268 writeRegCmdBuf(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr, sizeof(adr));
269 else // only LSB for pipes 2..5
270 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr[0]); //ODO:check this
271
272 // static
273 if (plLen) {
274 // set payload len
275 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), plLen);
276 // set EN_AA bit
277 tmp = readRegVal(RFM70_REG_EN_AA);
278 if (en_aa)
279 tmp |= 1 << nr;
280 else
281 tmp &= ~(1 << nr);
282 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp);
283 // clear DPL bit
284 tmp = readRegVal(RFM70_REG_DYNPD);
285 tmp &= ~(1 << nr);
286 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
287 // set Enable pipe bit
288 enableRxPipe(nr);
289 }
290 // dynamic
291 else
292 {
293 // set payload len to default
294 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), 0x20);
295 // set EN_AA bit
296 tmp = readRegVal(RFM70_REG_EN_AA);
297 tmp |= 1 << nr;
298 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp);
299 // set DPL bit
300 tmp = readRegVal(RFM70_REG_DYNPD);
301 tmp |= 1 << nr;
302 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
303 // set Enable pipe bit
304 enableRxPipe(nr);
305 }
306 return 1;
307 }
308
309 void enableRxPipe(uint8_t pipe_nr)
310 {
311 uint8_t nr = pipe_nr - 1;
312 if (nr > 5) return;
313 uint8_t tmp;
314 // set Enable pipe bit
315 tmp = readRegVal(RFM70_REG_EN_RXADDR);
316 tmp |= 1 << nr;
317 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_RXADDR, tmp);
318 }
319
320 void disableRxPipe(uint8_t pipe_nr)
321 {
322 uint8_t nr = pipe_nr - 1;
323 if (nr > 5) return;
324 uint8_t tmp;
325 // set Enable pipe bit
326 tmp = readRegVal(RFM70_REG_EN_RXADDR);
327 tmp &= ~(1 << nr);
328 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_RXADDR, tmp);
329
330 }
331
332 void configTxPipe(uint8_t * adr, uint8_t pltype)
333 {
334 // write TX address
335 writeRegCmdBuf(RFM70_CMD_WRITE_REG | RFM70_REG_TX_ADDR, adr, sizeof(adr));
336 // write RX0 address
337 writeRegCmdBuf(RFM70_CMD_WRITE_REG | RFM70_REG_RX_ADDR_P0, adr, sizeof(adr));
338 // set static or dynamic payload
339 uint8_t tmp;
340 tmp = readRegVal(RFM70_REG_DYNPD);
341 if(pltype == TX_DPL) // dynamic
342 tmp |= 1;
343 else
344 tmp &= ~(1 << 0);
345 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp);
346 }
347
348 uint8_t sendPayload(uint8_t * payload, uint8_t len, uint8_t toAck) // choose 0=nAck, 1=AckRequest
349 {
350
351 // check TX_FIFO
352 uint8_t status;
353 status = readRegVal(RFM70_REG_FIFO_STATUS);
354 if (status & RFM70_FIFO_STATUS_TX_FULL)
355 {
356 debug(RFM70_DEBUG_FIFO_FULL);
357 return 0;
358 }
359
360 // send payload
361 CSN_OFF();
362 _delay_ms(RFM70_CS_DELAY);
363 if(toAck == -1)
364 transmitSPI(RFM70_CMD_W_ACK_PAYLOAD);
365 else if (toAck == 0)
366 transmitSPI(RFM70_CMD_W_TX_PAYLOAD_NOACK);
367 else
368 transmitSPI(RFM70_CMD_WR_TX_PLOAD);
369 while(len--)
370 {
371 transmitSPI(*(payload++));
372 //ScrollText(*payload, to_rgb565(255,255,255));
373 }
374 CSN_ON();
375 _delay_ms(RFM70_CS_DELAY);
376 //PORTA ^= (1<<PA4);
377 return 1;
378 }
379
380 uint8_t receivePayload(uint8_t *payload)
381 {
382 uint8_t len;
383 // check RX_FIFO
384 uint8_t status;
385 status = readRegVal(RFM70_REG_STATUS);
386 if (status & RFM70_IRQ_STATUS_RX_DR) { // RX_DR
387 //PORTA ^= (1<<PA4);
388 //while(1) {
389 uint8_t fifo_sta;
390 len = readRegVal(RFM70_CMD_RX_PL_WID); // Payload width
391 readRegBuf(RFM70_CMD_RD_RX_PLOAD, payload, len);
392 fifo_sta = readRegVal(RFM70_REG_FIFO_STATUS);
393 //if (fifo_sta & RFM70_FIFO_STATUS_RX_EMPTY) break; // read until RX_FIFO empty
394 //}
395
396 if (fifo_sta & RFM70_FIFO_STATUS_RX_EMPTY) {
397 status|= 0x40 & 0xCF; // clear status bit rx_dr
398 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, status);
399 }
400 return len;
401 }
402 else
403 {
404
405 return 0;
406 }
407 }
408
409
410 void flushTxFIFO()
411 {
412 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_tx, sizeof(RFM70_cmd_flush_tx)); // Flush TX FIFO
413 }
414
415 void flushRxFIFO()
416 {
417 writeRegPgmBuf((uint8_t *)RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Flush RX FIFO
418 }
419
420
421
422
423
424 uint8_t readRegVal(uint8_t cmd)
425 {
426 uint8_t res;
427 CSN_OFF();
428 _delay_ms(RFM70_CS_DELAY);
429
430 transmitSPI(cmd);
431
432 res=transmitSPI(0);
433 CSN_ON();
434 _delay_ms(RFM70_CS_DELAY);
435 return res;
436 }
437
438 uint8_t writeRegVal(uint8_t cmd, uint8_t val)
439 {
440 CSN_OFF();
441 _delay_ms(RFM70_CS_DELAY);
442 transmitSPI(cmd);
443 transmitSPI(val);
444 CSN_ON();
445 _delay_ms(RFM70_CS_DELAY);
446 return 1;
447 }
448
449 void readRegBuf(uint8_t reg, uint8_t * buf, uint8_t len)
450 {
451 uint8_t status, byte_ctr;
452 CSN_OFF();
453 _delay_ms(RFM70_CS_DELAY);
454 status = transmitSPI(reg); // Select register to write, and read status UINT8
455 for(byte_ctr = 0; byte_ctr < len; byte_ctr++)
456 buf[byte_ctr] = transmitSPI(0); // Perform SPI_RW to read UINT8 from RFM70
457 CSN_ON();
458 _delay_ms(RFM70_CS_DELAY);
459 }
460
461
462
463 uint8_t writeRegPgmBuf(uint8_t * cmdbuf, uint8_t len)
464 {
465 CSN_OFF();
466 _delay_ms(RFM70_CS_DELAY);
467 while(len--) {
468 transmitSPI(pgm_read_byte(cmdbuf++));
469 }
470 CSN_ON();
471 _delay_ms(RFM70_CS_DELAY);
472 return 1;
473 }
474
475 uint8_t writeRegCmdBuf(uint8_t cmd, uint8_t * buf, uint8_t len)
476 {
477 CSN_OFF();
478 _delay_ms(RFM70_CS_DELAY);
479 transmitSPI(cmd);
480 while(len--)
481 {
482 transmitSPI(*(buf++));
483 }
484 CSN_ON();
485 _delay_ms(RFM70_CS_DELAY);
486 return 1;
487 }
488
489 void configRfPower(uint8_t pwr)
490 {
491 if (pwr > 3) return;
492 uint8_t tmp = readRegVal(RFM70_REG_RF_SETUP);
493 tmp &= 0xF9;
494 tmp |= pwr << 1;
495 writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_RF_SETUP, tmp);
496 }
497
498
499
500
501 void debug(uint8_t token)
502 {
503 switch(token)
504 {
505 case 0x01:
506 ScrollText("rfm error: the reseive chip id is invalid!\n", to_rgb565(255,255,255));
507 break;
508
509 case 0x02:
510 ScrollText("rfm error: the fifo is full!\n", to_rgb565(255,255,255));
511 break;
512 }
513 }
514
515 void spiSetClockDivider(uint8_t rate)
516 {
517 //SPIC.CTRL = (SPIC.CTRL & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK);
518 //SPIC.STATUS = (SPIC.STATUS & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK);
519 }
>PORTC.OUTCLR &=~ (1<<CE)
Schau dir nochmal das Datenblatt des xmegas an. Da passiert nicht das
was du glaubst
DS
Daniel S.
(sany)
OP
17.03.2013 03:43
#3089694
Hallo Timmo,
Danke ;-)
Hab das Problem nun gelöst, da war wohl ein Pin nicht ganz auf Output
gestellt :-)
Grüße,
Daniel
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren