New to GCB and the first few test projects I created have worked OK. So I appologise if I paosted incorrectly. I did do some searches for a similar issue, but pinned nothing down.
Moved onto something more complicated with being an I2C Slave on an ATTiny84a. I have attached a ZIP of the files that I think are relevant. Let me know if you need anything else.
GCB version: 1.76.2 Release: 23074
Basically the code appears to referance TW (Twin Wire) hardware, but the 84a uses a USI (Universal Serial Interface) for I2C communications. So when you compile you get an undeclared register (TWCR). Which is not surprising as the hardware is USIxxxx.
Thank you for your reply. I had worked out that theT84 (and a range of other Atmel devices) used different hardware for I2C. It is a shame that the USI hardware is not supported by GCB currently.
Although I'm well versed with BASIC, sadly I'm not in a position to write the required GCB code to support I2C via USI at this time. For this project, I shall return to using C/C++, where the relevant hardware libraries already exist. The project timelines do not have resources to code and test drivers. And I'm not conversant enough with GCB and I2C at this time to make a good job of such a task. I'm not interested in bit banging an implementation for an I2C slave. Various forums (including AVRFreaks) indicate that I2C slave bit banging is unreliable on this hardware.
If you have a link to implementing such addons so that such a library can be included into any T84 project automatically (not via include, but detected by the compilation process), I'll gladly take a look in the future. But it appears today, that GCB does not fully support the T84 hardware (and other models that use USI).
Could this be noted in the GCB IC2 documentation that USI based devices are NOT supported please.
Adam.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is an untested implementation of USI I2C Slave
GCBASIC library for USI TWI (I2C) Slave driver on ATtiny84A
Implements TWI slave functionality using USI module
Based on Atmel AVR312: Using the USI module as an I2C slave
Created for ATtiny84A with SDA on PA6 and SCL on PA4
What Does it Do?
The main loop in the the example GCBASIC program that demonstrates how to use the USI library functions to configure an ATtiny84A microcontroller as an I2C slave device.
Functionality
Initializes the ATtiny84A as an I2C Slave:
Sets the I2C slave address to 0x20 (32 in decimal) using USI_TWI_Slave_Init(0x20).
Configures the USI module to handle I2C communication (SDA on PA6, SCL on PA4).
Runs a Loop to Process I2C Data:
Checks if data is available in the receive buffer using USI_TWI_Available().
If data is available, reads a byte using USI_TWI_Read().
Writes the received byte plus 1 back to the transmit buffer using USI_TWI_Write(Data + 1).
This creates an "echo + 1" behavior: if the master sends 0x05, the slave responds with 0x06.
Purpose: It’s a simple test program to verify the I2C slave functionality. The slave responds to I2C write requests by storing received data and to read requests by sending back the last received data incremented by 1.
Set Up the Hardware
Microcontroller: Use an ATtiny84A (or ATtiny84, as they’re compatible).
I2C Pins:
SDA: PA6 (pin 7 on the 14-pin SOIC package).
SCL: PA4 (pin 9).
Pull-Up Resistors: Connect 4.7kΩ pull-up resistors from SDA and SCL to VCC (typically 3.3V or 5V, matching your setup).
Power Supply: Connect VCC and GND to a stable 3.3V or 5V supply. The code assumes an 8 MHz internal oscillator, so no external crystal is needed unless you’ve changed the fuses.
I2C Master: Use a microcontroller (e.g., Arduino with Wire library), Raspberry Pi, or I2C master device to communicate with the ATtiny84A. Connect the master’s SDA and SCL pins to the ATtiny84A’s PA6 and PA4, ensuring a common ground.
Test with an I2C Master
Write Test:
Use an I2C master to send data to address 0x20.
Example (Arduino with Wire library):
#include<Wire.h>#define SLAVE_ADDRESS 0x20 // I2C address of ATtiny84A (set in main.gcb)#define TEST_BYTE 0x05 // Byte to send to the slavevoidsetup(){// Initialize I2C as masterWire.begin();// Initialize Serial for debuggingSerial.begin(9600);Serial.println("I2C Master Test Program Started");}voidloop(){// Write test byte to slaveSerial.print("Sending 0x");Serial.print(TEST_BYTE,HEX);Serial.print(" to address 0x");Serial.println(SLAVE_ADDRESS,HEX);Wire.beginTransmission(SLAVE_ADDRESS);Wire.write(TEST_BYTE);// Send 0x05intwriteResult=Wire.endTransmission();if(writeResult==0){Serial.println("Write successful");}else{Serial.print("Write failed with error: ");Serial.println(writeResult);}// Wait briefly to ensure slave processes the writedelay(10);// Read one byte from slaveSerial.print("Reading from address 0x");Serial.println(SLAVE_ADDRESS,HEX);Wire.requestFrom(SLAVE_ADDRESS,1);// Request 1 byteif(Wire.available()){bytereceived=Wire.read();Serial.print("Received: 0x");Serial.println(received,HEX);// Should print 0x06 (TEST_BYTE + 1)}else{Serial.println("No data received");}// Wait before next testSerial.println("---");delay(1000);}
The ATtiny84A will receives 0x05, stores it in TWI_RxBuf, and adds 0x06 to TWI_TxBuf.
Many thanks for the prompt support and example. I have a hardware setup on the bench and should be able to take a look-see tomorrow. I will report back. However, power outages here are not helping anything, hopeully they will be cleared up overnight.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
New to GCB and the first few test projects I created have worked OK. So I appologise if I paosted incorrectly. I did do some searches for a similar issue, but pinned nothing down.
Moved onto something more complicated with being an I2C Slave on an ATTiny84a. I have attached a ZIP of the files that I think are relevant. Let me know if you need anything else.
GCB version: 1.76.2 Release: 23074
Basically the code appears to referance TW (Twin Wire) hardware, but the 84a uses a USI (Universal Serial Interface) for I2C communications. So when you compile you get an undeclared register (TWCR). Which is not surprising as the hardware is USIxxxx.
Am I in error, or the compiler?
Many thanks,
Adam.
Hello Adam,
These chips use USI for TWI and the GCBASIC library assume the TWI registers not the USI.
You can implement the USI will some ease but it may be a lot easier to use software I2C for your solution.
Anobium,
Thank you for your reply. I had worked out that theT84 (and a range of other Atmel devices) used different hardware for I2C. It is a shame that the USI hardware is not supported by GCB currently.
Although I'm well versed with BASIC, sadly I'm not in a position to write the required GCB code to support I2C via USI at this time. For this project, I shall return to using C/C++, where the relevant hardware libraries already exist. The project timelines do not have resources to code and test drivers. And I'm not conversant enough with GCB and I2C at this time to make a good job of such a task. I'm not interested in bit banging an implementation for an I2C slave. Various forums (including AVRFreaks) indicate that I2C slave bit banging is unreliable on this hardware.
If you have a link to implementing such addons so that such a library can be included into any T84 project automatically (not via include, but detected by the compilation process), I'll gladly take a look in the future. But it appears today, that GCB does not fully support the T84 hardware (and other models that use USI).
Could this be noted in the GCB IC2 documentation that USI based devices are NOT supported please.
Adam.
If the C libraries are published then porting is a relatively easy task. The datasheet was vague on how to use USI.
If that is the case. Do you want a link for a good library, or do you have some notes to port and I'll take a bash?
:-)
Post what source is out there.
https://github.com/rambo/TinyWire/tree/master/TinyWireS
There are plenty of Master libraries to choose from.
There are also Atmel Application Notes: 310 and 312 covering using the USI as TWI. Covering Master and Slave modes respectively.
Here is an untested implementation of USI I2C Slave
What Does
it
Do?The
main loop
in the the example GCBASIC program that demonstrates how to use theUSI
library functions to configure an ATtiny84A microcontroller as an I2C slave device.Functionality
0x20
(32 in decimal) usingUSI_TWI_Slave_Init(0x20)
.USI_TWI_Available()
.USI_TWI_Read()
.USI_TWI_Write(Data + 1)
.0x05
, the slave responds with0x06
.Purpose: It’s a simple test program to verify the I2C slave functionality. The slave responds to I2C write requests by storing received data and to read requests by sending back the last received data incremented by 1.
Microcontroller: Use an ATtiny84A (or ATtiny84, as they’re compatible).
I2C Pins:
SDA: PA6 (pin 7 on the 14-pin SOIC package).
SCL: PA4 (pin 9).
Pull-Up Resistors: Connect 4.7kΩ pull-up resistors from SDA and SCL to VCC (typically 3.3V or 5V, matching your setup).
Power Supply: Connect VCC and GND to a stable 3.3V or 5V supply. The code assumes an 8 MHz internal oscillator, so no external crystal is needed unless you’ve changed the fuses.
I2C Master: Use a microcontroller (e.g., Arduino with Wire library), Raspberry Pi, or I2C master device to communicate with the ATtiny84A. Connect the master’s SDA and SCL pins to the ATtiny84A’s PA6 and PA4, ensuring a common ground.
Write Test:
Use an I2C master to send data to address 0x20.
Example (Arduino with Wire library):
The ATtiny84A will receives 0x05, stores it in TWI_RxBuf, and adds 0x06 to TWI_TxBuf.
Many thanks for the prompt support and example. I have a hardware setup on the bench and should be able to take a look-see tomorrow. I will report back. However, power outages here are not helping anything, hopeully they will be cleared up overnight.
The logic will need testing and validating. It may, or it may not work. :-)