ltflash wrote on Thursday, August 13, 2015:
Hi,
Thanks a lot for your reply.
Yes, I’ve checked the datasheet about all the modes and furthermore, I’ve tried to re-initialize the SPI bus right after MCU wake-up, but with no luck. I’ve also tested same code on Atmel SAM3S MCU.
Here are some details from datasheet. Please take into account that I definitely tried to re-enable clocks to SPI peripheral after wake-up, but that didn’t help. I actually did the whole initialize procedure, please see below.
I have no issues with using Slepp mode, but after Wait mode I can’t read/write to SPI. I’m using a RTT as a wake-up and tick source for FreeRTOS.
Sleep Mode
The purpose of Sleep mode is to optimize power consumption of the device versus response time. In this mode,
only the core clock is stopped. The peripheral clocks can be enabled. The current consumption in this mode is
application dependent.
This mode is entered via Wait for Interrupt (WFI) or WFE instructions with bit LPM = 0 in PMC_FSMR.
The processor can be woken up from an interrupt if the WFI instruction of the Cortex-M4 is used or from an event
if the WFE instruction is used.
Wait Mode
The purpose of Wait mode is to achieve very low power consumption while maintaining the whole device in a
powered state for a startup time of less than 10 μs. Current consumption in Wait mode is typically 32 μA (total
current consumption) if the internal voltage regulator is used.
In this mode, the clocks of the core, peripherals and memories are stopped. However, the core, peripherals and
memories power supplies are still powered. From this mode, a fast start up is available.
This mode is entered by setting the WAITMODE bit to 1 in the PMC Clock Generator Main Oscillator Register
(CKGR_MOR) in conjunction with the Flash Low Power Mode field FLPM = 0 or FLPM = 1 in the PMC Fast Startup
Mode Register (PMC_FSMR) or by the WFE instruction.
The Cortex-M4 is able to handle external or internal events in order to wake-up the core. This is done by
configuring the external lines WKUP0–15 as fast startup wake-up pins (refer to Section 5.8 “Fast Start-up”). RTC
or RTT Alarm and USB wake-up events can be used to wake up the CPU.
Here’s my SPI init function that works perfectly well until I start using WAIT mode:
static void spi_init()
{
const freertos_peripheral_options_t driver_options = {
NULL,
0,
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,
SPI_MASTER,
( USE_TX_ACCESS_MUTEX | USE_RX_ACCESS_MUTEX | WAIT_TX_COMPLETE | WAIT_RX_COMPLETE )
};
freertos_spi = freertos_spi_master_init( SPI, &driver_options );
pmc_enable_periph_clk(ID_PIOA);
pio_configure(PIOA,PIO_PERIPH_A,(PIO_PA12A_MISO | PIO_PA13A_MOSI | PIO_PA14A_SPCK | PIO_PA11A_NPCS0),PIO_DEFAULT);
pmc_enable_periph_clk(ID_SPI);
spi_disable(SPI);
spi_set_clock_polarity(SPI, CHIP_SELECT, CLOCK_POLARITY);
spi_set_clock_phase(SPI, CHIP_SELECT, CLOCK_PHASE);
spi_set_bits_per_transfer(SPI, CHIP_SELECT, SPI_CSR_BITS_8_BIT);
spi_set_baudrate_div(SPI, CHIP_SELECT,(sysclk_get_cpu_hz() / BAUD_RATE));
spi_configure_cs_behavior(SPI, CHIP_SELECT, SPI_CS_KEEP_LOW);
spi_set_peripheral_chip_select_value(SPI, spi_get_pcs(CHIP_SELECT));
spi_enable(SPI);
}