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++; }}