How do you flush the CRC engine? It appears that putting 6 bytes of different data through it every 27ms produces the first CRC and then every corresponding CRC after that is the same...
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
How do you flush the CRC engine? It appears that putting 6 bytes of different data through it every 27ms produces the first CRC and then every corresponding CRC after that is the same...
I don't see your symptom as described. I hacked up the CRC example to run 6 triplets of data through the CRC unit. The results were all different (except for one duplicate I introduced) and all matched the software-computed CRCs.
You probably need to show what you were doing to encounter this.
// Started life as msp430fr235x_CRC.c. Edited for brevity.
#include <msp430.h>
unsigned int CRC_Init = 0xFFFF;
unsigned int i, j;
unsigned success;
#define CRC_M 6 // 6 rows
#define CRC_N 3 // 3 cols
// These are from the example, but broken up into 5 groups of 3.
unsigned int CRC_Input[CRC_M][CRC_N]= {
0x0fc0, 0x1096, 0x5042,
0x0010, 0x7ff7, 0xf86a,
0xb58e, 0x7651, 0x8b88,
0x0010, 0x7ff7, 0xf86a, // Duplicate
0x0679, 0x0123, 0x9599,
0xc58c, 0xd1e2, 0xe144
};
unsigned int CRC_Results;
unsigned int SW_Results;
unsigned int CRC_New;
unsigned sw_res[CRC_M], hw_res[CRC_M];
// Software Algorithm Function Definition (down at the bottom)
unsigned int CCITT_Update(unsigned int, unsigned int);
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
unsigned mask = 0x0001;
P1OUT &= ~BIT0; // Clear P1.0 output state
P1DIR |= BIT0; // Set P1.0 to output direction
PM5CTL0 &= ~LOCKLPM5; // Engage GPIOs
for(i=0 ; i < CRC_M ; i++) // 6 test cases
{
CRCINIRES = CRC_Init; // Init CRC with 0xFFFF
for (j = 0 ; j < CRC_N ; ++j)
{
CRCDIRB = CRC_Input[i][j]; // Input data in CRC
__no_operation();
}
CRC_Results = CRCINIRES; // Save results (per CRC-CCITT standard)
CRC_New = CRC_Init; // Put CRC Init value into CRC_New
for (j = 0 ; j < CRC_N ; ++j)
{
// Input values into Software algorithm (requires 8-bit inputs)
// Clear upper 8 bits to get lower byte
unsigned int LowByte = (CRC_Input[i][j] & 0x00FF);
// Shift right 8 bits to get upper byte
unsigned int UpByte = (CRC_Input[i][j] >> 8);
// First input lower byte
CRC_New = CCITT_Update(CRC_New,LowByte);
// Then input upper byte
CRC_New = CCITT_Update(CRC_New,UpByte);
}
SW_Results = CRC_New;
// Compare data output results
if(CRC_Results==SW_Results) // if data is equal
{
P1OUT |= BIT0; // set the LED
success |= mask; // Got one right
}
else
{
P1OUT &= ~BIT0; // if not, clear LED
while (1) /*EMPTY*/; // Halt on failure
}
mask <<= 1;
sw_res[i] = SW_Results;
hw_res[i] = CRC_Results;
}
while(1); // Stall here forever
}
// Software algorithm - CCITT CRC16 code
unsigned int CCITT_Update(unsigned int init, unsigned int input)
{
unsigned int CCITT;
CCITT =(unsigned char)(init >> 8)|(init << 8);
CCITT ^= input;
CCITT ^= (unsigned char)(CCITT & 0xFF) >> 4;
CCITT ^= (CCITT << 8) << 4;
CCITT ^= ((CCITT & 0xFF) << 4) << 1;
return CCITT;
}
Well I'll do my best to show....Lots of code so I will taylor it down in the hopes you may see something. In short mssg[8]....The code sends out four 8 byte blocks....One every ~27ms....I see these 4 distinct groups on the logic analyzer....I also see P5OUT bits 1 toggling about 2us after each case statement is entered and lasting for about 7.5us before returning high (5.1 is entry and exit out of CRC)....the first CRC I see on the logic analyzer is unique, however the next three CRCs on the next 3 UNIQUE patterns are the same....This second CRC is different from the first block of 8. Essentially it seems as if the data going through the CRC for group 2-4 is the same yet my logic analyzer and the debugger (when I break it appropriately) show that all the packets are unique. Now one caveat that I did just notice and haven't put my finger on is that I see entry and exit 5x in/out of CRC module
some defn:
pTx = mssg;
pRx = incoming;
pSysID = systemID;
mssg[0] = (permanent_Info[0]);
mssg[1] = (permanent_Info[1]);
mssg[2] = (permanent_Info[2]);
mssg[3] = (permanent_Info[3]);
Here is code:
if (!swInfo.err && (swInfo.twoSec & 0x0080)) {
if (!flag) {
p_Seq = systemIdentification(systemID);
flag = T;
}
switch (i) {
case 0:
P5OUT ^= BIT0;
mssg[4] = (0xC0);
mssg[5] = *p_Seq;
break;
case 1:
P5OUT ^= BIT0;
mssg[4] = (0xA0);
mssg[5] = *(p_Seq + 1);
break;
case 2:
P5OUT ^= BIT0;
mssg[4] = (0x90);
mssg[5] = *(p_Seq + 2);
break;
case 3:
P5OUT ^= BIT0;
mssg[4] = (0x88);
mssg[5] = *(p_Seq + 3);
break;
default : break;
}
i++;
CRC_Result = CRC(pTx);
mssg[6] = (char)((CRC_Result >> 8) & 0xFF);
mssg[7] = (char)(CRC_Result & 0xFF);
volumeButtonReleased = 3;
}
}
if (!radioBusy) {
if ((volumeButtonReleased == 3)) {
if (i <= 4) {
pTx = mssg;
UCA1IE |= UCTXIE; //send out message
__bis_SR_register(LPM3_bits);
}
else {
UCA1IE &= ~UCTXIE;
i = 0;
pTx = mssg;
currentSwState = 0;
swInfo.anySw = F;
swInfo.err = F;
swInfo.twoSec = 0;
memset(swInfo.hits, 0, sizeof(swInfo.hits));
mssgPopulated = F;
volumeButtonReleased = 0;
P2IFG &= ~0x06;
P1IFG &= ~0xFE;
}
}
}
Here is the CRC function:
unsigned int CRC (char *payload) {
unsigned int CRC_Result;
unsigned int i, k;
const unsigned int CRC_Init = 0xFFFF;
P5OUT &= ~BIT1;
CRCINIRES = CRC_Init;
for(i=0; i<PAYLOAD_SIZE ;i+=2)
{
k = (*(payload + i)<<8) | *(payload + (i+1));
CRCDIRB = k; //input data into CRC
__no_operation();
}
CRC_Result = CRCINIRES;
P5OUT |= BIT1;
return CRC_Result;
}
> CRC_Result = CRC(pTx);
As I recall, pTx is a walking pointer. After walking through each packet, it probably points to the end of the packet -- random but probably static data. Try:
> CRC_Result = CRC(mssg); pTx isn't a walking pointer....A breakpoint at VolumeButtonReleased shows pointer aligns with mssg and all data except the CRC look good....Not sure what it means yet but it is very telling that packet 1 always returns a unique pattern BUT packet 2 - 4 ALWAYS returns 0x0E10....this either clearly points to static data being used (although I am inclined to not think so as the mssg and pointer look good) OR the code I am using for the function is bad somehow....Can you see anything that stands out with this function :
PAYLOAD SIZE is 6 -- after CRC produces 2 bytes the mssg becomes 8 bytes....Am I doing anything wrong with type casting or concatenation?
unsigned int CRC (char *payload) {
unsigned int CRC_Result;
unsigned int i, k;
const unsigned int CRC_Init = 0xFFFF;
P5OUT &= ~BIT1;
CRCINIRES = CRC_Init;
for(i=0; i<PAYLOAD_SIZE ;i+=2)
{
k = (*(payload + i)<<8) | *(payload + (i+1));
CRCDIRB = k; //input data into CRC
__no_operation();
}
CRC_Result = CRCINIRES;
P5OUT |= BIT1;
return CRC_Result;
}
What does pTx look like the second time you call CRC()? I'm guessing it points to &mssg[6]. (Otherwise you wouldn't have a need to refresh it before sending the packet.)
Bruce...
After carefully looking at what you said....short answer ....You were right!!! Thank you! My tx isr increments ptx then breaks after the mssg hits ptx + 7....i don't reset it until I get into the (i <= 4) statement above to send the message.
You've been a great help
Thanks again
Steve
**Attention** This is a public forum