Hi all,
we cam from: https://community.freescale.com/message/63224#63224
I understand that I have something worng in my code, I read a lot of documentation and look for some examples but I don't find a solution, my problem know is that I receive teh data from the sensor in reversebit mode (1=low and 0=high).
I configured the SPI modulo as:
// SPI
SPIC1_SPE=1;
SPIC1_SPIE=0;//1
SPIC1_MSTR=1;
SPIC1_CPHA=0;
SPIC1_SSOE=1;
SPIC1_CPOL=1;
SPIC1_LSBFE=0;
//SPIC2
SPIC2_MODFEN=0;
SPIC2_BIDIROE=0;
//SPIBR SPI clock = BUSCLK/4 = 1MHz
SPIBR_SPPR2=1;
SPIBR_SPR1=1;
then a GPIO as a SS, and make a loop as:
STROBE=0;
for (vegades=0;vegades<2;vegades++){
while (SPIS_SPTEF==0) clrWD();
SPID=counter;
while (SPIS_SPRF==0) clrWD();
res[vegades] = SPID;
counter=26; //dummy
}
STROBE=1;
SO in that way I recevie 2 byte with the 10 bit angular position and 6 bits with the sensor status and all is ok.
But now I checking the sensor behavior: the data output with the PWM sensor output and when the PWM output is like 26 I receive 998, I didn't realize of that the first time because I didn't need to compare both signals, and also I'm not able to localize the status bits (where are they and the logic levels don't match with the reality).
So i'm doing something wrong?
Hello,
I notice that the code within the file main.c differs from the posted code snippet in that the STROBE signal is becoming inactive after each byte received. The STROBE line should remain low for the duration of the 16-bit transfer, as shown in the snippet.
I notice that you have also defined DATA as the pin corresponding to MOSI. While this may be a spurious macro definition, I presume that the actual connection between the encoder and the MCU is DO -> MISO (PTBD4)?
The following line seems to contain an error:
resL = ReceivedByteH & 0x70;
I would suspect that the mask value should be 0xE0. i also think that there is a related problem where you combine the two bytes into a single word value,
resultat = (resH *
It would seem that the division should be by 32 to achieve a value of 0 to 7. Maybe I would tend to use the following alternative expression, as a personal choice:
resultat = (resH << 3) + (resL >> 5);
With your SPI initialisation, you are separately initialising individual bits within the same register. In addition to creating inefficient code, it may lead to additional sequencing problems. The best approach is to simultaneously initialise all bits in the registers, for example:
SPIC1 = 0x58;
SPIC2 = 0x00;
Additional documentation on the details of the setup should be included as comments. Your SPI clock rate seems to be bus clock /8, rather than the intended bus clock /4.
Some more general comments about your coding:
word get_pos( void){ word resH, resL; STROBE = 0; while (!SPIS_SPTEF); SPID = 0; // Send dummy byte while (!SPIS_SPRF); // Wait for completion of send resH = SPID & 0x007F; SPID = 0; // Send next dummy byte while (!SPIS_SPRF); // Wait for completion of send resL = SPID & 0x00E0; STROBE = 1; return ((resH << 3) + (resL >> 5));}
for (i = 0; i < arrayPos; i++) bufferRead[i] = get_pos();
Regards,
Mac
Hi bigmac
I notice that the code within the file main.c differs from the posted code snippet in that the STROBE signal is becoming inactive after each byte received. The STROBE line should remain low for the duration of the 16-bit transfer, as shown in the snippet.
Yes thats true it's just a problem of save as ... sorry for the mistake.
I notice that you have also defined DATA as the pin corresponding to MOSI. While this may be a spurious macro definition, I presume that the actual connection between the encoder and the MCU is DO -> MISO (PTBD4)?
Yes it is.
The following line seems to contain an error:resL = ReceivedByteH & 0x70;
Yes it should be ReceivedByteL, anyway I will test all of your porpousal, seems to be more easy to manage it.
I tested the code that you wrote to me (thxs) but I still having the same problem (maybe I need to read more carefully the encoder doc) when I spected to receive 1000 I received the 24 (the complementary data), and I'm not able to localize the satuts bit, I will explain it with an example:
Iamgine that the magnet over the enconder is in the 90º (256) (359º equals 1024), I can adjust the position using the PWM output from the encoder, so the data transmit should be:
D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 OCF COF LIN MIN MDEC EPAR
0 0 1 1 1 1 1 1 1 1 0 ? ? 0 0 ?
I'm searching for the angular position and for the COF bit or MIN + MDEC, but I can decode 270º(768):
D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 OCF COF LIN MIN MDEC EPAR
0 1 1 0 0 0 0 0 0 0 0 ? ? 1 1 ?
thta's my problem, I supossed thta I'm doing something worng, and then I started to make samll changes with no result.
thxs for all
Cram
Hello Cram,
The status bits were masked out within the get_pos() function. If you need to monitor these, perhaps this function should simply return the raw 16-bit data.
word get_pos( void){ word result; STROBE = 0; while (!SPIS_SPTEF); SPID = 0; // Send dummy byte while (!SPIS_SPRF); // Wait for completion of send result = (SPID & 0x007F) << 8; SPID = 0; // Send next dummy byte while (!SPIS_SPRF); // Wait for completion of send result += SPID; // Includes status bits STROBE = 1; return result;}
#define ERRMASK 0x0C // COF and LIN error bitsword val;byte status;val = get_pos();status = (byte)(val & 0x001F)... if ((status & ERRMASK) == 0) { bufferRead[i] = val >> 5; // Right align 10-bit position value ...} else { // Reading error action }
How do you know that your reference rotational position is 90 degrees, rather than 270 degrees? If you are comparing the absolute result with the PWM waveform, is it possible that your measurement of the PWM pulse period may be incorrect, perhaps by starting with the wrong edge? This is likely to be so if the absolute reading increases with clockwise rotation, but the measured pulse period decreases.
Regards,
Mac
How do you know that your reference rotational position is 90 degrees, rather than 270 degrees? If you are comparing the absolute result with the PWM waveform, is it possible that your measurement of the PWM pulse period may be incorrect, perhaps by starting with the wrong edge? This is likely to be so if the absolute reading increases with clockwise rotation, but the measured pulse period decreases.
I checked it (rotational reference) with and oscilloscope and the PWM output from the encoder without data adquisition. So when I saw a PWM signal I receive the complementary data from the encoder (ok I can something like result=1024-getpos(); and then I have the same position, but it's not logical to have a PWM output and the complementary for the SPI).
So my doubt is if I was setting up the modulo in the wrong sense and I misunderstood the logical level 0 and 1. And when I need to check if the recevied byte is valid or invalid I must check the COF (0= valida data and 1=invalid data) but now for me is in the revers emode, So I need to validate the behavior, I will ask to the supplier in order to assure the measure.
Thxs for all.
Cram
I will test you mask proposal, it's more or less like mine but anyway I'll test it.
Hello Cram,
Another test that you might try is to slowly rotate the magnet unil you get the index output pulse, and then check the corresponding absolute reading and PWM duty cycle. You might also check whether the absolute reading and the PWM output increases or decreases as the magnet is turned clockwise.
The expression to get the ones complement of a 10-bit value should actually be -
result = 1023 - (getpos() >> 5);
Another alternative to this expression would be -
result = (getpos() >> 5) ^ 0x03FF;
For both of these expressions I have added the right shift required to eliminate the status bits.
Regards,
Mac