Helpful ReplyHot!USART Interrupt 4 Byte Limit???

Page: 123 > Showing page 1 of 3
Author
Blackglade
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2017/12/07 22:20:56
  • Location: 0
  • Status: offline
2018/02/14 13:30:15 (permalink)
0

USART Interrupt 4 Byte Limit???

So this is extremely similar to the issue I posted about here in my previous thread (and apparently I can't link the thread without the forum software freaking out over permission errors), but since I made some modifications to my code and am using a slightly different way of handling my data, I figured I should make a separate thread.
 
For context, I am now using interrupts to receive my data with my chip setup as a Synchronous Recieve Slave and am repeatedly sending the string "World" followed by a 
__ms_delay(2000);
. I have the transmitter clocked at 4Mhz with a KBAUD value of 9.615 (decimal value for SPBRG being 103). I am using two PIC16F628A's, one acting as a transmitter and the other a receiver. 
 
Here is my reciever code: 
 
volatile unsigned char addr = 0x00;

void USART_init(void){
    TRISBbits.TRISB1 = 1;
    TRISBbits.TRISB2 = 1;
    
    TXSTAbits.SYNC = 1;
    RCSTAbits.SPEN = 1;
    TXSTAbits.CSRC = 0;

    PIE1bits.RCIE = 1;
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    
    RCSTAbits.CREN = 1;
}

void writestuff(unsigned char x){
    EEPROM_WRITE(addr, x);
    addr++;
}

void interrupt message(void){
    if(PIR1bits.RCIF == 1){
        unsigned char d = RCREG;
        writestuff(d);
    }
}

void main(void) {
    USART_init();
    while(1){}
}

 
Because of some of the feedback I received, I learned how to implement interrupts and put the processing/write of data to the EEPROM in a separate function with a buffer... Yet still, when I receive the data and read the EEPROM, all I get is "WorlWorlWorlWorlWorl", the d is never written. I have confirmed several times that the d is indeed sent by checking for it specifically so it's not an issue with my transmitter code.
 
How can I make sure the d is indeed written and processed correctly?
 
I have gotten the recommendation that if I know the size of the data, I can just store it in a universal buffer and then write it all at once to EEPROM, but for production purposes of this section of my project, in reality, the data that I receive by a chip will be random in size, ranging from 8 to 15 bytes with no null terminator and I have to correctly process and store this. This random stream of data will be sent to me every couple of seconds or so. So that leads me back to the question of how I can make sure to accurately process the data without losing anything?
post edited by Blackglade - 2018/02/14 13:35:09
#1
rodims
Super Member
  • Total Posts : 1353
  • Reward points : 0
  • Joined: 2009/02/10 11:08:59
  • Location: 51.9627, 7.6262
  • Status: online
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 13:39:30 (permalink)
0
I dont' think this does make much sense to create a new thread, if you always have to refer to your previous post
http://www.microchip.com/forums/m1038435.aspx
 
#2
jack@kksound
code tags!
  • Total Posts : 2762
  • Reward points : 0
  • Joined: 2014/05/14 10:03:19
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 13:40:53 (permalink) ☄ Helpfulby Blackglade 2018/02/16 12:56:44
+1 (1)
You are actually performing the eeprom write function within your ISR, possibly not a great idea.
Your code as shown has no "4 byte limit" so either it is in the EEPROM_Write() function or in code you do not show. Possibly the EEPROM_Write() takes too long? Or hits an error?
For testing, echo the received data back out the transmitter and monitor that to see what is received.
#3
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 14:34:17 (permalink)
+1 (1)
As above.
You gained nothing by adding interrupts if you put the EEPROM write inside the interrupt service.

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#4
jack@kksound
code tags!
  • Total Posts : 2762
  • Reward points : 0
  • Joined: 2014/05/14 10:03:19
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 14:47:45 (permalink)
+1 (1)
I have a simple testing suggestion:
Pick an unused port pin, set it as an output. In your ISR toggle the pin when you read a byte from the USART.
Pick another unused port pin, make it an output. Set the pin HIGH just before the EEPROM)WRITE() function call and set it LOW just after the call. Check the relationship of the two outputs to see if you are overlapping (EEPROM_WRITE takes too long).
#5
1and0
Access is Denied
  • Total Posts : 8396
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 15:40:02 (permalink)
+1 (1)
At 9615 baud, a character of 8 bits takes less than 1 ms. EEPROM write can take up to 4 ms.
 
#6
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 15:44:08 (permalink)
0
If you are writing strings to the eeprom, add 1 to include the null terminator.
 
const char *g="Gort1951";
somefunc(g,strlen(g)+1); //9 bytes inc. null
 
Or use Pascal strings with the length as the first byte. <8>Gort1951

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#7
1and0
Access is Denied
  • Total Posts : 8396
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 15:51:42 (permalink)
0
Also, EEPROM_WRITE() does _not_ wait for the write to complete, so I think you have a race condition. 
post edited by 1and0 - 2018/02/14 16:35:39
#8
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:09:53 (permalink)
0
Specify:
 
_epwrite:  ;int epwrite(uint Address, const void *Src, int Len);
 
epwrite(0,g,strlen(g)+1);
 
 
Writing latch buffers is a lot faster than byte writes.

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#9
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:18:45 (permalink)
0
You can wait on eeprom writes, it's very simple.

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#10
jack@kksound
code tags!
  • Total Posts : 2762
  • Reward points : 0
  • Joined: 2014/05/14 10:03:19
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:24:12 (permalink)
0
Gort2015
Specify:
 
_epwrite:  ;int epwrite(uint Address, const void *Src, int Len);
 
epwrite(0,g,strlen(g)+1);
 
 
Writing latch buffers is a lot faster than byte writes.


epwrite()? in XC8? What is that?
#11
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:31:17 (permalink)
0
Just a standard proto. you would use to write data to an eeprom.  That is external eeprom/s.
 
I've lost track with two threads.

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#12
1and0
Access is Denied
  • Total Posts : 8396
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:36:57 (permalink)
+1 (1)
Correction, EEPROM_WRITE() checks for write complete before writing; it is EEPROM_READ() that does not wait for write to complete.
 
When 'W' is received, it is written to the EEPROM. Since it takes ~4 ms to complete the write, "orl" are received in the meantime into the double-buffered FIFO and the RSR, and the letter 'd' is lost.
#13
1and0
Access is Denied
  • Total Posts : 8396
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:38:15 (permalink)
0
Gort2015
You can wait on eeprom writes, it's very simple.

XC8 has lowercase eeprom_write().
#14
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 16:46:10 (permalink)
0
Are you writing to an external eeprom?

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#15
1and0
Access is Denied
  • Total Posts : 8396
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 17:09:41 (permalink)
0
Gort2015
Are you writing to an external eeprom?

No. EEPROM_WRITE is for internal.
#16
Gort2015
Klaatu Barada Nikto
  • Total Posts : 2668
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 18:02:46 (permalink)
0
Just checking through some old PIC18F4520 code.
 
eeprom_read and eeprom_write in lowercase on that chip, the busy/wait is built into the eeprom_Write function.
 
I would have thought it would be the same for EEPROM_WRITE on this chip.

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#17
qɥb
Monolothic Member
  • Total Posts : 3329
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 18:27:18 (permalink)
0
No need to guess.
5.5.5.3 EEPROM ACCESS FUNCTIONS
and
5.5.5.4 EEPROM ACCESS MACROS
in the XC8 User Guide tell you exactly what the function/macro versions do.
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#18
Aussie Susan
Super Member
  • Total Posts : 3338
  • Reward points : 0
  • Joined: 2008/08/18 22:20:40
  • Location: Melbourne, Australia
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 18:36:49 (permalink)
0
I'm also a bit concerned about the underlying approach the OP is taking - writing to EEPROM on each and every character.
I'm not sure if this is an internal EEPROM, emulated EEPROM in FLASH or an external EEPROM but whichever, they have limits on the erase/write cycles they can maintain.
Even if that is 1,000,000 (as many external EEPROMs are) then you will wear out the cells in a small number of days of continuous reception at 9600 BAUD.
Even writing to a buffer and then saving that would be better.
Susan
#19
Urme27
New Member
  • Total Posts : 2
  • Reward points : 0
  • Joined: 2018/02/13 10:03:43
  • Location: 0
  • Status: offline
Re: USART Interrupt 4 Byte Limit??? 2018/02/14 23:29:14 (permalink)
0
I noticed that you did not clear the UART interrupt flag before leaving the ISR.  this will not allow another interrupt flag to be set.  Hence you will not be able to receive again from the uart channel. Put this statement anywhere within the isr routine
 
PIR1bits. RCIF=0;
 
For me I will rewrite the ISR code as:
 
unsigned char d; 
void interupt(){                           
                        if(PIR1bits. RCIF) {                                                             
                                                    d=RCREG;                                                              
                                                    PIR1bits. RCIF=0;                                                              
                                                    }                             
                        }
 
void main(){
                  Uart1_Init(9600);
                  INTCON.GIE=1;
                  INTCON. PEIE=1;
                  PIR. RCIF=0;
                  PIR. RCIE=1;
                  d=0;
                  while(1){               
                               if(d!=0){                             
                                            writestuff(d);         //call your EEPROM Write function here                             
                                            d=0;                    //clear the variable                               
                                           }                 
                              }
                }
post edited by Urme27 - 2018/02/15 04:32:05
#20
Page: 123 > Showing page 1 of 3
Jump to:
© 2018 APG vNext Commercial Version 4.5