SPI worked strangely(external SPI Fash)

Hi,

I am using custom board with nRF52832.In the custom board, there is a SPI flash to storage some data.

I can read or write the flash normally at the beginning,but whenI create a timer to read/write the flash, the SPI interface will never work normally again. The spi_xfer_done will never turn to true.

Before into for(;;), I can read/wirite the data normally in W25QXX_Init() or W25QXX_test().But when I create a 1s timer to read/write again(W25QXX_test()), the RTT Viewer will always print "SPI WRITE".

BTW, my application is based on examples\ble_peripheral\ble_app_uart\pca10040\s112 and I have closed the bspxx to avoid the conflict of GPIO. To find the reason of SPI error, I added LOG in SPI driver when create the timer.

Here is the application code.

int main(void)
{
//    bool erase_bonds;
//		ret_code_t err_code;

    // Initialize.
  
    log_init();
		// Initialize the async SVCI interface to bootloader before any interrupts are enabled.
//    err_code = ble_dfu_buttonless_async_svci_init();
//    APP_ERROR_CHECK(err_code);
	
    timers_init();
//    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init();
//		sd_power_dcdc_mode_set(NRF_POWER_DCDC_DISABLE);
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

		m_application_config();
		m_timer_init();
//		m_work_upgrade_event();
    // Start execution.
    NRF_LOG_INFO("Debug logging for UART over RTT started.");
    advertising_start();

		W25QXX_test();
    // Enter main loop.
    for (;;)
    {
//				m_work_nus_event();
        idle_state_handle();
    }
}

/**@brief Function for configurate IO.
 *
 * @details        
 */
void m_application_config(void)
{
		nrf_gpio_cfg_output(M_OUT_OE_PIN);
		nrf_gpio_pin_set(M_OUT_OE_PIN);
	
		nrf_gpio_cfg_output(M_OUT_RESET_PIN);
		nrf_gpio_pin_set(M_OUT_RESET_PIN);
	
		nrf_gpio_cfg_output(M_OUT_BOOT_PIN);
		nrf_gpio_pin_clear(M_OUT_BOOT_PIN);

	
		W25QXX_Init();
}
void W25QXX_Init(void)
{
		uint8_t flash_w_data[9]="12345678";
		uint8_t flash_r_data[8]={0};
		m_spi_init();		   			//³õʼ»¯SPI
		W25QXX_PowerDown();
		W25QXX_WAKEUP();
		W25QXX_TYPE=W25QXX_ReadID();	//¶ÁÈ¡FLASH ID.
		NRF_LOG_INFO("W25QXX ID: %04x",W25QXX_TYPE);
		
		W25QXX_Write(flash_w_data,0,8);
		W25QXX_Write(flash_w_data,8,8);
		W25QXX_Write(flash_w_data,16,8);
		W25QXX_Write(flash_w_data,24,8);
		W25QXX_Read(flash_r_data,0,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,8,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,16,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,24,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Erase_Chip();

}
void W25QXX_test(void)
{
		uint8_t flash_w_data[9]="TESTBLE!";
		uint8_t flash_r_data[8]={0};
		
		W25QXX_PowerDown();
		W25QXX_WAKEUP();
		W25QXX_Write(flash_w_data,0,8);
		W25QXX_Write(flash_w_data,8,8);
		W25QXX_Write(flash_w_data,16,8);
		W25QXX_Write(flash_w_data,24,8);
		W25QXX_Read(flash_r_data,0,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,8,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,16,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,24,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
	
}

/**@brief Function for transmit device log imformation.
 */
static void m_log_device_app_timeout_handler(void * p_context)
{
		UNUSED_PARAMETER(p_context);
		uint8_t num_zh = 0;
		uint8_t num_yu = 0;
		uint8_t log_data[200];
		W25QXX_test();
//		if(m_nus_data.log_status == true)
//		{
//				if((m_nus_data.uart_num!=0)&&(m_nus_data.uart_num<=200))
//				{
//						m_nus_transmit_data(m_nus_data.uart_buff,m_nus_data.uart_num,NUS_NOTIFY_LOG);
////						NRF_LOG_HEXDUMP_INFO(m_nus_data.uart_buff,m_nus_data.uart_num);
//				}else if(m_nus_data.uart_num>200)
//				{
//						num_zh = m_nus_data.uart_num/200;//取整
//						num_yu = m_nus_data.uart_num%200;//取余	
//						for(int i=0;i<num_zh;i++)
//						{
//								for(int j=0;j<200;j++)
//								{
//										log_data[j] = m_nus_data.uart_buff[200*i+j];
//								}
//								m_nus_transmit_data(log_data,200,NUS_NOTIFY_LOG);
//						}
//						if(num_yu!=0)//最后一条数据
//						{
//								for(int k=0;k<num_yu;k++)
//								{
//										log_data[k] = m_nus_data.uart_buff[200*num_zh+k];
//								}
//								m_nus_transmit_data(log_data,num_yu,NUS_NOTIFY_LOG);
////								NRF_LOG_HEXDUMP_INFO(log_data,num_yu);
//						}
//				}
//		}else if(m_nus_data.log_status == false)
//		{
//				m_log_timer_stop();
//		}

//		m_nus_data.uart_num = 0;
}
/**@brief Function for user timer.
 */
void m_timer_init(void)
{
		ret_code_t err_code;
		// Create log timer.
    err_code = app_timer_create(&m_log_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                m_log_device_app_timeout_handler);
    APP_ERROR_CHECK(err_code);
	
		err_code = app_timer_create(&m_cmd_timer_id,
                                APP_TIMER_MODE_SINGLE_SHOT,
                                m_command_timeout_handler);
    APP_ERROR_CHECK(err_code);
	
		err_code = app_timer_start(m_log_timer_id,M_LOG_INTERVAL,NULL);
																APP_ERROR_CHECK(err_code);
}

Here is the SPI interface.

#include "w25qxx.h" 
#include "nrf_drv_spi.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
 
#define SPI_INSTANCE  0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
 
uint16_t W25QXX_TYPE=W25Q128;	//ĬÈÏÊÇW25Q128

uint8_t   SPI_Tx_Buf[8];
uint8_t   SPI_Rx_Buf[8];

volatile  uint8_t   SPIReadLength, SPIWriteLength;
/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    spi_xfer_done = true;
}
/**
 * @brief SPI init.
 * @param 
 */
static void m_spi_init(void)
{
		nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
//    spi_config.ss_pin   = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MOSI_PIN;
    spi_config.mosi_pin = SPI_MISO_PIN;
    spi_config.sck_pin  = SPI_SCK_PIN;
		nrf_gpio_cfg_output(SPI_SS_PIN);
		nrf_gpio_pin_clear(SPI_SS_PIN);     //ƬѡÎÞЧ
    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));	
		nrf_delay_ms(200);
    nrf_gpio_pin_set(SPI_SS_PIN);     //ƬѡÎÞЧ
		nrf_delay_ms(200);
}
/**
 * @brief SPI read/write byte.
 * @param 
 */
void W25QXX_write_reg(int data)
{
    spi_xfer_done = false;
    SPIWriteLength = 1;
    SPIReadLength = 0;
    SPI_Tx_Buf[0] = data;  
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, SPI_Tx_Buf, SPIWriteLength, SPI_Rx_Buf, SPIReadLength));
		while (!spi_xfer_done)
		{
				__WFE();
				NRF_LOG_INFO("SPI Write.");
				NRF_LOG_FLUSH();
		}
}
uint8_t W25QXX_read_reg(int reg)
{
    spi_xfer_done = false;
    SPI_Tx_Buf[0] = reg;
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, SPI_Tx_Buf, 0, SPI_Rx_Buf,1));
		while (!spi_xfer_done)
		{
				__WFE();
				NRF_LOG_INFO("SPI Read.");
				NRF_LOG_FLUSH();
		}
    return SPI_Rx_Buf[0];
}
//4KbytesΪһ¸öSector
//16¸öÉÈÇøΪ1¸öBlock
//W25Q128
//ÈÝÁ¿Îª16M×Ö½Ú,¹²ÓÐ128¸öBlock,4096¸öSector 
													 
//³õʼ»¯SPI FLASHµÄIO¿Ú

void W25QXX_Init(void)
{
		uint8_t flash_w_data[9]="12345678";
		uint8_t flash_r_data[8]={0};
		m_spi_init();		   			//³õʼ»¯SPI
		W25QXX_PowerDown();
		W25QXX_WAKEUP();
		W25QXX_TYPE=W25QXX_ReadID();	//¶ÁÈ¡FLASH ID.
		NRF_LOG_INFO("W25QXX ID: %04x",W25QXX_TYPE);
		
		W25QXX_Write(flash_w_data,0,8);
		W25QXX_Write(flash_w_data,8,8);
		W25QXX_Write(flash_w_data,16,8);
		W25QXX_Write(flash_w_data,24,8);
		W25QXX_Read(flash_r_data,0,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,8,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,16,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,24,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Erase_Chip();

}
void W25QXX_test(void)
{
		uint8_t flash_w_data[9]="TESTBLE!";
		uint8_t flash_r_data[8]={0};
		
		W25QXX_PowerDown();
		W25QXX_WAKEUP();
		W25QXX_Write(flash_w_data,0,8);
		W25QXX_Write(flash_w_data,8,8);
		W25QXX_Write(flash_w_data,16,8);
		W25QXX_Write(flash_w_data,24,8);
		W25QXX_Read(flash_r_data,0,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,8,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,16,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
		W25QXX_Read(flash_r_data,24,8);
		NRF_LOG_HEXDUMP_INFO(flash_r_data,8);
	
}

//¶ÁÈ¡W25QXXµÄ״̬¼Ä´æÆ÷
//BIT7  6   5   4   3   2   1   0
//SPR   RV  TB BP2 BP1 BP0 WEL BUSY
//SPR:ĬÈÏ0,״̬¼Ä´æÆ÷±£»¤Î»,ÅäºÏWPʹÓÃ
//TB,BP2,BP1,BP0:FLASHÇøÓòд±£»¤ÉèÖÃ
//WEL:дʹÄÜËø¶¨
//BUSY:æ±ê¼Çλ(1,æ;0,¿ÕÏÐ)
//ĬÈÏ:0x00
uint8_t W25QXX_ReadSR(void)
{
	uint8_t byte=0;   
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
	W25QXX_write_reg(W25X_ReadStatusReg);    //·¢ËͶÁȡ״̬¼Ä´æÆ÷ÃüÁî    
	byte=W25QXX_read_reg(0Xff);             //¶ÁÈ¡Ò»¸ö×Ö½Ú  
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ     
	return byte;   
}
//дW25QXX״̬¼Ä´æÆ÷
//Ö»ÓÐSPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)¿ÉÒÔд!!!
void W25QXX_Write_SR(uint8_t sr)   
{   
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
	W25QXX_write_reg(W25X_WriteStatusReg);   //·¢ËÍдȡ״̬¼Ä´æÆ÷ÃüÁî    
	W25QXX_write_reg(sr);               //дÈëÒ»¸ö×Ö½Ú  
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
}   
//W25QXXдʹÄÜ	
//½«WELÖÃλ   
void W25QXX_Write_Enable(void)   
{
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_WriteEnable);      //·¢ËÍдʹÄÜ  
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
} 
//W25QXXд½ûÖ¹	
//½«WELÇåÁã  
void W25QXX_Write_Disable(void)   
{  
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_WriteDisable);     //·¢ËÍд½ûÖ¹Ö¸Áî    
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
} 		
//¶ÁȡоƬID
//·µ»ØÖµÈçÏÂ:				   
//0XEF13,±íʾоƬÐͺÅΪW25Q80  
//0XEF14,±íʾоƬÐͺÅΪW25Q16    
//0XEF15,±íʾоƬÐͺÅΪW25Q32  
//0XEF16,±íʾоƬÐͺÅΪW25Q64 
//0XEF17,±íʾоƬÐͺÅΪW25Q128 	  
uint16_t W25QXX_ReadID(void)
{
	uint16_t Temp = 0;	  
	SPI_NSS_LOW();				    
	W25QXX_write_reg(0x90);//·¢ËͶÁÈ¡IDÃüÁî	    
	W25QXX_write_reg(0x00); 	    
	W25QXX_write_reg(0x00); 	    
	W25QXX_write_reg(0x00); 	 			   
	Temp|=W25QXX_read_reg(0xFF)<<8;  
	Temp|=W25QXX_read_reg(0xFF);	 
	SPI_NSS_HIGH();				    
	return Temp;
}   		    
//¶ÁÈ¡SPI FLASH  
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼¶ÁÈ¡Ö¸¶¨³¤¶ÈµÄÊý¾Ý
//pBuffer:Êý¾Ý´æ´¢Çø
//ReadAddr:¿ªÊ¼¶ÁÈ¡µÄµØÖ·(24bit)
//NumByteToRead:Òª¶ÁÈ¡µÄ×Ö½ÚÊý(×î´ó65535)
void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)   
{ 
 	uint16_t i;   										    
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_ReadData);         //·¢ËͶÁÈ¡ÃüÁî   
    W25QXX_write_reg((uint8_t)((ReadAddr)>>16));  //·¢ËÍ24bitµØÖ·    
    W25QXX_write_reg((uint8_t)((ReadAddr)>>8));   
    W25QXX_write_reg((uint8_t)ReadAddr);   
    for(i=0;i<NumByteToRead;i++)
	{ 
        pBuffer[i]=W25QXX_read_reg(0XFF);   //Ñ­»·¶ÁÊý  
    }
	SPI_NSS_HIGH();  				    	      
}  
//SPIÔÚÒ»Ò³(0~65535)ÄÚдÈëÉÙÓÚ256¸ö×Ö½ÚµÄÊý¾Ý
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´Èë×î´ó256×Ö½ÚµÄÊý¾Ý
//pBuffer:Êý¾Ý´æ´¢Çø
//WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit)
//NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó256),¸ÃÊý²»Ó¦¸Ã³¬¹ý¸ÃÒ³µÄÊ£Óà×Ö½ÚÊý!!!	 
void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
 	uint16_t i;  
    W25QXX_Write_Enable();                  //SET WEL 
	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_PageProgram);      //·¢ËÍдҳÃüÁî   
    W25QXX_write_reg((uint8_t)((WriteAddr)>>16)); //·¢ËÍ24bitµØÖ·    
    W25QXX_write_reg((uint8_t)((WriteAddr)>>8));   
    W25QXX_write_reg((uint8_t)WriteAddr);   
    for(i=0;i<NumByteToWrite;i++)W25QXX_write_reg(pBuffer[i]);//Ñ­»·Ð´Êý  
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ 
	W25QXX_Wait_Busy();					   //µÈ´ýдÈë½áÊø
} 
//ÎÞ¼ìÑéдSPI FLASH 
//±ØÐëÈ·±£ËùдµÄµØÖ··¶Î§ÄÚµÄÊý¾ÝÈ«²¿Îª0XFF,·ñÔòÔÚ·Ç0XFF´¦Ð´ÈëµÄÊý¾Ý½«Ê§°Ü!
//¾ßÓÐ×Ô¶¯»»Ò³¹¦ÄÜ 
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´ÈëÖ¸¶¨³¤¶ÈµÄÊý¾Ý,µ«ÊÇҪȷ±£µØÖ·²»Ô½½ç!
//pBuffer:Êý¾Ý´æ´¢Çø
//WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit)
//NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó65535)
//CHECK OK
void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)   
{ 			 		 
	uint16_t pageremain;	   
	pageremain=256-WriteAddr%256; //µ¥Ò³Ê£ÓàµÄ×Ö½ÚÊý		 	    
	if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//²»´óÓÚ256¸ö×Ö½Ú
	while(1)
	{	   
		W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);
		if(NumByteToWrite==pageremain)break;//дÈë½áÊøÁË
	 	else //NumByteToWrite>pageremain
		{
			pBuffer+=pageremain;
			WriteAddr+=pageremain;	

			NumByteToWrite-=pageremain;			  //¼õÈ¥ÒѾ­Ð´ÈëÁ˵Ä×Ö½ÚÊý
			if(NumByteToWrite>256)pageremain=256; //Ò»´Î¿ÉÒÔдÈë256¸ö×Ö½Ú
			else pageremain=NumByteToWrite; 	  //²»¹»256¸ö×Ö½ÚÁË
		}
	};	    
} 
//дSPI FLASH  
//ÔÚÖ¸¶¨µØÖ·¿ªÊ¼Ð´ÈëÖ¸¶¨³¤¶ÈµÄÊý¾Ý
//¸Ãº¯Êý´ø²Á³ý²Ù×÷!
//pBuffer:Êý¾Ý´æ´¢Çø
//WriteAddr:¿ªÊ¼Ð´ÈëµÄµØÖ·(24bit)						
//NumByteToWrite:ҪдÈëµÄ×Ö½ÚÊý(×î´ó65535)   
uint8_t W25QXX_BUFFER[4096];		 
void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)   
{ 
	uint32_t secpos;
	uint16_t secoff;
	uint16_t secremain;	   
 	uint16_t i;    
	uint8_t * W25QXX_BUF;	  
   	W25QXX_BUF=W25QXX_BUFFER;	     
 	secpos=WriteAddr/4096;//ÉÈÇøµØÖ·  
	secoff=WriteAddr%4096;//ÔÚÉÈÇøÄÚµÄÆ«ÒÆ
	secremain=4096-secoff;//ÉÈÇøÊ£Óà¿Õ¼ä´óС   
 	//printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//²âÊÔÓÃ
 	if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//²»´óÓÚ4096¸ö×Ö½Ú
	while(1) 
	{	
		W25QXX_Read(W25QXX_BUF,secpos*4096,4096);//¶Á³öÕû¸öÉÈÇøµÄÄÚÈÝ
		for(i=0;i<secremain;i++)//УÑéÊý¾Ý
		{
			if(W25QXX_BUF[secoff+i]!=0XFF)break;//ÐèÒª²Á³ý  	  
		}
		if(i<secremain)//ÐèÒª²Á³ý
		{
			W25QXX_Erase_Sector(secpos);//²Á³ýÕâ¸öÉÈÇø
			for(i=0;i<secremain;i++)	   //¸´ÖÆ
			{
				W25QXX_BUF[i+secoff]=pBuffer[i];	  
			}
			W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//дÈëÕû¸öÉÈÇø  

		}else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);//дÒѾ­²Á³ýÁ˵Ä,Ö±½ÓдÈëÉÈÇøÊ£ÓàÇø¼ä. 				   
		if(NumByteToWrite==secremain)break;//дÈë½áÊøÁË
		else//дÈëδ½áÊø
		{
			secpos++;//ÉÈÇøµØÖ·Ôö1
			secoff=0;//Æ«ÒÆλÖÃΪ0 	 

		   	pBuffer+=secremain;  //Ö¸ÕëÆ«ÒÆ
			WriteAddr+=secremain;//дµØÖ·Æ«ÒÆ	   
		   	NumByteToWrite-=secremain;				//×Ö½ÚÊýµÝ¼õ
			if(NumByteToWrite>4096)secremain=4096;	//ÏÂÒ»¸öÉÈÇø»¹ÊÇд²»Íê
			else secremain=NumByteToWrite;			//ÏÂÒ»¸öÉÈÇø¿ÉÒÔдÍêÁË
		}	 
	};	 
}
//²Á³ýÕû¸öоƬ		  
//µÈ´ýʱ¼ä³¬³¤...
void W25QXX_Erase_Chip(void)   
{                                   
    W25QXX_Write_Enable();                  //SET WEL 
    W25QXX_Wait_Busy();   
  	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_ChipErase);        //·¢ËÍƬ²Á³ýÃüÁî  
		SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
		W25QXX_Wait_Busy();   				   //µÈ´ýоƬ²Á³ý½áÊø
		NRF_LOG_INFO("Erase flash W25QXX.");
}   
//²Á³ýÒ»¸öÉÈÇø
//Dst_Addr:ÉÈÇøµØÖ· ¸ù¾Ýʵ¼ÊÈÝÁ¿ÉèÖÃ
//²Á³ýÒ»¸öɽÇøµÄ×îÉÙʱ¼ä:150ms
void W25QXX_Erase_Sector(uint32_t Dst_Addr)   
{  
	//¼àÊÓfalsh²Á³ýÇé¿ö,²âÊÔÓà   
// 	printf("fe:%x\r\n",Dst_Addr);	  
 	Dst_Addr*=4096;
    W25QXX_Write_Enable();                  //SET WEL 	 
    W25QXX_Wait_Busy();   
  	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_SectorErase);      //·¢ËÍÉÈÇø²Á³ýÖ¸Áî 
    W25QXX_write_reg((uint8_t)((Dst_Addr)>>16));  //·¢ËÍ24bitµØÖ·    
    W25QXX_write_reg((uint8_t)((Dst_Addr)>>8));   
    W25QXX_write_reg((uint8_t)Dst_Addr);  
	SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
    W25QXX_Wait_Busy();   				   //µÈ´ý²Á³ýÍê³É
}  
//µÈ´ý¿ÕÏÐ
void W25QXX_Wait_Busy(void)   
{   
	while((W25QXX_ReadSR()&0x01)==0x01);   // µÈ´ýBUSYλÇå¿Õ
}  
//½øÈëµôµçģʽ
void W25QXX_PowerDown(void)   
{ 
  	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_PowerDown);        //·¢Ë͵ôµçÃüÁî  
		SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
    nrf_delay_us(30);                               //µÈ´ýTDP£¬¸ù¾ÝdatasheetÉèÖÃ
}   
//»½ÐÑ
void W25QXX_WAKEUP(void)   
{  
  	SPI_NSS_LOW();                            //ʹÄÜÆ÷¼þ   
    W25QXX_write_reg(W25X_ReleasePowerDown);   //  send W25X_PowerDown command 0xAB    
		SPI_NSS_HIGH();                            //È¡ÏûƬѡ     	      
    nrf_delay_us(30);                               //µÈ´ýTRES1£¬¸ù¾ÝdatasheetÉèÖÃ
}   

Parents Reply Children
  • Have you tried using the debugger and see if your program is stuck somewhere?

    If I using SPI interface in timer timeout,it will stuck in W25QXX_write_reg().The spi_xfer_done will never turn to true.Is that mean I can not using SPI in timer interrupt?

    void W25QXX_write_reg(int data)
    {
    		uint8_t SPIWriteLength,SPIReadLength;
    		uint8_t SPI_Tx_Buf[1]={0};
    		uint8_t SPI_Rx_Buf[1]={0};
        spi_xfer_done = false;
        SPIWriteLength = 1;
        SPIReadLength = 0;
        SPI_Tx_Buf[0] = data;  
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, SPI_Tx_Buf, SPIWriteLength, SPI_Rx_Buf, SPIReadLength));
    		while (!spi_xfer_done)
    		{
    				__WFE();
    		}
    }

  • Hi,

    Taylor said:
    If I using SPI interface in timer timeout,

    You need to move this outside of interrupt context by moving W25QXX_write_reg() to outside the timeout callback handler. Set a flag in timeout handler that you check in the main loop and then call W25QXX_write_reg() instead of calling it directly in the main loop. 

    regards

    Jared 

Related