John F. Fitter says:
These routines are written in Hi-Tech C and are for use with the 'F876. Specificly, they write to a MAX3100 spi->rs232 interface chip.
/*********************************************************************************************/
/* Program : SPI.C */
/* Function : MOI Machine Controller SPI Utility Control Procedures */
/* Author : John F. Fitter B.E. */
/* */
/* Rev No. Rev date Test date Test platform Description */
/* ------- -------- --------- --------------- ---------------------------------- */
/* 00 6jun98 Original in HiTech C */
/* */
/* Copyright © 1998 Eagle Air Australia Pty. Ltd. All rights reserved */
/*********************************************************************************************/
#define _SPI_C
#include "commdefs.h"
#include "moi.h"
#include "spi.h"
// Procedure to setup the spi and the spi port pin directions
void setup_spi(unsigned char mode) {
sdo_dir = B_OUT; // make SDO output
sck_dir = (mode & SPI_SLAVE) ? B_IN : B_OUT; // make SCK input(slave) or output
sdi_dir = B_IN; // make SDI input
if(mode & SPI_SLAVE & 0xf) ss_dir = B_IN; // set SS mode bit to input if required
spi_enable(false); // disable ssp
SSPCON = mode; // set ssp mode
spi_enable(true); // re-enable ssp
}
// Procedure to read and return data from the spi - could call spi_write
// but will trade rom for stack levels in this case.
// The argument is the data to be transmitted (use 0 if none is required)
#pragma interrupt_level 1
unsigned char
Ispi_read(unsigned char txdata) { // write and return received data
unsigned char rxdata;
rxdata = SSPBUF; // lose any data in buffer, clear BF
SSPBUF = txdata; // load transmit data
while(!spi_data_is_in()); // wait until transmit complete
return SSPBUF; // get received data, clear BF
}
// Procedure to read and return data from the spi - could call spi_write
// but will trade rom for stack levels in this case.
// The argument is the data to be transmitted (use 0 if none is required)
unsigned char spi_read(unsigned char txdata)
{ // write and return received data
unsigned char rxdata;
rxdata = SSPBUF; // lose any data in buffer, clear BF
SSPBUF = txdata; // load transmit data
while(!spi_data_is_in()); // wait until transmit complete
return SSPBUF; // get received data, clear BF
}
// Procedure to write data to the spi
void spi_write(unsigned char txdata) {
unsigned char rxdata;
rxdata = SSPBUF; // lose any data in buffer, clear BF
SSPBUF = txdata; // load transmit data
while(!spi_data_is_in()); // wait until transmit complete
}
void
InitSPI(void)
{
union regs3140 Spi_Regs;
unsigned char c1, c2;
//set EXT interrupt for falling edge,used for RCV from MAX3140
INTEDG = 1;
//setup SPI to work with external max3140 USART
//(uses a non-standard mode)
TRISC4 = 1; //SPI Slave In
TRISC5 = 0; //SPI Slave Out
TRISC3 = 0; //SPI Slave CLK In
TRISC0 = 0; //SPI SS Enabled Out as chip select
SSPEN = 1; //SPI port pins enabled
CKP = 0; //Clock idle is low
STAT_SMP = 1; //SPI master mode Sample at END
STAT_CKE = 1; //Data on rising edge
SSPM0 = 0; //Slave Mode SS pin Disabled
SSPM1 = 0;
SSPM2 = 0;
SSPM3 = 0;
spi_cs = 0;
Spi_Regs.word.high = spi_read( 0b11000100 ); //Write CFG - IRQ on RCV
Spi_Regs.word.low = spi_read( 0b00001010 ); //19200 BPS @ 3.6864MHz
spi_cs = 1;
spi_cs = 0;
c1 = spi_read( RDCFG1 );
c2 = spi_read( RDCFG2 );
spi_cs = 1;
}
void
WriteSPIByte(int byte)
{
unsigned char t, c;
union regs3140 Spi_Regs;
t = (unsigned char)byte;
spi_cs = 0;
Spi_Regs.word.high = spi_read( 0b10000000 );
if(Spi_Regs.flag.R)
RADEnQueue(spi_read(t));
else
c = spi_read(t);
spi_cs = 1;
DelayMs(1);
}
void
WriteSPI(int p1, ...)
{
int temp=p1, temp1=0;
unsigned char numBytes;
va_list marker;
if(p1 == -1)
return;
va_start(marker, int);
while(temp != -1)
{
temp1+=temp;
WriteSPIByte(temp);
temp = va_arg(marker, int);
}
va_end(marker);
}
// ***** EOF SPI.C *****
// SPIINT.C
#pragma interrupt_level 1
void interrupt
isr(void)
{
unsigned char i=0;
union regs3140 Spi_Regs;
if(INTF && INTE)
{
while(!RB0)
{
spi_cs=0;
Spi_Regs.word.high = Ispi_read( 0x00 );
if(Spi_Regs.flag.R)
IRADEnQueue(Ispi_read(0x00));
else
i = Ispi_read( 0x00 );
spi_cs=1;
}
INTF=0; // Turn off the interrupt
}
}
// ****** EOF SPIINT.C
//Here are some data structures if you want to easily manage the configuration bits
struct flags3140
{ //Bits 0 .. 15
unsigned BAUD : 4; //Baud Rate - 1011=9600BPS
unsigned L : 1; //0=8 Bit word
unsigned PE : 1; //0=No parity
unsigned ST : 1; //0=1 stop bit
unsigned IR : 1; //0=not use IRDA timing
unsigned RAM : 1;
unsigned PM : 1; //0=do not assert IRQ for parity
unsigned RM : 1; //1=assert IRQ for data received
unsigned TM : 1; //1=assert IRQ for transmit empty
unsigned SHDN : 1;
unsigned FEN : 1;
unsigned T : 1;
unsigned R : 1;
};
struct word3140
{ //Bits 0 .. 15
unsigned char low;
unsigned char high;
};
union regs3140
{
struct flags3140 flag;
struct word3140 word;
};
Questions: