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: