# Understanding a PIC FIFO

Status
Not open for further replies.

#### camerart

##### Active Member
Hi,
I'm using a PIC to control a radio module SX1278. This means there will be two FIFOs, one on the PIC and one on the SX.
I have questions about the SX FIFO here: http://www.electro-tech-online.com/...ion-receiving-using-scr-radio-modules.149198/
This is regarding the PIC FIFO:
Am I correct, that a serial sentence enters the PIC via the RX pin, and is stored in the FIFO, till a HSEROUT command is given? How big is the FIFO on an 18LF2520 PIC?

Cheers, Camerart.

#### ericgibbs

##### Well-Known Member
Morning C,
The Receive buffer can hold 2 bytes of incoming data, if a third byte is received an error flag is raised, so the buffer [ fifo] holds two bytes.
E

Last edited:

#### camerart

##### Active Member
Morning E,
If I recall correctly, we've done this before with NMEA sentences (Which of course is one of the uses for this set-up) I can now visualise the HSERIN/OUT Oshonsoft simulations. I think what is puzzling me is that in real life it happens a bit quicker, so a sentence comes into the PIC completely in one string.
Where is the sentence held and how do I send it to the SX1278 at the correct timing?
Thanks.
C.

Last edited:

#### ericgibbs

##### Well-Known Member
hi C,
If you want to hold/buffer an incoming serial data string you would enable the UART's interrupt.
When the first byte of the incoming string appears in the UART buffer it will raise an interrupt.

Loop:
The ISR [Interrupt service subroutine] would read the recv buffer and move the received byte into a software buffer, the program would increment the software buffer address pointer.
If the received byte is LF [0x0a] that is the incoming string terminating byte. EXIT
else
keep reading the UART s RCIF and if set, read the UART recv buffer and move the byte to the software buffer.
Loop.

An alternative method is to use the RCIF to jump to the ISR on every byte, I prefer the former method.
The downside is, if the LF byte never arrives the program is stuck in the ISR loop!!! , You have to use a PIC Timer to check if its time to escape from the ISR.

It is also important that when entering the ISR due a RCIF, you test the OERR [over run error]
If there is an Error you must clear the error flags.

E

#### Pommie

##### Well-Known Member
I use a software fifo to keep the code flowing,
Code:
#define FifoLength 32
unsigned char RXFifoBuffer[FifoLength];
unsigned char *RXFifoStart;
unsigned char *RXFifoEnd;

void InitFifo(void){
RXFifoStart=RXFifoBuffer;
RXFifoEnd=RXFifoBuffer;
}

void PutRXFifo(unsigned char chr){
*RXFifoEnd++=chr;
if(RXFifoEnd==RXFifoBuffer+FifoLength)      //reached end
RXFifoEnd=RXFifoBuffer;                 //yes so wrap
if(RXFifoStart==RXFifoEnd){                 //is head eating tail?
//fifo full so deal with it!!
}
}

unsigned char GetRXFifo(void){
unsigned char chr;
while(RXFifoStart==RXFifoEnd);              //if fifo empty then wait
chr=*RXFifoStart++;
if(RXFifoStart==RXFifoBuffer+FifoLength)    //wrapped?
RXFifoStart=RXFifoBuffer;               //yes
return(chr);
}

unsigned char RXFifoCount(void){
if(RXFifoEnd>=RXFifoStart){
return(RXFifoEnd-RXFifoStart);
}else{
return(FifoLength-(RXFifoStart-RXFifoEnd));
}
}
Then in the interrupt I have,
Code:
    if(RCIF&&RCIE)
PutRXFifo(RCREG);
And in the main code I can do,
Code:
if(RXFifoCount()!=0){
var=GetRXFifo();
}
Just calling GetRXFifo will force it to wait until a character is received.

Mike.

#### camerart

##### Active Member
Hi M,
Thanks for the CODE, but it's written in a foreign language for me. I only speak BASIC, sorry. Also it appears to have a FIFO size where the FIFO is limited to a couple of BYTES.

Hi E,
This FIFO lark isn't an easy one is it
Can you visualise the speed of the other program here: http://www.electro-tech-online.com/...ion-receiving-using-scr-radio-modules.149198/
having the speed to accept an incoming sentence on the fly? This would solve a lot of things. In real life, when connected to 'say' a GPS module, it would send a message at 1 to 5 sentences/sec, so I suppose there would be no need for storage.
C.

#### Pommie

##### Well-Known Member
The fifo in the above code is set at 32 bytes (FifoLength) but can be any length. I actually use a fifo on both receive and transmit and find the transmit one most useful as I can send a long sentence without pausing the code.

Maybe Eric could convert above to basic. Does OBasic have pointers?

Mike.

#### camerart

##### Active Member
The fifo in the above code is set at 32 bytes (FifoLength) but can be any length. I actually use a fifo on both receive and transmit and find the transmit one most useful as I can send a long sentence without pausing the code.

Maybe Eric could convert above to basic. Does OBasic have pointers?

Mike.
Hi M,
Ok, thanks.
I'll finish the program here: http://www.electro-tech-online.com/...ion-receiving-using-scr-radio-modules.149198/ first to the best of my abilities, first, then try to test it and see a FIFO is necessary.

NOTE: When referring to the SX1278 FIFO, I will colour it BLUE, for clarification. Here we are talking about the 18LF2520 FIFO.
Eric, don't convert anything yet
Ok, back to the other thread!
C.

#### ericgibbs

##### Well-Known Member
having the speed to accept an incoming sentence on the fly?
hi,
IIRC you are programming the TX as well the RX ends of the LoRa radio link, so why are the rates so high.??
You can select a lower rate.??
E

#### camerart

##### Active Member
hi,
IIRC you are programming the TX as well the RX ends of the LoRa radio link, so why are the rates so high.??
You can select a lower rate.??
E
View attachment 106777
Hi E,
Well spotted, however, I notice that this is in the FSK/OOK not the LORA section of the DATA sheet. I would have to double check whether this is relevant. You will notice that the LORA sections are in light blue. Having said that, there are some shared sections. A DATA sheet to send you mad
EDIT: I searched, and don't think this is used in LORA MODE.

C.

Last edited:

#### plawrence14

##### New Member
Hi Camerart,

I have read this post with interest I have been trying to control a sx1278 from a PIC18F45K22 and while if I slow the program down i can see the spi bits and they look ok. I'm getting nothing from the sx1278 on my spectrum analyser. I have posted my mikroBasic code could you have a look please?

Thanks

Paul

program bitBangSPItosx1278

' Declarations section
dim NCS as sbit at LATA.4 'set a4 as nss output
dim MCK as sbit at LATC.3 'set c3 as clk outout
dim MOSI as sbit at LATC.5 'set c5 as write outpur
dim MISO as sbit at PORTC.4 'set c4 as read input

dim bitcnt as byte ' used as count for sending a byte
dim address as byte ' used to hold register address to write too
dim payload as byte ' used to hold data to be sent

Sub procedure sendByte()
MOSI = 0 'set MOSI start at 0
NCS = 0 'NCS low to select sx1278
MCK =0
'first write address byte
for bitcnt = 0 to 7 'counts through all bits in byte
MCK = 0 'clock low
if address AND 0x80 then 'checks MSB against address for 1to decide what to write to mosi
MOSI = 1
else
MOSI = 0
end if
delay_ms (200) 'just used so I can watch the bits on dev board
MCK = 1 'clock high
delay_ms (200) 'just used so I can watch the bits on dev board
next bitcnt

'now write data byte
for bitcnt = 0 to 7 'counts through all bits in byte
MCK = 0 'clock low
if payload AND 0x80 then 'checks MSB against payloadfor 1to decide what to write to mosi
MOSI = 1
else
MOSI = 0
end if
delay_ms (200) 'just used so I can watch the bits on dev board
MCK = 1 'clock high
delay_ms (200) 'just used so I can watch the bits on dev board
next bitcnt 'loop to next bit in byte
MCK = 0 'clock low
NCS = 1 'NCS sent low unselecting sx1278
end sub

sub procedure Standby()

payload = 0x89 ' in standby mode
sendByte()

end sub

sub procedure FSTX()

payload = 0x8A ' in FSTX mode
sendByte()

end sub

sub procedure transmit()

payload = 0x8B ' in TX mode (used transmit as name of sub as TX reserved
sendByte()

end sub

main:
' Main program

OSCCON = 0x60 'set to 8 negs
PLLEN_Bit = true 'multiple of 4 so 32 megs
ANSELB = 0 ' set port b to digital
ANSELC = 0 ' set port c to digital
ANSELD = 0 ' set port d to digital
TRISA = 0x00
TRISD = 0X00 'SET AS OUT PUT
TRISC = 0x10 'set port C as output except pin 4 thats an input
TRISB0_bit =1 'sets RB0 pin as a input
TRISB1_bit =1 'sets RB1 pin as a input
TRISB2_bit =1 'sets RB2 pin as a input
TRISB3_bit =1 'sets RB3 pin as a input
NCS = 1
Standby() ' in standby mode

while true
if (BUTTON(PORTB, 0, 1, 1)) then ' check scondition of button attached to B0 run if pressed
LATD = 0xFF

FSTX()

payload = 0x01 'data to be transmitted

sendByte()

transmit()

LATD = 0x00
end if
wend

end.

#### Nigel Goodwin

##### Super Moderator
Make sure you're using the right SPI mode - I've messed up (and struggled for ages) a few times by using the wrong one.

#### plawrence14

##### New Member
Thanks nigel
Im just bit banging the spi, would this not work?
I have set my loop so that the data is written as the clock pulse rises a quick google shows there are three different approaches for writing to SPI

Thanks

paul

Last edited:

#### Nigel Goodwin

##### Super Moderator
Thanks nigel
Im just bit banging the spi, would this not work?
I have set my loop so that the data is written as the clock pulse rises a quick google shows there are three different approaches for writing to SPI
Are you bit-banging the correct mode?, and why not use the SPI hardware anyway?.

#### plawrence14

##### New Member
I was originally using the hardware spi lib I swapped to bit banging so i could slow sown the program and check what was coming out of each pin.
Thanks you have given me something to play with i've just been reading about the different modes so will try and adjust to see if i get any thing different

Paul

#### Nigel Goodwin

##### Super Moderator
Figure 2 on this site shows the different modes, you need to make sure you're using the correct one, do you know what the device needs?.

#### plawrence14

##### New Member
Ill have a look and compare it too the sx1278 datasheet. I think it is on the rising edge that it should be seeing data on the mosi pin but will check. thank you again

Paul

#### camerart

##### Active Member
Hi Camerart,

I have read this post with interest I have been trying to control a sx1278 from a PIC18F45K22 and while if I slow the program down i can see the spi bits and they look ok. I'm getting nothing from the sx1278 on my spectrum analyser. I have posted my mikroBasic code could you have a look please?

Thanks

Paul
Hi P,
Since my last post here Jun 29, 2017 I changed to the HC-12 radio module, and hope to return to the SX1278, as soon as possible. I've been on a different journey, in electronics and programming.

I see you're getting help, but if you don't succeed, I'll try to help.

C.

Status
Not open for further replies.