PIC 16F Software SPI

Im having some difficulties setting up software SPI on a pic 16F88 I have the following Code. I know the 88 has hardware SPI but im trying to setup software SPI on it for now.

//#define CE PORTB.0; //PIN 6

//#define CSN PORTB.3; //PIN 7

//#define SCK PORTB.4; //PIN 9

//#define MOSI PORTB.2; //PIN 10

//#define MISO PORTB.1; //PIN 15

//#define IRQ PORTA.0; //PIN 17

//Basic SPI send and receive

unsigned char spi_comm(unsigned char outgoing_byte)

{

unsigned char incoming_byte, x;

for(x = 0 ; x < 8 ; x++)

{

portb.2 = outgoing_byte.7; //Put bit on SPI data bus

outgoing_byte <<= 1; //Rotate byte 1 to the left

portb.4 = 1; //Toggle the SPI clock

portb.4 = 0;

incoming_byte <<= 1; //Rotate byte 1 to the left

incoming_byte.0 = porta.1; //Read bit on SPI data bus

}

return(incoming_byte);

}

Does anyone see any flaws?

SFE has some software SPI code for the MiRF V2.

Leon

Do they have a simple send recieve function? If so where do I download it at?

spi_send_read:
	banksel	PORTB
	bcf		PORTB,SPI_SCK	;SCK low
	movfw	TXDATA
	movlw	8				;8 bits to send
	movwf	count
sp1_1:
	rlf		TXDATA,f		;MS bit in C
	btfss	STATUS,C		;C = 0?		
	goto	spi_2			;no, jump
	bsf		PORTB,SPI_SO	;yes, output one
	goto	spi_3
spi_2:
	bcf		PORTB,SPI_SO	;output zero
spi_3:
	btfsc	PORTB,SPI_SI	;SPI_SI input low?
	goto	spi_4			;no, jump
	bcf		STATUS,C		;yes, clear carry bit
	goto	spi_5
spi_4:
	bsf		STATUS,C		;set carry bit
spi_5:
	rlf		RXDATA,f		;rotate RXDATA left
	bsf		PORTB,SPI_SCK	;SCK high to latch bit
	decfsz	count,f			;count = 0?
	goto	sp1_1			;no, loop back
	return					;yes, return

Leon

I was hoping to get the code in C if possible as im not to familiar with assembly yet. I have downloaded various versions and read different articles on software spi. The problem is all of the examples don’t have any consistency especially when your trying to learn how it works. For instance I read an article that says you have to pull the csn bit low when your going to send information to get the slave to listen. But two different functions I have seen one pulls it low and the other sets it as high. Im also confused as to when the read takes place. It is my understanding that after your loop sends each bit. Do you immediatly follow with another loop to read the bits on the MISO line?

I think that function was originally in C and I converted it into assembler. It works with the Nordic NRF24L01 wireless chips. The original was on the SFE web site somewhere.

Leon

The only code I could find was some spi firmware for the nrf which is close to what I need but the firmware uses multiple for loops to perform the spi routines…Not exactly a send recieve function unless I missed another file some where.

I just found my original code with software SPI written in C on my system. Here it is:

http://www.leonheller.com/MiRF%20V2/MiR … F4520).zip

I converted the SFE CC5X code to C18.

Leon

Thanks I will see if I can get it to work tonight.

Could you explain the following code for me?

spi_Send_Read(0x20);

spi_Send_Read(0x38);

SPI_CSN = 1;

SPI_CSN = 0;

Why do you have 2 spi send read function calls. It looks like one sends a command and one sends data? Is that necessary?

The comment says // PTX, CRC enabled, mask a couple of ints

It should be in the nRF24L01 data sheet.

Try Test.c first. It will show if the SPI is working.

Leon

In your code what is PB ? and what should I set it to on my 16F88?

I set PB to an input I was just wondering what the abreviation was for and what its purpose it? And should the LED stay on when the code is working?

You don’t need them. PB is a push-button on my PCB.

You have to use an ICD 2 to see if the code is working, with the MPLAB debugger.

Leon

I have ICD2 Programming my chip but when I set it as the debugger im getting this error:

ICDWarn0015: Program memory has changed since last program operation? Continue with Debug operation?

Running Target

ICD0083: Debug: Unable to enter debug mode. Please double click this message for more information.

ICD0069: Debug: Unable to run target

Nevermind got it working What should I be looking for in the debugger code?

Just check that you get the correct values.

Leon

I think I have everything working except my reciever is not recieving the transmitter payload but it is using different code.

Thankyou for all of your patience in helping a Noob get setup with wireless!

(The code im referring to in the Tx.c file from your zipped folder)

One last question The reciever Im using uses different code and I believe its payload width is 1 byte and the code you gave me has a payload width of 4 bytes. What are the absolute minimum requirements to get the two to talk? As I understand they have to have the same payload width as well the correct address and channel but im not entirely certain. Also what is the transmitter transmitting out? I just need it to send a character to the other reciever.

Start with my Tx and Rx code, to make sure that the receiver is working properly. You should then be able to get some transmit code working to match the receive code that you have.

Leon

As im going over the code I think i fully understand how everything works. But another question remains…The nrf accepts commands and changes in the form of:

spi(command)

spi(data)

csn =1

csn = 0

next statements…

After looking at the data sheet it seems that there are only 8 commands:

nrf24l01_R_REGISTER 0x00

nrf24l01_W_REGISTER 0x20

nrf24l01_R_RX_PAYLOAD 0x61

nrf24l01_W_TX_PAYLOAD 0xA0

nrf24l01_FLUSH_TX 0xE1

nrf24l01_FLUSH_RX 0xE2

nrf24l01_REUSE_TX_PL 0xE3

nrf24l01_NOP 0xFF

In your code for the transmitter you have:

//clear previous ints

spi_Send_Read(0x27);

spi_Send_Read(0x7E);

I dont see a command refrence for 0x27 ?

or

spi_Send_Read(0x23);

spi_Send_Read(0x03);

or 0x23 etc.