Hi,
I am using TMS320F28379s C2000 series micro controller (Master) to interface SRAM 23LCV1024 (Slave) via SPI. I have configured the SPI in the FIFO mode as per the example code provided in the control suite, SPI Configuration are as follows controller is in master mode, Clock polarity to rising, clock phase is normal (0), data character length is 8 bit and bit rate is 500KHz have been configured.
I’m trying to write the 1 byte data - 111 (0x6F) to the NVRAM and to read the same from the NVRAM IC. But I’m not getting the data as expected 111 (0x6F) instead I’m getting as 255 (0xFF) always…! while checking the pulses of the SPI pins I’m getting the data from the Slave device(in MISO pin)
But the responded data is not fetched by MCU.. while checking in oscilloscope the below results were observed in below case 1 the pulse pattern found correct but in MCU read SPI memory 0xff is found always.
I have attached the Pulse pattern in the attached document & SPI Code for reference.
Thanks
Rajamurugan
#define CPU_FREQ 200 // CPU_Freq is 200MHz #define SPI_CLK_in_KHz 500 // 2500 -> 2.5 MHz // 1000 -> 1MHz (Now its for the 500KHz) #define LSPCLK_in_KHz 50000 // (200 MHz / 4) = 50 MHz #define SPI_BRR (LSPCLK_in_KHz / SPI_CLK_in_KHz) - 1 #define RAM_INS_READ 0x03 //Read data from memory array beginning at selected address #define RAM_INS_WRITE 0x02 //Write data to memory array beginning at selected address #define RAM_INS_RDMR 0x05 //Read Mode Register #define RAM_INS_WRMR 0x01 //Write Mode Register unsigned char write_array[20]; unsigned char Read_array[20]; unsigned char Read_NVRAM_data = 0; unsigned int _10ms_timer_counter = 0; __interrupt void cpu_timer0_isr(void) // 50us timer Interrrupt void chip_select_NVRAM1(void); void chip_deselect_NVRAM1(void); void NVRAM1_set_mode(unsigned char mode); void Write_to_NVRAM(unsigned char Write_data, unsigned long int Write_address); unsigned char Read_From_NVRAM(unsigned long int Read_address); void ram_write_data(unsigned long int write_address, unsigned char *write_buffer, unsigned int write_buffer_size); void read_data(unsigned long int read_address, unsigned char *read_buffer, unsigned int read_buffer_size); void Setup_GPIO() { EALLOW; // For enabling the access for the protected registers // SPI GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable internal pull-up for the selected SPI pin - MOSI GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0; // Enable internal pull-up for the selected SPI pin - MISO GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0; // Enable internal pull-up for the selected SPI pin - CLK GpioCtrlRegs.GPAPUD.bit.GPIO27 = 0; // Enable internal pull-up for the selected SPI pin - EN GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3; // Set qualification for the selected SPI pin - MOSI GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 3; // Set qualification for the selected SPIpin - MISO GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 3; // Set qualification for the selected SPIpin - CLK GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 3; // Set qualification for the selected SPIpin - EN GpioCtrlRegs.GPAGMUX2.bit.GPIO24 = 1; // Configure GPIO24 as SPI pin - MOSI GMUX selection GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 2; // GPIO24 is MOSI GpioCtrlRegs.GPAGMUX2.bit.GPIO25 = 1; // Configure GPIO25 as SPI pin - MISO GMUX selection GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 2; // GPIO25 is MISO GpioCtrlRegs.GPAGMUX2.bit.GPIO26 = 1; // Configure GPIO26 as SPI_CLK- GMUX selection GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 2; // GPIO26 is CLK GpioCtrlRegs.GPAGMUX2.bit.GPIO27 = 1; // Configure GPIO27 as SPI_EN- GMUX selection GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 2; // GPIO27 is EN // GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0; // GPIO27 is EN // GpioCtrlRegs.GPADIR.bit.GPIO27 = 1; // Making the GPIO27 as the Digital Output EDIS; // For disabling the access for the protected registers } void SetupTimers() { ConfigCpuTimer(&CpuTimer0, CPU_FREQ, 50); //Timer0 is configured to interrupt on every 50 µ seconds with the time base of 200MHz CpuTimer0Regs.TCR.all = 0x4000; // Use write-only instruction to set TSS bit = 0 & TIE = 1 (Start the timer & Timer interrupt is enabled) } void SetupSPI(void) { SpibRegs.SPIFFTX.all = 0xE040; // FIFO Transmit register 1.Interrupt clear 2.Release transmit FIFO from reset 3.Enhancement enable 4.SPI FIFO resume transmit or receive. SpibRegs.SPIFFRX.all = 0x2044; // SPI FIFO Receive Register // To clear receive FIFO interrupt ,re enable receive FIFO operation. SpibRegs.SPIFFCT.all = 0x0000; // SPI FIFO Control Register // delayed transfer. SpibRegs.SPICCR.bit.SPISWRESET = 0; // Set reset low before configuration changes SpibRegs.SPICCR.bit.CLKPOLARITY = 1; // Clock polarity selection (0 == rising, 1 == falling) SpibRegs.SPICCR.bit.HS_MODE = 0; // SPI High Speed mode Enable Bit (0 == Disable, 1 == Enable) SpibRegs.SPICCR.bit.SPILBK = 0; // SPI Loop back Mode Select (0 == Disable, 1 == Enable) SpibRegs.SPICCR.bit.SPICHAR = (8-1);// Character length control bit - 8-bit SpibRegs.SPICTL.bit.OVERRUNINTENA = 0; // Overrun Interrupt Enable bit (0 == Disable, 1 == Enable) SpibRegs.SPICTL.bit.CLK_PHASE = 0; // SPI CLOCK PHASE SELECT (0 == normal, 1 == delayed) SpibRegs.SPICTL.bit.MASTER_SLAVE = 1; // Enable Master mode (0 == slave, 1 == master) SpibRegs.SPICTL.bit.TALK = 1; // Enable Transmission (Talk) SpibRegs.SPICTL.bit.SPIINTENA = 0; // SPI interrupts are disabled SpibRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR; // Set the baud rate SpibRegs.SPIPRI.bit.FREE = 1; // Set FREE bit // Halting on a breakpoint will not halt the SPI SpibRegs.SPICCR.bit.SPISWRESET = 1; // Release the SPI from reset WHEN the value = 1 SPI ready to transmit and receive NVRAM1_set_mode(RAM_MODE_BYTE); // NVRAM1_set_mode(RAM_MODE_SEQUENTIAL); } unsigned char rdata = 0; unsigned char spi_xmit(unsigned char sdata) { // while (SpibRegs.SPIFFTX.bit.TXFFST != 0); SpibRegs.SPITXBUF = sdata<<8; // SPI Serial Output Buffer Register -SPITXBUF while (SpibRegs.SPIFFRX.bit.RXFFST == 0); rdata = SpibRegs.SPIRXBUF; // SPI Serial Input Buffer Register return rdata; } void SetupInterrupt(void) // Interrupts that are used in this example are re-mapped to ISR functions found within this file. { PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TIMER0_INT = &cpu_timer0_isr; // Interrupts that are used in this example are re-mapped to ISR functions found within this file EDIS; // This is needed to disable write to EALLOW protected registers PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE: Group 1 interrupt 7 IER |= M_INT1; // Enable CPU int1 which is connected to CPU-Timer 0 EINT; // Enable Global interrupt INTM ERTM; // Enable Global real time interrupt DBGM } void main(void) { InitSysCtrl(); // For Initialize PLL,Peripheral clocks & Disable watch dog timer DINT; // Disable all CPU interrupts and initialize PIE vector table interrupts InitPieCtrl(); // Initialize the PieControl registers IER = 0x0000; // Disable All CPU interrupts IFR = 0x0000; // Clear All interrupt Flags InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR). InitCpuTimers(); // Initialization of timer module InitGpio(); Setup_GPIO(); // Set the GPIOs configuration registers SetupTimers(); // Set the Timer configuration registers SetupSPI(); // Set the SPI configuration registers SetupInterrupt(); // Set the common interrupt Enable Function Write_to_NVRAM(111, 5000); // Write the data to NVRAM Using Function Call - (Data, Address) // unsigned int i = 0; // for (i = 0; i < 10; i++) // { // write_array[i] = i; // } // // ram_write_data(123,write_array,10); while (1) { } } //****************************************************************************************************** // Function : chip_select_NVRAM1() // Purpose : Sets the SS pin to the low state in order to enable SPI mode //****************************************************************************************************** void chip_select_NVRAM1(void) { GpioDataRegs.GPACLEAR.bit.GPIO27 = 1; } //****************************************************************************************************** // Function : chip_deselect_NVRAM1() // Purpose : Sets the SS pin to the high state in order to disable SPI mode //****************************************************************************************************** void chip_deselect_NVRAM1(void) { GpioDataRegs.GPASET.bit.GPIO27 = 1; } //****************************************************************************************************** // Function : NVRAM1_send_address() // Purpose : sending address in a specified format as mentioned in datasheet //****************************************************************************************************** void NVRAM1_send_address(unsigned long int address) { spi_xmit((address >> 16) & 0xFF); spi_xmit((address >> 8) & 0xFF); spi_xmit((address) & 0xFF); } //********************************************************************************************************************************************** // Function : NVRAM1_set_mode() // Purpose : Send the address to the mode register in order to Set the memory operation mode (byte, page, sequential <default>) //********************************************************************************************************************************************** void NVRAM1_set_mode(unsigned char mode) { chip_select_NVRAM1(); spi_xmit(RAM_INS_WRMR); spi_xmit(mode); chip_deselect_NVRAM1(); } //************************************************************************************************************************ // Function : NVRAM1_read_mode() // Purpose : To know which mode is selected for the write operation among byte, page, sequential operations //************************************************************************************************************************ unsigned char NVRAM1_read_mode(void) { unsigned char data; chip_select_NVRAM1(); spi_xmit(RAM_INS_RDMR); data = spi_xmit(0); chip_deselect_NVRAM1(); return data; } void Write_to_NVRAM(unsigned char Write_data, unsigned long int Write_address) { chip_select_NVRAM1(); spi_xmit(RAM_INS_WRITE); NVRAM1_send_address(Write_address); spi_xmit(Write_data); chip_deselect_NVRAM1(); } //************************************************************************************************************************ // Function : ram_write_data() // Purpose : To write data into the SRAM in page wise //************************************************************************************************************************ void ram_write_data(unsigned long int write_address, unsigned char *write_buffer, unsigned int write_buffer_size) { unsigned long int write_page; chip_select_NVRAM1(); spi_xmit(RAM_INS_WRITE); NVRAM1_send_address(write_address); for (write_page = 0; write_page < write_buffer_size; ++write_page) { spi_xmit(*(write_buffer + write_page)); } chip_deselect_NVRAM1(); } unsigned char Read_From_NVRAM(unsigned long int Read_address) { unsigned char Read_data; chip_select_NVRAM1(); spi_xmit(RAM_INS_READ); spi_xmit(Read_address >> 16); spi_xmit(Read_address >> 8); spi_xmit(Read_address); Read_data = spi_xmit(0x00); chip_deselect_NVRAM1(); return Read_data; } //************************************************************************************************************************ // Function : read_data() // Purpose : To read a data from SRAM page wise //************************************************************************************************************************ void read_data(unsigned long int read_address, unsigned char *read_buffer, unsigned int read_buffer_size) { chip_select_NVRAM1(); spi_xmit(RAM_INS_READ); NVRAM1_send_address(read_address); while (read_buffer_size) { *read_buffer = spi_xmit(0); ++read_buffer; --read_buffer_size; } chip_deselect_NVRAM1(); } __interrupt void cpu_timer0_isr(void) // 50us timer Interrrupt { _10ms_timer_counter++; if (_10ms_timer_counter >= 200) // For 10milli second { _10ms_timer_counter = 0; Read_NVRAM_data = Read_From_NVRAM(5000); // Read the data from NVRAM using the function call - (Address) // read_data(123,Read_array,10); GpioDataRegs.GPCTOGGLE.bit.GPIO88 = 1; // For Toggling the MCU_STS_LED GPIO } PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1 EDIS; // The CPU acknowledges the interrupt. }