This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLV2548: 不能正确获取CFR值

Part Number: TLV2548

 这是代码,两种方式都时使用过, 先发送0XA000到TLV2548, 再发送0xa102设置寄存器,56位为0:0.     最后使用0x9000读取CFR值,然后读取的值不是上一步写入的0x102。

 读出的值为0xffff。  这是为什么呢?

  • 您好,

    datasheet 13页 有写CFR的时序图,datasheet 11页有读CFR的时序图,建议您用示波器抓下波形,对照看下时序是否正确?

  •  我测量了时钟和cs片选信号,然后使用该代码进行发送和接收数据时,发现cs有从高到低的转换,cs应该是正常的,但是时钟没有信号。这个问题能确定是由spi master controler出现了问题是吗?感谢。

    int main(void)
    {
        int Status;
        int i, j;
        int value;
        u16 sendValue = 0;
        xil_printf("====SPI Selftest Example =======\r\n");
    
        Status = spi0_init();
        if (Status != XST_SUCCESS)
        {
            xil_printf("SPI0 Selftest Example Failed\r\n");
            return XST_FAILURE;
        }
        Status = spi1_init();
    	if (Status != XST_SUCCESS)
    	{
    		xil_printf("SPI1 Selftest Example Failed\r\n");
    		return XST_FAILURE;
    	}
        memset(WriteBuffer,0,1024);
    
    //    read_and_print_all();
    
        u32 value_cr0 = read_In32(0xe0006000, XSPIPS_CR_OFFSET);
        u32 value_cr1 = read_In32(0xe0007000, XSPIPS_CR_OFFSET);
        printf("cr0:0x%2x; cr1:0x%2x\r\n",value_cr0,value_cr1);
    
        int count = 0;
    
        //
    //	WriteBuffer[0] = 0x00;
    //	WriteBuffer[1] = 0x80;
    //	sendValue = 0x8000;
    //	SpiWrite(0,sendValue, 2);
    //	usleep(200);
    
        ////写使能, 加这个代码,才会有CS信号的跳变,不然CS没有反应
    #if 1
    	WriteBuffer[0] = 0x00;
    	WriteBuffer[1] = 0xA0;
    	sendValue = 0xA000;
    	SpiWrite(0,WriteBuffer, 2);
    	usleep(200);
    	read_and_print_all(0);
    #endif
    
        while(1)
        {
        	if(count++ >= 3)
        		break;
    #if 1
    		printf("===spi0===\r\n");
    
    		WriteBuffer[0] = 0x02;
    		WriteBuffer[1] = 0xa1;
    		sendValue = 0xA102;
    		SpiWrite(0,sendValue, 3);
    		usleep(200);
    //		read_and_print_all(0);
    		sleep(1);
    		WriteBuffer[0] = 0x99;
    		WriteBuffer[1] = 0x90;//这个顺序应该是正确的
    		sendValue = 0x9000;
    		SpiWrite(0,sendValue, 2);
    
    		usleep(2000);
    
    		read_and_print_all(0);
    		sleep(1);
    #endif
    
    #if 0
    		printf("===spi1===\r\n");
    		WriteBuffer[0] = 0xA0;
    		WriteBuffer[1] = 0x00;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    
    		WriteBuffer[0] = 0xA1;
    		WriteBuffer[1] = 0x02;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    
    		WriteBuffer[0] = 0x90;
    		WriteBuffer[1] = 0x90;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    		read_and_print_all(1);
    #endif
        }
    
        xil_printf("\r\nSuccessfully ran SPI Selftest Example\r\n\r\n");
        return XST_SUCCESS;
    }

  • 完整代码如下:

    #include "xparameters.h"
    #include "xspips.h"
    #include "xil_printf.h"
    #include "sleep.h"
    #include "xspips_hw.h"
    
    XSpiPs Spi0, Spi1;
    
    #define SpiPs_RecvByte(BaseAddress) \
        (u8) XSpiPs_In32((BaseAddress) + XSPIPS_RXD_OFFSET)
    
    #define SpiPs_SendByte(BaseAddress, Data) \
        XSpiPs_Out32((BaseAddress) + XSPIPS_TXD_OFFSET, (Data))
    
    int spi0_init();
    void spi0_one_write();
    void SpiRead(u8 spiNum, int ByteCount);
    void SpiWrite(u8 spiNum, u8 *Sendbuffer, int ByteCount);
    
    unsigned char ReadBuffer[1024];
    unsigned char WriteBuffer[1024] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
    
    void read_and_print_all(u8 spiNum)
    {
    	xil_printf("===========read_and_print_all: %d ========\r\n",spiNum);
    	memset(ReadBuffer, 0x00, 1024);
    	if(spiNum == 0)
    		SpiRead(0,512);
    	else
    		SpiRead(1,512);
    	for (int j = 0; j < 512; j++)
    	{
    		xil_printf("0x%02x,", ReadBuffer[j]);
    	}
    	xil_printf("\r\n");
    }
    
    static INLINE u32 read_In32(UINTPTR Addr, u32 offset)
    {
    	return *(volatile u32 *) (Addr+offset);
    }
    
    int main(void)
    {
        int Status;
        int i, j;
        int value;
        u16 sendValue = 0;
        xil_printf("====SPI Selftest Example =======\r\n");
    
        Status = spi0_init();
        if (Status != XST_SUCCESS)
        {
            xil_printf("SPI0 Selftest Example Failed\r\n");
            return XST_FAILURE;
        }
        Status = spi1_init();
    	if (Status != XST_SUCCESS)
    	{
    		xil_printf("SPI1 Selftest Example Failed\r\n");
    		return XST_FAILURE;
    	}
        memset(WriteBuffer,0,1024);
    
    //    read_and_print_all();
    
        u32 value_cr0 = read_In32(0xe0006000, XSPIPS_CR_OFFSET);
        u32 value_cr1 = read_In32(0xe0007000, XSPIPS_CR_OFFSET);
        printf("cr0:0x%2x; cr1:0x%2x\r\n",value_cr0,value_cr1);
    
        int count = 0;
    
        //
    //	WriteBuffer[0] = 0x00;
    //	WriteBuffer[1] = 0x80;
    //	sendValue = 0x8000;
    //	SpiWrite(0,sendValue, 2);
    //	usleep(200);
    
        ////写使能, 加这个代码,才会有CS信号的跳变,不然CS没有反应
    #if 1
    	WriteBuffer[0] = 0x00;
    	WriteBuffer[1] = 0xA0;
    	sendValue = 0xA000;
    	SpiWrite(0,WriteBuffer, 2);
    	usleep(200);
    	read_and_print_all(0);
    #endif
    
        while(1)
        {
        	if(count++ >= 3)
        		break;
    #if 1
    		printf("===spi0===\r\n");
    
    		WriteBuffer[0] = 0x02;
    		WriteBuffer[1] = 0xa1;
    		sendValue = 0xA102;
    		SpiWrite(0,sendValue, 3);
    		usleep(200);
    //		read_and_print_all(0);
    		sleep(1);
    		WriteBuffer[0] = 0x99;
    		WriteBuffer[1] = 0x90;//这个顺序应该是正确的
    		sendValue = 0x9000;
    		SpiWrite(0,sendValue, 2);
    
    		usleep(2000);
    
    		read_and_print_all(0);
    		sleep(1);
    #endif
    
    #if 0
    		printf("===spi1===\r\n");
    		WriteBuffer[0] = 0xA0;
    		WriteBuffer[1] = 0x00;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    
    		WriteBuffer[0] = 0xA1;
    		WriteBuffer[1] = 0x02;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    
    		WriteBuffer[0] = 0x90;
    		WriteBuffer[1] = 0x90;
    		SpiWrite(1,WriteBuffer, 2);
    
    		usleep(200);
    		read_and_print_all(1);
    #endif
        }
    
        xil_printf("\r\nSuccessfully ran SPI Selftest Example\r\n\r\n");
        return XST_SUCCESS;
    }
    
    void SpiRead(u8 spiNum, int ByteCount)
    {
    	if(spiNum == 0)
    	{
    		int Count;
    		u32 StatusReg;
    
    		StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
    								   XSPIPS_SR_OFFSET);
    
    		/*
    		 * Polling the Rx Buffer for Data
    		 */
    		do
    		{
    			StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
    									   XSPIPS_SR_OFFSET);
    		} while (!(StatusReg & XSPIPS_IXR_RXNEMPTY_MASK));
    
    		/*
    		 * Reading the Rx Buffer
    		 */
    		for (Count = 0; Count < ByteCount; Count++)
    		{
    			ReadBuffer[Count] = SpiPs_RecvByte(
    				Spi0.Config.BaseAddress);
    		}
    	}
    	else
    	{
    		int Count;
    		u32 StatusReg;
    
    		StatusReg = XSpiPs_ReadReg(Spi1.Config.BaseAddress,
    								   XSPIPS_SR_OFFSET);
    
    		/*
    		 * Polling the Rx Buffer for Data
    		 */
    		do
    		{
    			StatusReg = XSpiPs_ReadReg(Spi1.Config.BaseAddress,
    									   XSPIPS_SR_OFFSET);
    		} while (!(StatusReg & XSPIPS_IXR_RXNEMPTY_MASK));
    
    		/*
    		 * Reading the Rx Buffer
    		 */
    		for (Count = 0; Count < ByteCount; Count++)
    		{
    			ReadBuffer[Count] = SpiPs_RecvByte(
    				Spi1.Config.BaseAddress);
    		}
    	}
    }
    
    void SpiWrite(u8 spiNum, u8 *Sendbuffer, int ByteCount)
    {
    	if(spiNum == 0)
    	{
    		u32 StatusReg;
    		int TransCount = 0;
    
    		StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
    								   XSPIPS_SR_OFFSET);
    
    		while ((ByteCount > 0) &&
    			   (TransCount < XSPIPS_FIFO_DEPTH))
    		{
    			SpiPs_SendByte(Spi0.Config.BaseAddress,
    						   *Sendbuffer);
    			Sendbuffer++;
    			++TransCount;
    			ByteCount--;
    		}
    
    		/*
    		 * Wait for the transfer to finish by polling Tx fifo status.
    		 */
    		do
    		{
    			StatusReg = XSpiPs_ReadReg(
    				Spi0.Config.BaseAddress,
    				XSPIPS_SR_OFFSET);
    		} while ((StatusReg & XSPIPS_IXR_TXOW_MASK) == 0);
    	}
    	else
    	{
    		u32 StatusReg;
    		int TransCount = 0;
    
    		StatusReg = XSpiPs_ReadReg(Spi1.Config.BaseAddress,
    								   XSPIPS_SR_OFFSET);
    
    		while ((ByteCount > 0) &&
    			   (TransCount < XSPIPS_FIFO_DEPTH))
    		{
    			SpiPs_SendByte(Spi1.Config.BaseAddress,
    						   *Sendbuffer);
    			Sendbuffer++;
    			++TransCount;
    			ByteCount--;
    		}
    
    		/*
    		 * Wait for the transfer to finish by polling Tx fifo status.
    		 */
    		do
    		{
    			StatusReg = XSpiPs_ReadReg(
    				Spi1.Config.BaseAddress,
    				XSPIPS_SR_OFFSET);
    		} while ((StatusReg & XSPIPS_IXR_TXOW_MASK) == 0);
    	}
    }
    s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel);
    int spi0_init()
    {
        int Status;
        XSpiPs_Config *SpiConfig;
    
        /*
         * Initialize the SPI device.
         */
        SpiConfig = XSpiPs_LookupConfig(XPAR_XSPIPS_0_DEVICE_ID);
        if (NULL == SpiConfig)
        {
            return XST_FAILURE;
        }
    
        Status = XSpiPs_CfgInitialize(&Spi0, SpiConfig, SpiConfig->BaseAddress);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
    
        /*
         * Perform a self-test to check hardware build.
         */
        Status = XSpiPs_SelfTest(&Spi0);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
        xil_printf("%s self test succ\r\n", __func__);
    
        Status = XSpiPs_SetOptions(&Spi0, XSPIPS_FORCE_SSELECT_OPTION |XSPIPS_MASTER_OPTION);
        if (Status != XST_SUCCESS)
        {
            xil_printf("%s XSpiPs_SetOptions fail\r\n", __func__);
            return XST_FAILURE;
        }
        Status = XSpiPs_SetClkPrescaler(&Spi0, XSPIPS_CLK_PRESCALE_64);
        if (Status != XST_SUCCESS)
        {
            xil_printf("%s XSpiPs_SetClkPrescaler fail\r\n", __func__);
            return XST_FAILURE;
        }
    
        //lsh
    #if 0
        XSpiPs_SetSlaveSelect(&Spi0,0);
    	if (Status != XST_SUCCESS)
    	{
    		xil_printf("%s XSpiPs_SetSlaveSelect fail\r\n", __func__);
    		return XST_FAILURE;
    	}
    
    #endif
        XSpiPs_Enable(&Spi0);
        xil_printf("spi 0 config finish\r\n");
        return XST_SUCCESS;
    }
    
    
    int spi1_init()
    {
        int Status;
        XSpiPs_Config *SpiConfig;
    
        /*
         * Initialize the SPI device.
         */
        SpiConfig = XSpiPs_LookupConfig(XPAR_XSPIPS_1_DEVICE_ID);
        if (NULL == SpiConfig)
        {
            return XST_FAILURE;
        }
    
        Status = XSpiPs_CfgInitialize(&Spi1, SpiConfig, SpiConfig->BaseAddress);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
    
        /*
         * Perform a self-test to check hardware build.
         */
        Status = XSpiPs_SelfTest(&Spi1);
        if (Status != XST_SUCCESS)
        {
            return XST_FAILURE;
        }
        xil_printf("%s self test succ\r\n", __func__);
    #if 1
        Status = XSpiPs_SetOptions(&Spi1, XSPIPS_MASTER_OPTION);
        if (Status != XST_SUCCESS)
        {
            xil_printf("%s XSpiPs_SetOptions fail\r\n", __func__);
            return XST_FAILURE;
        }
        Status = XSpiPs_SetClkPrescaler(&Spi1, XSPIPS_CLK_PRESCALE_64);
        if (Status != XST_SUCCESS)
        {
            xil_printf("%s XSpiPs_SetClkPrescaler fail\r\n", __func__);
            return XST_FAILURE;
        }
    #endif
        XSpiPs_Enable(&Spi1);
        xil_printf("spi 1 config finish\r\n");
        return XST_SUCCESS;
    }
    

  • 我刚注意到 TLV2548产品首页的状态标黄了,即此产品已经停产了,请知晓这一点:

    这个问题能确定是由spi master controler出现了问题是吗?

    基本可以确定是spi master的问题,因为TLV2548 的时钟信号是输入,但保险起见建议做以下测试:

    spi master 与 TLV2548 时钟信号之间有电阻吗?有的话,建议去掉电阻即悬空master 时钟输出看下master 时钟是否有输出,这样就排除了TLV2548 对此信号的影响。或直接焊掉TLV2548 芯片去测试。