Skip to content

Commit

Permalink
Fix for broken I2C functionality on x41 chips
Browse files Browse the repository at this point in the history
    - CLK/SDA Pins are swapped and comments are misleading
    - Pin swap Discussion can be viewed here:
        #833
    - Fix recursive call: Wire.cpp in soft master / hw slave
  • Loading branch information
Ali Shah committed Feb 16, 2024
1 parent 91e0fb9 commit dda3c5a
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 19 deletions.
3 changes: 1 addition & 2 deletions avr/libraries/Wire/src/SoftI2CMaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,14 @@ void i2c_delay_half(void)
__asm__ __volatile__ (" ret");
// 7 cycles for call and return
#else
uint8_t temp = 0;
__asm__ __volatile__
(
" ldi r25, %[DELAY] ; load delay constant ; 4C \n\t"
"_Lidelay: \n\t"
" dec r25 ; decrement counter ; 4C + xC \n\t"
" brne _Lidelay ; 5C+(x-1)2C + xC\n\t"
" ret ; 9C+(x-1)2C + xC = 7C + xC"
:"+d" ((uint8_t) temp) : [DELAY] "M" I2C_DELAY_COUNTER);
: : [DELAY] "M" I2C_DELAY_COUNTER : "r25");
// 7 cycles + 3 times x cycles
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions avr/libraries/Wire/src/SoftWire.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ class SoftWire : public Stream
beginTransmission(address);
// the maximum size of internal address is 3 bytes
if (isize > 3) {
isize = 3;
isize = 3;
}
// write internal register address - most significant byte first
while (isize-- > 0)
write((uint8_t)(iaddress >> (isize*8)));
write((uint8_t)(iaddress >> (isize*8)));
endTransmission(false);
}
// clamp to buffer length
Expand Down
9 changes: 4 additions & 5 deletions avr/libraries/Wire/src/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,10 +732,9 @@
return value;
}
#else // Implementations for slave only mode
void TwoWire::begin(int address) {
begin((uint8_t)address);
void TwoWire::begin(uint8_t address) {
TinyWireS.begin((uint8_t)address, 0);
}

// must be called in slave onRequest event callback
size_t TwoWire::write(uint8_t data) {
size_t numBytes = 0;
Expand Down Expand Up @@ -814,15 +813,15 @@
/* END MASTER ONLY METHODS */

/* BEGIN SLAVE ONLY METHODS */
#if defined(SLAVE_MASTER_ONLY) || defined(WIRE_BOTH)
#if defined(WIRE_SLAVE_ONLY) || defined(WIRE_BOTH)

void TwoWire::onReceive( void (*function)(size_t)) {
TinyWireS.onReceive(function);
}
void TwoWire::onReceive( void (*function)(int)) {
// arduino api compatibility fixer:
// really hope size parameter will not exceed 2^31 :)
static_assert(sizeof(int) == sizeof(size_t), "something is wrong in Arduino kingdom");
static_assert(sizeof(int) == sizeof(size_t), "something is wrong in the Arduino kingdom");
TinyWireS.onReceive(reinterpret_cast<void(*)(size_t)>(function));
}
// sets function called on slave read
Expand Down
10 changes: 5 additions & 5 deletions avr/variants/tinyx41_cw/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,13 @@ anyway) and instead just use TOCPMCOE bits to control whether PWM is output */
* a markedly inferior software TWI master implementation if that is requested.
*---------------------------------------------------------------------------*/

/* Hardware I2C slave */
#define SCL PIN_PA6
/* Used by hardware I2C slave and software I2C master */
#define SCL PIN_PA4
#define SCL_PORT (PORTA)
#define SCL_PIN (6)
#define SDA PIN_PA4
#define SCL_PIN (4)
#define SDA PIN_PA6
#define SDA_PORT (PORTA)
#define SDA_PIN (4)
#define SDA_PIN (6)

/* Hardware SPI */
#if defined(SET_REMAP) && SET_REMAP > 1
Expand Down
10 changes: 5 additions & 5 deletions avr/variants/tinyx41_legacy/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,13 @@ anyway) and instead just use TOCPMCOE bits to control whether PWM is output */
* a markedly inferior software TWI master implementation if that is requested.
*---------------------------------------------------------------------------*/

/* Hardware I2C slave */
#define SCL PIN_PA6
/* Used by hardware I2C slave and software I2C master */
#define SCL PIN_PA4
#define SCL_PORT (PORTA)
#define SCL_PIN (6)
#define SDA PIN_PA4
#define SCL_PIN (4)
#define SDA PIN_PA6
#define SDA_PORT (PORTA)
#define SDA_PIN (4)
#define SDA_PIN (6)

/* Hardware SPI */
#if defined(SET_REMAP) && SET_REMAP > 1
Expand Down

0 comments on commit dda3c5a

Please sign in to comment.