/**
* @file	spi.c
* @brief	SPI functions
*
* Implement SPI inteface communications
*
* @author      Rustem Kalimullin
* @par E-mail:
*              hellos@mail.ru
* @par Copyright:
*              (c) Kurt, 2005
*/
 
 
#include "common.h"
 
#define SPI_PORT_WR  (P3OUT)  //!< Output port
#define SPI_PORT_RD  (P3IN)   //!< Input port
#define SPI_PORT_DIR (P3DIR)
#define SPI_PORT_SEL (P3SEL)  //!< Port options
#define SPI_DO (1<<1)         //!< Output pin mask
#define SPI_DI (1<<2)         //!< Input pin mask
#define SPI_CK (1<<3)         //!< Clock pin mask
 
//---------------------------------------------------------
//! Send @a data to serial line. Word length in @a bits
unsigned int spi_write_bits( unsigned int data, unsigned int bits )
{
	if( (bits > 16) || (bits == 0) ) return 0xFFFF;
 
	for( unsigned int i=16-bits; i > 0; i-- ) data <<= 1;  // Align data word to left
 
	unsigned int read = 0;
	do {
 
		if( data & 0x8000 ) {
			SPI_PORT_WR |= SPI_DO;
		} else {
			SPI_PORT_WR &= ~SPI_DO;
		}
 
		SPI_PORT_WR |= SPI_CK;
		for( unsigned int i=3; i; --i ) continue;
		SPI_PORT_WR &= ~SPI_CK;
 
		data <<= 1;
		read <<= 1;
		if( SPI_PORT_RD & SPI_DI ) read |= 1;
 
	} while( --bits );
 
	return read;
}
 
//---------------------------------------------------------
//! Enable hardware SPI
void spi_enable(void)
{
	U0CTL  |= SWRST;
	SPI_PORT_SEL |= (SPI_DO | SPI_DI | SPI_CK );  // enable SPI option
	SPI_PORT_DIR |= (SPI_DO | SPI_CK);            // output pins
	SPI_PORT_DIR &= ~(SPI_DI);                    // input pins
	U0ME   |= USPIE0;                             // Enable USART0 SPI mode
	U0CTL  &= ~SWRST;
}
 
//---------------------------------------------------------
//! Disable hardware SPI
void spi_disable(void)
{
	U0CTL  |= SWRST;
	SPI_PORT_SEL &= ~(SPI_DO | SPI_DI | SPI_CK ); // disable SPI option
	SPI_PORT_DIR |= (SPI_DO | SPI_CK);            // output pins
	SPI_PORT_DIR &= ~(SPI_DI);                    // input pins
	U0ME   &= ~USPIE0;                            // Disable USART0 SPI mode
	U0CTL  &= ~SWRST;
}
 
 
//---------------------------------------------------------
//! Init hardware SPI
void spi_init( void )
{
	U0CTL   = CHAR | SYNC | MM | SWRST;        // 8-bit SPI Master
#ifdef KR_SPI_FULLSPEED	
	U0TCTL  = CKPL+SSEL0+SSEL1+STC;            // ACLK, 3-pin mode
	U0BR0   = 0x02;                            // UCLK = SMCLK
#else
	U0TCTL  = CKPL+SSEL1+SSEL0+STC;            // SMCLK, 3-pin mode
	U0BR0   = 0x04;                            // UCLK/4
#endif	
	U0BR1   = 0x00;
	U0MCTL  = 0x00;                            // no modulation
	spi_enable();
}
 
//---------------------------------------------------------
//! Send @a data byte to serial line.
unsigned char spi_write( unsigned char data )
{
	unsigned int tot;
	tot = 0xFFF;
	do {
		if( 0 == --tot ) return 0xFF;
	} while( !(U0IFG & UTXIFG0) );  // USART0 TX buffer ready?
 
	U0TXBUF = data;
	tot = 0xFFF;
	do {
		if ( 0 == --tot ) return 0xFF;
	} while( !(U0TCTL & TXEPT) );   // USART0 Transmit complete?
	return U0RXBUF;
}
 
//---------------------------------------------------------
//! Receive byte from serial line.
unsigned char spi_read( void )
{
	return spi_write(0x00);
}
 
sources/spi0.txt · Последние изменения: 2021/10/09 14:22 kurt