rad 0.2.2 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. data/History.txt +34 -0
  2. data/Manifest.txt +113 -7
  3. data/{README.txt → README.rdoc} +17 -5
  4. data/Rakefile +3 -0
  5. data/bin/rad +106 -1
  6. data/lib/examples/add_hysteresis.rb +13 -0
  7. data/lib/examples/basic_blink.rb +10 -0
  8. data/lib/examples/blink_m_address_assignment.rb +104 -0
  9. data/lib/examples/blink_m_hello.rb +14 -0
  10. data/lib/examples/blink_m_multi.rb +61 -0
  11. data/lib/examples/blink_with_serial.rb +16 -0
  12. data/lib/examples/configure_pa_lcd_boot.rb +91 -0
  13. data/lib/examples/debounce_methods.rb +49 -0
  14. data/lib/examples/external_variable_fu.rb +26 -0
  15. data/lib/examples/external_variables.rb +32 -0
  16. data/lib/examples/first_sound.rb +23 -0
  17. data/lib/examples/frequency_generator.rb +30 -0
  18. data/lib/examples/hello_array.rb +48 -0
  19. data/lib/examples/hello_array2.rb +79 -0
  20. data/lib/examples/hello_array_eeprom.rb +59 -0
  21. data/lib/examples/hello_clock.rb +84 -0
  22. data/lib/examples/hello_eeprom.rb +51 -0
  23. data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
  24. data/lib/examples/hello_format_print.rb +94 -0
  25. data/lib/examples/hello_lcd_charset.rb +75 -0
  26. data/lib/examples/hello_pa_lcd.rb +59 -0
  27. data/lib/examples/hello_servos.rb +88 -0
  28. data/lib/examples/hello_spectra_sound.rb +38 -0
  29. data/lib/examples/hello_world.rb +11 -0
  30. data/lib/examples/hello_xbee.rb +12 -0
  31. data/lib/examples/hysteresis_duel.rb +39 -0
  32. data/lib/examples/i2c_with_clock_chip.rb +124 -0
  33. data/lib/examples/midi_beat_box.rb +86 -0
  34. data/lib/examples/midi_scales.rb +94 -0
  35. data/lib/examples/motor_knob.rb +30 -0
  36. data/lib/examples/servo_buttons.rb +23 -0
  37. data/lib/examples/servo_calibrate_continuous.rb +92 -0
  38. data/lib/examples/servo_throttle.rb +40 -0
  39. data/lib/examples/sparkfun_lcd.rb +48 -0
  40. data/lib/examples/spectra_soft_pot.rb +34 -0
  41. data/lib/examples/times_method.rb +8 -0
  42. data/lib/examples/toggle.rb +10 -0
  43. data/lib/examples/twitter.rb +57 -0
  44. data/lib/examples/two_wire.rb +14 -0
  45. data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
  46. data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
  47. data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
  48. data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
  49. data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
  50. data/lib/libraries/DS1307/DS1307.cpp +162 -0
  51. data/lib/libraries/DS1307/DS1307.h +66 -0
  52. data/lib/libraries/{SWSerLCDpa → DS1307}/keywords.txt +1 -1
  53. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
  54. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
  55. data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
  56. data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
  57. data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
  58. data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
  59. data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
  60. data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
  61. data/lib/libraries/LoopTimer/keywords.txt +27 -0
  62. data/lib/libraries/OneWire/OneWire.cpp +194 -0
  63. data/lib/libraries/OneWire/OneWire.h +63 -0
  64. data/lib/libraries/OneWire/keywords.txt +35 -0
  65. data/lib/libraries/OneWire/readme.txt +13 -0
  66. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +93 -47
  67. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +16 -9
  68. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
  69. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
  70. data/lib/libraries/Servo/Servo.cpp +192 -0
  71. data/lib/libraries/Servo/Servo.h +61 -0
  72. data/lib/libraries/Stepper/Stepper.cpp +220 -0
  73. data/lib/libraries/Stepper/Stepper.h +86 -0
  74. data/lib/libraries/Stepper/keywords.txt +28 -0
  75. data/lib/libraries/Wire/Wire.cpp +262 -0
  76. data/lib/libraries/Wire/Wire.h +67 -0
  77. data/lib/libraries/Wire/keywords.txt +31 -0
  78. data/lib/libraries/Wire/twi.h +57 -0
  79. data/lib/libraries/Wire/utility/twi.c +449 -0
  80. data/lib/libraries/Wire/utility/twi.h +57 -0
  81. data/lib/plugins/bitwise_ops.rb +54 -0
  82. data/lib/plugins/blink.rb +25 -0
  83. data/lib/plugins/blink_m.rb +356 -0
  84. data/lib/plugins/debounce.rb +138 -0
  85. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  86. data/lib/plugins/hysteresis.rb +52 -0
  87. data/lib/plugins/input_output_state.rb +84 -0
  88. data/lib/plugins/lcd_padding.rb +58 -0
  89. data/lib/plugins/mem_test.rb +37 -0
  90. data/lib/plugins/midi.rb +60 -0
  91. data/lib/plugins/parallax_ping.rb +50 -0
  92. data/lib/plugins/servo_pulse.rb +31 -0
  93. data/lib/plugins/servo_setup.rb +86 -0
  94. data/lib/plugins/smoother.rb +54 -0
  95. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  96. data/lib/plugins/spectra_symbol.rb +79 -0
  97. data/lib/plugins/twitter_connect.rb +145 -0
  98. data/lib/rad/README.rdoc +5 -0
  99. data/lib/rad/arduino_plugin.rb +246 -0
  100. data/lib/rad/arduino_sketch.rb +351 -257
  101. data/lib/rad/generators/makefile/makefile.erb +1 -1
  102. data/lib/rad/generators/makefile/makefile.rb +9 -10
  103. data/lib/rad/hardware_library.rb +813 -0
  104. data/lib/rad/init.rb +3 -1
  105. data/lib/rad/rad_processor.rb +128 -0
  106. data/lib/rad/rad_rewriter.rb +94 -0
  107. data/lib/rad/rad_type_checker.rb +26 -0
  108. data/lib/rad/sim/arduino_sketch.rb +57 -0
  109. data/lib/rad/sketch_compiler.rb +47 -0
  110. data/lib/rad/tasks/build_and_make.rake +146 -24
  111. data/lib/rad/variable_processing.rb +153 -0
  112. data/lib/rad/version.rb +1 -1
  113. data/spec/examples/hello_world.rb +11 -0
  114. data/spec/examples/serial_motor.rb +12 -0
  115. data/spec/models/sketch_compiler_spec.rb +96 -0
  116. data/spec/sim/hello_world_spec.rb +42 -0
  117. data/test/test_array_processing.rb +179 -0
  118. data/test/test_plugin_loading.rb +151 -0
  119. data/test/test_translation_post_processing.rb +185 -0
  120. data/test/test_variable_processing.rb +238 -0
  121. data/website/index.html +22 -7
  122. data/website/stylesheets/screen.css +32 -1
  123. metadata +130 -13
@@ -0,0 +1,57 @@
1
+ /*
2
+ twi.h - TWI/I2C library for Wiring & Arduino
3
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #ifndef twi_h
21
+ #define twi_h
22
+
23
+ #include <inttypes.h>
24
+
25
+ //#define ATMEGA8
26
+
27
+ #ifndef CPU_FREQ
28
+ #define CPU_FREQ 16000000L
29
+ #endif
30
+
31
+ #ifndef TWI_FREQ
32
+ #define TWI_FREQ 100000L
33
+ #endif
34
+
35
+ #ifndef TWI_BUFFER_LENGTH
36
+ #define TWI_BUFFER_LENGTH 32
37
+ #endif
38
+
39
+ #define TWI_READY 0
40
+ #define TWI_MRX 1
41
+ #define TWI_MTX 2
42
+ #define TWI_SRX 3
43
+ #define TWI_STX 4
44
+
45
+ void twi_init(void);
46
+ void twi_setAddress(uint8_t);
47
+ uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
48
+ uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
49
+ uint8_t twi_transmit(uint8_t*, uint8_t);
50
+ void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
51
+ void twi_attachSlaveTxEvent( void (*)(void) );
52
+ void twi_reply(uint8_t);
53
+ void twi_stop(void);
54
+ void twi_releaseBus(void);
55
+
56
+ #endif
57
+
@@ -0,0 +1,449 @@
1
+ /*
2
+ twi.c - TWI/I2C library for Wiring & Arduino
3
+ Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+ #include <math.h>
21
+ #include <stdlib.h>
22
+ #include <inttypes.h>
23
+ #include <avr/io.h>
24
+ #include <avr/interrupt.h>
25
+ #include <avr/signal.h>
26
+ #include <compat/twi.h>
27
+
28
+ #ifndef cbi
29
+ #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
30
+ #endif
31
+
32
+ #ifndef sbi
33
+ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
34
+ #endif
35
+
36
+ #include "twi.h"
37
+
38
+ static volatile uint8_t twi_state;
39
+ static uint8_t twi_slarw;
40
+
41
+ static void (*twi_onSlaveTransmit)(void);
42
+ static void (*twi_onSlaveReceive)(uint8_t*, int);
43
+
44
+ static uint8_t* twi_masterBuffer;
45
+ static volatile uint8_t twi_masterBufferIndex;
46
+ static uint8_t twi_masterBufferLength;
47
+
48
+ static uint8_t* twi_txBuffer;
49
+ static volatile uint8_t twi_txBufferIndex;
50
+ static volatile uint8_t twi_txBufferLength;
51
+
52
+ static uint8_t* twi_rxBuffer;
53
+ static volatile uint8_t twi_rxBufferIndex;
54
+
55
+ /*
56
+ * Function twi_init
57
+ * Desc readys twi pins and sets twi bitrate
58
+ * Input none
59
+ * Output none
60
+ */
61
+ void twi_init(void)
62
+ {
63
+ // initialize state
64
+ twi_state = TWI_READY;
65
+
66
+ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__)
67
+ // activate internal pull-ups for twi
68
+ // as per note from atmega8 manual pg167
69
+ sbi(PORTC, 4);
70
+ sbi(PORTC, 5);
71
+ #else
72
+ // activate internal pull-ups for twi
73
+ // as per note from atmega128 manual pg204
74
+ sbi(PORTD, 0);
75
+ sbi(PORTD, 1);
76
+ #endif
77
+
78
+ // initialize twi prescaler and bit rate
79
+ cbi(TWSR, TWPS0);
80
+ cbi(TWSR, TWPS1);
81
+ TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;
82
+
83
+ /* twi bit rate formula from atmega128 manual pg 204
84
+ SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
85
+ note: TWBR should be 10 or higher for master mode
86
+ It is 72 for a 16mhz Wiring board with 100kHz TWI */
87
+
88
+ // enable twi module, acks, and twi interrupt
89
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
90
+
91
+ // allocate buffers
92
+ twi_masterBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
93
+ twi_txBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
94
+ twi_rxBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t));
95
+ }
96
+
97
+ /*
98
+ * Function twi_slaveInit
99
+ * Desc sets slave address and enables interrupt
100
+ * Input none
101
+ * Output none
102
+ */
103
+ void twi_setAddress(uint8_t address)
104
+ {
105
+ // set twi slave address (skip over TWGCE bit)
106
+ TWAR = address << 1;
107
+ }
108
+
109
+ /*
110
+ * Function twi_readFrom
111
+ * Desc attempts to become twi bus master and read a
112
+ * series of bytes from a device on the bus
113
+ * Input address: 7bit i2c device address
114
+ * data: pointer to byte array
115
+ * length: number of bytes to read into array
116
+ * Output byte: 0 ok, 1 length too long for buffer
117
+ */
118
+ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
119
+ {
120
+ uint8_t i;
121
+
122
+ // ensure data will fit into buffer
123
+ if(TWI_BUFFER_LENGTH < length){
124
+ return 1;
125
+ }
126
+
127
+ // wait until twi is ready, become master receiver
128
+ while(TWI_READY != twi_state){
129
+ continue;
130
+ }
131
+ twi_state = TWI_MRX;
132
+
133
+ // initialize buffer iteration vars
134
+ twi_masterBufferIndex = 0;
135
+ twi_masterBufferLength = length;
136
+
137
+ // build sla+w, slave device address + w bit
138
+ twi_slarw = TW_READ;
139
+ twi_slarw |= address << 1;
140
+
141
+ // send start condition
142
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
143
+
144
+ // wait for read operation to complete
145
+ while(TWI_MRX == twi_state){
146
+ continue;
147
+ }
148
+
149
+ // copy twi buffer to data
150
+ for(i = 0; i < length; ++i){
151
+ data[i] = twi_masterBuffer[i];
152
+ }
153
+
154
+ return 0;
155
+ }
156
+
157
+ /*
158
+ * Function twi_writeTo
159
+ * Desc attempts to become twi bus master and write a
160
+ * series of bytes to a device on the bus
161
+ * Input address: 7bit i2c device address
162
+ * data: pointer to byte array
163
+ * length: number of bytes in array
164
+ * wait: boolean indicating to wait for write or not
165
+ * Output byte: 0 ok, 1 length too long for buffer
166
+ */
167
+ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
168
+ {
169
+ uint8_t i;
170
+
171
+ // ensure data will fit into buffer
172
+ if(TWI_BUFFER_LENGTH < length){
173
+ return 1;
174
+ }
175
+
176
+ // wait until twi is ready, become master transmitter
177
+ while(TWI_READY != twi_state){
178
+ continue;
179
+ }
180
+ twi_state = TWI_MTX;
181
+
182
+ // initialize buffer iteration vars
183
+ twi_masterBufferIndex = 0;
184
+ twi_masterBufferLength = length;
185
+
186
+ // copy data to twi buffer
187
+ for(i = 0; i < length; ++i){
188
+ twi_masterBuffer[i] = data[i];
189
+ }
190
+
191
+ // build sla+w, slave device address + w bit
192
+ twi_slarw = TW_WRITE;
193
+ twi_slarw |= address << 1;
194
+
195
+ // send start condition
196
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
197
+
198
+ // wait for write operation to complete
199
+ while(wait && (TWI_MTX == twi_state)){
200
+ continue;
201
+ }
202
+
203
+ return 0;
204
+ }
205
+
206
+ /*
207
+ * Function twi_transmit
208
+ * Desc fills slave tx buffer with data
209
+ * must be called in slave tx event callback
210
+ * Input data: pointer to byte array
211
+ * length: number of bytes in array
212
+ * Output 1 length too long for buffer
213
+ * 2 not slave transmitter
214
+ * 0 ok
215
+ */
216
+ uint8_t twi_transmit(uint8_t* data, uint8_t length)
217
+ {
218
+ uint8_t i;
219
+
220
+ // ensure data will fit into buffer
221
+ if(TWI_BUFFER_LENGTH < length){
222
+ return 1;
223
+ }
224
+
225
+ // ensure we are currently a slave transmitter
226
+ if(TWI_STX != twi_state){
227
+ return 2;
228
+ }
229
+
230
+ // set length and copy data into tx buffer
231
+ twi_txBufferLength = length;
232
+ for(i = 0; i < length; ++i){
233
+ twi_txBuffer[i] = data[i];
234
+ }
235
+
236
+ return 0;
237
+ }
238
+
239
+ /*
240
+ * Function twi_attachSlaveRxEvent
241
+ * Desc sets function called before a slave read operation
242
+ * Input function: callback function to use
243
+ * Output none
244
+ */
245
+ void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) )
246
+ {
247
+ twi_onSlaveReceive = function;
248
+ }
249
+
250
+ /*
251
+ * Function twi_attachSlaveTxEvent
252
+ * Desc sets function called before a slave write operation
253
+ * Input function: callback function to use
254
+ * Output none
255
+ */
256
+ void twi_attachSlaveTxEvent( void (*function)(void) )
257
+ {
258
+ twi_onSlaveTransmit = function;
259
+ }
260
+
261
+ /*
262
+ * Function twi_reply
263
+ * Desc sends byte or readys receive line
264
+ * Input ack: byte indicating to ack or to nack
265
+ * Output none
266
+ */
267
+ void twi_reply(uint8_t ack)
268
+ {
269
+ // transmit master read ready signal, with or without ack
270
+ if(ack){
271
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);
272
+ }else{
273
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);
274
+ }
275
+ }
276
+
277
+ /*
278
+ * Function twi_stop
279
+ * Desc relinquishes bus master status
280
+ * Input none
281
+ * Output none
282
+ */
283
+ void twi_stop(void)
284
+ {
285
+ // send stop condition
286
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);
287
+
288
+ // wait for stop condition to be exectued on bus
289
+ // TWINT is not set after a stop condition!
290
+ while(TWCR & _BV(TWSTO)){
291
+ continue;
292
+ }
293
+
294
+ // update twi state
295
+ twi_state = TWI_READY;
296
+ }
297
+
298
+ /*
299
+ * Function twi_releaseBus
300
+ * Desc releases bus control
301
+ * Input none
302
+ * Output none
303
+ */
304
+ void twi_releaseBus(void)
305
+ {
306
+ // release bus
307
+ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);
308
+
309
+ // update twi state
310
+ twi_state = TWI_READY;
311
+ }
312
+
313
+ SIGNAL(SIG_2WIRE_SERIAL)
314
+ {
315
+ switch(TW_STATUS){
316
+ // All Master
317
+ case TW_START: // sent start condition
318
+ case TW_REP_START: // sent repeated start condition
319
+ // copy device address and r/w bit to output register and ack
320
+ TWDR = twi_slarw;
321
+ twi_reply(1);
322
+ break;
323
+
324
+ // Master Transmitter
325
+ case TW_MT_SLA_ACK: // slave receiver acked address
326
+ case TW_MT_DATA_ACK: // slave receiver acked data
327
+ // if there is data to send, send it, otherwise stop
328
+ if(twi_masterBufferIndex < twi_masterBufferLength){
329
+ // copy data to output register and ack
330
+ TWDR = twi_masterBuffer[twi_masterBufferIndex++];
331
+ twi_reply(1);
332
+ }else{
333
+ twi_stop();
334
+ }
335
+ break;
336
+ case TW_MT_SLA_NACK: // address sent, nack received
337
+ case TW_MT_DATA_NACK: // data sent, nack received
338
+ twi_stop();
339
+ break;
340
+ case TW_MT_ARB_LOST: // lost bus arbitration
341
+ twi_releaseBus();
342
+ break;
343
+
344
+ // Master Receiver
345
+ case TW_MR_DATA_ACK: // data received, ack sent
346
+ // put byte into buffer
347
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
348
+ case TW_MR_SLA_ACK: // address sent, ack received
349
+ // ack if more bytes are expected, otherwise nack
350
+ if(twi_masterBufferIndex < twi_masterBufferLength){
351
+ twi_reply(1);
352
+ }else{
353
+ twi_reply(0);
354
+ }
355
+ break;
356
+ case TW_MR_DATA_NACK: // data received, nack sent
357
+ // put final byte into buffer
358
+ twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
359
+ case TW_MR_SLA_NACK: // address sent, nack received
360
+ twi_stop();
361
+ break;
362
+ // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case
363
+
364
+ // Slave Receiver
365
+ case TW_SR_SLA_ACK: // addressed, returned ack
366
+ case TW_SR_GCALL_ACK: // addressed generally, returned ack
367
+ case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack
368
+ case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack
369
+ // enter slave receiver mode
370
+ twi_state = TWI_SRX;
371
+ // indicate that rx buffer can be overwritten and ack
372
+ twi_rxBufferIndex = 0;
373
+ twi_reply(1);
374
+ break;
375
+ case TW_SR_DATA_ACK: // data received, returned ack
376
+ case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
377
+ // if there is still room in the rx buffer
378
+ if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
379
+ // put byte in buffer and ack
380
+ twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
381
+ twi_reply(1);
382
+ }else{
383
+ // otherwise nack
384
+ twi_reply(0);
385
+ }
386
+ break;
387
+ case TW_SR_STOP: // stop or repeated start condition received
388
+ // put a null char after data if there's room
389
+ if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
390
+ twi_rxBuffer[twi_rxBufferIndex] = '\0';
391
+ }
392
+ // callback to user defined callback
393
+ twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);
394
+ // ack future responses
395
+ twi_reply(1);
396
+ // leave slave receiver state
397
+ twi_state = TWI_READY;
398
+ break;
399
+ case TW_SR_DATA_NACK: // data received, returned nack
400
+ case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack
401
+ // nack back at master
402
+ twi_reply(0);
403
+ break;
404
+
405
+ // Slave Transmitter
406
+ case TW_ST_SLA_ACK: // addressed, returned ack
407
+ case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack
408
+ // enter slave transmitter mode
409
+ twi_state = TWI_STX;
410
+ // ready the tx buffer index for iteration
411
+ twi_txBufferIndex = 0;
412
+ // set tx buffer length to be zero, to verify if user changes it
413
+ twi_txBufferLength = 0;
414
+ // request for txBuffer to be filled and length to be set
415
+ // note: user must call twi_transmit(bytes, length) to do this
416
+ twi_onSlaveTransmit();
417
+ // if they didn't change buffer & length, initialize it
418
+ if(0 == twi_txBufferLength){
419
+ twi_txBufferLength = 1;
420
+ twi_txBuffer[0] = 0x00;
421
+ }
422
+ // transmit first byte from buffer, fall
423
+ case TW_ST_DATA_ACK: // byte sent, ack returned
424
+ // copy data to output register
425
+ TWDR = twi_txBuffer[twi_txBufferIndex++];
426
+ // if there is more to send, ack, otherwise nack
427
+ if(twi_txBufferIndex < twi_txBufferLength){
428
+ twi_reply(1);
429
+ }else{
430
+ twi_reply(0);
431
+ }
432
+ break;
433
+ case TW_ST_DATA_NACK: // received nack, we are done
434
+ case TW_ST_LAST_DATA: // received ack, but we are done already!
435
+ // ack future responses
436
+ twi_reply(1);
437
+ // leave slave receiver state
438
+ twi_state = TWI_READY;
439
+ break;
440
+
441
+ // All
442
+ case TW_NO_INFO: // no state information
443
+ break;
444
+ case TW_BUS_ERROR: // bus error, illegal stop/start
445
+ twi_stop();
446
+ break;
447
+ }
448
+ }
449
+