diff options
Diffstat (limited to 'digital-driver/firmware/TinyWireS/examples')
5 files changed, 0 insertions, 935 deletions
| diff --git a/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Master/TinyWireS_Stress_Master.ino b/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Master/TinyWireS_Stress_Master.ino deleted file mode 100644 index d50adb7..0000000 --- a/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Master/TinyWireS_Stress_Master.ino +++ /dev/null @@ -1,184 +0,0 @@ -// --------------------------------- -// Stress test program/example for TinyWireS I2C library. -// Run this master program on the Arduino Uno R3. -// Run the other slave program on the Attiny. -// --------------------------------- -// Written by Scott Hartog, 2/6/2016 -// This is the I2C master program which runs on on a regular Arduino -// (not a AtTiny). This program uses the regular Wire library from the Arduino IDE. -// -// It performs these steps in a loop: -//    1. picks a random number of bytes between 1 and 12 -//    2. sends that many bytes of random data to the AtTiny slave within -//       a single Wire.beginTransmission() / Wire.write() / Wire.endTransmission() set -//    3. reads that same number of bytes back with a single Wire.requestFrom() call -//    4. compares the received data to the originally transmitted data -//    5. displays the number of requests, number of requests with mismatches, -//       and enough of the data so that the operator can tell it's working. -// -#include <Wire.h> - -// BREADBOARD SETUP: -// Arduino Uno R3 (D18/SDA) = I2C SDA  -//     connect to SDA on slave with external pull-up (~4.7K) -// Arduino Uno R3 (D19/SCL) = I2C SCL  -//     connect to SCL on slave with external pull-up (~4.7K) -// Arduino Uno R3 (D2) -//     connect to !RST on slave -//     Can alternatively connect !RST on slave to the Ardiuno "!RESET" pin - -#define I2C_SLAVE_ADDR  0x26            // i2c slave address (38, 0x26) - -#if defined(ESP8266) -  // pins that work for Monkey Board ESP8266 12-E -  // SCL=5, SDA=4 -  #define SLAVE_RESET_PIN 2 -  #define ALL_OK_LED_PIN 16 -  #define OK_LED_PIN 14 -  #define ERROR_LED_PIN 13 -#else -  // pins that work for Micro Pro, Uno, Mega 2560 -  // reference documentation for SCL and SDA pin locations -  // Uno SDA=D18, SCL=D19 -  #define SLAVE_RESET_PIN 6 -  #define ALL_OK_LED_PIN 9 -  #define OK_LED_PIN 7 -  #define ERROR_LED_PIN 8 -#endif - -uint16_t count = 0;       // total number of passes so far -uint16_t error_count = 0; // total errors encountered so far - -char c_buf[64]; // for creating messages - -void setup() -{ -  // set pin modes  -  pinMode(SLAVE_RESET_PIN,OUTPUT);  // active low reset to slave device -  pinMode(OK_LED_PIN,OUTPUT);       // indicates last transaction matched -  pinMode(ALL_OK_LED_PIN,OUTPUT);   // indicates all transactions so far have matched -  pinMode(ERROR_LED_PIN,OUTPUT);    // indicates last transaction mismatched - -  // init the serial port -  Serial.begin(9600); - -  // print some useful pinnout info for the Arduino -  //Serial.println(String("SCL:")+String(SCL)+String(", SDA:")+String(SDA)); -  //Serial.println(String("MOSI:")+String(MOSI)+String(", SCK:")+String(SCK)); - -  // init the Wire object (for I2C) -  Wire.begin();  - -  // init the i2c clock -  // default is 100kHz if not changed -  // Wire.setClock(400000L);  // 400kHz -   -  // reset the slave -  digitalWrite(SLAVE_RESET_PIN, LOW); -  delay(10); -  digitalWrite(SLAVE_RESET_PIN, HIGH); - -  // set the all okay pin high -  digitalWrite(ALL_OK_LED_PIN, HIGH); -   -  // wait for slave to finish any init sequence -  delay(2000); -} - -void loop() -{ -  uint8_t i; -  uint8_t req_rtn;       // num bytes returned by requestFrom() call -  uint8_t rand_byte_count; -  uint8_t out_rand[16];  // data written from master -  uint8_t in_rand[16];   // data read back from slave - -  bool mismatch; - -  // count total number of request -  count++; - -  // compute random number of bytes for this pass -  rand_byte_count = random(16) + 1; - -  // force the first three requests to be small so that the tx buffer doesn't overflow -  // instantly and the user can see at least one successful transaction and some -  // mismtaches before the usiTwiSlave.c library hangs on the line "while ( !txCount );". -  if (count <= 3) rand_byte_count = 2; - -  // generate, save, and send N random byte values -  Wire.beginTransmission(I2C_SLAVE_ADDR); -  for (i = 0; i < rand_byte_count; i++) -    Wire.write(out_rand[i] = random(256)); -  Wire.endTransmission(); -   -  // delay 20 milliseconds to accomodate slave onReceive() callback -  // function. The actual time that slave takes is application dependent, but -  // just storing the master's transmitted data does not take -  // anywhere near 20ms. -  delay(20); -   -  // read N bytes from slave -  req_rtn = Wire.requestFrom(I2C_SLAVE_ADDR, (int)rand_byte_count);      // Request N bytes from slave -  for (i = 0; i < req_rtn; i++) -    in_rand[i] = Wire.read(); - -  // compare in/out data values -  mismatch = false; -  for (i = 0; i < rand_byte_count; i++) -    mismatch = mismatch || (out_rand[i] != in_rand[i]); - -  // increment the error counter if the number of byte variables don't match or -  // if the data itself doesn't match -  if (mismatch || (rand_byte_count != req_rtn))  -  { -    error_count++; -    digitalWrite(ERROR_LED_PIN, HIGH); -    digitalWrite(OK_LED_PIN, LOW); -    // If there's ever an error, reset the ALL_OK_LED -    // and it is not set again until the master resets. -    digitalWrite(ALL_OK_LED_PIN, LOW); -  } -  else -  { -    digitalWrite(ERROR_LED_PIN, LOW); -    digitalWrite(OK_LED_PIN, HIGH); -  } - -  // The rest of the program just displays the results to the serial port -   -  // display total requests so far and error count so far -  snprintf(c_buf, sizeof(c_buf), "req: %3d,err: %3d", count, error_count); -  Serial.println(c_buf); - -  // display the random byte count, the number of bytes read back, and "MATCH"/"MISMATCH" -  snprintf(c_buf, sizeof(c_buf), "size: %2d/%2d,%s", rand_byte_count, req_rtn, rand_byte_count != req_rtn?"MISMATCH  <<--- !!!":"MATCH"); -  Serial.println(c_buf); -   -  // display whether the data compare matched or mismatched -  snprintf(c_buf, sizeof(c_buf), "data: %s", mismatch?"MISMATCH  <<--- !!!":"MATCH"); -  Serial.println(c_buf); - -  // send up to three tx/rx bytes so that random data can be -  // visually verified -  if (rand_byte_count >= 1) -  { -    snprintf(c_buf, sizeof(c_buf), "rand[0]: %02x/%02x", out_rand[0], in_rand[0]); -    Serial.println(c_buf); -  } - -  if (rand_byte_count >= 2) -  { -    snprintf(c_buf, sizeof(c_buf), "rand[1]: %02x/%02x", out_rand[1], in_rand[1]); -    Serial.println(c_buf); -  } - -  if (rand_byte_count >= 3) -  { -    snprintf(c_buf, sizeof(c_buf), "rand[2]: %02x/%02x", out_rand[2], in_rand[2]); -    Serial.println(c_buf); -  } - -  // delay 1 second so user can watch results -  delay(1000); -} diff --git a/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Slave/TinyWireS_Stress_Slave.ino b/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Slave/TinyWireS_Stress_Slave.ino deleted file mode 100644 index c7fbe41..0000000 --- a/digital-driver/firmware/TinyWireS/examples/TinyWireS_Stress_Slave/TinyWireS_Stress_Slave.ino +++ /dev/null @@ -1,143 +0,0 @@ -// --------------------------------- -// Stress test program/example for TinyWireS I2C library. -// Run this slave program on the Attiny. -// Run the other master program on the Arduino Uno R3. -// --------------------------------- -// // Written by Scott Hartog, 2/6/2016, to stress test the TinyWireS library. -// https://github.com/rambo/TinyWire -// -// This project uses the Tiny85 as an I2C slave. -// -// The slave program using TinyWireS, running on a Attiny85, receives -// N bytes of random data in a single receiveEvent() callback and -// stores that data in a global buffer. It then responds the first requestEvent() -// callback with that same data. The requestEvent() callback overwrites the data -// buffer with zeros after responding so it will only respond correctly to the -// first requestEvent() callback after each receiveEvent() callback. Subsequent -// requestEvent() will respond with 0xff for all data bytes. -// -// -// SETUP: -// AtTiny Pin 5 (PB0/SDA) = I2C SDA  -//     connect to SDA on master with external pull-up (~4.7K) -// AtTiny Pin 7 (PB0/SCL) = I2C SCL  -//     connect to SCL on master with external pull-up (~4.7K) -// AtTiny Pin 1 (PB5/!RST) -//     connect to reset on master (or just pull-up) -// -// Please see credits and usage for usiTwiSlave and TinyWireS in the .h files of  -// those libraries. - -#include <avr/sleep.h> -#include <avr/wdt.h> -#include "TinyWireS.h"                  // wrapper class for I2C slave routines - -#define I2C_SLAVE_ADDR  0x26            // i2c slave address (38, 0x26) - -// turns on code that makes the Tiny85 sleep between transactions -// This is optional. The Tiny85 current drops from -// about 2mA to about 20uA when the CPU is put into -// PowerDown sleep mode. -#define USE_CPU_SLEEP - -// global buffer to store data sent from the master. -uint8_t master_data[16]; -// global variable to number of bytes sent from the master. -uint8_t master_bytes; - -// Gets called when the ATtiny receives an i2c write slave request -// This routine runs from the usiTwiSlave interrupt service routine (ISR) -// so interrupts are disabled while it runs. -void receiveEvent(uint8_t num_bytes) -{ -  uint8_t i; - -  // save the number of bytes sent from the master -  master_bytes = num_bytes; - -  // store the data from the master into the data buffer -  for (i = 0; i < master_bytes; i++) -    master_data[i] = TinyWireS.receive(); -     -} - -// Gets called when the ATtiny receives an i2c read slave request -// This routine runs from the usiTwiSlave interrupt service routine (ISR) -// so interrupts are disabled while it runs. -void requestEvent() -{ -  uint8_t i; -   -  // send the data buffer back to the master -  for (i = 0; i < master_bytes; i++) -    TinyWireS.send(master_data[i]); - -  // corrupt the byte values in the data buffer -  // so that any subsequent call won't match -  for (i = 0; i < master_bytes; i++) -    master_data[i] += 0x5a; - -  // corrupt length of the request, but don't make it zero -   -  // if the usiTwiSlave.c is working fine, then this number is completely irrelevant -  // because the requestEvent() callback will not be called again until -  // after the next receiveEvent() callback, so the master_data and -  // master_bytes variables will be overwritten by that call. - -  // If the usiTwiSlave.c has the issue of calling the requestFrom() callback -  // for each byte sent, the buffer will accumulate by this amount *for each byte -  // in the original request*. (This problem is fixed in the recent version.) -  //  -  // Making it zero will obscure the 1-byte send issue in the usiTwiSlave.c -  // that is being tested. -  // Making it small will allow a few requests to succeed before the tx buffer -  // overflows and the usiTwiSlave.c hangs on the "while ( tmphead == txTail );" -  // line -  master_bytes = 2;  -} - -void setup() -{ -  //pinMode(1,OUTPUT);   // This pin can be used for rudimentary debug -   -  // initialize the TinyWireS and usiTwiSlave libraries -  TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode - -  // register the onReceive() callback function -  TinyWireS.onReceive(receiveEvent); -   -  // register the onRequest() callback function -  TinyWireS.onRequest(requestEvent); - - // disable the watchdog timer so that it doesn't -  // cause power-up, code is from datasheet -  // Clear WDRF in MCUSR – MCU Status Register -  // MCUSR provides information on which reset source caused an MCU Reset. -  MCUSR = 0x00; -  // WDTCR - Watchdog Timer Control Register -  // Write logical one to WDCE and WDE (must be done before disabling) -  WDTCR |= ( _BV(WDCE) | _BV(WDE) ); -  // Turn off WDT -  WDTCR = 0x00; - -#ifdef USE_CPU_SLEEP -  // enable power down sleep mode -  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // sleep mode -  sleep_enable(); -#endif - -  sei();                                // enable interrupts - -} - -void loop() -{ - -#ifdef USE_CPU_SLEEP -  // optionally put the CPU to sleep. It will be woken by a USI interrupt -  // when it sees a "start condition" on the I2C bus. Everything interesting -  // happens in the usiTwiSlave ISR. -  sleep_cpu(); -#endif - -} diff --git a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_analog/attiny85_i2c_analog.ino b/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_analog/attiny85_i2c_analog.ino deleted file mode 100644 index 7190c93..0000000 --- a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_analog/attiny85_i2c_analog.ino +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Example sketch for writing to and reading from a slave in transactional manner - * - * NOTE: You must not use delay() or I2C communications will fail, use tws_delay() instead (or preferably some smarter timing system) - * - * On write the first byte received is considered the register addres to modify/read - * On each byte sent or read the register address is incremented (and it will loop back to 0) - * - * You can try this with the Arduino I2C REPL sketch at https://github.com/rambo/I2C/blob/master/examples/i2crepl/i2crepl.ino  - * If you have bus-pirate remember that the older revisions do not like the slave streching the clock, this leads to all sorts of weird behaviour - * Examples use bus-pirate semantics (like the REPL) - * - * The basic idea is: - *  1. Choose your ADC channel (0-X), use "byte ch = 1;" for example. - *  2. Combine the channel and conversion start flag to single calue: byte start_on_ch = (ch | _BV(7)); // This is 0x81 - *  3. Write start_on_ch to the first register on the attiny [ 8 0  81 ] - *  4. Come back later and check the first register [ 8 0 [ r ], if the value is same as ch then the conversion is complete, you can now read the value - *  5. read the value [ 8 2 [ r r ] (first one is low, second high byte) - * - * You need to have at least 8MHz clock on the ATTiny for this to work (and in fact I have so far tested it only on ATTiny85 @8MHz using internal oscillator) - * Remember to "Burn bootloader" to make sure your chip is in correct mode  - */ - - -/** - * Pin notes by Suovula, see also http://hlt.media.mit.edu/?p=1229 - * - * DIP and SOIC have same pinout, however the SOIC chips are much cheaper, especially if you buy more than 5 at a time - * For nice breakout boards see https://github.com/rambo/attiny_boards - * - * Basically the arduino pin numbers map directly to the PORTB bit numbers. - * -// I2C -arduino pin 0 = not(OC1A) = PORTB <- _BV(0) = SOIC pin 5 (I2C SDA, PWM) -arduino pin 2 =           = PORTB <- _BV(2) = SOIC pin 7 (I2C SCL, Analog 1) -// Timer1 -> PWM -arduino pin 1 =     OC1A  = PORTB <- _BV(1) = SOIC pin 6 (PWM) -arduino pin 3 = not(OC1B) = PORTB <- _BV(3) = SOIC pin 2 (Analog 3) -arduino pin 4 =     OC1B  = PORTB <- _BV(4) = SOIC pin 3 (Analog 2) - */ -#define I2C_SLAVE_ADDRESS 0x4 // the 7-bit address (remember to change this when adapting this example) -// Get this from https://github.com/rambo/TinyWire -#include <TinyWireS.h> -// The default buffer size, though we cannot actually affect it by defining it in the sketch -#ifndef TWI_RX_BUFFER_SIZE -#define TWI_RX_BUFFER_SIZE ( 16 ) -#endif -// For the ADC_xxx helpers -#include <core_adc.h> - -// The "registers" we expose to I2C -volatile uint8_t i2c_regs[] = -{ -    0x0, // Status register, writing (1<<7 & channel) will start a conversion on that channel, the flag will be set low when conversion is done. -    0x1, // Averaging count, make this many conversions in row and average the result (well, actually it's a rolling average since we do not want to have the possibility of integer overflows) -    0x0, // low byte  -    0x0, // high byte -}; -const byte reg_size = sizeof(i2c_regs); -// Tracks the current register pointer position -volatile byte reg_position; -// Tracks wheter to start a conversion cycle -volatile boolean start_conversion; -// Counter to track where we are averaging -byte avg_count; -// Some temp value holders -int avg_temp1; -int avg_temp2; - -/** - * This is called for each read request we receive, never put more than one byte of data (with TinyWireS.send) to the  - * send-buffer when using this callback - */ -void requestEvent() -{   -    TinyWireS.send(i2c_regs[reg_position]); -    // Increment the reg position on each read, and loop back to zero -    reg_position++; -    if (reg_position >= reg_size) -    { -        reg_position = 0; -    } -} - -/** - * The I2C data received -handler - * - * This needs to complete before the next incoming transaction (start, data, restart/stop) on the bus does - * so be quick, set flags for long running tasks to be called from the mainloop instead of running them directly, - */ -void receiveEvent(uint8_t howMany) -{ -    if (howMany < 1) -    { -        // Sanity-check -        return; -    } -    if (howMany > TWI_RX_BUFFER_SIZE) -    { -        // Also insane number -        return; -    } - -    reg_position = TinyWireS.receive(); -    howMany--; -    if (!howMany) -    { -        // This write was only to set the buffer for next read -        return; -    } -    while(howMany--) -    { -        i2c_regs[reg_position] = TinyWireS.receive(); -        if (   reg_position == 0 // If it was the first register -            && bitRead(i2c_regs[0], 7) // And the highest bit is set -            && !ADC_ConversionInProgress() // and we do not actually have a conversion running already -            ) -        { -            start_conversion = true; -        } -        reg_position++; -        if (reg_position >= reg_size) -        { -            reg_position = 0; -        } -    } -} - - -void setup() -{ -    // TODO: Tri-state this and wait for input voltage to stabilize  -    pinMode(3, OUTPUT); // OC1B-, Arduino pin 3, ADC -    digitalWrite(3, LOW); // Note that this makes the led turn on, it's wire this way to allow for the voltage sensing above. - -    pinMode(1, OUTPUT); // OC1A, also The only HW-PWM -pin supported by the tiny core analogWrite - -    /** -     * Reminder: taking care of pull-ups is the masters job -     */ - -    TinyWireS.begin(I2C_SLAVE_ADDRESS); -    TinyWireS.onReceive(receiveEvent); -    TinyWireS.onRequest(requestEvent); - -     -    // Whatever other setup routines ? -     -    digitalWrite(3, HIGH); -} - -void loop() -{ -    /** -     * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716) -     * it needs to be called in a very tight loop in order not to miss any (REMINDER: Do *not* use delay() anywhere, use tws_delay() instead). -     * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop. -     */ -    TinyWireS_stop_check(); - -    // Thus stuff is basically copied from wiring_analog.c -    if (start_conversion) -    { -        //Avoid doubled starts -        start_conversion = false; -        byte adcpin = (i2c_regs[0] & 0x7f); // Set the channel from the control reg, dropping the highest bit. -#if defined( CORE_ANALOG_FIRST ) -        if ( adcpin >= CORE_ANALOG_FIRST ) adcpin -= CORE_ANALOG_FIRST; // allow for channel or pin numbers -#endif -        // NOTE: These handy helpers (ADC_xxx) are only present in the tiny-core, for other cores you need to check their wiring_analog.c source. -        ADC_SetInputChannel( (adc_ic_t)adcpin ); // we need to typecast -        ADC_StartConversion(); -        // Reset these variables -        avg_count = 0; -        avg_temp2 = 0; -    } -     -    if (   bitRead(i2c_regs[0], 7) // We have conversion flag up -        && !ADC_ConversionInProgress()) // But the conversion is complete -    { -        // So handle it -        avg_temp1 = ADC_GetDataRegister(); -        // Rolling average -        if (avg_count) -        { -            avg_temp2 = (avg_temp2+avg_temp1)/2; -        } -        else -        { -            avg_temp2 = avg_temp1; -        } -        avg_count++; -        if (avg_count >= i2c_regs[1]) -        { -            // All done, set the bytes to registers -            cli(); -            i2c_regs[2] = lowByte(avg_temp2); -            i2c_regs[3] = highByte(avg_temp2); -            sei(); -            // And clear the conversion flag so the master knows we're ready -            bitClear(i2c_regs[0], 7); -        } -        else -        { -            // Re-trigger conversion -            ADC_StartConversion(); -        } -    } - -} diff --git a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave/attiny85_i2c_slave.ino b/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave/attiny85_i2c_slave.ino deleted file mode 100644 index df2532f..0000000 --- a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave/attiny85_i2c_slave.ino +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Example sketch for writing to and reading from a slave in transactional manner - * - * NOTE: You must not use delay() or I2C communications will fail, use tws_delay() instead (or preferably some smarter timing system) - * - * On write the first byte received is considered the register addres to modify/read - * On each byte sent or read the register address is incremented (and it will loop back to 0) - * - * You can try this with the Arduino I2C REPL sketch at https://github.com/rambo/I2C/blob/master/examples/i2crepl/i2crepl.ino  - * If you have bus-pirate remember that the older revisions do not like the slave streching the clock, this leads to all sorts of weird behaviour - * - * To read third value (register number 2 since counting starts at 0) send "[ 8 2 [ 9 r ]", value read should be 0xBE - * If you then send "[ 9 r r r ]" you should get 0xEF 0xDE 0xAD as response (demonstrating the register counter looping back to zero) - * - * You need to have at least 8MHz clock on the ATTiny for this to work (and in fact I have so far tested it only on ATTiny85 @8MHz using internal oscillator) - * Remember to "Burn bootloader" to make sure your chip is in correct mode  - */ - - -/** - * Pin notes by Suovula, see also http://hlt.media.mit.edu/?p=1229 - * - * DIP and SOIC have same pinout, however the SOIC chips are much cheaper, especially if you buy more than 5 at a time - * For nice breakout boards see https://github.com/rambo/attiny_boards - * - * Basically the arduino pin numbers map directly to the PORTB bit numbers. - * -// I2C -arduino pin 0 = not(OC1A) = PORTB <- _BV(0) = SOIC pin 5 (I2C SDA, PWM) -arduino pin 2 =           = PORTB <- _BV(2) = SOIC pin 7 (I2C SCL, Analog 1) -// Timer1 -> PWM -arduino pin 1 =     OC1A  = PORTB <- _BV(1) = SOIC pin 6 (PWM) -arduino pin 3 = not(OC1B) = PORTB <- _BV(3) = SOIC pin 2 (Analog 3) -arduino pin 4 =     OC1B  = PORTB <- _BV(4) = SOIC pin 3 (Analog 2) - */ -#define I2C_SLAVE_ADDRESS 0x4 // the 7-bit address (remember to change this when adapting this example) -// Get this from https://github.com/rambo/TinyWire -#include <TinyWireS.h> -// The default buffer size, Can't recall the scope of defines right now -#ifndef TWI_RX_BUFFER_SIZE -#define TWI_RX_BUFFER_SIZE ( 16 ) -#endif - - -volatile uint8_t i2c_regs[] = -{ -    0xDE,  -    0xAD,  -    0xBE,  -    0xEF,  -}; -// Tracks the current register pointer position -volatile byte reg_position; -const byte reg_size = sizeof(i2c_regs); - -/** - * This is called for each read request we receive, never put more than one byte of data (with TinyWireS.send) to the  - * send-buffer when using this callback - */ -void requestEvent() -{   -    TinyWireS.send(i2c_regs[reg_position]); -    // Increment the reg position on each read, and loop back to zero -    reg_position++; -    if (reg_position >= reg_size) -    { -        reg_position = 0; -    } -} - -// TODO: Either update this to use something smarter for timing or remove it alltogether -void blinkn(uint8_t blinks) -{ -    digitalWrite(3, HIGH); -    while(blinks--) -    { -        digitalWrite(3, LOW); -        tws_delay(50); -        digitalWrite(3, HIGH); -        tws_delay(100); -    } -} - -/** - * The I2C data received -handler - * - * This needs to complete before the next incoming transaction (start, data, restart/stop) on the bus does - * so be quick, set flags for long running tasks to be called from the mainloop instead of running them directly, - */ -void receiveEvent(uint8_t howMany) -{ -    if (howMany < 1) -    { -        // Sanity-check -        return; -    } -    if (howMany > TWI_RX_BUFFER_SIZE) -    { -        // Also insane number -        return; -    } - -    reg_position = TinyWireS.receive(); -    howMany--; -    if (!howMany) -    { -        // This write was only to set the buffer for next read -        return; -    } -    while(howMany--) -    { -        i2c_regs[reg_position] = TinyWireS.receive(); -        reg_position++; -        if (reg_position >= reg_size) -        { -            reg_position = 0; -        } -    } -} - - -void setup() -{ -    // TODO: Tri-state this and wait for input voltage to stabilize  -    pinMode(3, OUTPUT); // OC1B-, Arduino pin 3, ADC -    digitalWrite(3, LOW); // Note that this makes the led turn on, it's wire this way to allow for the voltage sensing above. - -    pinMode(1, OUTPUT); // OC1A, also The only HW-PWM -pin supported by the tiny core analogWrite - -    /** -     * Reminder: taking care of pull-ups is the masters job -     */ - -    TinyWireS.begin(I2C_SLAVE_ADDRESS); -    TinyWireS.onReceive(receiveEvent); -    TinyWireS.onRequest(requestEvent); - -     -    // Whatever other setup routines ? -     -    digitalWrite(3, HIGH); -} - -void loop() -{ -    /** -     * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716) -     * it needs to be called in a very tight loop in order not to miss any (REMINDER: Do *not* use delay() anywhere, use tws_delay() instead). -     * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop. -     */ -    TinyWireS_stop_check(); -} diff --git a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave_task/attiny85_i2c_slave_task.ino b/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave_task/attiny85_i2c_slave_task.ino deleted file mode 100644 index 4b3f269..0000000 --- a/digital-driver/firmware/TinyWireS/examples/attiny85_i2c_slave_task/attiny85_i2c_slave_task.ino +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Example sketch for writing to and reading from a slave in transactional manner, it will also blink a led attached to pin 3 (which is the SOIC pin 2) - * (provided you're using one of my ATTiny85 boards from https://github.com/rambo/attiny_boards with the led soldered)  - * - * NOTE: You must not use delay() or I2C communications will fail, use tws_delay() instead (or preferably some smarter timing system, like the Task library used in this example) - * - * On write the first byte received is considered the register addres to modify/read - * On each byte sent or read the register address is incremented (and it will loop back to 0) - * - * You can try this with the Arduino I2C REPL sketch at https://github.com/rambo/I2C/blob/master/examples/i2crepl/i2crepl.ino  - * If you have bus-pirate remember that the older revisions do not like the slave streching the clock, this leads to all sorts of weird behaviour - * - * By default this blinks the SOS morse pattern and then has long on/off time to indicate end of pattern, send [ 8 0 32 ] (using the REPL/bus-pirate  - * semantics) to make the delay per bit smaller (and thus blinking faster). The pattern lenght is calculated from the register size, it would be fairly - * trivial to make it yet another variable changeable via I2C. - * - * You need to have at least 8MHz clock on the ATTiny for this to work (and in fact I have so far tested it only on ATTiny85 @8MHz using internal oscillator) - * Remember to "Burn bootloader" to make sure your chip is in correct mode  - */ - - -/** - * Pin notes by Suovula, see also http://hlt.media.mit.edu/?p=1229 - * - * DIP and SOIC have same pinout, however the SOIC chips are much cheaper, especially if you buy more than 5 at a time - * For nice breakout boards see https://github.com/rambo/attiny_boards - * - * Basically the arduino pin numbers map directly to the PORTB bit numbers. - * -// I2C -arduino pin 0 = not(OC1A) = PORTB <- _BV(0) = SOIC pin 5 (I2C SDA, PWM) -arduino pin 2 =           = PORTB <- _BV(2) = SOIC pin 7 (I2C SCL, Analog 1) -// Timer1 -> PWM -arduino pin 1 =     OC1A  = PORTB <- _BV(1) = SOIC pin 6 (PWM) -arduino pin 3 = not(OC1B) = PORTB <- _BV(3) = SOIC pin 2 (Analog 3) -arduino pin 4 =     OC1B  = PORTB <- _BV(4) = SOIC pin 3 (Analog 2) - */ -#define I2C_SLAVE_ADDRESS 0x4 // the 7-bit address (remember to change this when adapting this example) -// Get this from https://github.com/rambo/TinyWire -#include <TinyWireS.h> -// The default buffer size, Can't recall the scope of defines right now -#ifndef TWI_RX_BUFFER_SIZE -#define TWI_RX_BUFFER_SIZE ( 16 ) -#endif -// Get this library from http://bleaklow.com/files/2010/Task.tar.gz  -// and read http://bleaklow.com/2010/07/20/a_very_simple_arduino_task_manager.html for background and instructions -#include <Task.h> -#include <TaskScheduler.h> - -// The led is connected so that the tiny sinks current -#define LED_ON LOW -#define LED_OFF HIGH - -// The I2C registers -volatile uint8_t i2c_regs[] = -{ -    150, // Delay between each position (ms, remeber that this isa byte so 255 is max) -    B10101000, // SOS pattern  -    B01110111,  -    B01110001, -    B01010000,  -    B00000000, -    B11111111, // Long on and off to mark end of pattern -    B00000000, -}; -// Tracks the current register pointer position -volatile byte reg_position; -const byte reg_size = sizeof(i2c_regs); - - -/** - * BEGIN: PatternBlinker task based on the Task library Blinker example - */ -// Timed task to blink a LED. -const byte pattern_lenght = (sizeof(i2c_regs)-1) * 8; // bits (first is the speed, rest is the pattern) -class PatternBlinker : public TimedTask -{ -public: -    // Create a new blinker for the specified pin and rate. -    PatternBlinker(uint8_t _pin); -    virtual void run(uint32_t now); -private: -    uint8_t pin;      // LED pin. -    uint8_t pattern_position; // Used to calcuate the register and bit offset -}; - -PatternBlinker::PatternBlinker(uint8_t _pin) -: TimedTask(millis()), -  pin(_pin) -{ -    pinMode(pin, OUTPUT);     // Set pin for output. -} - -void PatternBlinker::run(uint32_t now) -{ -    // Start by setting the next runtime -    incRunTime(i2c_regs[0]); - -    // Written out for clear code, the complier might optimize it to something more efficient even without it being unrolled into one line -    byte reg = i2c_regs[1+(pattern_position/8)]; // Get the register where the bit pattern position is stored -    byte shift_amount = 7 - (pattern_position % 7); // To have "natural" left-to-right pattern flow. -    bool state = (reg >> shift_amount) & 0x1; -    if (state) { -        digitalWrite(pin, LED_ON); -    } else { -        digitalWrite(pin, LED_OFF); -    } -    // Calculate the next pattern position -    pattern_position = (pattern_position+1) % pattern_lenght; -} -/** - * END: PatternBlinker task copied from the Task library example - */ -/** - * BEGIN: I2C Stop flag checker - * - * This task needs to run almost all the time due to the USI I2C implementation limitations - * - * So I2CStopCheck_YIELD_TICKS below is used to specify how often the task is run, not it's every 4 ticks - */ -#define I2CStopCheck_YIELD_TICKS 4 -class I2CStopCheck : public Task -{ -public: -    I2CStopCheck(); -    virtual void run(uint32_t now); -    virtual bool canRun(uint32_t now); -private: -    uint8_t yield_counter; // Incremented on each canRun call, used to yield to other tasks. -}; - -I2CStopCheck::I2CStopCheck() -: Task() -{ -} - -// We can't just return true since then no other task could ever run (since we have the priority) -bool I2CStopCheck::canRun(uint32_t now) -{ -    yield_counter++; -    bool ret = false; -    if (yield_counter == I2CStopCheck_YIELD_TICKS) -    { -        ret = true; -        yield_counter = 0; -    } -    return ret; -} - -void I2CStopCheck::run(uint32_t now) -{ -    TinyWireS_stop_check(); -} -/** - * END: I2C Stop flag checker - */ - -// Create the tasks. -PatternBlinker blinker(3); -I2CStopCheck checker; - -// Tasks are in priority order, only one task is run per tick -Task *tasks[] = { &checker, &blinker, }; -TaskScheduler sched(tasks, NUM_TASKS(tasks)); - - -/** - * This is called for each read request we receive, never put more than one byte of data (with TinyWireS.send) to the  - * send-buffer when using this callback - */ -void requestEvent() -{   -    TinyWireS.send(i2c_regs[reg_position]); -    // Increment the reg position on each read, and loop back to zero -    reg_position++; -    if (reg_position >= reg_size) -    { -        reg_position = 0; -    } -} - -/** - * The I2C data received -handler - * - * This needs to complete before the next incoming transaction (start, data, restart/stop) on the bus does - * so be quick, set flags for long running tasks to be called from the mainloop instead of running them directly, - */ -void receiveEvent(uint8_t howMany) -{ -    if (howMany < 1) -    { -        // Sanity-check -        return; -    } -    if (howMany > TWI_RX_BUFFER_SIZE) -    { -        // Also insane number -        return; -    } - -    reg_position = TinyWireS.receive(); -    howMany--; -    if (!howMany) -    { -        // This write was only to set the buffer for next read -        return; -    } -    while(howMany--) -    { -        i2c_regs[reg_position] = TinyWireS.receive(); -        reg_position++; -        if (reg_position >= reg_size) -        { -            reg_position = 0; -        } -    } -} - - -void setup() -{ -    // TODO: Tri-state this and wait for input voltage to stabilize  -    pinMode(3, OUTPUT); // OC1B-, Arduino pin 3, ADC -    digitalWrite(3, LED_ON); // Note that this makes the led turn on, it's wire this way to allow for the voltage sensing above. - -    pinMode(1, OUTPUT); // OC1A, also The only HW-PWM -pin supported by the tiny core analogWrite - -    /** -     * Reminder: taking care of pull-ups is the masters job -     */ - -    TinyWireS.begin(I2C_SLAVE_ADDRESS); -    TinyWireS.onReceive(receiveEvent); -    TinyWireS.onRequest(requestEvent); - -     -    // Whatever other setup routines ? -     -    digitalWrite(3, LED_OFF); -} - -void loop() -{ -    // Run the scheduler - never returns. -    sched.run(); -} | 
