Mozzi  version v2.0
sound synthesis library for Arduino
twi_nonblock.hpp
1 /*
2  * twi_nonblock.cpp
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Marije Baalman and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #include "hardware_defines.h"
13 #if !IS_AVR()
14 #error Wrong include
15 #endif
16 
17 // Added by TB2014 for Mozzi library, to hide code from Teensy 3.1
18 
19 
20 #include <avr/interrupt.h>
21 
22 uint8_t twi_writeAddress;
23 uint8_t * twi_writeData;
24 uint8_t twi_writeLength;
25 
26 uint8_t twi_readAddress;
27 // uint8_t * twi_writeData;
28 uint8_t twi_readLength;
29 
30 /*
31  * Function twi_init
32  * Desc readys twi pins and sets twi bitrate
33  * Input none
34  * Output none
35  */
36 void initialize_twi_nonblock(){
37  rxBufferIndex = 0;
38  rxBufferLength = 0;
39 
40  txBufferIndex = 0;
41  txBufferLength = 0;
42 
43  // initialize state
44  twi_state = TWI_READY;
45 
46  #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
47  // activate internal pull-ups for twi
48  // as per note from atmega8 manual pg167
49  sbi(PORTC, 4);
50  sbi(PORTC, 5);
51  #else
52  // activate internal pull-ups for twi
53  // as per note from atmega128 manual pg204
54  sbi(PORTD, 0);
55  sbi(PORTD, 1);
56  #endif
57 
58  // initialize twi prescaler and bit rate
59  cbi(TWSR, TWPS0);
60  cbi(TWSR, TWPS1);
61  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
62 
63  /* twi bit rate formula from atmega128 manual pg 204
64  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
65  note: TWBR should be 10 or higher for master mode
66  It is 72 for a 16mhz Wiring board with 100kHz TWI */
67 
68  // enable twi module, acks, and twi interrupt
69  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
70 }
71 
72 
73 uint8_t twowire_requestFromBlocking(uint8_t address, uint8_t quantity)
74 {
75  // clamp to buffer length
76  if(quantity > BUFFER_LENGTH){
77  quantity = BUFFER_LENGTH;
78  }
79  // perform blocking read into buffer
80  uint8_t read = twi_readFromBlocking(address, rxBuffer, quantity);
81  // set rx buffer iterator vars
82  rxBufferIndex = 0;
83  rxBufferLength = read;
84 
85  return read;
86 }
87 
88 void twowire_beginTransmission( uint8_t address ){
89  // indicate that we are transmitting
90  transmitting = 1;
91  // set address of targeted slave
92  txAddress = address;
93  // reset tx buffer iterator vars
94  txBufferIndex = 0;
95  txBufferLength = 0;
96 }
97 
98 void twowire_send( uint8_t data ){
99  if(transmitting){
100  // in master transmitter mode
101  // don't bother if buffer is full
102  if(txBufferLength >= BUFFER_LENGTH){
103  return;
104  }
105  // put byte in tx buffer
106  txBuffer[txBufferIndex] = data;
107  ++txBufferIndex;
108  // update amount in buffer
109  txBufferLength = txBufferIndex;
110  }
111 }
112 
113 uint8_t twowire_endTransmission(void)
114 {
115  // transmit buffer (blocking)
116  int8_t ret = twi_writeToBlocking(txAddress, txBuffer, txBufferLength, 1);
117  // reset tx buffer iterator vars
118  txBufferIndex = 0;
119  txBufferLength = 0;
120  // indicate that we are done transmitting
121  transmitting = 0;
122  return ret;
123 }
124 
125 /*
126  * Function twi_readFrom
127  * Desc attempts to become twi bus master and read a
128  * series of bytes from a device on the bus
129  * Input address: 7bit i2c device address
130  * data: pointer to byte array
131  * length: number of bytes to read into array
132  * Output number of bytes read
133  */
134 /// TODO: make non-blocking
135 uint8_t twi_readFromBlocking(uint8_t address, uint8_t* data, uint8_t length)
136 {
137  uint8_t i;
138 
139  // ensure data will fit into buffer
140  if(TWI_BUFFER_LENGTH < length){
141  return 0;
142  }
143 
144  // wait until twi is ready, become master receiver
145  while(TWI_READY != twi_state){
146  continue;
147  }
148 
149  twi_state = TWI_MRX;
150  // reset error state (0xFF.. no error occured)
151  twi_error = 0xFF;
152 
153  // initialize buffer iteration vars
154  twi_masterBufferIndex = 0;
155  twi_masterBufferLength = length-1; // This is not intuitive, read on...
156  // On receive, the previously configured ACK/NACK setting is transmitted in
157  // response to the received byte before the interrupt is signalled.
158  // Therefor we must actually set NACK when the _next_ to last byte is
159  // received, causing that NACK to be sent in response to receiving the last
160  // expected byte of data.
161 
162  // build sla+w, slave device address + w bit
163  twi_slarw = TW_READ;
164  twi_slarw |= address << 1;
165 
166  // send start condition
167  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
168 
169  // wait for read operation to complete
170  while(TWI_MRX == twi_state){
171  continue;
172  }
173 
174  if (twi_masterBufferIndex < length)
175  length = twi_masterBufferIndex;
176 
177  // copy twi buffer to data
178  for(i = 0; i < length; ++i){
179  data[i] = twi_masterBuffer[i];
180  }
181 
182  return length;
183 }
184 
185 
186 
187 /// ---------- non-blocking version ----------
188 
189 
190 uint8_t twi_initiateReadFrom(uint8_t address, uint8_t length)
191 {
192 
193  // ensure data will fit into buffer
194  if(TWI_BUFFER_LENGTH < length){
195  return 0;
196  }
197 
198  twi_readLength = length;
199  twi_readAddress = address;
200 
201  if ( TWI_READY == twi_state ){
202  twi_continueReadFrom();
203  } else {
204  twi_state = TWI_PRE_MRX;
205  }
206  if (twi_error == 0xFF)
207  return 0; // success
208  else if (twi_error == TW_MT_SLA_NACK)
209  return 2; // error: address send, nack received
210  else if (twi_error == TW_MT_DATA_NACK)
211  return 3; // error: data send, nack received
212  else
213  return 4; // other twi error
214 }
215 
216 
217 
218 void twi_continueReadFrom(){
219 
220  twi_state = TWI_MRX;
221  // reset error state (0xFF.. no error occured)
222  twi_error = 0xFF;
223 
224  // initialize buffer iteration vars
225  twi_masterBufferIndex = 0;
226  twi_masterBufferLength = twi_readLength-1; // This is not intuitive, read on...
227  // On receive, the previously configured ACK/NACK setting is transmitted in
228  // response to the received byte before the interrupt is signalled.
229  // Therefor we must actually set NACK when the _next_ to last byte is
230  // received, causing that NACK to be sent in response to receiving the last
231  // expected byte of data.
232 
233  // build sla+w, slave device address + w bit
234  twi_slarw = TW_READ;
235  twi_slarw |= twi_readAddress << 1;
236 
237  // send start condition
238  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
239 }
240 
241 
242 
243 uint8_t twi_readMasterBuffer( uint8_t* data, uint8_t length ){
244  uint8_t i;
245  if (twi_masterBufferIndex < length)
246  length = twi_masterBufferIndex;
247 
248  // copy twi buffer to data
249  for(i = 0; i < length; ++i){
250  data[i] = twi_masterBuffer[i];
251  }
252 
253  return length;
254 }
255 
256 
257 
258 /// ----end------ non-blocking version ----------
259 
260 
261 /*
262  * Function twi_writeTo
263  * Desc attempts to become twi bus master and write a
264  * series of bytes to a device on the bus
265  * Input address: 7bit i2c device address
266  * data: pointer to byte array
267  * length: number of bytes in array
268  * wait: boolean indicating to wait for write or not
269  * Output 0 .. success
270  * 1 .. length to long for buffer
271  * 2 .. address send, NACK received
272  * 3 .. data send, NACK received
273  * 4 .. other twi error (lost bus arbitration, bus error, ..)
274  */
275 /// TODO: make non-blocking
276 uint8_t twi_writeToBlocking(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
277 {
278  uint8_t i;
279 
280  // ensure data will fit into buffer
281  if(TWI_BUFFER_LENGTH < length){
282  return 1;
283  }
284 
285  // wait until twi is ready, become master transmitter
286  while(TWI_READY != twi_state){
287  continue;
288  }
289 
290  twi_state = TWI_MTX;
291  // reset error state (0xFF.. no error occured)
292  twi_error = 0xFF;
293 
294  // initialize buffer iteration vars
295  twi_masterBufferIndex = 0;
296  twi_masterBufferLength = length;
297 
298  // copy data to twi buffer
299  for(i = 0; i < length; ++i){
300  twi_masterBuffer[i] = data[i];
301  }
302 
303  // build sla+w, slave device address + w bit
304  twi_slarw = TW_WRITE;
305  twi_slarw |= address << 1;
306 
307  // send start condition
308  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
309 
310  // wait for write operation to complete
311  while(wait && (TWI_MTX == twi_state)){
312  continue;
313  }
314 
315  if (twi_error == 0xFF)
316  return 0; // success
317  else if (twi_error == TW_MT_SLA_NACK)
318  return 2; // error: address send, nack received
319  else if (twi_error == TW_MT_DATA_NACK)
320  return 3; // error: data send, nack received
321  else
322  return 4; // other twi error
323 }
324 
325 
326 
327 /// ----------------- non-blocking ---------
328 
329 
330 uint8_t twi_initiateWriteTo(uint8_t address, uint8_t* data, uint8_t length )
331 {
332  // ensure data will fit into buffer
333  if(TWI_BUFFER_LENGTH < length){
334  return 1;
335  }
336  twi_writeAddress = address;
337  twi_writeData = data;
338  twi_writeLength = length;
339 
340  if ( TWI_READY == twi_state ){
341  twi_continueWriteTo();
342  } else {
343  twi_state = TWI_PRE_MTX;
344  }
345  if (twi_error == 0xFF)
346  return 0; // success
347  else if (twi_error == TW_MT_SLA_NACK)
348  return 2; // error: address send, nack received
349  else if (twi_error == TW_MT_DATA_NACK)
350  return 3; // error: data send, nack received
351  else
352  return 4; // other twi error
353 }
354 
355 
356 
357 void twi_continueWriteTo(){
358  uint8_t i;
359  // wait until twi is ready, become master transmitter
360 // while(TWI_READY != twi_state){
361 // continue;
362 // }
363 
364  twi_state = TWI_MTX;
365  // reset error state (0xFF.. no error occured)
366  twi_error = 0xFF;
367 
368  // initialize buffer iteration vars
369  twi_masterBufferIndex = 0;
370  twi_masterBufferLength = twi_writeLength;
371 
372  // copy data to twi buffer
373  for(i = 0; i < twi_writeLength; ++i){
374  twi_masterBuffer[i] = twi_writeData[i];
375  }
376 
377  // build sla+w, slave device address + w bit
378  twi_slarw = TW_WRITE;
379  twi_slarw |= twi_writeAddress << 1;
380 
381  // send start condition
382  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
383 }
384 
385 
386 // -----------end non-blocking --------------------
387 
388 
389 /*
390  * Function twi_reply
391  * Desc sends byte or readys receive line
392  * Input ack: byte indicating to ack or to nack
393  * Output none
394  */
395 void twi_reply(uint8_t ack)
396 {
397  // transmit master read ready signal, with or without ack
398  if(ack){
399  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
400  }else{
401  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
402  }
403 }
404 
405 
406 
407 /*
408  * Function twi_stop
409  * Desc relinquishes bus master status
410  * Input none
411  * Output none
412  */
413 void twi_stop(void)
414 {
415  // send stop condition
416  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
417 
418  // wait for stop condition to be exectued on bus
419  // TWINT is not set after a stop condition!
420  while(TWCR & _BV(TWSTO)){ //FIXME: does this cause a delay?
421  continue;
422  }
423 
424  twi_oldstate = twi_state;
425  // update twi state
426  twi_state = TWI_READY;
427  if ( twi_oldstate == TWI_PRE_MTX ){
428  twi_continueWriteTo();
429  } else if ( twi_oldstate == TWI_PRE_MRX ){
430  twi_continueReadFrom();
431  }
432 }
433 
434 
435 
436 /*
437  * Function twi_releaseBus
438  * Desc releases bus control
439  * Input none
440  * Output none
441  */
442 void twi_releaseBus(void)
443 {
444  // release bus
445  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
446 
447  twi_oldstate = twi_state;
448  // update twi state
449  twi_state = TWI_READY;
450  if ( twi_oldstate == TWI_PRE_MTX ){
451  twi_continueWriteTo();
452  } else if ( twi_oldstate == TWI_PRE_MRX ){
453  twi_continueReadFrom();
454  }
455 }
456 
457 // SIGNAL(TWI_vect)
458 // ISR(TWI_vect, ISR_NOBLOCK )
459 ISR(TWI_vect)
460 {
461  switch(TW_STATUS){
462  // All Master
463  case TW_START: // sent start condition
464  case TW_REP_START: // sent repeated start condition
465  // copy device address and r/w bit to output register and ack
466  TWDR = twi_slarw;
467  twi_reply(1);
468  break;
469 
470  // Master Transmitter
471  case TW_MT_SLA_ACK: // slave receiver acked address
472  case TW_MT_DATA_ACK: // slave receiver acked data
473  // if there is data to send, send it, otherwise stop
474  if(twi_masterBufferIndex < twi_masterBufferLength){
475  // copy data to output register and ack
476  TWDR = twi_masterBuffer[twi_masterBufferIndex++];
477  twi_reply(1);
478  }else{
479  twi_stop();
480  }
481  break;
482  case TW_MT_SLA_NACK: // address sent, nack received
483  twi_error = TW_MT_SLA_NACK;
484  twi_stop();
485  break;
486  case TW_MT_DATA_NACK: // data sent, nack received
487  twi_error = TW_MT_DATA_NACK;
488  twi_stop();
489  break;
490  case TW_MT_ARB_LOST: // lost bus arbitration
491  twi_error = TW_MT_ARB_LOST;
492  twi_releaseBus();
493  break;
494 
495  // Master Receiver
496  case TW_MR_DATA_ACK: // data received, ack sent
497  // put byte into buffer
498  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
499  case TW_MR_SLA_ACK: // address sent, ack received
500  // ack if more bytes are expected, otherwise nack
501  if(twi_masterBufferIndex < twi_masterBufferLength){
502  twi_reply(1);
503  }else{
504  twi_reply(0);
505  }
506  break;
507  case TW_MR_DATA_NACK: // data received, nack sent
508  // put final byte into buffer
509  twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
510  case TW_MR_SLA_NACK: // address sent, nack received
511  twi_stop();
512  break;
513  // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
514 
515 // // Slave Receiver
516 // case TW_SR_SLA_ACK: // addressed, returned ack
517 // case TW_SR_GCALL_ACK: // addressed generally, returned ack
518 // case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
519 // case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
520 // // enter slave receiver mode
521 // twi_state = TWI_SRX;
522 // // indicate that rx buffer can be overwritten and ack
523 // twi_rxBufferIndex = 0;
524 // twi_reply(1);
525 // break;
526 // case TW_SR_DATA_ACK: // data received, returned ack
527 // case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
528 // // if there is still room in the rx buffer
529 // if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
530 // // put byte in buffer and ack
531 // twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
532 // twi_reply(1);
533 // }else{
534 // // otherwise nack
535 // twi_reply(0);
536 // }
537 // break;
538 // case TW_SR_STOP: // stop or repeated start condition received
539 // // put a null char after data if there's room
540 // if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
541 // twi_rxBuffer[twi_rxBufferIndex] = '\0';
542 // }
543 // // sends ack and stops interface for clock stretching
544 // twi_stop();
545 // // callback to user defined callback
546 // twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
547 // // since we submit rx buffer to "wire" library, we can reset it
548 // twi_rxBufferIndex = 0;
549 // // ack future responses and leave slave receiver state
550 // twi_releaseBus();
551 // break;
552 // case TW_SR_DATA_NACK: // data received, returned nack
553 // case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
554 // // nack back at master
555 // twi_reply(0);
556 // break;
557 //
558 // // Slave Transmitter
559 // case TW_ST_SLA_ACK: // addressed, returned ack
560 // case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
561 // // enter slave transmitter mode
562 // twi_state = TWI_STX;
563 // // ready the tx buffer index for iteration
564 // twi_txBufferIndex = 0;
565 // // set tx buffer length to be zero, to verify if user changes it
566 // twi_txBufferLength = 0;
567 // // request for txBuffer to be filled and length to be set
568 // // note: user must call twi_transmit(bytes, length) to do this
569 // twi_onSlaveTransmit();
570 // // if they didn't change buffer & length, initialize it
571 // if(0 == twi_txBufferLength){
572 // twi_txBufferLength = 1;
573 // twi_txBuffer[0] = 0x00;
574 // }
575 // // transmit first byte from buffer, fall
576 // case TW_ST_DATA_ACK: // byte sent, ack returned
577 // // copy data to output register
578 // TWDR = twi_txBuffer[twi_txBufferIndex++];
579 // // if there is more to send, ack, otherwise nack
580 // if(twi_txBufferIndex < twi_txBufferLength){
581 // twi_reply(1);
582 // }else{
583 // twi_reply(0);
584 // }
585 // break;
586 // case TW_ST_DATA_NACK: // received nack, we are done
587 // case TW_ST_LAST_DATA: // received ack, but we are done already!
588 // // ack future responses
589 // twi_reply(1);
590 // // leave slave receiver state
591 // twi_state = TWI_READY;
592 // break;
593 
594  // All
595  case TW_NO_INFO: // no state information
596  break;
597  case TW_BUS_ERROR: // bus error, illegal stop/start
598  twi_error = TW_BUS_ERROR;
599  twi_stop();
600  break;
601  }
602 }