Hello!
I have a question about the SPI /SS Pin on a HCS08 device. Have all HCS08 devices a active low state on SS Pin during data transfer? What can I do when my slave peripherial need a high Chip select wire during data transfer (to slave)?
regards,
Ingo
Hello!
I include a standart SN7404 inverter and it works now fine!
But it interest me how I could do this without a logic device.
suggestions are welcome!
regards,
Ingo
Hello Ingo,
Slave select is usually an active low signal.
Most of the time it is not even used as it is of little use and uses up a valuable pin.
Most slave devices can just be made active permanently and where you have multiple devices, if you don't serially chain them, you need to generate your own selects anyway.
I would suggest that if you really need an active high select on your peripheral then just do it your self.
You can still use the SS pin just disable the SS function and drive it as a GPIO. The timing of this signal on the slave/peripheral is usually not critical at all.
Hello Peg,
i know but my peripherial meet not the regulations to an standard spi protocol. It is a VMUSIC2 from Vinculum company.
http://www.vinculum.com/documents/datasheets/DS_VMUSIC2.pdf
I think that normally spi uses byte per byte transmition. For this peripherial I have to send 10 bits per block. Thats something but not spi.
The JM60 Freescale MCU can send 16bit per block on spi. Can you tell me which data register should be written at least
SPIxDHPIxDL to start a 16bit transmition? The Datasheet tells me that if the spi module is configured for 16bit transmition it will start the transmition when both data registers are written. The datasheet tells me not which, high or low.
Thank you for your suggestions!
Regards,
Ingo
Hello Ingo,
Since you are controlling the CS signal through firmware control of a GPIO pin, it should be possible to handle the data transfer as two separate bytes, using a standard 8-bit SPI module. The first byte sent would contain the R/W bit and the ADR bit, followed by the first six MS bits of the data, for a write operation. The next byte sent would contain the final two bits of the of the data, with the remaining bits being don't care. The status bit would be at the bit-5 position of the second returned byte.
For a read operation, the first returned byte would contain the right justified six MS bits of the data, and the second returned byte would contain the left justified final two bits of the data, followed by the status bit.
The CS lead would be taken high just prior to sending the first byte, and taken low after the second byte send is completed.
Regards,
Mac
Hello Peg! Hello Mac!
Thanks for investing so much time! I worked over the last weekend on an routine which can do this what you mean Mac.
This is the result:
SPI2TX:
psha ;save A for the rest of the whole program
lda SPI2TXDATA ;data to send on SPI2
lsra ;shift two times right to get the first five Bits, the RW Bit and the ADD Bit
lsra ;RW Bit and ADD Bit must be all zero
sta spi2txfirstbyte ;save actions on first Byte
lda SPI2TXDATA ;restore the original data
nsa ;nibble swap command saves left shift operations
lsla ;but it must done two times
lsla
and #$C0 ;clear Bits 5-0
sta spi2txsecondbyte ;save actions on second byte to complete the 10Bit transmition
brclr 5,SPI2S,* ;wait for Transmitter empty flag
bset 3,PTBD ;set chip select
mov #spi2txfirstbyte,SPI2D ;send first byte
brclr 5,SPI2S,* ;wait for transmitter empty flag
mov #spi2txsecondbyte,SPI2D ;send second byte
jsr delay ;small delay to held chip select
bclr 3,PTBD ;clear chip select
pula ;restore A for the rest of the whole program
rts
This routine acts pretty good in simulation and looks near perfect on my logic analyser screen. Two things I wanna try next time is save some buscycles between the frst and the second byte transfer. It could be critical if there is too much time between both byte transfers.
Thanks a lot!
Regards,
Ingo
Hello Ingo,
I can see some issues with you proposed code. The specific lines involved are shown below.
mnemonic wrote:
SPI2TX:
psha ;save A for the rest of the whole program
lda SPI2TXDATA ;data to send on SPI2
lsra ;shift two times right
lsra ;RW Bit and ADD Bit must be all zero
sta spi2txfirstbyte;save actions on first Byte
lda SPI2TXDATA ;restore the original data
nsa ;nibble swap command saves left shift operations
lsla ;but it must done two times
lsla
and #$C0 ;clear Bits 5-0
sta spi2txsecondbyte ;save actions on second byte to complete transmition
brclr 5,SPI2S,* ;wait for Transmitter empty flag
bset 3,PTBD ;set chip select
mov #spi2txfirstbyte,SPI2D ;send first byte
brclr 5,SPI2S,* ;wait for transmitter empty flag
mov #spi2txsecondbyte,SPI2D ;send second byte
jsr delay ;small delay to held chip select
bclr 3,PTBD ;clear chip select
pula ;restore A for the rest of the whole program
rts
The registers spi2txfirstbyte and spi2txsecondbyte are clearly RAM locations, since they are being written. The use of immediate addressing is thus not valid. You would be sending the address of the RAM locations, rather than their contents.
I would recommend that, following the send of each byte, that you wait until the SPRF flag becomes set (and not bother about the SPTEF flag). This will also avoid the need for the delay routine call, since both byte transmissions will be complete when the flag becomes set after each byte.
Why do you think that a small gap between the sending of each byte is a problem? This is normally not so since the clock signal originates from the MCU. Is there a minimum clock frequency actually specified for the device?
The following code is a possible alternative approach, that does not require any RAM registers for its operation.
; SEND DATA TO DEVICE
; On entry, X = byte value to be sent; CF = ADR bit state
;
CS EQU 3 ; PTBD bit for CS
SPTEF EQU 5 ; SPI2S bits
SPRF EQU 7
;
SPI2SEND: PSHA ; Save current value
LDA #$FF ; Unused bits of 2nd byte are 1's
RORX ; Shift in ADR bit state
RORA
LSRX ; R/W bit is zero
RORA
BSET CS,PTBD ; Set CS active
BRCLR SPTEF,SPI2S,* ; Wait until SPTEF flag is set
STX SPI2D ; Send first byte
BRCLR SPRF,SPI2S,* ; Wait until SPRF flag is set
STA SPI2D ; Send second byte
BRCLR SPRF,SPI2S,* ; Wait until SPRF flag is set
BCLR CS,PTBD ; Set CS inactive
PULA ; Restore previous value
RTS
;
;
Regards,
Mac
Hello Mac!
Thank you for answering!
I was on Embedded World in Nürnberg/Germany and talked to a guy from FREESCALE about SPI and chip select. It is no HCS08 device avaiable which can change the edge of chip select. Okay thats not the problem. I can do this with a normal GPIO Pin.
I looked on the webpage to Vinculum´s VNC1L Chip and found a APP Note which describes a connection between a PICDEM2 Plus Demoboard and a VMUSIC2. They also provide uncompiled C code which has to be compiled with Source Boost. I thoght that I should rebuild this Application and look on their timings.
I got from an FTDI engineer which I meet on the Embedded World the hexfiles for the PIC. Today in the morning I build a PIC Programmer and burned the hexfile on the pic. After rebuilding this Application I checked the timings from their Application with my Logicport Logicanalyzer and found that they do "something" but not SPI.
You have right I point on the address with this instruction. I hear this the first time. I tryed this in my debugger and I it was exactly how you told me. The delay wich I have in my code delays only for some buscycles. If I do not the chip select change to fast. I also try to send fast as possible byte per byte cause I only want be on the savety side. I do not know what will my peripherial do when between both bytes is to much time. It could be that to much time between the bytes be a 0 or a 1 for the peripherial and my bitshifting could crash. The maximum clock for the peripherial is 12Mhz but in the DEMO with the pic they drive the clock near 3Khz. All facts what I found out pointing to a software SPI solution.
I attached a screenshot in a word document. D1 is the clocksignal from the HCS08 device, D5 is from the vinculum peripherial. There you can see that "something" is happend not SPI.
Thank you for you experience and also investing so much time.
Regards,
Ingo
Hello again,
My peripherial is also controlable with UART. I will take a QG8 MCU to build a SPI to UART bridge. That will much more stressless as controling the peripherial over SPI.
Yesterday, I had a problem with the attachment.
Regards,
Ingo
Hello again Ingo
I have done 10 bit transfers before but what you do is just set bits 11 to 15 to all 1 or 0 (i forget).
I also have not seen these 16 bit SPID's so cannot comment (I guess I could read the data sheet).
But I think it is always the case that a SPI transfer is always bytes or multiple bytes there is no possibility to sent partial bytes.
The way they get around it is the slave just ignores the extra bits.