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.
- data/History.txt +34 -0
- data/Manifest.txt +113 -7
- data/{README.txt → README.rdoc} +17 -5
- data/Rakefile +3 -0
- data/bin/rad +106 -1
- data/lib/examples/add_hysteresis.rb +13 -0
- data/lib/examples/basic_blink.rb +10 -0
- data/lib/examples/blink_m_address_assignment.rb +104 -0
- data/lib/examples/blink_m_hello.rb +14 -0
- data/lib/examples/blink_m_multi.rb +61 -0
- data/lib/examples/blink_with_serial.rb +16 -0
- data/lib/examples/configure_pa_lcd_boot.rb +91 -0
- data/lib/examples/debounce_methods.rb +49 -0
- data/lib/examples/external_variable_fu.rb +26 -0
- data/lib/examples/external_variables.rb +32 -0
- data/lib/examples/first_sound.rb +23 -0
- data/lib/examples/frequency_generator.rb +30 -0
- data/lib/examples/hello_array.rb +48 -0
- data/lib/examples/hello_array2.rb +79 -0
- data/lib/examples/hello_array_eeprom.rb +59 -0
- data/lib/examples/hello_clock.rb +84 -0
- data/lib/examples/hello_eeprom.rb +51 -0
- data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
- data/lib/examples/hello_format_print.rb +94 -0
- data/lib/examples/hello_lcd_charset.rb +75 -0
- data/lib/examples/hello_pa_lcd.rb +59 -0
- data/lib/examples/hello_servos.rb +88 -0
- data/lib/examples/hello_spectra_sound.rb +38 -0
- data/lib/examples/hello_world.rb +11 -0
- data/lib/examples/hello_xbee.rb +12 -0
- data/lib/examples/hysteresis_duel.rb +39 -0
- data/lib/examples/i2c_with_clock_chip.rb +124 -0
- data/lib/examples/midi_beat_box.rb +86 -0
- data/lib/examples/midi_scales.rb +94 -0
- data/lib/examples/motor_knob.rb +30 -0
- data/lib/examples/servo_buttons.rb +23 -0
- data/lib/examples/servo_calibrate_continuous.rb +92 -0
- data/lib/examples/servo_throttle.rb +40 -0
- data/lib/examples/sparkfun_lcd.rb +48 -0
- data/lib/examples/spectra_soft_pot.rb +34 -0
- data/lib/examples/times_method.rb +8 -0
- data/lib/examples/toggle.rb +10 -0
- data/lib/examples/twitter.rb +57 -0
- data/lib/examples/two_wire.rb +14 -0
- data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
- data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
- data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
- data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
- data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
- data/lib/libraries/DS1307/DS1307.cpp +162 -0
- data/lib/libraries/DS1307/DS1307.h +66 -0
- data/lib/libraries/{SWSerLCDpa → DS1307}/keywords.txt +1 -1
- data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
- data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
- data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
- data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
- data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
- data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
- data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
- data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
- data/lib/libraries/LoopTimer/keywords.txt +27 -0
- data/lib/libraries/OneWire/OneWire.cpp +194 -0
- data/lib/libraries/OneWire/OneWire.h +63 -0
- data/lib/libraries/OneWire/keywords.txt +35 -0
- data/lib/libraries/OneWire/readme.txt +13 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +93 -47
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +16 -9
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
- data/lib/libraries/Servo/Servo.cpp +192 -0
- data/lib/libraries/Servo/Servo.h +61 -0
- data/lib/libraries/Stepper/Stepper.cpp +220 -0
- data/lib/libraries/Stepper/Stepper.h +86 -0
- data/lib/libraries/Stepper/keywords.txt +28 -0
- data/lib/libraries/Wire/Wire.cpp +262 -0
- data/lib/libraries/Wire/Wire.h +67 -0
- data/lib/libraries/Wire/keywords.txt +31 -0
- data/lib/libraries/Wire/twi.h +57 -0
- data/lib/libraries/Wire/utility/twi.c +449 -0
- data/lib/libraries/Wire/utility/twi.h +57 -0
- data/lib/plugins/bitwise_ops.rb +54 -0
- data/lib/plugins/blink.rb +25 -0
- data/lib/plugins/blink_m.rb +356 -0
- data/lib/plugins/debounce.rb +138 -0
- data/lib/plugins/debug_output_to_lcd.rb +71 -0
- data/lib/plugins/hysteresis.rb +52 -0
- data/lib/plugins/input_output_state.rb +84 -0
- data/lib/plugins/lcd_padding.rb +58 -0
- data/lib/plugins/mem_test.rb +37 -0
- data/lib/plugins/midi.rb +60 -0
- data/lib/plugins/parallax_ping.rb +50 -0
- data/lib/plugins/servo_pulse.rb +31 -0
- data/lib/plugins/servo_setup.rb +86 -0
- data/lib/plugins/smoother.rb +54 -0
- data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
- data/lib/plugins/spectra_symbol.rb +79 -0
- data/lib/plugins/twitter_connect.rb +145 -0
- data/lib/rad/README.rdoc +5 -0
- data/lib/rad/arduino_plugin.rb +246 -0
- data/lib/rad/arduino_sketch.rb +351 -257
- data/lib/rad/generators/makefile/makefile.erb +1 -1
- data/lib/rad/generators/makefile/makefile.rb +9 -10
- data/lib/rad/hardware_library.rb +813 -0
- data/lib/rad/init.rb +3 -1
- data/lib/rad/rad_processor.rb +128 -0
- data/lib/rad/rad_rewriter.rb +94 -0
- data/lib/rad/rad_type_checker.rb +26 -0
- data/lib/rad/sim/arduino_sketch.rb +57 -0
- data/lib/rad/sketch_compiler.rb +47 -0
- data/lib/rad/tasks/build_and_make.rake +146 -24
- data/lib/rad/variable_processing.rb +153 -0
- data/lib/rad/version.rb +1 -1
- data/spec/examples/hello_world.rb +11 -0
- data/spec/examples/serial_motor.rb +12 -0
- data/spec/models/sketch_compiler_spec.rb +96 -0
- data/spec/sim/hello_world_spec.rb +42 -0
- data/test/test_array_processing.rb +179 -0
- data/test/test_plugin_loading.rb +151 -0
- data/test/test_translation_post_processing.rb +185 -0
- data/test/test_variable_processing.rb +238 -0
- data/website/index.html +22 -7
- data/website/stylesheets/screen.css +32 -1
- 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
|
+
|