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
  • Hi,

    1. Have you tried using the debugger and see if your program is stuck somewhere?
    2. What do you see if you probe the SPI lines? Is the CS and clock asserted correctly? Do you see the expected output on the MISO line?

    regards

    Jared

  • 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 

Reply Children
No Data
Related