SPI SSEL control

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI SSEL control

920 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Sat Aug 01 05:10:31 MST 2015
Does anyone have any ideas why SSEL is de-asserted after the first iteration of fetchlevel ?

The debugger says that it remains asserted, but my 'scope says otherwise.
It is asserted for e2busy, de-asserted afterwards, asserted again at MOVT R0,#0xF4D, and then is de-asserted 48 clocks later. 32 clocks are the command and 16 clocks are the first iteration of fetchlevel. It is then asserted for the second iteration and remains like that until the end of the routine.

The routines waitspitx and waitspirx wait for the TXRDY and RXRDY flags respectively.
The scope trace shows the SSEL line in yellow and CLK in blue. Clock speed is 5MHz.

flash_to_page:  @ scene number in R0, page number in R1
                PUSH {R4-R5,LR}
                BICS R4,R0,#0xFC00                          @ remove CSP header
                MOVS R5,R1
                LDR R3,=LPC_SPI0_BASE
                MOVS R2,#clockspeed/5000000
                STR R2,[R3,SPIDIV]
                BL e2busy
                MOVS R2,#0x03000000                        @ read command
                ADDS R2,R2,R4,LSL #6
                BL waitspitx
                LSRS R0,R2,#16
                MOVT R0,#0xF4D                              @ 16 bit, ignore rx, eeprom cs
                STR R0,[R3,SPITXDATCTL]
                BL waitspitx
                UXTH R0,R2
                MOVT R0,#0xF6D
                STR R0,[R3,SPITXDATCTL]

                LDR R4,=PAGELEVELS
                MOVS R2,#0
                ADDS R4,R4,R5,LSL #4
fetchlevel:     BL waitspitx
                LDR R0,=0xF2D0000
                STR R0,[R3,SPITXDATCTL]
                BL waitspirx
                LDR R0,[R3,SPIRXDAT]
                STRH R0,[R4],#2
                ADDS R2,#2
                CMP R2,#16
                BLO.n fetchlevel

                LDR R4,=PAGEALLOCS
                MOVS R2,#0
                ADDS R4,R4,R5,LSL #5
fetchalloc:     BL waitspitx
                LDR R0,=0xF2D0000
                STR R0,[R3,SPITXDATCTL]
                BL waitspirx
                LDR R0,[R3,SPIRXDAT]
                STRH R0,[R4],#2
                ADDS R2,#1
                CMP R2,#16
                BLO.n fetchalloc

                MOVS R0,#0x80
                STR R0,[R3,SPISTAT]                         @ force EOT
                POP {R4-R5,PC}

waitspirx:      LDR R0,[R3,SPISTAT]                         @ R3 points to SPI
                LSRS R0,R0,#1
                BCC.n waitspirx
                BX LR
waitspitx:      LDR R0,[R3,SPISTAT]                         @ R3 points to SPI
                LSRS R0,R0,#2
                BCC.n waitspitx
                BX LR

e2busy:         PUSH {LR}
                LDR R3,=LPC_SPI0_BASE
                BL waitspitx
                MOVS R0,#5
                MOVT R0,#0x74D                              @ 8 bit write, ignore RX, EEPROM cs
                STR R0,[R3,SPITXDATCTL]

writecomplete:  BL waitspitx
                MOVT R0,0x70D                               @ 8 bit write, EEPROM cs
                STR R0,[R3,SPITXDATCTL]
                BL waitspirx
                LDR R0,[R3,SPIRXDAT]                        @ keep reading status register until ready
                LSRS R0,R0,#1
                BCS.n writecomplete
                MOVS R0,#0x80
                STR R0,[R3,SPISTAT]                         @ end transmission
                POP {PC}
Labels (1)
0 Kudos
5 Replies

604 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Thu Aug 06 05:52:36 MST 2015
Well, they kept quite about that in the data sheet!

Presumably, I have to wait until the IDLE flag is true before I turn off SSEL, otherwise it might still be transmitting.
0 Kudos

604 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Sun Aug 02 05:05:42 MST 2015
Yes,  automatic SSEL operations cannot be used in any programs where interrupts are used.

Yes, the auto-SSEL feature is a bit of a waste of good silicon.

Even if you use DMA to fill the SPI TX Buffer, it is possible for another DMA to block the SPI DMA, so you can not reliable make back-to-back transfers with automatic SSEL operation.

You have to do SSEL by hand (GPIO). You have to wait until the TX buffer is empty (status flag).
0 Kudos

604 Views
dimitrissideris
Contributor III

Hi there,

How can i wait until the tx buffer is done.

I know that TFE bit of status register indicates that tx buffer is empty but how can i wait until tx buffer is empty if i dont force tx buff to empty?

Can you share some code or make any suggestion of what the meaning of waiting until tx buf is empty?

0 Kudos

604 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Sat Aug 01 07:51:39 MST 2015
Many thanks for the fast reply. I wondered if that were the case, but having checked the data sheet and user manual and not found any mention of a SSEL timeout in either, I presumed that there wasn't. It would, however, make sense of what was observed.

Does this mean that the automatic SSEL operations cannot be used in any programs where interrupts are used? (It seems that the delay in which SSEL was de-asserted was when the interrupt routine was running) If this were the case, isn't the auto-SSEL feature a bit of a waste of good silicon?

It would be nice if NXP could let us know how long we have to get our SPI transfers completed, as any mention of an SSEL timeout is conspicuous by its absence in the data sheet.

Luckily, I have routines written for LPC11xx where SSEL is operated by GPIO; but I thought I'd give the auto feature a try just because it's there.
0 Kudos

604 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mysepp on Sat Aug 01 05:58:42 MST 2015
Is your SSEL controlled by SPI/SSP peripheral or configured as GPIO?
If it is the first case, I assume you are not filling data fast enough, so peripheral assumes, it is done.
Then solution could be to configure it as GPIO and control it by yourself.
0 Kudos