这是代码,两种方式都时使用过, 先发送0XA000到TLV2548, 再发送0xa102设置寄存器,56位为0:0. 最后使用0x9000读取CFR值,然后读取的值不是上一步写入的0x102。
读出的值为0xffff。 这是为什么呢?
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.
我测量了时钟和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 芯片去测试。