This thread is old by now, but I just had a chance to try your suggestion, Joe. I agree that it appears that you cannot disable SDI. So, I tied it high, set it as an input, and then reverted back to the old method of using SPI (stream the next byte into the buffer as soon as it says that the buffer is not full rather than waiting for the entire byte transfer to finish before loading the next byte) and the problem is still there. It is good practice to tie SDI to some level and not let it float, but the problem still exists. Any more ideas? I have copied my original message below Joe's reply for reference. Thanks, Sean On Sat, Sep 24, 2011 at 10:13 PM, IVP wrote: >> the SDI pin on the PIC is left floating and its TRIS bit is >> cleared. I do not know whether it remains an output when >> the SPI module is enabled > > Sean, I don't believe you can disable SDI if SPI is enabled, for the > dsPICs I use anyway. SDO and SCLK you can. If that's true for > the 610 then SDI will be a floating input and a accident waiting to > 'appen > > Look at the control bits in SPIxCON1 > > Joe > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > O great piclist, I must once again approach you with a request for help :) I have a project where a dsPIC33FJ64GS610 communicates with an AD5060 16-bit DAC using SPI. This is a uni-directional transfer, so the data received by the PIC is discarded and the SDI pin on the PIC is left floating and its TRIS bit is cleared. I do not know whether it remains an output when the SPI module is enabled. The problem I am having is this: in this three byte transfer, the first byte is always 00, the second is the MSByte of the commanded codeword, and the third is the LSByte of the commanded codeword. The transfer always works fine if I hardcode delays (longer than 1 byte time) between each line of code which loads the next byte into the SPI2BUF register. However, if I try to use the SPI status bits to complete the transfer as efficiently as possible (i.e., use the fact that I can be loading the next byte while it is transferring the first), then sometimes, seemingly randomly, the MSbit of the middle byte will get set. There are certain codewords where this never happens and then others where it happens about 50% of the time. It seems that the MSbit of the third byte is what determines whether this problem can happen. If the MSbit of the third byte is 0, then the problem never seems to happen. If it is 1, then it sometimes happens - almost as if the third byte's MSbit is being copied to the middle byte's MSbit. I checked the errata for this part and there doesn't seem to be any errata for the simple SPI master mode that I am using. Interestingly, some other PICs in the dsPIC family have an erratum for the SPI port where certain values get transmitted as a 0x80, which sounds suspiciously like this problem. On my scope, I can see that, when this problem happens, it is caused by a narrow glitch on the SDO line from the PIC. In the SPI mode I am using, data should change on the rising edge of the clock and get sampled by the DAC on the falling edge. This glitch happens right before the falling edge of the 9th bit of the 24-bit transfer. The falling edge of the glitch seems to happen simultaneously to the falling edge of the clock. As I say, this glitch only happens for certain codewords and even then, only about half the time. To see scope screen shots of this, please see: http://www.cheapgalvis.com/D001.BMP http://www.cheapgalvis.com/D002.BMP The bottom two traces are zoomed-in versions of the top two. The clock is the trace with the regular transitions. The glitch is most easily visible in the bottom-most trace (zoomed-in version of the SDO line). The D001 shot is zoomed out further to see the beginning of the transfer and the D002 is zoomed in enough to show the width of the glitch. For those who are kind enough to really look into this problem with me, please see the initialization code and actual SPI transfer function below. It is written in C, and I am compiling this using MPLAB X beta 7.01 with the included free version of the C30 compiler, and programming it into the PIC using a PICkit 3. Thank you! Sean Here is the initialization code: #include // 7372800 MHz Fosc // div by 2 to get Fcy=3D #define FCY 3686400 #include #include #include _FOSCSEL (FNOSC_PRI) _FOSC(POSCMD_HS & OSCIOFNC_OFF & FCKSM_CSDCMD) _FWDT(FWDTEN_OFF) TRISGbits.TRISG0=3D0; // unused TRISGbits.TRISG1=3D0; // unused TRISGbits.TRISG2=3D0; // unused TRISGbits.TRISG3=3D0; // unused // TRISG4,TRISG5 do not exist TRISGbits.TRISG6=3D1; // -- SCK2 - DAC_SCLK TRISGbits.TRISG7=3D0; // unused TRISGbits.TRISG8=3D1; // -- SDO2 - DAC_SDATA TRISGbits.TRISG9=3D0; // unused // TRISG10,TRISG11 do not exist TRISGbits.TRISG12=3D0; // unused TRISGbits.TRISG13=3D0; // unused TRISGbits.TRISG14=3D0; // unused TRISGbits.TRISG15=3D0; // unused // Configure SPI2 for DAC SPI2CON1bits.MSTEN=3D1; // Enable master mode SPI2CON1bits.CKP=3D1; // Idle CLK state is high SPI2CON1bits.CKE=3D1; // Data changes on transition from active to idle SPI2CON1bits.DISSCK=3D0; // Do not disable the SCK pin SPI2CON1bits.DISSDO=3D0; // Do not disable the SDO pin SPI2CON1bits.MODE16=3D0; // 8 bit wide SPI2CON1bits.SMP=3D0; // Unused since we do not read any result from DAC= s SPI2CON1bits.SPRE=3D0; // three bits long, 000 sets to 8:1 prescale SPI2CON1bits.PPRE=3D2; // two bits long, 10 sets to 4:1 prescale // SCK will be FCY/32 SPI2CON2=3D0; // We do not use framing features SPI2STATbits.SPISIDL=3D0; // Do not stop in idle mode SPI2STATbits.SPIEN=3D1; // Enable module SPI2STATbits.SPIROV=3D0; Here is the actual transmit function: void set_pin_dac ( unsigned int pin_word ) { unsigned char dac_spi_rx_byte; // Clear receive buffer full bit if (SPI2STATbits.SPIRBF) dac_spi_rx_byte=3DSPI2BUF; // Clear RX overflow bit SPI2STATbits.SPIROV=3D0; LATDbits.LATD8=3D1; // Reset DAC's SPI module while(SPI2STATbits.SPITBF); // Wait for register to be empty __delay_us(200); // Wait for more than 1 byte time to ensure // that SPI2 system is idle LATDbits.LATD8=3D0; // Begin transfer __delay_us(2); SPI2BUF=3D0x00; // Load first byte into buffer while(SPI2STATbits.SPITBF); // Wait for TX buffer to be empty // Should happen almost right away because system was idle when we // loaded 1st byte. SPI2BUF=3D(pin_word>>8)&0x00FF; // Load next byte into buffer while (!SPI2STATbits.SPIRBF); // Wait for 1st transfer to complete dac_spi_rx_byte=3DSPI2BUF; // Read result to clear RX buffer while(SPI2STATbits.SPITBF); // Wait for register to be empty // Should happen almost right away because we already waited for RX // buffer to be loaded SPI2BUF=3Dpin_word&0x00FF; // Load last byte into buffer while (!SPI2STATbits.SPIRBF); // Wait for 2nd transfer to complete dac_spi_rx_byte=3DSPI2BUF; // Read result to clear RX buffer while(SPI2STATbits.SPITBF); // Wait for register to be empty // Should happen almost right away because we already waited for RX // buffer to be loaded while (!SPI2STATbits.SPIRBF); // Wait for 3rd transfer to complete dac_spi_rx_byte=3DSPI2BUF; // Read result to clear RX buffer __delay_us(2); LATDbits.LATD8=3D1; // End transfer --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .