#include #include #include #include "xperipherals_i2c.h" #ifdef XPERIPHERALS_I2C_1 #if XPERIPHERALS_I2C_1__SCL_PORT != XPERIPHERALS_I2C_1__SDA_PORT //on tile[XPERIPHERALS_I2C_1__TILE_NUMBER] : port _xperipherals_i2c_1__port_scl = XPERIPHERALS_I2C_1__SCL_PORT; //on tile[XPERIPHERALS_I2C_1__TILE_NUMBER] : port _xperipherals_i2c_1__port_sda = XPERIPHERALS_I2C_1__SDA_PORT; #else //on tile[XPERIPHERALS_I2C_1__TILE_NUMBER] : port _xperipherals_i2c_1__port = XPERIPHERALS_I2C_1__SCL_PORT; xbyte _xperipherals_i2c_1__shadow = 0; #endif #if XPERIPHERALS_I2C_1__BUS_MASTER timer _xperipherals_i2c_1__timer; int _xperipherals_i2c_1__time; #else xbyte _xperipherals_i2c_1__scl; xbyte _xperipherals_i2c_1__sda; xbyte _xperipherals_i2c_1__pins; #endif int _xperipherals_i2c_1__state; int _xperipherals_i2c_1__shift; xbyte _xperipherals_i2c_1__data; xbyte _xperipherals_i2c_1__ackflag; // Calulate based on current system clock frequency #define _XPERIPHERALS_I2C_1__TIME_BASE ((400000 / XPERIPHERALS_I2C_1__BIT_RATE) * 62) #if XPERIPHERALS_I2C_1__SCL_PORT != XPERIPHERALS_I2C_1__SDA_PORT xbyte _xperipherals_i2c_1__read_scl( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_1__ACTIVE_HIGH == TRUE _xperipherals_i2c_1__port_scl <: 1; #else _xperipherals_i2c_1__port_scl :> bit; #endif return bit; } xbyte _xperipherals_i2c_1__read_sda( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_1__ACTIVE_HIGH == TRUE _xperipherals_i2c_1__port_sda <: 1; #else _xperipherals_i2c_1__port_sda :> bit; #endif return bit; } #if XPERIPHERALS_I2C_1__BUS_MASTER void _xperipherals_i2c_1__clear_scl( void ) {_xperipherals_i2c_1__port_scl <: 0;} void _xperipherals_i2c_1__clear_sda( void ) {_xperipherals_i2c_1__port_sda <: 0;} #else xbyte _xperipherals_i2c_1__clear_scl( void ) {return 0;} xbyte _xperipherals_i2c_1__clear_sda( void ) {return 0;} #endif #else xbyte _xperipherals_i2c_1__read_scl( void ) { _xperipherals_i2c_1__shadow |= (1 << XPERIPHERALS_I2C_1__SCL_BIT_POS); _xperipherals_i2c_1__port <: _xperipherals_i2c_1__shadow; return 0; } xbyte _xperipherals_i2c_1__read_sda( void ) { _xperipherals_i2c_1__shadow |= (1 << XPERIPHERALS_I2C_1__SDA_BIT_POS); _xperipherals_i2c_1__port <: _xperipherals_i2c_1__shadow; return 0; } void _xperipherals_i2c_1__clear_scl( void ) { _xperipherals_i2c_1__shadow &= ~(1 << XPERIPHERALS_I2C_1__SCL_BIT_POS); _xperipherals_i2c_1__port <: _xperipherals_i2c_1__shadow; } void _xperipherals_i2c_1__clear_sda( void ) { _xperipherals_i2c_1__shadow &= ~(1 << XPERIPHERALS_I2C_1__SDA_BIT_POS); _xperipherals_i2c_1__port <: _xperipherals_i2c_1__shadow; } #endif xbyte xperipherals_i2c_1__get_data( void ) {return _xperipherals_i2c_1__data;} xbyte xperipherals_i2c_1__get_ackflag( void ) {return _xperipherals_i2c_1__ackflag;} int xperipherals_i2c_1__start( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_1__begin_start(); while( TRUE ) { select {case xperipherals_i2c_1__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_1__stop( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_1__begin_stop(); while( TRUE ) { select {case xperipherals_i2c_1__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_1__write( xbyte data, xbyte& ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_1__begin_write( data ); while( TRUE ) { select {case xperipherals_i2c_1__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } ack_flag = _xperipherals_i2c_1__ackflag; return status; } int xperipherals_i2c_1__read( xbyte& data ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_1__begin_read(); while( TRUE ) { select {case xperipherals_i2c_1__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } data = _xperipherals_i2c_1__data; return status; } int xperipherals_i2c_1__ack( xbyte ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_1__begin_ack( ack_flag ); while( TRUE ) { select {case xperipherals_i2c_1__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } #if XPERIPHERALS_I2C_1__BUS_MASTER void xperipherals_i2c_1__initialize( void ) { _xperipherals_i2c_1__state = 0; _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__read_sda(); _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; _xperipherals_i2c_1__timer when timerafter( _xperipherals_i2c_1__time + 10 * _XPERIPHERALS_I2C_1__TIME_BASE ) :> void; } void xperipherals_i2c_1__begin_start( void ) { _xperipherals_i2c_1__state = 1; _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; } void xperipherals_i2c_1__begin_write( xbyte data ) { _xperipherals_i2c_1__data = data; _xperipherals_i2c_1__state = 4; _xperipherals_i2c_1__shift = 7; _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; } void xperipherals_i2c_1__begin_read( void ) { _xperipherals_i2c_1__state = 11; _xperipherals_i2c_1__shift = 7; _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; } void xperipherals_i2c_1__begin_ack( xbool ack_flag ) { _xperipherals_i2c_1__data = ack_flag != 0; _xperipherals_i2c_1__state = 16; _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; } void xperipherals_i2c_1__begin_stop( void ) { _xperipherals_i2c_1__state = 20; _xperipherals_i2c_1__timer :> _xperipherals_i2c_1__time; } int _xperipherals_i2c_1__io_continue( void ) { switch( _xperipherals_i2c_1__state ) { // Start Condition case 1: _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__state = 2; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 2: _xperipherals_i2c_1__clear_scl(); _xperipherals_i2c_1__state = 3; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 3: _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; break; // Write Bits 7-0 case 4: if( (_xperipherals_i2c_1__data >> _xperipherals_i2c_1__shift) & 1 ) _xperipherals_i2c_1__read_sda(); else _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__shift--; _xperipherals_i2c_1__state = 5; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 5: _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__state = 6; _xperipherals_i2c_1__time += 2 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 6: _xperipherals_i2c_1__clear_scl(); if( _xperipherals_i2c_1__shift < 0 ) { _xperipherals_i2c_1__state = 7; _xperipherals_i2c_1__time += 2 * _XPERIPHERALS_I2C_1__TIME_BASE; } else { _xperipherals_i2c_1__state = 4; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; } break; // Sense ACK/NACK case 7: _xperipherals_i2c_1__data = _xperipherals_i2c_1__read_sda(); _xperipherals_i2c_1__state = 8; break; case 8: _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__state = 9; _xperipherals_i2c_1__time += 2 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 9: _xperipherals_i2c_1__clear_scl(); _xperipherals_i2c_1__state = 10; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 10: _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; break; // Read Bits 7-0 case 11: _xperipherals_i2c_1__read_sda(); _xperipherals_i2c_1__state = 12; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 12: _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__state = 13; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 13: (_xperipherals_i2c_1__data = _xperipherals_i2c_1__data >> 1) + _xperipherals_i2c_1__read_sda() << (_xperipherals_i2c_1__shift--); _xperipherals_i2c_1__state = 14; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 14: _xperipherals_i2c_1__clear_scl(); if( _xperipherals_i2c_1__shift < 0 ) _xperipherals_i2c_1__state = 15; else _xperipherals_i2c_1__state = 11; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 15: _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_READ; break; // Assert ACK/NACK case 16: if( _xperipherals_i2c_1__data ) _xperipherals_i2c_1__read_sda(); else _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__state = 17; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 17: _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__state = 18; _xperipherals_i2c_1__time += 2 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 18: _xperipherals_i2c_1__clear_scl(); _xperipherals_i2c_1__state = 19; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 19: _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; break; // Stop Condition case 20: _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__state = 21; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 21: _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__state = 22; _xperipherals_i2c_1__time += 1 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 22: _xperipherals_i2c_1__read_sda(); _xperipherals_i2c_1__state = 23; _xperipherals_i2c_1__time += 2 * _XPERIPHERALS_I2C_1__TIME_BASE; break; case 23: _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_1__continue_io( int& status ) { case _xperipherals_i2c_1__state > 0 => _xperipherals_i2c_1__timer when timerafter(_xperipherals_i2c_1__time) :> _xperipherals_i2c_1__time: status = _xperipherals_i2c_1__io_continue(); break; } #else void xperipherals_i2c_1__initialize( void ) { _xperipherals_i2c_1__state = 0; } void xperipherals_i2c_1__begin_start( void ) { while( TRUE ) { _xperipherals_i2c_1__scl = _xperipherals_i2c_1__read_scl(); _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); if( _xperipherals_i2c_1__scl && _xperipherals_i2c_1__sda ) break; } _xperipherals_i2c_1__pins = 0b1111; _xperipherals_i2c_1__state = 1; } void xperipherals_i2c_1__begin_stop( void ) { _xperipherals_i2c_1__state = 1; _xperipherals_i2c_1__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_1__read_scl(); // Release SCL _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); // Get current state } void xperipherals_i2c_1__begin_write( xbyte data ) { _xperipherals_i2c_1__data = data; _xperipherals_i2c_1__shift = 6; _xperipherals_i2c_1__state = 3; // Write first bit - SDA changes while SCL is low if( (_xperipherals_i2c_1__data >> 7) & 1 ) _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); else _xperipherals_i2c_1__sda = _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__scl = _xperipherals_i2c_1__read_scl(); // Release SCL, get current state _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); // Get current state } void xperipherals_i2c_1__begin_read() { _xperipherals_i2c_1__state = 6; _xperipherals_i2c_1__shift = 7; _xperipherals_i2c_1__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_1__scl = _xperipherals_i2c_1__read_scl(); // Release SCL, get current state _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); // Get current state } void xperipherals_i2c_1__begin_ack( xbool ack_flag ) { _xperipherals_i2c_1__data = ack_flag; _xperipherals_i2c_1__state = 7; // Write bit - SDA changes while SCL is low if( _xperipherals_i2c_1__data ) _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); else _xperipherals_i2c_1__sda = _xperipherals_i2c_1__clear_sda(); _xperipherals_i2c_1__scl = _xperipherals_i2c_1__read_scl(); // Release SCL, get current state _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); // Get current state } void xperipherals_i2c_1__end( void ) { _xperipherals_i2c_1__scl = _xperipherals_i2c_1__read_scl(); // Release SCL, get current state _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); // Get current state _xperipherals_i2c_1__state = 0; } int _xperipherals_i2c_1__continue_io( void ) { switch( _xperipherals_i2c_1__state ) { // Wait for start/stop Condition case 1: if( _xperipherals_i2c_1__pins == 0b1110 ) { // scl=1 sda->0 --- START _xperipherals_i2c_1__state = 2; } else if( _xperipherals_i2c_1__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; case 2: if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_1__clear_scl(); // Hold SCL Low _xperipherals_i2c_1__read_sda(); // Release SDA _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; } break; // Write Bits 6-0 case 3: if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X if( (_xperipherals_i2c_1__data >> _xperipherals_i2c_1__shift) & 1 ) _xperipherals_i2c_1__sda = _xperipherals_i2c_1__read_sda(); else _xperipherals_i2c_1__sda = _xperipherals_i2c_1__clear_sda(); if( --_xperipherals_i2c_1__shift < 0 ) _xperipherals_i2c_1__state = 4; else _xperipherals_i2c_1__state = 3; } else if( _xperipherals_i2c_1__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Sense ACK/NACK case 4: if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_1__state = 5; } break; case 5: if( _xperipherals_i2c_1__pins == 0b0111 || _xperipherals_i2c_1__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_1__ackflag = _xperipherals_i2c_1__read_sda(); } if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_1__clear_scl(); // Hold SCL Low _xperipherals_i2c_1__read_sda(); // Release SDA _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; } break; // Read Bits 7-0 case 6: if( _xperipherals_i2c_1__pins == 0b0111 || _xperipherals_i2c_1__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_1__data = (_xperipherals_i2c_1__data << 1) + _xperipherals_i2c_1__read_sda(); } else if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X if( --_xperipherals_i2c_1__shift >= 0 ) _xperipherals_i2c_1__state = 6; else { _xperipherals_i2c_1__clear_scl(); // Hold SCL Low _xperipherals_i2c_1__read_sda(); // Release SDA _xperipherals_i2c_1__state = 0; //printstr("READ: "); printhexln(_xperipherals_i2c_1__data); return XPERIPHERALS_I2C__STATUS__EVENT_READ; } } else if( _xperipherals_i2c_1__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Assert ACK/NACK case 7: if( _xperipherals_i2c_1__pins == 0b1101 || _xperipherals_i2c_1__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_1__clear_scl(); // Hold SCL Low _xperipherals_i2c_1__read_sda(); // Release SDA _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; } else if( _xperipherals_i2c_1__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_1__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_1__continue_io( int& status ) { case _xperipherals_i2c_1__port_scl when pinseq(!_xperipherals_i2c_1__scl) :> _xperipherals_i2c_1__scl: _xperipherals_i2c_1__pins = ((!_xperipherals_i2c_1__scl)<<3) + (_xperipherals_i2c_1__sda<<2) + (_xperipherals_i2c_1__scl<<1) + _xperipherals_i2c_1__sda; if( _xperipherals_i2c_1__scl == 0 ) _xperipherals_i2c_1__read_sda(); // release SDA on every SCL transition to low status = _xperipherals_i2c_1__io_continue(); break; case _xperipherals_i2c_1__port_sda when pinseq(!_xperipherals_i2c_1__sda) :> _xperipherals_i2c_1__sda: _xperipherals_i2c_1__pins = (_xperipherals_i2c_1__scl<<3) + ((!_xperipherals_i2c_1__sda)<<2) + (_xperipherals_i2c_1__scl<<1) + _xperipherals_i2c_1__sda; status = _xperipherals_i2c_1__io_continue(); break; } #endif #endif