I'm using a 6812DJ128B in a design, and I've noticed what seems to
be a buffering error with an SPI routine that I use. Some information about what's happening: This routine querries a MC33993 device (Switch monitor). To query the device, I send out 0x00 3 times, and each time it sends me back 1 byte of its status data, for a total of 3 bytes. Watching on the scope, I see the information come across in the correct order. However the value I read in the routine lags by one byte, so this is what i get: Byte 3 of the previous request, Byte 1 of current, Byte 2 of current. I've gotten around this by just asking for the status twice in a row, and grabbing the first returned byte(really byte 3 of the previous request) and putting it where it needs to go. The code for the routine is very simple, and I can't seem to see where this buffering problem comes from, since it only seems to happen with the MC33993, but it is the only SPI device I'm using that returns multiple bytes. Anyone have any ideas? Thanks, Tim Code: char QUERY_SPI_SWITCH_MON() { // This function Querys the status of the switch monitor // and returns negative values if something goes wrong int blah = 0xFFFF; MODRR &= 0xDF; //disable bit 5 in MODRR, routing SPI1 through PORTP SPI1CR1_SPE = 1; //enable SPI SPI1CR1_MSTR = 1; //set master mode SPI1BR_SPR0 = 0x03; //set baud rate to clock/x (16=0x03) (4=0x01) while( !SPI1SR_SPTEF && blah) { __asm NOP; //WAIT for the transmitter empty flag blah--; } if( !blah ) { return -1; //ERROR: timed out WAITing for transmitter empty } SPI1CR1_CPOL = 0; SPI1CR1_CPHA = 1; PORTB_BIT0 = 0; //enable switch mon SPI1DR=0x00; blah = 0xFFFF; while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for transmitter empty+data transfer { __asm NOP; blah--; } if( !blah ) { return -2; //ERROR: timed out WAITing for transmitter empty+data transfer } switch_mon_state_3=SPI1DR; while( !SPI1SR_SPTEF && blah) { __asm NOP; //WAIT for the transmitter empty flag blah--; } if( !blah ) { return -1; //ERROR: timed out WAITing for transmitter empty } SPI1CR1_CPOL = 0; SPI1CR1_CPHA = 1; PORTB_BIT0 = 0; //enable switch mon SPI1DR=0x00; blah = 0xFFFF; while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for transmitter empty+data transfer { __asm NOP; blah--; } if( !blah ) { return -2; //ERROR: timed out WAITing for transmitter empty+data transfer } switch_mon_state_1=SPI1DR; while( !SPI1SR_SPTEF && blah) { __asm NOP; //WAIT for the transmitter empty flag blah--; } if( !blah ) { return -1; //ERROR: timed out WAITing for transmitter empty } SPI1CR1_CPOL = 0; SPI1CR1_CPHA = 1; PORTB_BIT0 = 0; //enable switch mon SPI1DR=0x00; blah = 0xFFFF; while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for transmitter empty+data transfer { __asm NOP; blah--; } if( !blah ) { return -2; //ERROR: timed out WAITing for transmitter empty+data transfer } switch_mon_state_2=SPI1DR; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; __asm NOP; PORTB_BIT0 = 1; //disable switch mon } |
|
S12 SPI buffering problem
Started by ●September 30, 2003
Reply by ●October 1, 20032003-10-01
Hello Tim Some spi devices seem to need extra clock cycles to complete the request -- could you send it one extra byte with 0xff to clock through the last of the three bytes? Best regards Robert On Sep 30, 2003, at 23:16 Europe/Paris, Tim Raabe wrote: > > I'm using a 6812DJ128B in a design, and I've noticed what seems to > be a buffering error with an SPI routine that I use. > > Some information about what's happening: This routine querries a > MC33993 device (Switch monitor). To query the device, I send out > 0x00 3 times, and each time it sends me back 1 byte of its status > data, for a total of 3 bytes. Watching on the scope, I see the > information come across in the correct order. However the value I > read in the routine lags by one byte, so this is what i get: Byte 3 > of the previous request, Byte 1 of current, Byte 2 of current. > > I've gotten around this by just asking for the status twice in a > row, and grabbing the first returned byte(really byte 3 of the > previous request) and putting it where it needs to go. > > The code for the routine is very simple, and I can't seem to see > where this buffering problem comes from, since it only seems to > happen with the MC33993, but it is the only SPI device I'm using > that returns multiple bytes. > > Anyone have any ideas? > > Thanks, > Tim > > Code: > char QUERY_SPI_SWITCH_MON() > { // This function Querys the status of the switch monitor > // and returns negative values if something goes wrong > int blah = 0xFFFF; > MODRR &= 0xDF; //disable bit 5 in MODRR, routing > SPI1 through PORTP > SPI1CR1_SPE = 1; //enable SPI > SPI1CR1_MSTR = 1; //set master mode > SPI1BR_SPR0 = 0x03; //set baud rate to clock/x > (16=0x03) (4=0x01) > > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_3=SPI1DR; > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_1=SPI1DR; > > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_2=SPI1DR; > > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > > PORTB_BIT0 = 1; //disable switch mon > } > ------------------------ Yahoo! Groups Sponsor > ---------------------~--> > Upgrade to 128-Bit SSL Security! > http://us.click.yahoo.com/p7cEmB/s7qGAA/yigFAA/dN_tlB/TM > --------------------------------- > ~-> > > -------------------- > > ">http://docs.yahoo.com/info/terms/ > |
|
Reply by ●October 1, 20032003-10-01
I can give this a try, but I'm not sure it will help me. I use the same chip MC33993 with a PIC, and it works just fine. --- In , ra <swar@c...> wrote: > Hello Tim > > Some spi devices seem to need extra clock cycles to complete the > request -- could you send it one extra byte with 0xff to clock through > the last of the three bytes? > > Best regards > Robert > On Sep 30, 2003, at 23:16 Europe/Paris, Tim Raabe wrote: > > > > > I'm using a 6812DJ128B in a design, and I've noticed what seems to > > be a buffering error with an SPI routine that I use. > > > > Some information about what's happening: This routine querries a > > MC33993 device (Switch monitor). To query the device, I send out > > 0x00 3 times, and each time it sends me back 1 byte of its status > > data, for a total of 3 bytes. Watching on the scope, I see the > > information come across in the correct order. However the value I > > read in the routine lags by one byte, so this is what i get: Byte 3 > > of the previous request, Byte 1 of current, Byte 2 of current. > > > > I've gotten around this by just asking for the status twice in a > > row, and grabbing the first returned byte(really byte 3 of the > > previous request) and putting it where it needs to go. > > > > The code for the routine is very simple, and I can't seem to see > > where this buffering problem comes from, since it only seems to > > happen with the MC33993, but it is the only SPI device I'm using > > that returns multiple bytes. > > > > Anyone have any ideas? > > > > Thanks, > > Tim |
|
Reply by ●October 1, 20032003-10-01
I had a device (a couple years ago) that didn't work properly UNTIL (a) I not only clocked out a 0xFF as a "dummy" byte at the end WHEN (b) the MOSI pin clock polarity was opposite of what I started with. I remember I had to carefully examine the clocking logic on the chip to arrive at that conclusion: The chip demanded a '1' as the '9th bit', and a rising or falling edge to clock the last bit in, which was opposite of the rest of the latching logic. The frustrating part was that whether data got transferred correctly seemed to depend on what the value of the bytes were to begin with. I don't remember what that chip was, and don't ever want to find out again. At 07:53 AM 10/1/2003 +0200, you wrote: >Hello Tim > >Some spi devices seem to need extra clock cycles to complete the >request -- could you send it one extra byte with 0xff to clock through >the last of the three bytes? > >Best regards >Robert >On Sep 30, 2003, at 23:16 Europe/Paris, Tim Raabe wrote: > > > > > I'm using a 6812DJ128B in a design, and I've noticed what seems to > > be a buffering error with an SPI routine that I use. > > > > Some information about what's happening: This routine querries a > > MC33993 device (Switch monitor). To query the device, I send out > > 0x00 3 times, and each time it sends me back 1 byte of its status > > data, for a total of 3 bytes. Watching on the scope, I see the > > information come across in the correct order. However the value I > > read in the routine lags by one byte, so this is what i get: Byte 3 > > of the previous request, Byte 1 of current, Byte 2 of current. > > > > I've gotten around this by just asking for the status twice in a > > row, and grabbing the first returned byte(really byte 3 of the > > previous request) and putting it where it needs to go. > > > > The code for the routine is very simple, and I can't seem to see > > where this buffering problem comes from, since it only seems to > > happen with the MC33993, but it is the only SPI device I'm using > > that returns multiple bytes. > > > > Anyone have any ideas? > > > > Thanks, > > Tim > > > > Code: > > > > > > char QUERY_SPI_SWITCH_MON() > > { // This function Querys the status of the switch monitor > > // and returns negative values if something goes wrong > > int blah = 0xFFFF; > > MODRR &= 0xDF; //disable bit 5 in MODRR, routing > > SPI1 through PORTP > > SPI1CR1_SPE = 1; //enable SPI > > SPI1CR1_MSTR = 1; //set master mode > > SPI1BR_SPR0 = 0x03; //set baud rate to clock/x > > (16=0x03) (4=0x01) > > > > while( !SPI1SR_SPTEF && blah) > > { > > __asm NOP; //WAIT for the transmitter empty flag > > blah--; > > } > > if( !blah ) > > { > > return -1; //ERROR: timed out WAITing > > for transmitter empty > > } > > SPI1CR1_CPOL = 0; > > SPI1CR1_CPHA = 1; > > > > > > PORTB_BIT0 = 0; //enable switch mon > > > > SPI1DR=0x00; > > > > blah = 0xFFFF; > > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > > transmitter empty+data transfer > > { > > __asm NOP; > > blah--; > > } > > if( !blah ) > > { > > return -2; //ERROR: timed out WAITing > > for transmitter empty+data transfer > > } > > switch_mon_state_3=SPI1DR; > > > > > > while( !SPI1SR_SPTEF && blah) > > { > > __asm NOP; //WAIT for the transmitter empty flag > > blah--; > > } > > if( !blah ) > > { > > return -1; //ERROR: timed out WAITing > > for transmitter empty > > } > > SPI1CR1_CPOL = 0; > > SPI1CR1_CPHA = 1; > > > > > > PORTB_BIT0 = 0; //enable switch mon > > > > SPI1DR=0x00; > > > > blah = 0xFFFF; > > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > > transmitter empty+data transfer > > { > > __asm NOP; > > blah--; > > } > > if( !blah ) > > { > > return -2; //ERROR: timed out WAITing > > for transmitter empty+data transfer > > } > > switch_mon_state_1=SPI1DR; > > > > > > > > while( !SPI1SR_SPTEF && blah) > > { > > __asm NOP; //WAIT for the transmitter empty flag > > blah--; > > } > > if( !blah ) > > { > > return -1; //ERROR: timed out WAITing > > for transmitter empty > > } > > SPI1CR1_CPOL = 0; > > SPI1CR1_CPHA = 1; > > > > > > PORTB_BIT0 = 0; //enable switch mon > > > > SPI1DR=0x00; > > > > blah = 0xFFFF; > > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > > transmitter empty+data transfer > > { > > __asm NOP; > > blah--; > > } > > if( !blah ) > > { > > return -2; //ERROR: timed out WAITing > > for transmitter empty+data transfer > > } > > switch_mon_state_2=SPI1DR; > > > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > __asm NOP; > > > > PORTB_BIT0 = 1; //disable switch mon > > > > > > } > > > > > > ------------------------ Yahoo! Groups Sponsor > > ---------------------~--> > > Upgrade to 128-Bit SSL Security! > > http://us.click.yahoo.com/p7cEmB/s7qGAA/yigFAA/dN_tlB/TM > > --------------------------------- > > ~-> > > > > -------------------- > > > > > > > > ">http://docs.yahoo.com/info/terms/ > > >-------------------- > >">http://docs.yahoo.com/info/terms/ Jim Bacon Software Engineer Melles Griot Electro-Optics -- Longmont, Colorado <mailto:> 720-494-4938 x329 personal: <mailto: |
Reply by ●October 2, 20032003-10-02
----- Original Message ----- From: "Tim Raabe" <> To: <> Sent: Wednesday, October 01, 2003 12:16 AM Subject: [68HC12] S12 SPI buffering problem > I'm using a 6812DJ128B in a design, and I've noticed what seems to > be a buffering error with an SPI routine that I use. > SPI is double buffered and line > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for looks bad for me. How I'm understanding S12SPIV2.pdf : While in master mode SPTEF shows if you can write to SPDR. So you can schedule another byte for transmission while previous transfer isn't complete. SPIF shows if transfer's complete and you have smth ready to read from SPDR For buffered transfers only: for(;;){ while(!SPTEF); SPDR=xx; } For 2 bytes IO following scheme may work: // SPI is idle first, read SPI flags before first write to SPDR SPDR=outbyte1; while(!SPTEF); // SPTEF gets cleared very quickly, far before first transfer is complete SPDR=outbyte2; while(!SPIF); inbyte1=SPDR; while(!SPIF); inbyte2=SPDR; This scheme works while "inbyte1=SPDR" line gets executed before second transfer is complete . This means if interrupts are enabled / preemptive multitasking OS works / SPI clock is very high... you may loose received data because as SPI Block User Guide V02.07 states "When a transfer is complete, received data is moved into a receive data register. Data may be read from this double-buffered system any time before the next transfer is complete. " So following scheme is more safe? while(!SPTEF); // first time only SPDR=out1; while(!SPIF); in1=SPDR; SPDR=out2; while(!SPIF); in2=SPDR; SPDR=out3; ... Edward > Some information about what's happening: This routine querries a > MC33993 device (Switch monitor). To query the device, I send out > 0x00 3 times, and each time it sends me back 1 byte of its status > data, for a total of 3 bytes. Watching on the scope, I see the > information come across in the correct order. However the value I > read in the routine lags by one byte, so this is what i get: Byte 3 > of the previous request, Byte 1 of current, Byte 2 of current. > > I've gotten around this by just asking for the status twice in a > row, and grabbing the first returned byte(really byte 3 of the > previous request) and putting it where it needs to go. > > The code for the routine is very simple, and I can't seem to see > where this buffering problem comes from, since it only seems to > happen with the MC33993, but it is the only SPI device I'm using > that returns multiple bytes. > > Anyone have any ideas? > > Thanks, > Tim > > Code: > char QUERY_SPI_SWITCH_MON() > { // This function Querys the status of the switch monitor > // and returns negative values if something goes wrong > int blah = 0xFFFF; > MODRR &= 0xDF; //disable bit 5 in MODRR, routing > SPI1 through PORTP > SPI1CR1_SPE = 1; //enable SPI > SPI1CR1_MSTR = 1; //set master mode > SPI1BR_SPR0 = 0x03; //set baud rate to clock/x > (16=0x03) (4=0x01) > > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_3=SPI1DR; > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_1=SPI1DR; > > while( !SPI1SR_SPTEF && blah) > { > __asm NOP; //WAIT for the transmitter empty flag > blah--; > } > if( !blah ) > { > return -1; //ERROR: timed out WAITing > for transmitter empty > } > SPI1CR1_CPOL = 0; > SPI1CR1_CPHA = 1; > PORTB_BIT0 = 0; //enable switch mon > > SPI1DR=0x00; > > blah = 0xFFFF; > while((!SPI1SR_SPTEF && SPI1SR_SPIF) && blah) //WAIT for > transmitter empty+data transfer > { > __asm NOP; > blah--; > } > if( !blah ) > { > return -2; //ERROR: timed out WAITing > for transmitter empty+data transfer > } > switch_mon_state_2=SPI1DR; > > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > __asm NOP; > > PORTB_BIT0 = 1; //disable switch mon > } > ------------------------ Yahoo! Groups Sponsor ---------------------~--> > Upgrade to 128-Bit SSL Security! > http://us.click.yahoo.com/p7cEmB/s7qGAA/yigFAA/dN_tlB/TM > ---------------------- -----------~-> > > -------------------- > > ">http://docs.yahoo.com/info/terms/ > > |
Reply by ●October 8, 20032003-10-08
At 01:00 PM 10/1/03 +0000, you wrote: >I can give this a try, but I'm not sure it will help me. I use the >same chip MC33993 with a PIC, and it works just fine. You didn't mention what you are doing with CS and SCLK. The data sheet says that handling these correctly is critical for proper operation. Have you triple-checked them? Gary Olmstead Toucan Technology Ventura CA www.toucantechnology.com |
|
Reply by ●October 8, 20032003-10-08
--- In , Gary Olmstead <garyolmstead@e...> wrote: > At 01:00 PM 10/1/03 +0000, you wrote: > >I can give this a try, but I'm not sure it will help me. I use the > >same chip MC33993 with a PIC, and it works just fine. > > > > > You didn't mention what you are doing with CS and SCLK. The data sheet > says that handling these correctly is critical for proper operation. Have > you triple-checked them? > > Gary Olmstead > Toucan Technology > Ventura CA > www.toucantechnology.com Yep, I've checked them several times, and even ended up sending my scope plots out to the apps. engineer in charge of the MC33993, and everything looked like it should according to him. I did try sending out the 0xFF as the 4th bit, which did "fix" the problem on the S12. While sending out 4 bits is better than 6, I still don't like being forced to send out more than I really should have to. Since its works fine on my PIC, I still think there is some buffering problem, possibly like what Jim Bacon suggested earlier. It may need 1 extra bit to actually latch it in after the transfer's complete. I've gotten a few more suggestions to try, and hopefully I'll get it out soon |
Reply by ●October 10, 20032003-10-10
After several rounds with a few different Motorola reps, I finally discovered it was an apparent errata with the DJ128. I'm just amazed it took myself + 3 different people at Motorola over a month to figure that out. MSE9S12D128_1L40K When the SPI is enabled in master mode, with the CPHA bit set, back to back transmissions are possible. When a transmission completes and a further byte is available in the SPI Data Register, the second transmission begins directly after the "minimum trailing time". The problem occurs when, after the SPTEF flag has been set, a further byte is written into the SPI Data Register during the "1st pulse" of a subsequent transmission. |