Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Wierd PIC problem

Status
Not open for further replies.

chrischris

Member
Hi Guys,

I am trying to write POCSAG (pager protocol) encoding codes in to a PIC16LF1934, but I receive the following message in MPLAB........

Could not find space for variable G and C........

Here variable G is a 21 by 31 matrix and C is the 1 by 31 matrix, ...


the PIC16LF1934 has 7 KB memory and the code is very small, .. I actually can't put the code here because I am developing this for a company and this is my first job, while I am still doing my bachelor's so .... dont know how can I explain it anymore but if any one can help then I'll be very thankful.
 
Hi Guys,

I am trying to write POCSAG (pager protocol) encoding codes in to a PIC16LF1934, but I receive the following message in MPLAB........

Could not find space for variable G and C........

Here variable G is a 21 by 31 matrix and C is the 1 by 31 matrix, ...


the PIC16LF1934 has 7 KB memory and the code is very small, .. I actually can't put the code here because I am developing this for a company and this is my first job, while I am still doing my bachelor's so .... dont know how can I explain it anymore but if any one can help then I'll be very thankful.

21 by 31 matrix of what? That's 651 elements in the array. How big is the code? That seems like a pretty big array for a PIC16LF1934 which only has 256 bytes of RAM. Where are you putting this array, how is it declared? I'm no PIC guru, but if you're trying to put in RAM, it isn't going to fit. If it's constant, then you might have a chance...

Brad
 
Well as I said I can't put the whole code........ but what I am trying to do is CRC generation and for that I have to multiply two matrices, the fix generator matrix which is G[21][31] and the variable data matrix D[1][21], both the matrices are declared as int. so..... I dont know exactly where it will be in RAM or programming memory ,all the elements of the matrix is either 0 or 1 so not like some big data matrix.



Chris

* actually not CRC it is BCH(31,21) but kind of CRC
 
Last edited:
Yeah your whole idea of the way to perform the task is way off.
As stated the PIC16LF1934 has 256 bytes of RAM. It has 7KB of space for Program and constants, which cannot be used for variables at all.
G[21][31] in 16-bit "int" would require 1302 bytes of RAM.

But even IF you had a bigger, more expensive PIC which >2K RAM, this would not be a typical way to perform a CRC. In most cases you'd calculate a running tally for the CRC until the packet is done, and then find out whether the CRC is valid or not. However, this is a problem when you cannot begin to process data until it's known whether the CRC was correct or not, so an entire FRAME of data must be buffered. We try to avoid this in the microcontroller realm by, well, for one, not using >1KB frames! If we have control over the protocol and thus the frame size, we might do a 32 byte frame, 64 byte, whatever.

It is often NOT essential to buffer an entire frame before acting. For example, many scenarios have no way to re-request a frame anyways so can only note that bad data was received or stop/reset. You have to evaluate whether genuine harm would occur during the initial processing of the corrupted frame before the corruption was known about. If it's audio data, probably not much of a problem. If you're writing to a flash card, writing based on bad data.... well, if you can't continue and have to reset, the file it's writing is damaged and invalid anyways, right? Just don't write to random sectors of the flash card.

So, if you MUST know a frame is valid before acting, then you MUST have a larger part with enough RAM to hold a frame. None of the 16F series can do this, you'd need an 18F, and a higher-end one at that.
If you DON'T absolutely, positively have to hold your data until it's known to be valid, then calculate the CRC on-the-fly.

As an engineer, your job is to inform your boss of this situation ASAP. If he wants the part to start processing the data as it comes in, and bomb and reset when the CRC comes back bad to save money, so be it. If he wants to get a higher end 18F which can buffer a frame and thus respond more gracefully (if the other device can even be asked to resend a bad frame), so be it. Not your call.
 
Thanks for explanation but I am trying to encode BCH not decode and, can you please explain in more detail how to do running telly of CRC, this the first time I am working on DSP and in some theoretical examples I have seen this matrix way of doing CRC so I picked it up but if there is any other way please explain, as I said I am a student of B Tech and this is a good chance to make my place in industry so I will be really grateful of any help

Thanks
Chris


And I have seen a POCSAG encoder that uses 16C85 so I think 16LF1934 is far more capable .
 
Last edited:
Well, like, at the start of a frame you initialize the CRC register to whatever the CRC method used requires. You also initialize a word counter. As each word comes in, you apply it to the CRC routine, in whatever way your CRC routine requires, then send the word out. Then add the CRC to the end of the packet and send that out.

Computer Science people are almost always initially thrown into confusion, because the way they've been taught to perform tasks on a bigger computer won't work on a uC. You have to change your concept of problem-solving to work with limited RAM and processing time.

I can't tell you how to convert your matrix method of calculating CRC to the uC method. I do know that the uC method involves simple shifting and addition for each word it wishes to add to the CRC tally. I don't know if that's the same thing BCH uses.
 
Last edited:
But that's what I am doing I was just trying the BCH encoding for ASCII 'A' ; but then even I will need G[21][31] and data matrix D[1][21], because POCSAG protocol uses BCH 31,21


Chris
 
Well I can't solve the problem for you. The basic fact is the PIC16 series cannot store that matrix, no matter what you do. The higher end of the 18F series can- but it'll leave very little RAM left over.

However, glancing over the BCH, it looks like the encoding is just a polynomial sum. It looks like you can just break it down to how each word adds to the result and, well, do that for each word. Only decoding it to try and pinpoint a single-bit error requires matrix math with the entire matrix available.
 
Well thanks anyway, but as I said I have seen a code utilizing 16C84 , its in assembly so dont understand much I am giving the link for that , but I think it uses the shift method , usually for easy coding this method is done only to generate the generator matrix of 21 X31 but I think in case of MCU s it is done for every single message bit as the general matrix doesn't fit in to the MCU............. that is what I can make out of all this trouble so far ...will see how it goes.........but any way I will solve it anyhow and will post back

**broken link removed**

Thank you very much

Chris
 
Last edited:
After a long struggle I got it working for BCH (5,3), I have not tested it on PIC (16LF1934) but the code is build successfully and I have tried this code in Visual C and it gives expected output but when I tried the same code for BCH (31,21) it is not working , I will try to figure it out but for now if anybody can help with that I will be thankful.
Code:
int data,xmdx,p_xmdx,gx,n,a,b,c,d,t,m,x, parity, poc_out;
void bch_crc();
void reset();
void parity_gen();
void pocsag();
void main ()
{
	
	m=2;
	data=1 ; // 100
	printf ("Data is %d \n", data);
	xmdx=data<<2; //10000
	p_xmdx=xmdx ;
	n=16;
	b=0;
	gx=7;  // 111
	gx<<=m;//11100
	printf ("gx is %d \n", gx);
	bch_crc();
	printf("Remainder is %d \n",xmdx);
	printf ("BCH code word without parity is %d \n", p_xmdx+xmdx);
    parity_gen();
	pocsag();
	
}
//*********************************************************************
void bch_crc()
	{
loop:
	a=xmdx&n;
	if(a>0)
	{
	printf(" The MSB is %d bit \n",b);
	gx>>=b;
	printf ("gx is %d \n", gx);
	}
	else
	{
		n>>=1;
		b++;
		goto loop;
	}
	xmdx^=gx;
	reset();
}
//***********************************************************************
void reset()
{
	if(xmdx>3)  // because 4 is the smallest number 
	{
	n=16;
	b=0;
	gx=7;  // 111
	gx<<=m;//11100
	n=16;
	bch_crc();
		
	}
	
}
//*****************************************************************************
void parity_gen()
{
	c=p_xmdx+xmdx;
	n=16;
	parity=0;
for(t=0;t<=4;t++)
{
	x=c&n;
	if(x>0)
	{
		parity++;
		n>>=1;
	}
	else
	{
		n>>=1;
	}
	
}

printf("parity check value is %d \n", parity%2);
if(parity%2<=0 )
{
	printf (" even parity is %d \n",0 );
	
}
else
{
	printf (" even parity is %d \n",1 );
	parity=0;
}

}
//**********************************************************************************
void pocsag()
{
	c<<=1;
	poc_out=c|parity;
	printf("POCSAG encodedd data is %d \n", poc_out);
}




I think it is becomming more a programming problem than MCU so I will start a new thread about this.



Thanks
Chris
 
Ok the BCH (5,3 ) code does work for 31,21 as well, I just forgot to modify n in reset routine , But for now I got a question , may sound silly but let me explain......

Say I have a receiver(PIC or anything else ) that is programmed to dived the incoming data in to the frames of 4 bits and then it decodes that 4 bit of which MSB is even parity and the rest are data ........


Now say I want to transmit decimal 7 = 111 binary , so the transmitted data with even parity at MSB will be 1111 so the receiver will throw away parity and will have the data, but this works fine because the data with parity is 1111 means all four bits are used now say the data is decimal 5 = 101 so the data with even parity at MSB will be 0101 so the transmitter will transmit 101 because preceding 0 doesn't matter now the data becomes of only three bit and if these three bit data frame is transmitted right after the previous frame the whole transmission string will be 1111101 now the receiver will take first bit as parity for first frame and then three bit as data bit and then the next bit as parity bit for second frame , but that is actually not a parity bit :eek: ...................... so

my question is, does any one know how to add the actual parity bit which is 0 in the second frame ? I mean the data of these two example frame should be 11110101 and I have to proceed frame by frame so I can not treat 11110101 as a whole and transmit.



Actually I need to do this for a 32 bit data frame for POCSAG and that is why I am not starting a new thread for this question .

Any help will be grateful.

Thanks,
Chris
 
hello Chris,

this is what I did in my Pic18f2525

void encode_bch(uchar *codeword)
{
s8 i;
u8 j;
u8 feedback;
#define BCH3221_K_21 21
#define BCH3221_LENGTH_31 31
#define CRC_LEN 11
u8 crc[CRC_LEN];

for (i = 0; i < CRC_LEN -1; i++)
crc = 0;

for (i = BCH3221_K_21 - 1; i != -1 ; i--)
{
feedback = codeword ^ crc[(BCH3221_LENGTH_31 - BCH3221_K_21 - 1)];

if (feedback != 0)
{
for (j = BCH3221_LENGTH_31 - BCH3221_K_21 - 1; j > 0; j--)
if (g_poly[j] != 0)
crc[j] = crc[j - 1] ^ feedback;
else
crc[j] = crc[j - 1];
crc[0] = (g_poly[0] && feedback)? 1:0;
}
else
{
for (j = BCH3221_LENGTH_31 - BCH3221_K_21 - 1; j > 0; j--)
crc[j] = crc[j - 1];
crc[0] = 0;
}
}

load_chksum:;

for (i = 0; i < BCH3221_LENGTH_31 - BCH3221_K_21; i++)
{
codeword [BCH3221_K_21+i]= crc;
// bit1 = msg/capcode bit 20-21 = function bits
// bit21 ~bit 31 = data[20]~data[30] = CRC
}

j = 0;
for (i = 0; i < 31; i++)
if (codeword == 1)
j++;
j =j & 0b00000001;

if (j== 1)
codeword[31] = 1;
else
codeword[31] = 0;
}

Regrads,

Tomma
 
Status
Not open for further replies.

Latest threads

Back
Top