SPIM doesn't stop forever when Peer is PowerDown.

My environment is
nRF52840 + nRF5 SDK 17

I have nRF52840 and LCD module(ER-TFTM101-1) connected using SPIM2.

When LCD power is on, It's fine work.

But,
When LCD power is off, SPIM never STOP.

Follow is simple test code

	/* SCK */
	nrf_gpio_pin_drive_t pin_drive = NRF_GPIO_PIN_S0S1;
	nrf_gpio_pin_write(SPIM_CLK_PIN, 0);
	nrf_gpio_cfg(SPIM_CLK_PIN,
		NRF_GPIO_PIN_DIR_OUTPUT,
		NRF_GPIO_PIN_INPUT_CONNECT,
		NRF_GPIO_PIN_NOPULL,
		pin_drive,
		NRF_GPIO_PIN_NOSENSE);
	/* MOSI */
	nrf_gpio_pin_write(SPIM_MOSI_PIN, 0);
	nrf_gpio_cfg(SPIM_MOSI_PIN,
		NRF_GPIO_PIN_DIR_OUTPUT,
		NRF_GPIO_PIN_INPUT_DISCONNECT,
		NRF_GPIO_PIN_NOPULL,
		pin_drive,
		NRF_GPIO_PIN_NOSENSE);
	/* MISO */
	nrf_gpio_cfg(SPIM_MISO_PIN,
		NRF_GPIO_PIN_DIR_INPUT,
		NRF_GPIO_PIN_INPUT_CONNECT,
		NRF_GPIO_PIN_NOPULL,
		pin_drive,
		NRF_GPIO_PIN_NOSENSE);
	/* SS */
	nrf_gpio_pin_write(SPIM_SS_PIN, 1);
	nrf_gpio_cfg(SPIM_SS_PIN,
		NRF_GPIO_PIN_DIR_OUTPUT,
		NRF_GPIO_PIN_INPUT_DISCONNECT,
		NRF_GPIO_PIN_NOPULL,
		pin_drive,
		NRF_GPIO_PIN_NOSENSE);

	SpimReg.ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
	SpimReg.TASKS_STOP = 1;
	SpimReg.PSEL.SCK = SPIM_CLK_PIN;
	SpimReg.PSEL.MOSI = SPIM_MOSI_PIN;
	SpimReg.PSEL.MISO = SPIM_MISO_PIN;
	SpimReg.FREQUENCY = SPIM_FREQ;
	SpimReg.RXD.PTR = uint32_t(m_recv_buff),
	SpimReg.RXD.MAXCNT = 2;
	SpimReg.RXD.LIST = 0;
	SpimReg.TXD.PTR = uint32_t(m_send_buff),
	SpimReg.TXD.MAXCNT = 2;
	SpimReg.TXD.LIST = 0;
	SpimReg.CONFIG = 0; /* active-high / Leading / MsbFirst */
	SpimReg.ORC = 0x00;
	actCS(true); /* assert CS */
	SpimReg.EVENTS_END = 0;
	SpimReg.TASKS_START = 1;

EVENTS_STARTED is 1
EVENTS_STOPPED/EVENTS_ENDRX/EVENTS_END/EVENTS_ENDTX never be 1.

in the above condition,
when LCD power is turned on, EVENTS_STOPPED/EVENTS_ENDRX/EVENTS_END/EVENTS_ENDTX is 1.

after that, when LCD power is turned off,

Again, When TASKS_START set 1, EVENTS_STARTED  and EVENTS_STOPPED/EVENTS_ENDRX/EVENTS_END/EVENTS_ENDTX is 1.

how is this going?

** SPIM returns EVENT_STOP if the SCLK signal line is determined while the LCD is power down.

Parents
  • Hi 

    Do I understand your problem correctly that you are not getting events before powering LCD, but you get events after powering LCD, and you still get events after powering LCD off again? Or am I misunderstanding?

    What exactly do you mean by LCD power turned on/off? Are you enabling/disabling a module, or are you setting a gpio high/low, or something else?

    Maybe you could scope the lines to get a better idea of what is going on?

    Also, I believe you should config SPIM before you enable it. Right now it looks like you're doing it the other way around which could be a source of errors.

    Best regards,

    Einar

  • I did some more research.

    Apparently, SCLK and GND are short-circuited when LCD power is turned off.

    I changed the way we test.
    1. When CLK of SPIM is connected to GND, EVENTS_END is '0' even if TASK_START is set to 1.
    2. When
    CLK is opend,  EVENTS_END is '1'.

    After 1, do following
    a) DISABLE_SPIM
    b) CLK is opend
    c) ENABLE_SPIM
    Even though I did not set TASKS_START to '1', EVENTS_END became '1'.

    I have two doubts.
    1. If the CLK signal cannot change (such as being shorted to GND), will the SPIM state machine remain stopped(not END)?
    2. If the state machine is not completed (not END), disabling SPIM will not stop the state machine itself?

  • Reading in the data sheet, it seems like STOPPED will trigger ENDTX and ENDRX, which will trigger END.

    Usually the END event will be used to check if the SPI device is ready and not busy, so it could make sense that these events are set to 1 when the peripheral is initiated.

    Have you tried setting the events to 0 after you've initiated the peripheral, and see how it acts when you try using the SPI?

    -Einar

  • At first, SCLK is connected to GND.

    write '0' to EVENTS_STOPPED / EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX / EVENTS_STARTED.

    write '1' to TASKS_START

    EVENTS_STARTED change to '1'

    But, EVENTS_STOPPED / EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX never change to '1'.

    (When write '1' to TASKS_STOP, EVENTS_STOPPED  never change to '1'.)

    After that, SCLK disconnect from GND( be opend.)

    As soon as, EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX  change to '1'.

    What happen?

Reply
  • At first, SCLK is connected to GND.

    write '0' to EVENTS_STOPPED / EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX / EVENTS_STARTED.

    write '1' to TASKS_START

    EVENTS_STARTED change to '1'

    But, EVENTS_STOPPED / EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX never change to '1'.

    (When write '1' to TASKS_STOP, EVENTS_STOPPED  never change to '1'.)

    After that, SCLK disconnect from GND( be opend.)

    As soon as, EVENTS_ENDRX / EVENTS_END / EVENTS_ENDTX  change to '1'.

    What happen?

Children
  • As I said these events can be used to check that the SPI is ready and not busy, and it makes sense that it is not ready before SCLK is opened and operational, so I don't think it sounds strange that these events get set to 1 when the SPI is ready to be used and not busy.

    Have you tried using the SPI to see if it works?

  • My test code.

    #define	SPIM_SS_PIN			28
    #define	SPIM_CLK_PIN		29
    #define	SPIM_MOSI_PIN		30
    #define	SPIM_MISO_PIN		31
    
    #define	SpimReg				(*NRF_SPIM0)
    
    volatile uint32_t s_counter;
    
    uint8_t m_recv_buff[2];
    uint8_t m_send_buff[2] = { 0xA5, 0x3C };
    
    int main(void)
    {
    	/* SCK */
    	nrf_gpio_pin_drive_t pin_drive = NRF_GPIO_PIN_S0S1;
    	nrf_gpio_pin_write(SPIM_CLK_PIN, 0);
    	nrf_gpio_cfg(SPIM_CLK_PIN,
    		NRF_GPIO_PIN_DIR_OUTPUT,
    		NRF_GPIO_PIN_INPUT_CONNECT,
    		NRF_GPIO_PIN_NOPULL,
    		pin_drive,
    		NRF_GPIO_PIN_NOSENSE);
    	/* MOSI */
    	nrf_gpio_pin_write(SPIM_MOSI_PIN, 0);
    	nrf_gpio_cfg(SPIM_MOSI_PIN,
    		NRF_GPIO_PIN_DIR_OUTPUT,
    		NRF_GPIO_PIN_INPUT_DISCONNECT,
    		NRF_GPIO_PIN_NOPULL,
    		pin_drive,
    		NRF_GPIO_PIN_NOSENSE);
    	/* MISO */
    	nrf_gpio_cfg(SPIM_MISO_PIN,
    		NRF_GPIO_PIN_DIR_INPUT,
    		NRF_GPIO_PIN_INPUT_CONNECT,
    		NRF_GPIO_PIN_NOPULL,
    		pin_drive,
    		NRF_GPIO_PIN_NOSENSE);
    
    	/* SS */
    	nrf_gpio_pin_write(SPIM_SS_PIN, 1);
    	nrf_gpio_cfg(SPIM_SS_PIN,
    		NRF_GPIO_PIN_DIR_OUTPUT,
    		NRF_GPIO_PIN_INPUT_DISCONNECT,
    		NRF_GPIO_PIN_NOPULL,
    		pin_drive,
    		NRF_GPIO_PIN_NOSENSE);
    
    	/**/
    	SpimReg.TASKS_STOP = 1;
    	SpimReg.PSEL.SCK = SPIM_CLK_PIN;
    	SpimReg.PSEL.MOSI = SPIM_MOSI_PIN;
    	SpimReg.PSEL.MISO = SPIM_MISO_PIN;
    	SpimReg.FREQUENCY = SPIM_FREQUENCY_FREQUENCY_K125;
    	SpimReg.RXD.PTR = uint32_t(m_recv_buff),
    	SpimReg.RXD.MAXCNT = 2;
    	SpimReg.RXD.LIST = 0;
    	SpimReg.TXD.PTR = uint32_t(m_send_buff),
    	SpimReg.TXD.MAXCNT = 2;
    	SpimReg.TXD.LIST = 0;
    	SpimReg.CONFIG = 0; /* active-high / Leading / MsbFirst */
    	SpimReg.ORC = 0x00;
    
    	SpimReg.ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
    
    	nrf_gpio_pin_clear(SPIM_SS_PIN);
    
    	SpimReg.EVENTS_END = 0;
    	SpimReg.TASKS_START = 1;
    
    	for (;;) {
    		s_counter++;
    	}
    }
    

    When SCLK is open.

    SS and MOSI wave form

    EVENTS

    When write to TASKS_START=1, as soon as, EVENTS_ENDRX/EVENTS_END/EVENTS_ENDTX is '1'.

    When SCLK is connect to GND.

    SS and MOSI wave form(MOSI is not change.)

    EVENTS

    EVENTS_ENDRX/EVENTS_END/EVENTS_ENDTX is never '1'.

    Is this move as expected?

    Even if the SPIM-peer is in such a state, I want the SPIM to always complete. Is there any workaround?

  • Again, have you tried sending messages on the SPI?

    Does it work?

  • Look at the [SCLK is open] waveform.
    0xA5, 0x3C are sent in order.

    No data is sent to MOSI in the [SCLK is connect to GND.] waveform.

  • Well yes, it should not be surprising that no data is sent when SCLK is connected to GND?

    When "LCD power" is turned on and SCLK is open, does SPI work as expected?

Related