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ÉèÖÃ
}