AnsweredAssumed Answered

Problem with SPI - Transferring 32 bit on MPC5644A

Question asked by Vaisakh P S on Jun 29, 2011
Latest reply on Jul 4, 2011 by TomE

Hi Everyone,

 

I am trying to interface a DAC(DAC8168) on to Freescale's MPC5644A evaluation kit over SPI_B interface. The SPI controller FIFO allows us to write 16-bit at a time, and if the chip select is deasserted before ADC samples 32-bit, the data will be discard. Now this is where the problem resides. 

 

In my implementation of SPI driver, I am using continous chip select assertion during the taransfer, but after transferring first 16-bit, there is a small glitch (or a transition )in chip select and clock lines. How to solve this???

 

I have attached waveforms observed in CRO and source code.

 

Regards,

Vaisakh P S

 

 

#include "MPC5644A.h"extern void SpiDrvrInit();extern void SpiDrvrWrite32(unsigned char cs,unsigned int databuff);       /* **************************************************************************** * PLL Code * **************************************************************************** */typedef struct { uint8_t eprediv; uint8_t emfd; uint8_t erfd; }T_FMPLL_INITVALS;#define  FMPLL_MHZ_INDEX  0/* * Table containing initialisation values for FMPLL */T_FMPLL_INITVALS fmpll_init_vals [] = { {0x04, 0x46, 0x01},   };/* * Function to initialise system clock and PLL values * */void initSysclk (int req_clk_index) {  uint32_t esyncr1_val = 0xF0000000         | (((uint32_t)(fmpll_init_vals[req_clk_index].eprediv)) << 16)        | ((uint32_t)(fmpll_init_vals[req_clk_index].emfd));  uint32_t esyncr2_val = ((uint32_t)(fmpll_init_vals[req_clk_index].erfd));         FMPLL.ESYNCR2.R = esyncr2_val;   /*Set */    FMPLL.ESYNCR1.R  = esyncr1_val;          while (FMPLL.SYNSR.B.LOCK != 1) {};  /* Wait for FMPLL to LOCK  */  }       /* **************************************************************************** * SPI Code * **************************************************************************** */static void initDSPI_B(void) { //configure pads SIU.PCR[102].R = 0x0606;  // SPI Clock DSPI_B_CSK, primary, out SIU.PCR[103].R = 0x0500;  // DSPI_B_SIN, primary SIU.PCR[105].R = 0x0604; // Chip select DSPI_B_CS, primary,out //~~SIU.PCR[105].R = 0x0205; // Chip select DSPI_B_CS, GPIO,out //~~SIU.GPDO[105].B.PDO = 1;  SIU.PCR[104].R = 0x0605;  // DSPI_B_SOUT, primary  // DAC GPIOS SIU.PCR[203].R = 0x0200; SIU.GPDO[203].B.PDO = 0; SIU.PCR[204].R = 0x0200; SIU.GPDO[204].B.PDO = 0; // configure controller   DSPI_B.MCR.R = 0xA0010001;     /* Configure DSPI_B as master */}static void StartDSPI_B(void) { // configure controller DSPI_B.SR.B.EOQF = 0x0; DSPI_B.MCR.B.FRZ = 0x0; DSPI_B.MCR.B.HALT = 0x0;     /* Leave HALT mode*/ // Wait until running state is set while (DSPI_B.SR.B.TXRXS == 0){} }static void StopDSPI_B(void) { DSPI_B.SR.B.EOQF = 0x1; DSPI_B.MCR.B.FRZ = 0x1; DSPI_B.MCR.B.HALT = 0x1;     /* Enter HALT mode*/ while (DSPI_B.SR.B.TXRXS != 0){}}void SpiDrvrWrite32(unsigned char cs,   // chip select to be asserted     unsigned int databuff) // buffer containinng data to be transmitted{ unsigned short *tbuffptr = (unsigned short *)&databuff;  // Setting  //  framesize to 16 bits,  //  SCLK to active high //  Data is captured on leading edge and changed on falling //  Baudrate scaler to 0xF //  Baudrate Pre scaler to 0x3 DSPI_B.CTAR[0].R = 0x7A03000A; //0x7A030001; - for LSB First // set configuration for transfer //~~SIU.GPDO[105].B.PDO = 0; StartDSPI_B(); //select chip selects switch(cs) {  case 0: DSPI_B.PUSHR.B.PCS0 = 1;break;  case 1: DSPI_B.PUSHR.B.PCS1 = 1;break;  case 2: DSPI_B.PUSHR.B.PCS2 = 1;break;  case 3: DSPI_B.PUSHR.B.PCS3 = 1;break;  case 4: DSPI_B.PUSHR.B.PCS4 = 1;break;  case 5: DSPI_B.PUSHR.B.PCS5 = 1;break;  case 6: DSPI_B.PUSHR.B.PCS6 = 1;break;  case 7: DSPI_B.PUSHR.B.PCS7 = 1;break; } DSPI_B.PUSHR.B.TXDATA = tbuffptr[0]; DSPI_B.PUSHR.B.TXDATA = tbuffptr[1]; // Wait for transmission completion while(DSPI_B.SR.B.TCF == 0){} StopDSPI_B(); //~~SIU.GPDO[105].B.PDO = 1; } /* **************************************************************************** * DAC Code - DAC8168 * **************************************************************************** */#define DAC8168_CMD_WRITE_REG   0x00#define DAC8168_CMD_UPDATE_REG   0x01#define DAC8168_CMD_WRTSELREG_UPDALL 0x02#define DAC8168_CMD_WRTSELREG_UPDRESP 0x03#define DAC8168_CMD_PWRDOWN    0x04#define DAC8168_CMD_WRITE_TO_CC_REG  0x05#define DAC8168_CMD_WRITE_TO_LDAC_REG 0x06#define DAC8168_CMD_SOFTWARE_RESET  0x07#define DAC8168_CHANNEL_ADDR_A   0x00#define DAC8168_CHANNEL_ADDR_B   0x01#define DAC8168_CHANNEL_ADDR_C   0x02#define DAC8168_CHANNEL_ADDR_D   0x03#define DAC8168_CHANNEL_ADDR_E   0x04#define DAC8168_CHANNEL_ADDR_F   0x05#define DAC8168_CHANNEL_ADDR_G   0x06#define DAC8168_CHANNEL_ADDR_H   0x07#define DAC8168_CHANNEL_ADDR_ALL  0x0Fvoid Dac8168Send(uint8_t cmd,uint8_t channel, uint16_t data){ uint32_t spi_data = 0x00000000;  // pull LDAC line up SIU.GPDO[204].B.PDO = 1; spi_data = ((uint32_t)(cmd & 0x0F)) << 24; spi_data |= ((uint32_t)(channel & 0x0F)) << 20; spi_data |= ((uint32_t)(data & 0x3FFF)) << 6; SpiDrvrWrite32(0x0, spi_data);  // pull down LDAC to load new value to DAC output SIU.GPDO[204].B.PDO = 0; //TODO: induce a sleep and drive the line back high return;}int main(void) { volatile int i = 0; //initialise peripherals & pll initSysclk(FMPLL_MHZ_INDEX); initDSPI_B(); //initialise dac  //Dac8168Send(DAC8168_CMD_SOFTWARE_RESET, DAC8168_CHANNEL_ADDR_ALL, 0x0FFFu); Dac8168Send(DAC8168_CMD_WRTSELREG_UPDALL, DAC8168_CHANNEL_ADDR_ALL, 0x0FFFu); /* Loop forever */ for (;;) {  //Dac8168Send(DAC8168_CMD_WRTSELREG_UPDALL, DAC8168_CHANNEL_ADDR_ALL, 0x0FFFu); //i++; }}

 

Outcomes