Hi to all, do you think it is possible link 4-wires SPI on my qe64 to 3-wires spi of "si4432" (silicon labs)?
Solved! Go to Solution.
Hello Roberto,
As this interface is synchronous the master can stop/start/change speed whenever it feels like it and the slave end will just follow the clock and read the input/set the output at the appropriate time. So the pause is not an issue.
However by properly utilising the buffered nature of the SCID you can join the data stream together.
Example:
PTBD_PTBD5 = 0;// enable ss while (!SPI1S_SPTEF); // wait transmit buffer empty flag SPI1D = address; // send address while (!SPI1S_SPTEF); // wait transmit buffer empty flag SPI1D = data; // new data while (!SPI1S_SPRF); // wait SPI1D; // clear flag while (!SPI1S_SPRF); // wait SPI1D; // clear flag PTBD_PTBD5 = 1; // disable ss
By always waiting until the SCID is truly MT in the routine, the SCID transmit side will always be truly MT (both shift register and buffer) when you enter the routine. This allows you to stuff two bytes before you start reading. This scheme can be extended to produce a longer continuous stream.
Happy SPIing
Hello Roberto,
In fact the SI4432 device does require four connections for the SPI interface.
SDI <-> MOSI
SDO <-> MISO
SCLK <-> SPCLK
nSEL <-> (SS)
nSEL may connect to any GP output pin, and must be controlled by your code. If you choose to use the SS pin, this will also need to be configured as GP output. Automatic operation of the SS output is not appropriate because of the multiple byte commands required by the transceiver device.
Regards,
Mac
Thank you, I have read the data sheet, and I come to the same end. The only «doubt» is on the behaviour of SDO, but in short I think i could try it...
Regards,
roberto
Hi, now I'm trying to connect it... using SPI on my qe64.
I need to realize a timing like in figure.
I'm using these settings:
SPI1C1 = 0x50; // master mode CPOL = CPHA = 0, ssoe = 0
SPI1C2 = 0x00; // modfen = 0 => ss = gpio
and this routine:
void spi_write_register (unsigned char address, unsigned char data)
{
__asm SEI;
PTBD_PTBD5 = 0;// enable ss
while (!SPI1S_SPTEF); // wait transmit buffer empty flag
SPI1D = address; // send address
while (!SPI1S_SPRF); // wait
SPI1D; // clear flag
SPI1D = data; // new data
while (!SPI1S_SPRF); // wait
PTBD_PTBD5 = 1; // disable ss
__asm CLI;
}
I'm getting something similar at the figure attached. But, between bit a0 and bit d7,
i have an extra-pause. How can I kill it?
If someone could help me, thanks a lot,
Best regards
Roberto
Hello Roberto,
As this interface is synchronous the master can stop/start/change speed whenever it feels like it and the slave end will just follow the clock and read the input/set the output at the appropriate time. So the pause is not an issue.
However by properly utilising the buffered nature of the SCID you can join the data stream together.
Example:
PTBD_PTBD5 = 0;// enable ss while (!SPI1S_SPTEF); // wait transmit buffer empty flag SPI1D = address; // send address while (!SPI1S_SPTEF); // wait transmit buffer empty flag SPI1D = data; // new data while (!SPI1S_SPRF); // wait SPI1D; // clear flag while (!SPI1S_SPRF); // wait SPI1D; // clear flag PTBD_PTBD5 = 1; // disable ss
By always waiting until the SCID is truly MT in the routine, the SCID transmit side will always be truly MT (both shift register and buffer) when you enter the routine. This allows you to stuff two bytes before you start reading. This scheme can be extended to produce a longer continuous stream.
Happy SPIing
it works! thank you Peg, thank you Big Mac.
Regards,
Roberto
Hi,
again on this.
If I use SPI communication between mcu and transceiver with Prescaler 8 (1:1:1) and Rate Divisor 4 (0:0:1) (f_bus = 20 Mhz => sclk = 625 khz) it works everything. But I have a lot of data so I think to speed up communication with Prescaler 8 and Rate divisor 2 (0:0:0) (sclk = 1,25 Mhz ). With this baud rate the transceiver doesn't trasmit. With an oscilloscope I see a normal SPI communication between devices but there is transmission.
Any suggestion?
Hello Roberto,
As Peg has already suggested, if you are using the code that utilizes the double buffering capability of the SCI module, it is possible for an overrun condition to occur, where the transmission of the second byte is completed before the first byte can be read. Data will be lost. For the original SPI clock rate, the value of the first received byte must be read within less than 256 bus cycles from the completion of the transfer. By doubling the SPI clock rate, the critical read period would be halved to 128 bus cycles.
It is therefore possible that a timer, or other interrupt may occur at the critical point, and may take more than 128 cycles to complete execution.
Solution 1: Globally disable interrupts just prior to sending the second byte, and re-enable interrupts after the first byte has been read, and the flag cleared.
Solution 2: Do not send the second byte until after the first byte has been read. This will eliminate any critical timing.
Regards,
Mac
Hello Roberto,
I'm not sure I am understanding you.
Are you saying you have a working setup and then when you speed up the SPI clock it stops working?
You are seeing the data on the SPI lines but it is not working?
A not on the code presented previously:
This style of SPI code is generally not used as it is not interrupt proof.
It relies on being able to load both bytes before the first one has completely shifted out.
Indeed single stepping the routine will cause it to hang.
You could disable interrupts during the critical stage but you have to ask yourself whether you really need those back to back transmissions. With enough differential between buss clock and SPI clock speeds you get it anyway.
@PEG Yes I had a working setup and speed up action stopped all.
I disable interrupts and it works.
I use this new routine:
SS = 0; // enable SS
while (!SPI1S_SPTEF); // wait: "transmit buffer empty flag"
SPI1S;
SPI1D = address;
while (!SPI1S_SPRF); // wait: "reader buffer full flag"
SPI1S; // clear flag
SPI1D;
SPI1D = data;
while (!SPI1S_SPRF); // wait: "reader buffer full flag"
SPI1S;
SPI1D; // clear flag
SS = 1; // disable SS
It works with or without interrupts.
Thank you for all Peg and Bigmac,
Regards.
Roberto
Hello Roberto,
Glad you got it sorted out.
The additinal SPI1S reads (SPI1S should not be required.
You are doing a read in the flag test line above it.
If i remove additional reads to SPIS it doesn't work...:smiley sad:
Hi,
Must be due to a timing issue at the other end then.
Hello Roberto,
The slight delay is due to the fetching of the data byte following the transmission of the address byte. This is of no consequence since the next clock pulses generated by the master is also delayed. On the same basis, it is usually unnecessary that interrupts need to be disabled and re-enabled.
Are you able to operate the SPI device as intended?
Regards,
Mac
Hello,
Yes this is possible. The SS signal is very much optional.
Connect the clocks MOSI MISO together ans set one as master the other as slave and off you go!