@Sternthaler:
Das mit dem TWI Stop hab ich so implementiert:
Code:
385 void
386 i2c::wait_for_twi_stopped() const
387 {
388 // make sure stop was already sent
389 while(TWCR & (1<<TWSTO));
390 }
Die sende/lese Routine stellt sicher, dass der Bus frei ist wenn ich was machen will.
Code:
449 void
450 i2c::write_to_slave(unsigned char address, const char* data, unsigned char len)
451 {
452 // when the I2C is busy, we need to wait
453 while (is_busy()) _delay_ms(1);
454
455 // make sure stop was already sent
456 wait_for_twi_stopped();
457
458 // set the mode and prevent others from interfering with the registers
459 // the irq routine will clear it again to idle
460 m_mode = master_transmit;
Code:
475 void
476 i2c::read_from_slave(unsigned char address, const char* data, unsigned char tx_len, unsigned char rx_len)
477 {
478 // when the I2C is busy, we need to wait
479 while (is_busy()) _delay_ms(1);
480
481 // make sure stop was already sent
482 wait_for_twi_stopped();
483
484 // set the mode and prevent others from interfering with the registers
485 // the irq routine will clear it again to idle
486 m_mode = master_receive;
is_budy ist nur eine Abfrage auf meie interne I2C Statemachine
Code:
529 bool
530 i2c::is_busy() const
531 {
532 return m_mode != idle;
533 }
Da das ganze in C++ und in einer Klasse implementiert ist (alle Hilfsfunktionen private), kann ich so sicherstellen, das wirklich die Reihenfolge eingehalten wird und das Interface anch aussen sehr simpel ist.
Code:
8 class I2C
9 {
10 public:
11 enum error_code_t
12 {
13 no_error = 0,
14
15 tx_no_answer_tw_start,
16 tx_no_answer_tw_mt_sla_ack,
17 tx_no_answer_tw_mt_data_ack,
18
19 rx_no_answer_tw_start,
20 rx_no_answer_sla_mt_or_sla_mr_ack,
21 rx_no_answer_tw_mt_data_ack,
22 rx_no_answer_tw_rep_start,
23 rx_no_answer_tw_mr_sla_ack,
24 rx_no_answer_tw_mr_data_ack,
25 };
26
27 i2c();
28 void init();
29
30 // handle the IRQs
31 void handle_irq();
32
33 // read/write something from/to a slave
34 void
35 write_to_slave(unsigned char address, const char* data, unsigned char len);
36 void
37 read_from_slave(unsigned char address, const char* data, unsigned char tx_len, unsigned char rx_len);
38
39 // status information
40 unsigned char rx_size() const;
41 unsigned char tx_size() const;
42 error_code_t is_error() const;
43 bool is_busy() const;
44
45 // get received data
46 i2c& operator >> (char& data);
47 private:
Bei interesse kann ich den Code gerne ganz hochladen.
Lesezeichen