Electronic Wednesday 27/05

Hi all
I’ll be on the discord server tonight fron 1900.

Talk to you all there

In tonights discussion we got into some detailed stuff on Atmel AVR and I2C. Mainly this was between myself and Jono. I have gone back through my notes and this is what I found.

Devices like the attiny2313 and attiny4313 now come with a Universal Serial Interface (USI). Basically a pair of shift registers and enough glue logic to implement either SPI or I2C interfaces without resorting to bit bang.

SPI Master

There are a couple of setup tasks:

  1. Determine pins used by USI and their associated port

  2. Select another GPIO to operate as /CS; this is not supported by the USI interface

  3. Set USCK, DO and /CS pins as outputs in the relevant DDRx register

  4. Select a method of clocking the bits out

    // SPI mode 0 example
    // - clock idle low
    // - data sampled on SCK rising edge
    // - data shifted on SCK trailing edge
    // NB. Manually clocking the bits out
    // i.e. one step above a bit bang solution

    // Setup

    DDRx = _BV(USCK_BIT) | _BV(DO_BIT) | _BV(CS_BIT) ; // USCK, DO and /CS as outputs
    USICR = _BV(USIWM0); // USI in 3 wire (SPI) mode

    // USI IO function
    uint8_t usi_transact(uint8_t b) {

     USIDR = b;                                    // Load data for output, DO updates immediately
     for (int i = 0; i < 8; i++) {
         USICR = _BV(USIWM0) | _BV(USITC);   // USCK goes high, DI sampled
         USICR = _BV(USIWM0) | _BV(USICLK) | _BV(USITC); // USCK goes low, data shifts 1 bit
     return USIDR;


1 Like

Realise that this is an SPI example, not i2c. My point is to show that it operates at a much lower level than you would expect. You have to get the code to drive the clock. I imagine that an i2c port using the USI will need to do a fair bit of its own heavy lifting.

Had a quick search regarding USI and I2C, this looks pretty good: https://www.instructables.com/id/ATTiny-USI-I2C-The-detailed-in-depth-and-infor/

Good stuff @sjdavies