<TODO>
<TODO>
<TODO>
<TODO>
<TODO>
xperipherals_i2c.h I2C peripheral interface xperipherals_i2c_1.xc I2C peripheral #1 implementation xperipherals_i2c_2.xc I2C peripheral #2 implementation xperipherals_i2c_1.xc I2C peripheral #3 implementation
#ifndef XPERIPHERALS_I2C__INCLUDED #define XPERIPHERALS_I2C__INCLUDED #include "xsystem_types.h" // Configuration - These must be defined in "xconfig.h" for each peripheral bus being used // // XPERIPHERALS_I2C_n No value // XPERIPHERALS_I2C_n__BUS_MASTER TRUE or FALSE // XPERIPHERALS_I2C_n__BIT_RATE Non-zero, non-negative integer // XPERIPHERALS_I2C_n__RESTARTS TRUE or FALSE // XPERIPHERALS_I2C_n__CLOCK_STRETCHING TRUE or FALSE // XPERIPHERALS_I2C_n__COLLISION_DET TRUE or FALSE // XPERIPHERALS_I2C_n__SCL_BIT_POS Non-negative integer // XPERIPHERALS_I2C_n__SDA_BIT_POS Non-negative integer // XPERIPHERALS_I2C_n__TILE_NUMBER integer, XS1 tile number // XPERIPHERALS_I2C_n__SCL_PORT XS1 port identifier // XPERIPHERALS_I2C_n__SDA_PORT XS1 port identifier // Status and Error Codes #define XPERIPHERALS_I2C__STATUS__EVENT_START ( 5) // Start or restart condition encountered (slave mode only) #define XPERIPHERALS_I2C__STATUS__EVENT_STOP ( 4) // Stop condition encountered (slave mode only) #define XPERIPHERALS_I2C__STATUS__EVENT_WRITE ( 3) // Write operation completed, no start/stop condition encountered #define XPERIPHERALS_I2C__STATUS__EVENT_READ ( 2) // Read operation completed, no start/stop condition encountered #define XPERIPHERALS_I2C__STATUS__EVENT_ACK ( 1) // ACK operation completed, no start/stop condition encountered #define XPERIPHERALS_I2C__STATUS__NONE ( 0) // I2C operation has not been started #define XPERIPHERALS_I2C__STATUS__ERROR_TIMEOUT ( -1) // Clock stretching (master mode) or wait for start/stop (slave) timeout #define XPERIPHERALS_I2C__STATUS__ERROR_BUSERR ( -2) // Bus Error (invalid start/stop sequence) #define XPERIPHERALS_I2C__STATUS__ERROR_ARBLOST ( -3) // Bus arbitration failure (lost abitration) #define XPERIPHERALS_I2C__STATUS__ERROR_ ( -4) // I2S transaction error #define XPERIPHERALS_I2C__ACK_VALUE 0 #define XPERIPHERALS_I2C__NACK_VALUE 1 // Master/Slave API Functions #define XPERIPHERALS_I2C__INTERFACE( N ) \ \ void xperipherals_i2c_##N##__initialize ( void ); \ \ /* Master/Slave Blocking API */ \ /* - Start, Stop, Write, Read and Ack functions will hold SCL low to give the application time to process. */ \ /* - The 'reset' function must be called if no other I/O operations are to follow. */ \ \ int xperipherals_i2c_##N##__start ( void ); /* Assert (master) or wait for (slave) START condition */ \ int xperipherals_i2c_##N##__stop ( void ); /* Assert (master) or wait for (slave) STOP condition */ \ int xperipherals_i2c_##N##__write ( xbyte data, xbyte& ack ); /* Write next byte (master or slave) */ \ int xperipherals_i2c_##N##__read ( xbyte& data ); /* Read next byte (master or slave) */ \ int xperipherals_i2c_##N##__ack ( xbyte ack_bit ); /* Assert ACK (sda=0) after a READ (master or slave) */ \ void xperipherals_i2c_##N##__reset ( void ); /* Reset state machine and release SCL */ \ \ /* Master/Slave Non-Blocking API */ \ /* - Start, Stop, Write, Read and Ack functions will hold SCL low to give the application time to process. */ \ /* - The End function must be called if no other I/O operations are to follow. */ \ \ void xperipherals_i2c_##N##__begin_start( void ); /* Begin START condition */ \ void xperipherals_i2c_##N##__begin_stop ( void ); /* Begin STOP condition */ \ void xperipherals_i2c_##N##__begin_write( xbyte data ); /* Begin data write */ \ void xperipherals_i2c_##N##__begin_read ( void ); /* Begin data read */ \ void xperipherals_i2c_##N##__begin_ack ( xbool ack_flag ); /* Begin ack flag write */ \ select xperipherals_i2c_##N##__continue_io( int& status ); /* Wait for event and advance I2C state machine */ \ xbyte xperipherals_i2c_##N##__get_data ( void ); /* Data or ACK flag from last I/O Event */ \ xbyte xperipherals_i2c_##N##__get_ackflag( void ); /* ACK flag from last I/O Event */ XPERIPHERALS_I2C__INTERFACE( 1 ) XPERIPHERALS_I2C__INTERFACE( 2 ) XPERIPHERALS_I2C__INTERFACE( 3 ) #endif
#include <xs1.h> #include <platform.h> #include <print.h> #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; // <TODO> 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
#include <xs1.h> #include <platform.h> #include <print.h> #include "xperipherals_i2c.h" #ifdef XPERIPHERALS_I2C__2 #if XPERIPHERALS_I2C_2__SCL_PORT != XPERIPHERALS_I2C_2__SDA_PORT on tile[XPERIPHERALS_I2C_2__TILE_NUMBER] : port _xperipherals_i2c_2__port_scl = XPERIPHERALS_I2C_2__SCL_PORT; on tile[XPERIPHERALS_I2C_2__TILE_NUMBER] : port _xperipherals_i2c_2__port_sda = XPERIPHERALS_I2C_2__SDA_PORT; #else on tile[XPERIPHERALS_I2C_2__TILE_NUMBER] : port _xperipherals_i2c_2__port = XPERIPHERALS_I2C_2__SCL_PORT; xbyte _xperipherals_i2c_2__shadow = 0; #endif #if XPERIPHERALS_I2C_2__BUS_MASTER timer _xperipherals_i2c_2__timer; int _xperipherals_i2c_2__time; #else xbyte _xperipherals_i2c_2__scl; xbyte _xperipherals_i2c_2__sda; xbyte _xperipherals_i2c_2__pins; #endif int _xperipherals_i2c_2__state; int _xperipherals_i2c_2__shift; xbyte _xperipherals_i2c_2__data; xbyte _xperipherals_i2c_2__ackflag; // <TODO> Calulate based on current system clock frequency #define _XPERIPHERALS_I2C_2__TIME_BASE ((400000 / XPERIPHERALS_I2C_2__BIT_RATE) * 62) #if XPERIPHERALS_I2C_2__SCL_PORT != XPERIPHERALS_I2C_2__SDA_PORT xbyte _xperipherals_i2c_2__read_scl( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_2__ACTIVE_HIGH == TRUE _xperipherals_i2c_2__port_scl <: 1; #else _xperipherals_i2c_2__port_scl :> bit; #endif return bit; } xbyte _xperipherals_i2c_2__read_sda( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_2__ACTIVE_HIGH == TRUE _xperipherals_i2c_2__port_sda <: 1; #else _xperipherals_i2c_2__port_sda :> bit; #endif return bit; } #if XPERIPHERALS_I2C_2__BUS_MASTER void _xperipherals_i2c_2__clear_scl( void ) {_xperipherals_i2c_2__port_scl <: 0;} void _xperipherals_i2c_2__clear_sda( void ) {_xperipherals_i2c_2__port_sda <: 0;} #else xbyte _xperipherals_i2c_2__clear_scl( void ) {return 0;} xbyte _xperipherals_i2c_2__clear_sda( void ) {return 0;} #endif #else xbyte _xperipherals_i2c_2__read_scl( void ) { _xperipherals_i2c_2__shadow |= (1 << XPERIPHERALS_I2C_2__SCL_BIT_POS); _xperipherals_i2c_2__port <: _xperipherals_i2c_2__shadow; return 0; } xbyte _xperipherals_i2c_2__read_sda( void ) { _xperipherals_i2c_2__shadow |= (1 << XPERIPHERALS_I2C_2__SDA_BIT_POS); _xperipherals_i2c_2__port <: _xperipherals_i2c_2__shadow; return 0; } void _xperipherals_i2c_2__clear_scl( void ) { _xperipherals_i2c_2__shadow &= ~(1 << XPERIPHERALS_I2C_2__SCL_BIT_POS); _xperipherals_i2c_2__port <: _xperipherals_i2c_2__shadow; } void _xperipherals_i2c_2__clear_sda( void ) { _xperipherals_i2c_2__shadow &= ~(1 << XPERIPHERALS_I2C_2__SDA_BIT_POS); _xperipherals_i2c_2__port <: _xperipherals_i2c_2__shadow; } #endif xbyte xperipherals_i2c_2__get_data( void ) {return _xperipherals_i2c_2__data;} xbyte xperipherals_i2c_2__get_ackflag( void ) {return _xperipherals_i2c_2__ackflag;} int xperipherals_i2c_2__start( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_2__begin_start(); while( TRUE ) { select {case xperipherals_i2c_2__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_2__stop( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_2__begin_stop(); while( TRUE ) { select {case xperipherals_i2c_2__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_2__write( xbyte data, xbyte& ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_2__begin_write( data ); while( TRUE ) { select {case xperipherals_i2c_2__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } ack_flag = _xperipherals_i2c_2__ackflag; return status; } int xperipherals_i2c_2__read( xbyte& data ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_2__begin_read(); while( TRUE ) { select {case xperipherals_i2c_2__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } data = _xperipherals_i2c_2__data; return status; } int xperipherals_i2c_2__ack( xbyte ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_2__begin_ack( ack_flag ); while( TRUE ) { select {case xperipherals_i2c_2__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } #if XPERIPHERALS_I2C_2__BUS_MASTER void xperipherals_i2c_2__initialize( void ) { _xperipherals_i2c_2__state = 0; _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__read_sda(); _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; _xperipherals_i2c_2__timer when timerafter( _xperipherals_i2c_2__time + 10 * _XPERIPHERALS_I2C_2__TIME_BASE ) :> void; } void xperipherals_i2c_2__begin_start( void ) { _xperipherals_i2c_2__state = 1; _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; } void xperipherals_i2c_2__begin_write( xbyte data ) { _xperipherals_i2c_2__data = data; _xperipherals_i2c_2__state = 4; _xperipherals_i2c_2__shift = 7; _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; } void xperipherals_i2c_2__begin_read( void ) { _xperipherals_i2c_2__state = 11; _xperipherals_i2c_2__shift = 7; _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; } void xperipherals_i2c_2__begin_ack( xbool ack_flag ) { _xperipherals_i2c_2__data = ack_flag != 0; _xperipherals_i2c_2__state = 16; _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; } void xperipherals_i2c_2__begin_stop( void ) { _xperipherals_i2c_2__state = 20; _xperipherals_i2c_2__timer :> _xperipherals_i2c_2__time; } int _xperipherals_i2c_2__io_continue( void ) { switch( _xperipherals_i2c_2__state ) { // Start Condition case 1: _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__state = 2; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 2: _xperipherals_i2c_2__clear_scl(); _xperipherals_i2c_2__state = 3; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 3: _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; break; // Write Bits 7-0 case 4: if( (_xperipherals_i2c_2__data >> _xperipherals_i2c_2__shift) & 1 ) _xperipherals_i2c_2__read_sda(); else _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__shift--; _xperipherals_i2c_2__state = 5; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 5: _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__state = 6; _xperipherals_i2c_2__time += 2 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 6: _xperipherals_i2c_2__clear_scl(); if( _xperipherals_i2c_2__shift < 0 ) { _xperipherals_i2c_2__state = 7; _xperipherals_i2c_2__time += 2 * _XPERIPHERALS_I2C_2__TIME_BASE; } else { _xperipherals_i2c_2__state = 4; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; } break; // Sense ACK/NACK case 7: _xperipherals_i2c_2__data = _xperipherals_i2c_2__read_sda(); _xperipherals_i2c_2__state = 8; break; case 8: _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__state = 9; _xperipherals_i2c_2__time += 2 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 9: _xperipherals_i2c_2__clear_scl(); _xperipherals_i2c_2__state = 10; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 10: _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; break; // Read Bits 7-0 case 11: _xperipherals_i2c_2__read_sda(); _xperipherals_i2c_2__state = 12; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 12: _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__state = 13; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 13: (_xperipherals_i2c_2__data = _xperipherals_i2c_2__data >> 1) + _xperipherals_i2c_2__read_sda() << (_xperipherals_i2c_2__shift--); _xperipherals_i2c_2__state = 14; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 14: _xperipherals_i2c_2__clear_scl(); if( _xperipherals_i2c_2__shift < 0 ) _xperipherals_i2c_2__state = 15; else _xperipherals_i2c_2__state = 11; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 15: _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_READ; break; // Assert ACK/NACK case 16: if( _xperipherals_i2c_2__data ) _xperipherals_i2c_2__read_sda(); else _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__state = 17; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 17: _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__state = 18; _xperipherals_i2c_2__time += 2 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 18: _xperipherals_i2c_2__clear_scl(); _xperipherals_i2c_2__state = 19; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 19: _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; break; // Stop Condition case 20: _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__state = 21; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 21: _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__state = 22; _xperipherals_i2c_2__time += 1 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 22: _xperipherals_i2c_2__read_sda(); _xperipherals_i2c_2__state = 23; _xperipherals_i2c_2__time += 2 * _XPERIPHERALS_I2C_2__TIME_BASE; break; case 23: _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_2__continue_io( int& status ) { case _xperipherals_i2c_2__state > 0 => _xperipherals_i2c_2__timer when timerafter(_xperipherals_i2c_2__time) :> _xperipherals_i2c_2__time: status = _xperipherals_i2c_2__io_continue(); break; } #else void xperipherals_i2c_2__initialize( void ) { _xperipherals_i2c_2__state = 0; } void xperipherals_i2c_2__begin_start( void ) { while( TRUE ) { _xperipherals_i2c_2__scl = _xperipherals_i2c_2__read_scl(); _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); if( _xperipherals_i2c_2__scl && _xperipherals_i2c_2__sda ) break; } _xperipherals_i2c_2__pins = 0b1111; _xperipherals_i2c_2__state = 1; } void xperipherals_i2c_2__begin_stop( void ) { _xperipherals_i2c_2__state = 1; _xperipherals_i2c_2__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_2__read_scl(); // Release SCL _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); // Get current state } void xperipherals_i2c_2__begin_write( xbyte data ) { _xperipherals_i2c_2__data = data; _xperipherals_i2c_2__shift = 6; _xperipherals_i2c_2__state = 3; // Write first bit - SDA changes while SCL is low if( (_xperipherals_i2c_2__data >> 7) & 1 ) _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); else _xperipherals_i2c_2__sda = _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__scl = _xperipherals_i2c_2__read_scl(); // Release SCL, get current state _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); // Get current state } void xperipherals_i2c_2__begin_read() { _xperipherals_i2c_2__state = 6; _xperipherals_i2c_2__shift = 7; _xperipherals_i2c_2__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_2__scl = _xperipherals_i2c_2__read_scl(); // Release SCL, get current state _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); // Get current state } void xperipherals_i2c_2__begin_ack( xbool ack_flag ) { _xperipherals_i2c_2__data = ack_flag; _xperipherals_i2c_2__state = 7; // Write bit - SDA changes while SCL is low if( _xperipherals_i2c_2__data ) _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); else _xperipherals_i2c_2__sda = _xperipherals_i2c_2__clear_sda(); _xperipherals_i2c_2__scl = _xperipherals_i2c_2__read_scl(); // Release SCL, get current state _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); // Get current state } void xperipherals_i2c_2__end( void ) { _xperipherals_i2c_2__scl = _xperipherals_i2c_2__read_scl(); // Release SCL, get current state _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); // Get current state _xperipherals_i2c_2__state = 0; } int _xperipherals_i2c_2__continue_io( void ) { switch( _xperipherals_i2c_2__state ) { // Wait for start/stop Condition case 1: if( _xperipherals_i2c_2__pins == 0b1110 ) { // scl=1 sda->0 --- START _xperipherals_i2c_2__state = 2; } else if( _xperipherals_i2c_2__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; case 2: if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_2__clear_scl(); // Hold SCL Low _xperipherals_i2c_2__read_sda(); // Release SDA _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; } break; // Write Bits 6-0 case 3: if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X if( (_xperipherals_i2c_2__data >> _xperipherals_i2c_2__shift) & 1 ) _xperipherals_i2c_2__sda = _xperipherals_i2c_2__read_sda(); else _xperipherals_i2c_2__sda = _xperipherals_i2c_2__clear_sda(); if( --_xperipherals_i2c_2__shift < 0 ) _xperipherals_i2c_2__state = 4; else _xperipherals_i2c_2__state = 3; } else if( _xperipherals_i2c_2__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Sense ACK/NACK case 4: if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_2__state = 5; } break; case 5: if( _xperipherals_i2c_2__pins == 0b0111 || _xperipherals_i2c_2__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_2__ackflag = _xperipherals_i2c_2__read_sda(); } if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_2__clear_scl(); // Hold SCL Low _xperipherals_i2c_2__read_sda(); // Release SDA _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; } break; // Read Bits 7-0 case 6: if( _xperipherals_i2c_2__pins == 0b0111 || _xperipherals_i2c_2__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_2__data = (_xperipherals_i2c_2__data << 1) + _xperipherals_i2c_2__read_sda(); } else if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X if( --_xperipherals_i2c_2__shift >= 0 ) _xperipherals_i2c_2__state = 6; else { _xperipherals_i2c_2__clear_scl(); // Hold SCL Low _xperipherals_i2c_2__read_sda(); // Release SDA _xperipherals_i2c_2__state = 0; //printstr("READ: "); printhexln(_xperipherals_i2c_2__data); return XPERIPHERALS_I2C__STATUS__EVENT_READ; } } else if( _xperipherals_i2c_2__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Assert ACK/NACK case 7: if( _xperipherals_i2c_2__pins == 0b1101 || _xperipherals_i2c_2__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_2__clear_scl(); // Hold SCL Low _xperipherals_i2c_2__read_sda(); // Release SDA _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; } else if( _xperipherals_i2c_2__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_2__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_2__continue_io( int& status ) { case _xperipherals_i2c_2__port_scl when pinseq(!_xperipherals_i2c_2__scl) :> _xperipherals_i2c_2__scl: _xperipherals_i2c_2__pins = ((!_xperipherals_i2c_2__scl)<<3) + (_xperipherals_i2c_2__sda<<2) + (_xperipherals_i2c_2__scl<<1) + _xperipherals_i2c_2__sda; if( _xperipherals_i2c_2__scl == 0 ) _xperipherals_i2c_2__read_sda(); // release SDA on every SCL transition to low status = _xperipherals_i2c_2__continue_io(); break; case _xperipherals_i2c_2__port_sda when pinseq(!_xperipherals_i2c_2__sda) :> _xperipherals_i2c_2__sda: _xperipherals_i2c_2__pins = (_xperipherals_i2c_2__scl<<3) + ((!_xperipherals_i2c_2__sda)<<2) + (_xperipherals_i2c_2__scl<<1) + _xperipherals_i2c_2__sda; status = _xperipherals_i2c_2__continue_io(); break; } #endif #endif
#include <xs1.h> #include <platform.h> #include <print.h> #include "xperipherals_i2c.h" #ifdef XPERIPHERALS_I2C__3 #if XPERIPHERALS_I2C_3__SCL_PORT != XPERIPHERALS_I2C_3__SDA_PORT on tile[XPERIPHERALS_I2C_3__TILE_NUMBER] : port _xperipherals_i2c_3__port_scl = XPERIPHERALS_I2C_3__SCL_PORT; on tile[XPERIPHERALS_I2C_3__TILE_NUMBER] : port _xperipherals_i2c_3__port_sda = XPERIPHERALS_I2C_3__SDA_PORT; #else on tile[XPERIPHERALS_I2C_3__TILE_NUMBER] : port _xperipherals_i2c_3__port = XPERIPHERALS_I2C_3__SCL_PORT; xbyte _xperipherals_i2c_3__shadow = 0; #endif #if XPERIPHERALS_I2C_3__BUS_MASTER timer _xperipherals_i2c_3__timer; int _xperipherals_i2c_3__time; #else xbyte _xperipherals_i2c_3__scl; xbyte _xperipherals_i2c_3__sda; xbyte _xperipherals_i2c_3__pins; #endif int _xperipherals_i2c_3__state; int _xperipherals_i2c_3__shift; xbyte _xperipherals_i2c_3__data; xbyte _xperipherals_i2c_3__ackflag; // <TODO> Calulate based on current system clock frequency #define _XPERIPHERALS_I2C_3__TIME_BASE ((400000 / XPERIPHERALS_I2C_3__BIT_RATE) * 62) #if XPERIPHERALS_I2C_3__SCL_PORT != XPERIPHERALS_I2C_3__SDA_PORT xbyte _xperipherals_i2c_3__read_scl( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_3__ACTIVE_HIGH == TRUE _xperipherals_i2c_3__port_scl <: 1; #else _xperipherals_i2c_3__port_scl :> bit; #endif return bit; } xbyte _xperipherals_i2c_3__read_sda( void ) { unsigned char bit=0; #if XPERIPHERALS_I2C_3__ACTIVE_HIGH == TRUE _xperipherals_i2c_3__port_sda <: 1; #else _xperipherals_i2c_3__port_sda :> bit; #endif return bit; } #if XPERIPHERALS_I2C_3__BUS_MASTER void _xperipherals_i2c_3__clear_scl( void ) {_xperipherals_i2c_3__port_scl <: 0;} void _xperipherals_i2c_3__clear_sda( void ) {_xperipherals_i2c_3__port_sda <: 0;} #else xbyte _xperipherals_i2c_3__clear_scl( void ) {return 0;} xbyte _xperipherals_i2c_3__clear_sda( void ) {return 0;} #endif #else xbyte _xperipherals_i2c_3__read_scl( void ) { _xperipherals_i2c_3__shadow |= (1 << XPERIPHERALS_I2C_3__SCL_BIT_POS); _xperipherals_i2c_3__port <: _xperipherals_i2c_3__shadow; return 0; } xbyte _xperipherals_i2c_3__read_sda( void ) { _xperipherals_i2c_3__shadow |= (1 << XPERIPHERALS_I2C_3__SDA_BIT_POS); _xperipherals_i2c_3__port <: _xperipherals_i2c_3__shadow; return 0; } void _xperipherals_i2c_3__clear_scl( void ) { _xperipherals_i2c_3__shadow &= ~(1 << XPERIPHERALS_I2C_3__SCL_BIT_POS); _xperipherals_i2c_3__port <: _xperipherals_i2c_3__shadow; } void _xperipherals_i2c_3__clear_sda( void ) { _xperipherals_i2c_3__shadow &= ~(1 << XPERIPHERALS_I2C_3__SDA_BIT_POS); _xperipherals_i2c_3__port <: _xperipherals_i2c_3__shadow; } #endif xbyte xperipherals_i2c_3__get_data( void ) {return _xperipherals_i2c_3__data;} xbyte xperipherals_i2c_3__get_ackflag( void ) {return _xperipherals_i2c_3__ackflag;} int xperipherals_i2c_3__start( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_3__begin_start(); while( TRUE ) { select {case xperipherals_i2c_3__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_3__stop( void ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_3__begin_stop(); while( TRUE ) { select {case xperipherals_i2c_3__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } int xperipherals_i2c_3__write( xbyte data, xbyte& ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_3__begin_write( data ); while( TRUE ) { select {case xperipherals_i2c_3__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } ack_flag = _xperipherals_i2c_3__ackflag; return status; } int xperipherals_i2c_3__read( xbyte& data ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_3__begin_read(); while( TRUE ) { select {case xperipherals_i2c_3__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } data = _xperipherals_i2c_3__data; return status; } int xperipherals_i2c_3__ack( xbyte ack_flag ) { int status = XPERIPHERALS_I2C__STATUS__NONE; xperipherals_i2c_3__begin_ack( ack_flag ); while( TRUE ) { select {case xperipherals_i2c_3__continue_io(status);} if( status != XPERIPHERALS_I2C__STATUS__NONE ) break; } return status; } #if XPERIPHERALS_I2C_3__BUS_MASTER void xperipherals_i2c_3__initialize( void ) { _xperipherals_i2c_3__state = 0; _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__read_sda(); _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; _xperipherals_i2c_3__timer when timerafter( _xperipherals_i2c_3__time + 10 * _XPERIPHERALS_I2C_3__TIME_BASE ) :> void; } void xperipherals_i2c_3__begin_start( void ) { _xperipherals_i2c_3__state = 1; _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; } void xperipherals_i2c_3__begin_write( xbyte data ) { _xperipherals_i2c_3__data = data; _xperipherals_i2c_3__state = 4; _xperipherals_i2c_3__shift = 7; _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; } void xperipherals_i2c_3__begin_read( void ) { _xperipherals_i2c_3__state = 11; _xperipherals_i2c_3__shift = 7; _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; } void xperipherals_i2c_3__begin_ack( xbool ack_flag ) { _xperipherals_i2c_3__data = ack_flag != 0; _xperipherals_i2c_3__state = 16; _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; } void xperipherals_i2c_3__begin_stop( void ) { _xperipherals_i2c_3__state = 20; _xperipherals_i2c_3__timer :> _xperipherals_i2c_3__time; } int _xperipherals_i2c_3__io_continue( void ) { switch( _xperipherals_i2c_3__state ) { // Start Condition case 1: _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__state = 2; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 2: _xperipherals_i2c_3__clear_scl(); _xperipherals_i2c_3__state = 3; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 3: _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; break; // Write Bits 7-0 case 4: if( (_xperipherals_i2c_3__data >> _xperipherals_i2c_3__shift) & 1 ) _xperipherals_i2c_3__read_sda(); else _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__shift--; _xperipherals_i2c_3__state = 5; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 5: _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__state = 6; _xperipherals_i2c_3__time += 2 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 6: _xperipherals_i2c_3__clear_scl(); if( _xperipherals_i2c_3__shift < 0 ) { _xperipherals_i2c_3__state = 7; _xperipherals_i2c_3__time += 2 * _XPERIPHERALS_I2C_3__TIME_BASE; } else { _xperipherals_i2c_3__state = 4; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; } break; // Sense ACK/NACK case 7: _xperipherals_i2c_3__data = _xperipherals_i2c_3__read_sda(); _xperipherals_i2c_3__state = 8; break; case 8: _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__state = 9; _xperipherals_i2c_3__time += 2 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 9: _xperipherals_i2c_3__clear_scl(); _xperipherals_i2c_3__state = 10; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 10: _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; break; // Read Bits 7-0 case 11: _xperipherals_i2c_3__read_sda(); _xperipherals_i2c_3__state = 12; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 12: _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__state = 13; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 13: (_xperipherals_i2c_3__data = _xperipherals_i2c_3__data >> 1) + _xperipherals_i2c_3__read_sda() << (_xperipherals_i2c_3__shift--); _xperipherals_i2c_3__state = 14; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 14: _xperipherals_i2c_3__clear_scl(); if( _xperipherals_i2c_3__shift < 0 ) _xperipherals_i2c_3__state = 15; else _xperipherals_i2c_3__state = 11; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 15: _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_READ; break; // Assert ACK/NACK case 16: if( _xperipherals_i2c_3__data ) _xperipherals_i2c_3__read_sda(); else _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__state = 17; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 17: _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__state = 18; _xperipherals_i2c_3__time += 2 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 18: _xperipherals_i2c_3__clear_scl(); _xperipherals_i2c_3__state = 19; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 19: _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; break; // Stop Condition case 20: _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__state = 21; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 21: _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__state = 22; _xperipherals_i2c_3__time += 1 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 22: _xperipherals_i2c_3__read_sda(); _xperipherals_i2c_3__state = 23; _xperipherals_i2c_3__time += 2 * _XPERIPHERALS_I2C_3__TIME_BASE; break; case 23: _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_3__continue_io( int& status ) { case _xperipherals_i2c_3__state > 0 => _xperipherals_i2c_3__timer when timerafter(_xperipherals_i2c_3__time) :> _xperipherals_i2c_3__time: status = _xperipherals_i2c_3__io_continue(); break; } #else void xperipherals_i2c_3__initialize( void ) { _xperipherals_i2c_3__state = 0; } void xperipherals_i2c_3__begin_start( void ) { while( TRUE ) { _xperipherals_i2c_3__scl = _xperipherals_i2c_3__read_scl(); _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); if( _xperipherals_i2c_3__scl && _xperipherals_i2c_3__sda ) break; } _xperipherals_i2c_3__pins = 0b1111; _xperipherals_i2c_3__state = 1; } void xperipherals_i2c_3__begin_stop( void ) { _xperipherals_i2c_3__state = 1; _xperipherals_i2c_3__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_3__read_scl(); // Release SCL _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); // Get current state } void xperipherals_i2c_3__begin_write( xbyte data ) { _xperipherals_i2c_3__data = data; _xperipherals_i2c_3__shift = 6; _xperipherals_i2c_3__state = 3; // Write first bit - SDA changes while SCL is low if( (_xperipherals_i2c_3__data >> 7) & 1 ) _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); else _xperipherals_i2c_3__sda = _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__scl = _xperipherals_i2c_3__read_scl(); // Release SCL, get current state _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); // Get current state } void xperipherals_i2c_3__begin_read() { _xperipherals_i2c_3__state = 6; _xperipherals_i2c_3__shift = 7; _xperipherals_i2c_3__read_sda(); // Release SDA - allow posbbile resulting SDA change while SCL is low _xperipherals_i2c_3__scl = _xperipherals_i2c_3__read_scl(); // Release SCL, get current state _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); // Get current state } void xperipherals_i2c_3__begin_ack( xbool ack_flag ) { _xperipherals_i2c_3__data = ack_flag; _xperipherals_i2c_3__state = 7; // Write bit - SDA changes while SCL is low if( _xperipherals_i2c_3__data ) _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); else _xperipherals_i2c_3__sda = _xperipherals_i2c_3__clear_sda(); _xperipherals_i2c_3__scl = _xperipherals_i2c_3__read_scl(); // Release SCL, get current state _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); // Get current state } void xperipherals_i2c_3__end( void ) { _xperipherals_i2c_3__scl = _xperipherals_i2c_3__read_scl(); // Release SCL, get current state _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); // Get current state _xperipherals_i2c_3__state = 0; } int _xperipherals_i2c_3__continue_io( void ) { switch( _xperipherals_i2c_3__state ) { // Wait for start/stop Condition case 1: if( _xperipherals_i2c_3__pins == 0b1110 ) { // scl=1 sda->0 --- START _xperipherals_i2c_3__state = 2; } else if( _xperipherals_i2c_3__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; case 2: if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_3__clear_scl(); // Hold SCL Low _xperipherals_i2c_3__read_sda(); // Release SDA _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_START; } break; // Write Bits 6-0 case 3: if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X if( (_xperipherals_i2c_3__data >> _xperipherals_i2c_3__shift) & 1 ) _xperipherals_i2c_3__sda = _xperipherals_i2c_3__read_sda(); else _xperipherals_i2c_3__sda = _xperipherals_i2c_3__clear_sda(); if( --_xperipherals_i2c_3__shift < 0 ) _xperipherals_i2c_3__state = 4; else _xperipherals_i2c_3__state = 3; } else if( _xperipherals_i2c_3__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Sense ACK/NACK case 4: if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_3__state = 5; } break; case 5: if( _xperipherals_i2c_3__pins == 0b0111 || _xperipherals_i2c_3__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_3__ackflag = _xperipherals_i2c_3__read_sda(); } if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_3__clear_scl(); // Hold SCL Low _xperipherals_i2c_3__read_sda(); // Release SDA _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_WRITE; } break; // Read Bits 7-0 case 6: if( _xperipherals_i2c_3__pins == 0b0111 || _xperipherals_i2c_3__pins == 0b0010 ) { // scl->1 sda=X _xperipherals_i2c_3__data = (_xperipherals_i2c_3__data << 1) + _xperipherals_i2c_3__read_sda(); } else if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X if( --_xperipherals_i2c_3__shift >= 0 ) _xperipherals_i2c_3__state = 6; else { _xperipherals_i2c_3__clear_scl(); // Hold SCL Low _xperipherals_i2c_3__read_sda(); // Release SDA _xperipherals_i2c_3__state = 0; //printstr("READ: "); printhexln(_xperipherals_i2c_3__data); return XPERIPHERALS_I2C__STATUS__EVENT_READ; } } else if( _xperipherals_i2c_3__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; // Assert ACK/NACK case 7: if( _xperipherals_i2c_3__pins == 0b1101 || _xperipherals_i2c_3__pins == 0b1000 ) { // scl->0 sda=X _xperipherals_i2c_3__clear_scl(); // Hold SCL Low _xperipherals_i2c_3__read_sda(); // Release SDA _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_ACK; } else if( _xperipherals_i2c_3__pins == 0b1011 ) { // scl=1 sda->1 --- STOP _xperipherals_i2c_3__state = 0; return XPERIPHERALS_I2C__STATUS__EVENT_STOP; } break; } return XPERIPHERALS_I2C__STATUS__NONE; } select xperipherals_i2c_3__continue_io( int& status ) { case _xperipherals_i2c_3__port_scl when pinseq(!_xperipherals_i2c_3__scl) :> _xperipherals_i2c_3__scl: _xperipherals_i2c_3__pins = ((!_xperipherals_i2c_3__scl)<<3) + (_xperipherals_i2c_3__sda<<2) + (_xperipherals_i2c_3__scl<<1) + _xperipherals_i2c_3__sda; if( _xperipherals_i2c_3__scl == 0 ) _xperipherals_i2c_3__read_sda(); // release SDA on every SCL transition to low status = _xperipherals_i2c_3__io_continue(); break; case _xperipherals_i2c_3__port_sda when pinseq(!_xperipherals_i2c_3__sda) :> _xperipherals_i2c_3__sda: _xperipherals_i2c_3__pins = (_xperipherals_i2c_3__scl<<3) + ((!_xperipherals_i2c_3__sda)<<2) + (_xperipherals_i2c_3__scl<<1) + _xperipherals_i2c_3__sda; status = _xperipherals_i2c_3__io_continue(); break; } #endif #endif