PPI will not stop SPIM, however EGU does.

Hi! Im doing a SPI transaction using EGU and PPI.

Software triggers the EGU, and PPI_CHANNEL_1 uses this event to start the SPIM transaction and set the CS pin low.
PPI_CHANNEL_2 uses the SPIM_EVENTS_END to set the CS pin high again, and also trigger the SPIM_TASKS_STOP to lower the current consumption.
However, the SPIM does not stop when using the PPI.

By attaching an interrupt to another EGU channel, and triggering the EGU channel by PPI instead, I am able to stop the SPIM. But this also seems to only be working if I reset the EVENT_END event first.

PPI_config that start the SPI Transaction:

static const ppi_channel_config_t ms5803_egu_start_ppi_config = {
    .event_address = &MS5803_EGU->EVENTS_TRIGGERED[MS5803_RESET_EGU_CHANNEL],
    .task0_address = &NRF_GPIOTE->TASKS_CLR[MS5803_CS_GPIOTE_CHANNEL],
    .task1_address = &MS5803_SPIM->TASKS_START,
};


PPI_config that stops the SPI Transaction: Note that the SPIM does not stop with the PPI, therefore the line is commented out.
static const ppi_channel_config_t ms5803_end_ppi_config = {
    .event_address = &MS5803_SPIM->EVENTS_END,
    .task0_address = &NRF_GPIOTE->TASKS_SET[MS5803_CS_GPIOTE_CHANNEL],
    .task1_address = &MS5803_EGU->TASKS_TRIGGER[4],
    //.task1_address = &MS5803_SPIM->TASKS_STOP,
};


EGU interrupt that actually stops the SPIM:
static void ms5803_spim_stop()
{
    spim_trigger(MS5803_SPIM, SPIM_TASK_STOP);
    spim_disable(MS5803_SPIM);
}

From further testing it seems that I am able to stop the SPIM by triggering the STOP_TASK through the debugger, and then triggering the START_TASK through the debugger.

Parents
  • Can you just check that you follow the description for Low power operation in the datasheet?

    When putting the system in low power and the peripheral is not needed, lowest possible power consumption is achieved by stopping, and then disabling the peripheral.

    The STOP task may not be always needed (the peripheral might already be stopped), but if it is sent, software shall wait until the STOPPED event was received as a response before disabling the peripheral through the ENABLE register.

Reply
  • Can you just check that you follow the description for Low power operation in the datasheet?

    When putting the system in low power and the peripheral is not needed, lowest possible power consumption is achieved by stopping, and then disabling the peripheral.

    The STOP task may not be always needed (the peripheral might already be stopped), but if it is sent, software shall wait until the STOPPED event was received as a response before disabling the peripheral through the ENABLE register.

Children
  • I agree that disabling the peripheral should yield the best power consumption. But I am seeing wildly different behavior depending on how much I use the PPI / EGU.

    With this code, where the PPI is not used at all. And the stop command is not sent, and the SPIM is not disabled (no writing the ENABLE register). I achieve an average current consumption of 1.33 uA for the whole board. Note that the spim_trigger(STOP) is even commented out, and I get good current consumption. However, while using the PPI, and sending the stop function. I have a total current draw of about 500 uA.

    uint32_t ms5803_command(ms5803_command_t command)
    {
        transmit_buffer[0] = (uint8_t)command;
        receive_config.max_count = 4;
        spim_set_rx_config(MS5803_SPIM, &receive_config);
        gpio_set_output(MS5803_CS_PIN, 0);
        spim_trigger(MS5803_SPIM, SPIM_TASK_START);
        while(spim_get_event_state(MS5803_SPIM, SPIM_EVENT_END) == 0);
        gpio_set_output(MS5803_CS_PIN, 1);
        spim_reset_event(MS5803_SPIM, SPIM_EVENT_END);
        //spim_trigger(MS5803_SPIM, SPIM_TASK_STOP);
        uint32_t data = 0;
        switch(ms5803_command_length[command])
        {
            case 2: data = (receive_buffer[1] << 8) | (receive_buffer[2]); break;
            case 3: data = (receive_buffer[1] << 16) | (receive_buffer[2] << 8) | (receive_buffer[3]); break;
        }
        return data;
    }

Related