#include #include #include #include #include "xperipherals_spi.h" #ifdef XPERIPHERALS_SPI_1 #if XPERIPHERALS_SPI_1__BUS_MASTER on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : out port _xperipherals_spi_1__pin_sclk = XPERIPHERALS_SPI_1__SCLK_PORT; on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : out port _xperipherals_spi_1__pin_mosi = XPERIPHERALS_SPI_1__MOSI_PORT; on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : in port _xperipherals_spi_1__pin_miso = XPERIPHERALS_SPI_1__MISO_PORT; #else on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : in port _xperipherals_spi_1__pin_sclk = XPERIPHERALS_SPI_1__SCLK_PORT; on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : out port _xperipherals_spi_1__pin_mosi = XPERIPHERALS_SPI_1__MOSI_PORT; on tile[XPERIPHERALS_SPI_1__TILE_NUMBER] : in port _xperipherals_spi_1__pin_miso = XPERIPHERALS_SPI_1__MISO_PORT; #endif #if XPERIPHERALS_SPI_1__BUS_MASTER static timer _xperipherals_spi_1__io_timer; static int _xperipherals_spi_1__io_time; #else static xbyte _xperipherals_spi_1__sclk; #endif static int _xperipherals_spi_1__io_state; static int _xperipherals_spi_1__shift_cnt; static xbyte _xperipherals_spi_1__mosi_data; static xbyte _xperipherals_spi_1__miso_data; static xbyte _xperipherals_spi_1__temp_data; // Calulate based on current system clock frequency #define _XPERIPHERALS_SPI_1__TIME_BASE ((400000 / XPERIPHERALS_SPI_1__BIT_RATE) * 62) #if XPERIPHERALS_SPI_1__BUS_MASTER void xperipherals_spi_1__initialize( void ) { _xperipherals_spi_1__io_state = 0; _xperipherals_spi_1__pin_sclk <: (XPERIPHERALS_SPI_1__MODE_CPOL != 0); _xperipherals_spi_1__io_timer :> _xperipherals_spi_1__io_time; _xperipherals_spi_1__io_timer when timerafter( _xperipherals_spi_1__io_time + 10 * _XPERIPHERALS_SPI_1__TIME_BASE ) :> void; } void xperipherals_spi_1__begin_write( xbyte mosi_data ) { xperipherals_spi_1__begin_xfer( mosi_data ); } void xperipherals_spi_1__begin_read ( void ) { xperipherals_spi_1__begin_xfer( 0x00 ); } void xperipherals_spi_1__begin_xfer( xbyte mosi_data ) { _xperipherals_spi_1__mosi_data = mosi_data; _xperipherals_spi_1__pin_sclk <: !((XPERIPHERALS_SPI_1__MODE_CPOL !=0) ^ (XPERIPHERALS_SPI_1__MODE_CPHA !=0 )); _xperipherals_spi_1__pin_mosi <: (xbyte)(_xperipherals_spi_1__mosi_data & 1); _xperipherals_spi_1__miso_data = 0; _xperipherals_spi_1__shift_cnt = 1; _xperipherals_spi_1__io_timer :> _xperipherals_spi_1__io_time; _xperipherals_spi_1__io_state = 1; } // +-------+ +-------+ +-------+ // CPOL = 0, CPHA = 0 | | | | | | // -------------+ +-------+ +-------+ + // +---------------+---------------+---------------+ // CPOL = 0, CPHA = 0 XXXXX| 0 | 1 | 2 | // +---------------+---------------+---------------+ // Beg S1 S2 S1 S2 S1 S2 // // -------------+ +-------+ +-------+ + // CPOL = 1, CPHA = 0 | | | | | | // +-------+ +-------+ +-------+ // +---------------+---------------+---------------+ // CPOL = 1, CPHA = 0 XXXXX| 0 | 1 | 2 | // +---------------+---------------+---------------+ // Beg S1 S2 S1 S2 S1 S2 // // +-------+ +-------+ +-------+ // CPOL = 0, CPHA = 1 | | | | | | // -----+ +-------+ +-------+ +-------+ // +---------------+---------------+---------------+ // CPOL = 0, CPHA = 1 XXXXX| 0 | 1 | 2 | // +---------------+---------------+---------------+ // Beg S1 S2 S1 S2 S1 S2 // // -----+ +-------+ +-------+ +-------+ // CPOL = 1, CPHA = 1 | | | | | | // +-------+ +-------+ +-------+ // +---------------+---------------+---------------+ // CPOL = 1, CPHA = 1 XXXXX| 0 | 1 | 2 | // +---------------+---------------+---------------+ // Beg S1 S2 S1 S2 S1 S2 select xperipherals_spi_1__continue_io( int& status ) { case _xperipherals_spi_1__io_state > 0 => _xperipherals_spi_1__io_timer when timerafter(_xperipherals_spi_1__io_time) :> _xperipherals_spi_1__io_time: switch( _xperipherals_spi_1__io_state ) { case 1: // S1 _xperipherals_spi_1__pin_miso :> _xperipherals_spi_1__temp_data; _xperipherals_spi_1__pin_sclk <: ((XPERIPHERALS_SPI_1__MODE_CPOL !=0) ^ (XPERIPHERALS_SPI_1__MODE_CPHA !=0 )); _xperipherals_spi_1__miso_data |= (_xperipherals_spi_1__temp_data << _xperipherals_spi_1__shift_cnt) & 1; _xperipherals_spi_1__io_state = 2; status = XPERIPHERALS_SPI__STATUS__NONE; break; case 2: // S2 if( _xperipherals_spi_1__shift_cnt <= 7 ) { _xperipherals_spi_1__pin_sclk <: !((XPERIPHERALS_SPI_1__MODE_CPOL !=0) ^ (XPERIPHERALS_SPI_1__MODE_CPHA !=0 )); _xperipherals_spi_1__pin_mosi <: (xbyte)(_xperipherals_spi_1__mosi_data >> _xperipherals_spi_1__shift_cnt++) & 1; _xperipherals_spi_1__io_state = 1; status = XPERIPHERALS_SPI__STATUS__NONE; } else { _xperipherals_spi_1__pin_sclk <: !((XPERIPHERALS_SPI_1__MODE_CPOL !=0 ) ^ (XPERIPHERALS_SPI_1__MODE_CPHA !=0 )); _xperipherals_spi_1__io_state = 0; status = XPERIPHERALS_SPI__STATUS__EVENT_IO_DONE; } break; } break; } xbyte xperipherals_spi_1__get_data( void ) { return _xperipherals_spi_1__miso_data; } int xperipherals_spi_1__write( xbyte mosi_data ) { xbyte tmp; return xperipherals_spi_1__transfer( mosi_data, tmp ); } int xperipherals_spi_1__read ( xbyte& miso_data ) { return xperipherals_spi_1__transfer( 0x00, miso_data ); } int xperipherals_spi_1__transfer( xbyte mosi_data, xbyte& miso_data ) { int status; xperipherals_spi_1__begin_write( mosi_data ); while( TRUE ) { select {case xperipherals_spi_1__io_continue( status );} if( status != XPERIPHERALS_SPI__STATUS__NONE ) break; } return status; } #else #if XPERIPHERALS_SPI_1__BUS_MASTER void xperipherals_spi_1__initialize( void ) { } int xperipherals_spi_1__write( xbyte mosi_data ) { return 0; } int xperipherals_spi_1__read( xbyte& miso_data ) { return 0; } xbyte xperipherals_spi_1__transfer( xbyte mosi_data ) { return 0; } void xperipherals_spi_1__xfer_start( xbyte mosi_data ) { return 0; } select xperipherals_spi_1__xfer_done( xbool& done_flag, xbyte& miso_data ) { return 0; } void xperipherals_spi_1__begin_write( xbyte mosi_data ) { return 0; } void xperipherals_spi_1__begin_read( void ) { return 0; } void xperipherals_spi_1__begin_xfer( xbyte mosi_data ) { #endif } select xperipherals_spi_1__continue_io( int& status ) { } xbyte xperipherals_spi_1__get_data( void ) { return _xperipherals_spi_1__data; } #endif #endif