Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

SPI trouble in MOSI pin

Status
Not open for further replies.

BiNa2605

Full Member level 3
Joined
Sep 1, 2015
Messages
179
Helped
6
Reputation
12
Reaction score
4
Trophy points
18
Location
VietNam
Activity points
1,357
Hi everyone,

I have a trouble in SPI transmission. I knew the problem but I don't know how to fix it. I connect MCU (PIC16F151x) to EEPROM in SPI mode.
SPI mode.JPG

I used MikroC to coding. As normal, the SPI transmission failed. However, when I connected one probe of Oscilloscope to the MOSI pin (just touched), I received the right data in EEPROM. Does anyone know the problem I met? I appreciate for any suggestion.

MCU operates in internal Clock mode, 1Mhz.

- - - Updated - - -

This is my code.
Code:
#define  SEN      PORTC.B1
#define PAGE_WR    0x0800
#define  WRITE     0x0000
#define  READ      0x4000
#define COMMANDMODE   0XC0

unsigned int uiTemp, uiTemp1, uiMo;
unsigned char ucwrData,ucKQ;
unsigned char Data[6] = {0x1C,0x2C,0x3C,0x4C,0x5C,0x6C};

//Command Mode for SL900A SPI interface
void SL900A_CommandMode(unsigned char ucData_FIFO){
     unsigned char sr;           //Status Register

     //Check the FIFO status
     do{
        SEN = 1;
        delay_us(200);
        SPI1_WRITE(0xE7);   //Write the command to read FIFO Status register
        sr = SPI1_READ(0x00);
        delay_us(50);
        SEN = 0;
     }while(!sr & 0x80);

     //Start SPI transfer
     SEN = 1;
     delay_us(500);
     //Transfer Data_IN
     SPI1_WRITE(0xE1);  //Write WRITE_FIFO command
     //delay_us(100);
     SPI1_WRITE(ucData_FIFO);
     delay_us(500);
     SEN = 0;
}
unsigned char SL900A_Read(unsigned int uirMode, unsigned int uirAddress){
     unsigned char ucResult;
     SEN = 1;
     delay_ms(1);
     uiTemp = uirMode | uirAddress;
     SPI1_Write(uiTemp >> 8);
     SPI1_Write(uirAddress & 0x00FF);
     //delay_ms(1);
     ucResult= SPI1_Read(0);
     delay_ms(1);
     SEN = 0;
     return ucResult;
}
//Write function for the SPI interface
void SL900A_Write(unsigned int uiMode, unsigned int uiAddress, unsigned char ucData){
     //SPI1_Init();
     SEN = 1;              //Enable Slave select
     delay_ms(1);          //SEN to first SCLK rising edge setup time
     //Transmit 16 bit data
     uiTemp = uiMode | uiAddress;
     uiTemp1 = uiTemp & 0xFF00;      //Lay 8 bit cao
     //SPI1_Write(ucMode >> 6);                 //Send WRITE Mode  (two highest bits)
     SPI1_Write(uiTemp >> 8);                 //Transmit higher 8 bit
     SPI1_Write(uiAddress & 0x00FF);                      //Transmit lower 8 bit
     SPI1_Write(ucData);                      //Data need to transmit
     delay_ms(1);
     SEN = 0;                                   //Stop
     uiTemp = 0;
}


void main()
{
     unsigned int uiAdd,i,uirMo;
     //FOSC = 0b110; INTOSC oscillator
     OSCCON = 0b01011011;           //Internal Oscillator 1Mhz --- SL900A -> 1.5v
     //OSCCON = 0b01101010;         //Internal Oscillator 4Mhz
     //OSCCON = 0b01110010;         //Internal Oscillator 8Mhz
     //OSCCON = 0b01111010;         //Internal Oscillator 16Mhz
     ANSELC = 0;                    //PortC is a digital output

     TRISC.B1 = 0;          //Chip Select
     TRISB.B4 = 0;          //RB4 output test led
     //PORTB.B4 = 0;

     //Initiate SPI
     //SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_LOW_2_HIGH);
     SPI1_Init();
     //Choose the Mode here
     //uirMo = READ;
     //uiAdd    = 0x0050;      //The first physical address of SL900A User_Memory

     uiAdd    = 0x0064;      //the last physical address of SL900A User_Memory
     //ucwrData = 0x29;
     uiMo     = WRITE;

     SEN = 0;


     while(1){
     for(i = 0; i < 6; i++)
     {
           SL900A_Write(uiMo, uiAdd+i, Data[i]);
           PORTB.B4 = 0;
           delay_ms(20);
           PORTB.B4 = 1;
           delay_ms(20);
     }
     }
}

I think the problem is the hardware not in programming.
 

Hi,

My assumption:
* Either it is a port setup problem (D_in needs to be input, all others output. Maybe you need to disable other periferals at the port pins)
* or it is a timing problem (clock out to data in. Maybe wrong SPI mode)

Ensure that the EEPROM has true push pull outputs.

Klaus
 
I appreciated your suggestions. In my opinion, I think I chose the right SPI mode. I chose the first mode in the picture based on the SPI timing figure in EEPROM.
MCU SPI Mode.JPG

SPI timing.JPG

-In MikroC, when we initialize SPI mode: SPIx_Init() all of pins related to SPI function had set up by default. Furthermore, when I measured by Osilloscope, the signals that I received, were the same with the application note of EEPROM -> I achieved good results. So I think the problem is not the ports set up.

-I don't know how to make sure EEPROM has true push pull outputs.

-Again, at normal state, the SPI transmission failed but when I connect a probe of oscilloscope, I received exactly what I want :cry:
 

Please show us the initialisation code for the SPI (basically, what is in 'SPI1_Init()'). Given that timing diagram, you should have CKP, CKE and SMP all 0.
How do you know that the "SPI transmission failed"? What values do you get?
What is the part number of the EEPROM? By looking at the data sheet you can tell how the MISO line is driven and when.
However, the title of the question is about the MOSI line. If you can see the SCK, \SS\ and MOSI (SDO) lines doing what they should on the scope, then you know the MCU is working correctly. If the MISO (SDI) line is OK on the scope but not in the MCU then you need to answer the questions above.
Susan
 

I appreciate for taking time support me Suan.

1.This is the description of SPI1_Init(), and I think it meet the requirement CKP, CKE, SMP all zero (clock idle state low, data transmitted on low to high edge, input data sampled at the middle of interval).

SPI init.JPG

2.The EEPROM is inside SL900A (RFID IC tag). I read the value of EEPROM using RFID reader and know exactly why the SPI transmission failed.

3.You know, when I used oscilloscope to test the signal, everything is ok that mean the values I want to write to EEPROM I received correctly on Reader GUI (graphic user interface). I did not use MISO pin of MCU Susan.
 

Hi BiNa2605,

The EEPROM is inside SL900A (RFID IC tag). I read the value of EEPROM using RFID reader and know exactly why the SPI transmission failed.

How you know the reason for SPI transmission failure?? How you identify it with RFID reader??

How you are sending the values to the reader GUI, with which communication.
 

Hi Chandu.Kurapati,

RFID reader read the memory of IC Tag, EEPROM, that means I could know SPI transmission failed or succeeded.

I send values from IC tag to RFID reader by using SPI communication and RF wave.

IC tag SPI.JPG

Although, the same SPI communication is used in storing data to EEPROM and transmitting data to Reader at IC tag, logging EEPROM operates in interrupt, high priority, and implemented first.
 

Hi,

show us one scope picture with MOSI, MISO, SCK and SS of a one byte transfer.

Klaus
 

+ MOSI and SCK
P_20160524_170304.jpg

+ SS and SCK
clock and chip select.jpg

I think these above pictures are right.

The data will be received correctly when I connect just only one probe (GND) to the MOSI pin. I don't know why.
Problem.JPG

I used GUI to read data from EPPROM to qulify the result because I'm not use MISO of MCU.
Data.JPG

When I operate at normal, not using oscilloscope to observe signals, it's not work even if I measure SCK and SS, I cannot read right data until I connect oscilloscope probe to MOSI.
 
Last edited:

Hi,

I can´t find out what signals are on the scope pictures and the timing between those signals.

show us one scope picture with MOSI, MISO, SCK and SS of a one byte transfer.
I expect one scope picture with all 4 signlas (maybe MISO is not necessary). But i need to be able to see each bit. Timing of MOSI to SCK. and SS to SCK.

I see your scope has USB. --> If possible give us the USB data. BMP picture and/or csv values.
And please give the information which channel is which signal.


Klaus
 

I'm not have enough probes so I just show 2 signals at the same time.

Timing SCK and MOSI.jpg
 

Hi,

it´s impossible to measure the time between clock_edge and change_of_data.
*****
Please:
* two signals: SCK and MOSI
* ONE complete byte. Stretched to fill almost the complete width of the screen.

Klaus
 

While we wait for usable images, one wild guess comes to mind: check the ground connection between the MCU and the RFID chip. If using the scope on the MOSI line makes it work, it could well be that it is providing the necessary ground connection.
Also, on the coding side I see that there are a number of delay function calls. Looking at the data sheet, I can see that there is a 150uSec delay required after raising the SEN line (and you have 200uSec, 500uSec and 1mSec delays in various places) but I cannot see the need for the 50uiSec, 500uSec and 1mSec delays after the exchanges are complete and before you lower the SEN line. These look to be unnecessary.
You have a comment where you initialise the OSCCON register to 1MHz based on the internal oscillator. (I assume that you somewhere else ensure that the delay functions are told of the Fosc value as well so you get accurate delay timing.) The comment would seem to imply that you are running a 1.5V but the scope traces you show would appear to show 3.3V. I assume that the comment is wrong but I do see in the RFID chip data sheet that the SPI timing is dependent on the voltage.
I really do not like using library functions for peripherals that are as straight forward as the MSSP as they hide a lot of important information but I assume that the default initialisation will be to use Fosc/4 as the clock speed which will more than satisfy the timing requirements for the SPI signals to the RFID chip (as per that chip's data sheet).
By the way, which specific chip are you using: PIC16F151x can cover a number of different chips with different characteristics.
Susan
 
@Susan: Your opinions look logical. I used PIC16F1518.
Yes, my comment is wrong, I used 1Mhz based on internal oscillator.
In the data sheet of RFID chip, they recommend to apply 150us after raising SEN, in my case I apply 1ms for delay to making sure SPI initialization is stable.
I checkec the ground connection before and it's ok Susan.

For 3 bytes SPI Write function.
SPI Write.jpg

1st byte (SCK and Write command 0x00)
Write byte.jpg

2nd byte (SCK and Address 0x0064 -- fist position of user memory in RFID Tag chip)
Address_byte.jpg

3nd byte (the last one SCK and Data 0x18)
Data_byte.jpg
 

This should have nothing to do with your problem but if you are using port B1 for the SEN line, it should be in digital mode.
Similarly, you should follow the golden rule (to avoid RMW problems) of "read from the PORT, write to the LAT" - this would apply to the SEN signal on Port B1.
Also taking a "belts and braces" approach, try setting the TRIS bits used by the MSSP peripheral correctly. Activating the MSSP peripheral *should* do this for you but it would not hurt.
I see there is an errata item for this device that relates to the MSSP in SPI master mode. It relates to the BF and IF bits being set half a SCK cycle too early which probably does not have an effect on your code. It might pay to learn what actually happens in the SPI1_Write function as you do have back-to-back calls to this function that could possibly execute faster than half a SCK cycle.
Susan
 

Hi,

In post#3, second picture you see that with rising SCK edge MOSI = EEPROM_DIN changes.

But in your scope picture (sending 0x64) you see that this takes place at the falling edge of SCK.


--> Select mode0: both CKP and CKE = 0
(I can't find this in your code)

Klaus
 
--> Select mode0: both CKP and CKE = 0
(I can't find this in your code)
Either the mikroC manual description of SPI1_Init() quoted in post #5 is wrong or you are setting the mode somewhere in your code,
 
Either the mikroC manual description of SPI1_Init() quoted in post #5 is wrong or you are setting the mode somewhere in your code,

I just used SPI1_Init(). Why is it wrong? I don't understand.

In post#3, second picture you see that with rising SCK edge MOSI = EEPROM_DIN changes.

But in your scope picture (sending 0x64) you see that this takes place at the falling edge of SCK.
The pink signal is SCK and is raising.

--> Select mode0: both CKP and CKE = 0
(I can't find this in your code)
It's include in SPI1_Init(); That I presented in post #5

- - - Updated - - -

Have you think about I need something to affect to MOSI pin?

I used another code (SPI communication) between MCU and Accelerometer (IDLE state is high and I have a function to identify this IC). When I apply SPI to RFID IC, I got trouble (as above discussions IDLE state is low, clock from low to high, and I am not have function to identify IC tag chip).

My study is apply them together, I read data from Accelerometer and send them to IC tag using SPI. Two different modes IDEL low and IDEL high. At this time I am struggling with RFID IC chip :(.

- - - Updated - - -

In post#3, second picture you see that with rising SCK edge MOSI = EEPROM_DIN changes.

But in your scope picture (sending 0x64) you see that this takes place at the falling edge of SCK.
Now I think I see what you mean. I will try to fix that.

- - - Updated - - -

Thank you @KlausST , @Susan, @FvM, I fixed that errors.
The reason as KlausST discovered based on the scope on the post #16. :thumbsup::thumbsup:

Code:
     SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
     SSPSTAT.SMP=0;  //Master Mode, Input data sampled at middle of data output time
     SSPSTAT.CKE=0;  //Transmit occurs on transition from Idle to active clock state
     SSPCON.CKP=0;   //Idle state for clock is a low level
     //OSC_DIV4
     SSPCON1.SSPM3=0;
     SSPCON1.SSPM2=0;
     SSPCON1.SSPM1=0;
     SSPCON1.SSPM0=0;
     SSPCON1.SSPEN=1;
 

I just used SPI1_Init(). Why is it wrong? I don't understand.
Apparently you don't compare the actual waveform with the datasheet specification as shown in post #3. According to it, DIN (= MOSI) should be set on the rising clock edge but it's actually set on the falling which could well explain the observed problems.
 
Yes, you are right @FvM. I compared and compared them several times but you know I did not recognize the difference of them, datasheet specification and actual wave, until @KlausST told. At first, as you can see I did not understand @KlausST explained but after that you reminded it again :oops:. Finally I recognized the error. Thank edaboard and you guys, electronic experts.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top