Ejemplo n.º 1
0
void mrf_write_short(uint8_t address, uint8_t data) {
    mrf_select();
    // 0 for top address, 1 bottom for write
    spi_tx((address<<1 & 0b01111110) | 0x01);
    spi_tx(data);
    mrf_deselect();
}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static const char *
program_page(unsigned long offset, const unsigned char *p, int nbytes)
{
  const unsigned char *end = p + nbytes;
  int s;

  wait_ready();

  write_enable();

  s = splhigh();
  SPI_FLASH_ENABLE();
  
  spi_tx(SPI_FLASH_INS_PP);
  spi_tx(offset >> 16);	/* MSB */
  spi_tx(offset >> 8);
  spi_tx(offset >> 0);	/* LSB */

  for(; p < end; p++) {
    spi_tx(~*p);
  }

  SPI_FLASH_DISABLE();
  splx(s);

  return p;
}
Ejemplo n.º 3
0
uint8_t mrf_read_short(uint8_t address) {
    mrf_select();
    // 0 top for short addressing, 0 bottom for read
    spi_tx(address<<1 & 0b01111110);
    uint8_t res = spi_tx(0x0);
    mrf_deselect();
    return res;
}
Ejemplo n.º 4
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static uint8_t sst25_busy( void )
{
	uint8_t st;
	DF_CS_0;
	spi_tx( 0x05 );
	st = spi_tx( 0xff );
	DF_CS_1;
	return st & 0x01;
}
Ejemplo n.º 5
0
void mrf_write_long(uint16_t address, uint8_t data) {
    mrf_select();
    uint8_t ahigh = address >> 3;
    uint8_t alow = address << 5;
    spi_tx(0x80 | ahigh);  // high bit for long
    spi_tx(alow | 0x10);  // last bit for write
    spi_tx(data);
    mrf_deselect();
}
Ejemplo n.º 6
0
uint8_t mrf_read_long(uint16_t address) {
    mrf_select();
    uint8_t ahigh = address >> 3;
    uint8_t alow = address << 5;
    spi_tx(0x80 | ahigh);  // high bit for long
    spi_tx(alow);
    uint8_t res = spi_tx(0);
    mrf_deselect();
    return res;
}
Ejemplo n.º 7
0
// Reads the JEDEC ID.
static uint32_t read_device_id() {
  start_command(COMMAND_JEDEC_ID);
  uint32_t id = 0;
  char* id_bytes = reinterpret_cast<char*>(&id);
  id_bytes[2] = spi_tx(0);
  id_bytes[1] = spi_tx(0);
  id_bytes[0] = spi_tx(0);
  end_command();

  return id;
}
Ejemplo n.º 8
0
/*---------------------------------------------------------------------------*/
int
xmem_pread(void *_p, int size, unsigned long offset)
{
  unsigned char *p = _p;
  const unsigned char *end = p + size;
  int s;
  wait_ready();

  ENERGEST_ON(ENERGEST_TYPE_FLASH_READ);

  s = splhigh();
  SPI_FLASH_ENABLE();

  spi_tx(SPI_FLASH_INS_READ);
  spi_tx(offset >> 16);	/* MSB */
  spi_tx(offset >> 8);
  spi_tx(offset >> 0);	/* LSB */
  
  FASTSPI_CLEAR_RX();
  for(; p < end; p++) {
    unsigned char u;
    FASTSPI_RX(u);
    *p = ~u;
  }

  SPI_FLASH_DISABLE();
  splx(s);

  ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ);

  return size;
}
Ejemplo n.º 9
0
// Read status reg.
static uint8_t read_status_reg() {
  start_command(COMMAND_READ_STATUS);
  uint8_t value = spi_tx(0);
  end_command();

  return value;
}
Ejemplo n.º 10
0
uint8 spi_aux_write(spi_dev *spi_device, const uint8 *data, uint32 length) {
    uint32 txed = 0;
    while (txed < length) {
        uint32 ret = spi_tx(spi_device, data + txed, length - txed);
        if(ret == -1) return 1;
        txed += ret;
    }
    return 0;
}
Ejemplo n.º 11
0
void sst25_write_back( uint32_t addr, uint8_t *p, uint16_t len )
{
	uint32_t	i, wr_addr;
	uint16_t	offset;
	uint8_t		*pbuf;


/*找到当前地址对应的4k=0x1000边界*/
	wr_addr = addr & 0xFFFFF000;        /*对齐到4k边界*/
	offset	= addr & 0xfff;             /*4k内偏移*/

	sst25_read( wr_addr, buf, 4096 );   /*读出数据*/
	sst25_erase_4k( wr_addr );          /*清除扇区*/

	memcpy( buf + offset, p, len );
	pbuf = buf;
	DF_CS_0;
	spi_tx( SST25_WREN );
	DF_CS_1;
	DF_CS_0;
	spi_tx( SST25_AAI ); /**/
	spi_tx( wr_addr >> 16 );
	spi_tx( wr_addr >> 8 );
	spi_tx( wr_addr & 0xff );
	spi_tx( *pbuf++ );
	spi_tx( *pbuf++ );
	DF_CS_1;
	while( sst25_busy( ) )
	{
		;                    
	}
	for( i = 0; i < 4094; i += 2 )
	{
		DF_CS_0;
		spi_tx( SST25_AAI );    /**/
		spi_tx( *pbuf++ );
		spi_tx( *pbuf++ );
		DF_CS_1;
		while( sst25_busy( ) )
		{
			;                
		}
	}
	DF_CS_0;
	spi_tx( SST25_WRDI );       //WRDI用于退出AAI写模式 所谓AAI 就是地址自动加
	DF_CS_1;
}
Ejemplo n.º 12
0
/**************************************************************************************************
* @fn          npSpiRxIsr
*
* @brief       This function handles the DMA Rx complete interrupt.
*
* input parameters
*
* None.
*
* output parameters
*
* None.
*
* @return      None.
**************************************************************************************************
*/
void npSpiRxIsr(void)
{
  uint8 *pBuf;
  mtRpcCmdType_t type = (mtRpcCmdType_t)(npSpiBuf[1] & MT_RPC_CMD_TYPE_MASK);
  
  NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_RX);
  switch (type)
  {
  case MT_RPC_CMD_POLL:
    npSpiState = NP_SPI_WAIT_TX;
    if ((pBuf = npSpiPollCallback()) != NULL)
    {
      /* Send TX packet using uDMA */
      spi_tx(pBuf);
      osal_msg_deallocate((uint8 *)pBuf);
    }
    else
    {
      /* If there is no data in the queue, send 3 zeros. */
      pBuf = npSpiBuf;
      npSpiBuf[0] = npSpiBuf[1] = npSpiBuf[2] = 0;
          
      /* Send TX packet using uDMA */
      spi_tx(pBuf);
    }
    break;
    
  case MT_RPC_CMD_SREQ:
    npSpiState = NP_SPI_WAIT_SREQ;
    osal_set_event(znpTaskId, ZNP_SPI_RX_SREQ_EVENT);
    break;
    
  case MT_RPC_CMD_AREQ:
    npSpiState = NP_SPI_WAIT_AREQ;
    osal_set_event(znpTaskId, ZNP_SPI_RX_AREQ_EVENT);
    break;
    
  default:
    npSpiState = NP_SPI_IDLE;
    break;
  }
}
Ejemplo n.º 13
0
/*搽除一个扇区,不需要连续删除*/
void sst25_erase_4k( uint32_t addr )
{
	while( sst25_busy( ) )
	{
		;
	}
	DF_CS_0;
	spi_tx( SST25_WREN );
	DF_CS_1;
	DF_CS_0;
	spi_tx( SectorErace_4KB );
	spi_tx( ( addr & 0xffFFFF ) >> 16 );
	spi_tx( ( addr & 0xffFF ) >> 8 );
	spi_tx( addr & 0xFF );
	DF_CS_1;
	while( sst25_busy( ) )
	{
		;
	}
}
Ejemplo n.º 14
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
void sst25_read( uint32_t addr, uint8_t *p, uint16_t len )
{
	uint8_t		*pdata		= p;
	uint32_t	readaddr	= addr;

	while( sst25_busy( ) )
	{
		;
	}
	DF_CS_0;
	spi_tx( SST25_READ );
	spi_tx( ( readaddr & 0xFF0000 ) >> 16 );
	spi_tx( ( readaddr & 0xFF00 ) >> 8 );
	spi_tx( readaddr & 0xFF );
	while( len-- )
	{
		*pdata = spi_tx( 0xA5 );
		pdata++;
	}
	DF_CS_1;
}
Ejemplo n.º 15
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static void sst25_bytewrite( uint32_t addr, uint8_t data )
{
	volatile uint8_t st;
	DF_CS_0;
	spi_tx( SST25_WREN );
	DF_CS_1;
	delay(3);
	DF_CS_0;
	spi_tx( SST25_BP );
	spi_tx( ( addr & 0xffffff ) >> 16 );
	spi_tx( ( addr & 0xff00 ) >> 8 );
	spi_tx( addr & 0xff );
	spi_tx( data );
	DF_CS_1;
	while( sst25_busy( ) )
	{
		;
	}
#if 0
	DF_CS_0;
	spi_tx( SST25_RDSR );
	do
	{
		st = spi_tx( 0xA5 );
	}
	while( st & 0x01 );
	DF_CS_1;
#endif
}
Ejemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static void
write_enable(void)
{
  int s;

  s = splhigh();
  SPI_FLASH_ENABLE();
  
  spi_tx(SPI_FLASH_INS_WREN);

  SPI_FLASH_DISABLE();
  splx(s);
}
Ejemplo n.º 17
0
// Read data.
static void read_data(uint32_t offset, char* buf, uint32_t size) {
  start_command(COMMAND_READ_DATA);
  write_address(offset);

  // The file data bit order is reversed.
  spi_set_bit_order(SPI_LSB_FIRST);
  for (; size > 0; --size, ++buf) {
    *buf = spi_tx(0);
  }
  spi_set_bit_order(SPI_MSB_FIRST);

  end_command();
}
Ejemplo n.º 18
0
// Programs a page of data.
static void page_program(uint32_t offset, const char* buf, uint16_t size) {
  start_command(COMMAND_PAGE_PROGRAM);
  write_address(offset);
  if (size > PAGE_SIZE) {
    size = PAGE_SIZE;
  }

  // The file data bit order is reversed.
  spi_set_bit_order(SPI_LSB_FIRST);
  for (; size > 0; --size, ++buf) {
    spi_tx(*buf);
  }
  spi_set_bit_order(SPI_MSB_FIRST);

  end_command();
}
Ejemplo n.º 19
0
int main() {

	led_on();
	usart_init();
	debugln("\nUSART initialized");

	spi_init_master();
	debugln("SPI master");

	for(int i=0; i<5; i++) {
		debugx(spi_tx(42)); debugln(" spi_tx");
	}

	for (;;){}

	return 1;
}
Ejemplo n.º 20
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static uint8_t sst25_info( void )
{
	//uint8_t n;
	DF_CS_0;
	spi_tx( 0x90 );
	spi_tx( 0x00 );
	spi_tx( 0x00 );
	spi_tx( 0x00 );
	mem_ID = spi_tx( 0xff )<<8;
	mem_ID |= spi_tx( 0xff );
	DF_CS_1;
	//rt_kprintf("\n MEM_ID=%04X",mem_ID);
}
Ejemplo n.º 21
0
/**************************************************************************************************
* @fn          npSpiSRspReady
*
* @brief       This function is called by MT to notify SPI driver that an SRSP is ready to Tx.
*
* input parameters
*
* @param       pBuf - Pointer to the buffer to transmit on the SPI.
*
* output parameters
*
* None.
*
* @return      None.
**************************************************************************************************
*/
void npSpiSRspReady(uint8 *pBuf)
{
  halIntState_t intState;

  HAL_ENTER_CRITICAL_SECTION_DEBUG(intState); 
  if ((npSpiState == NP_SPI_WAIT_SREQ) && (GPIOPinRead(HAL_SPI_SRDY_BASE, HAL_SPI_SRDY_PIN) == 0))
  {
    npSpiState = NP_SPI_WAIT_TX;
    
    /* Send TX packet using uDMA */
    spi_tx(pBuf);  
    HAL_EXIT_CRITICAL_SECTION_DEBUG(intState);
    osal_msg_deallocate((uint8 *)pBuf);
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION_DEBUG(intState);
  }
}
Ejemplo n.º 22
0
/*
 * Erase 64k bytes of data. It takes about 1s before WIP goes low!
 */
static void
erase_sector(unsigned long offset)
{
  int s;
  wait_ready();

  write_enable();

  s = splhigh();
  SPI_FLASH_ENABLE();
  
  spi_tx(SPI_FLASH_INS_SE);
  spi_tx(offset >> 16);	/* MSB */
  spi_tx(offset >> 8);
  spi_tx(offset >> 0);	/* LSB */

  SPI_FLASH_DISABLE();
  splx(s);
}
Ejemplo n.º 23
0
/*---------------------------------------------------------------------------*/
static unsigned
read_status_register(void)
{
  unsigned char u;

  int s;

  s = splhigh();
  SPI_FLASH_ENABLE();
  
  spi_tx(SPI_FLASH_INS_RDSR);

  FASTSPI_CLEAR_RX();
  FASTSPI_RX(u);

  SPI_FLASH_DISABLE();
  splx(s);

  return u;
}
Ejemplo n.º 24
0
int spi_isr(spi_p t)
{
	int			st;
	spir_p		reg;
	spi_xfr_p	bp;
	register int	actual, count, rem, inc;

	reg = t->r;
	st = io_rd32(reg->sta);
#if 0
	st &= io_rd32(reg->ier);
	if (!st)
#else
	if (!(st & io_rd32(reg->ier)))
#endif
	{
		dbg("spi: isr err - no source\n");
		return 0;
	}
//dbg("isr=%X\n", st);
	io_wr32(reg->sta, st);

	/* errors */
	if (st & (SPI_INT_WOVR | SPI_INT_WUNR | SPI_INT_FOVR))
	{
		dbg("spi: isr err - %X\n", st);
		t->evt(t->ctx, SPI_EVT_ERR);
	}

	/* data xfer */
	bp = t->bp;
	if (!bp)
	{
		dbg("spi: isr err - no buf, %X\n", st);
		return 0;
	}
	inc = t->inc;
	actual = bp->actual;
	rem = bp->len - actual;

	if (st & SPI_INT_TEMT)
	{
		/*	use transmitter empty to minimize io & irq for all cases
			except slave rx-only */
		int	size;

		size = t->fifosize << inc;
		count = MIN(size, rem);
		rem -= count;

		if (bp->rx)
		{
			spi_rx(&reg->rx, bp->rx + actual, count, inc);
		}

		actual += count;
		bp->actual = actual;
		if (!rem)
		{
			io_wr32(reg->ier, 0);
			io_wr32(reg->op, io_rd32(reg->op) & ~SPI_OP_EN);
			io_wr32(reg->ctl, 0);
#ifndef SPI_AUTOCS
			if (bp->csflag & SPI_XFR_NCS)
			{
				io_wr32(reg->master, io_rd32(reg->master) & ~SPI_MST_FSS);
			}
#endif
			t->bp = 0;
//ddump("spi: rx - ", bp->rx, bp->len);
//dbg("spi: isr info - done, %X %X\n", st, io_rd32(reg->sta));
			t->evt(t->ctx, SPI_EVT_DONE);
		}
		else
		{
			count = MIN(size, rem);
			rem = count >>= t->inc;
#ifdef SPI_AUTOCS
			if (t->master && !t->burst)
			{
				/* assert chip select for rest of xfer */
				io_wr32(reg->op, (io_rd32(reg->op) & ~SPI_OP_BURST(16)) 
									| SPI_OP_BURST(rem));
			}
#endif
			if (bp->tx)
			{
				spi_tx(&reg->tx, bp->tx + actual, count, inc);
			}
			else
			{
				while (rem--)
				{
					io_wr32(reg->tx, 0);
				}
			}
		}
	}
Ejemplo n.º 25
0
// Sends a 24-bit address over the SPI.
static void write_address(uint32_t address) {
  const char* address_bytes = reinterpret_cast<const char*>(&address);
  spi_tx(address_bytes[2]);
  spi_tx(address_bytes[1]);
  spi_tx(address_bytes[0]);
}
Ejemplo n.º 26
0
// Starts a command operation.
static void start_command(uint8_t command) {
  flash_spi_select();
  spi_tx(command);
}
Ejemplo n.º 27
0
void sst25_write_through( uint32_t addr, uint8_t *p, uint16_t len )
{
	volatile uint8_t	st = 0;
	uint32_t			wr_addr;
	uint8_t				*pdata	= p;
	uint16_t			remain	= len;
	uint32_t			delay_counter;
	wr_addr = addr;
	while( sst25_busy( ) )
	{
		;
	}
	if(mem_ID == 0xBF4A)		///存储设备为sst25
	{
		/*AAI方式写,要判读地址的奇偶*/
		if( len == 1 )
		{
			sst25_bytewrite( wr_addr, *pdata );
			return;
		}
		if( wr_addr & 0x01 ) /*AAI需要从A0=0开始*/
		{
			sst25_bytewrite( wr_addr++, *pdata++ );
			remain--;
		}

		DF_CS_0;
		spi_tx( SST25_WREN );
		DF_CS_1;
		delay(3);
		DF_CS_0;
		spi_tx( SST25_AAI ); /**/
		spi_tx( wr_addr >> 16 );
		spi_tx( wr_addr >> 8 );
		spi_tx( wr_addr & 0xff );
		spi_tx( *pdata++ );
		spi_tx( *pdata++ );
		DF_CS_1;
		while( sst25_busy( ) )
		{
			;                       //判忙
		}
		remain -= 2;
		while( remain > 1 )
		{
			DF_CS_0;
			spi_tx( SST25_AAI );    /**/
			spi_tx( *pdata++ );
			spi_tx( *pdata++ );
			DF_CS_1;
			while( sst25_busy( ) )
			{
				;                   //判忙
			}
			remain -= 2;
		}

		DF_CS_0;
		spi_tx( SST25_WRDI );       //WRDI用于退出AAI写模式 所谓AAI 就是地址自动加
		DF_CS_1;
		if( remain )
		{
			sst25_bytewrite( wr_addr + len - 1, *pdata );
		}
	}
	else
	{
Ejemplo n.º 28
0
void sst25_write_through( uint32_t addr, uint8_t *p, uint16_t len )
{
	volatile uint8_t	st = 0;
	uint32_t			wr_addr;
	uint8_t				*pdata	= p;
	uint16_t			remain	= len;
	wr_addr = addr;
	while( sst25_busy( ) )
	{
		;
	}
/*字节写的方式*/
#if 0
	while( remain-- )
	{
		sst25_bytewrite( wr_addr, *pdata++ );
		wr_addr++;
	}
#else
/*AAI方式写,要判读地址的奇偶*/
	if( len == 1 )
	{
		sst25_bytewrite( wr_addr, *pdata );
		return;
	}
	if( wr_addr & 0x01 ) /*AAI需要从A0=0开始*/
	{
		sst25_bytewrite( wr_addr++, *pdata++ );
		remain--;
	}

	DF_CS_0;
	spi_tx( SST25_WREN );
	DF_CS_1;
	DF_CS_0;
	spi_tx( SST25_AAI ); /**/
	spi_tx( wr_addr >> 16 );
	spi_tx( wr_addr >> 8 );
	spi_tx( wr_addr & 0xff );
	spi_tx( *pdata++ );
	spi_tx( *pdata++ );
	DF_CS_1;
	while( sst25_busy( ) )
	{
		;                       //判忙
	}
	remain -= 2;
	while( remain > 1 )
	{
		DF_CS_0;
		spi_tx( SST25_AAI );    /**/
		spi_tx( *pdata++ );
		spi_tx( *pdata++ );
		DF_CS_1;
		while( sst25_busy( ) )
		{
			;                   //判忙
		}
		remain -= 2;
	}

	DF_CS_0;
	spi_tx( SST25_WRDI );       //WRDI用于退出AAI写模式 所谓AAI 就是地址自动加
	DF_CS_1;
	if( remain )
	{
		sst25_bytewrite( wr_addr + len - 1, *pdata );
	}
#endif
}
Ejemplo n.º 29
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
void sst25_init( void )
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	SPI_InitTypeDef		SPI_InitStructure;
	uint32_t			delay_counter;

	/* Enable DF_SPI Periph clock */
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE );
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
	GPIO_PinAFConfig( GPIOB, GPIO_PinSource13, GPIO_AF_SPI2 );
	GPIO_PinAFConfig( GPIOB, GPIO_PinSource14, GPIO_AF_SPI2 );
	GPIO_PinAFConfig( GPIOB, GPIO_PinSource15, GPIO_AF_SPI2 );
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOD, ENABLE );

	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_25MHz;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_DOWN;

	/*!< SPI SCK pin configuration */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_Init( GPIOB, &GPIO_InitStructure );

	/*!< SPI MOSI pin configuration */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_Init( GPIOB, &GPIO_InitStructure );

	/*!< SPI MISO pin configuration */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init( GPIOB, &GPIO_InitStructure );

	//-------  CS _pin
	GPIO_InitStructure.GPIO_Pin		= GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_NOPULL;
	GPIO_Init( GPIOD, &GPIO_InitStructure );
	
	//PA4 pin: CS		SD_CARD
	GPIO_InitStructure.GPIO_Pin		= GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_NOPULL;
	GPIO_Init( GPIOA, &GPIO_InitStructure );
	GPIO_SetBits(GPIOA,GPIO_Pin_4);

	//-------  WP  _pin
	GPIO_InitStructure.GPIO_Pin		= GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_NOPULL;
	GPIO_Init( GPIOD, &GPIO_InitStructure );

	/*------------------------ DF_SPI configuration ------------------------*/
	SPI_InitStructure.SPI_Direction			= SPI_Direction_2Lines_FullDuplex;  //SPI_Direction_1Line_Tx;
	SPI_InitStructure.SPI_Mode				= SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize			= SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL				= SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA				= SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_NSS				= SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;          /* 42M/4=10.5M */
	SPI_InitStructure.SPI_FirstBit			= SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial		= 7;

	//SPI1->CR2=0x04;                                   //NSS ---SSOE
	//   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	//SPI_InitStructure.SPI_Mode = SPI_Mode_Master;       //MSTR

	SPI_I2S_DeInit( SPI2 );
	SPI_Init( SPI2, &SPI_InitStructure );

	/* Enable SPI_MASTER */
	SPI_Cmd( SPI2, ENABLE );
	SPI_CalculateCRC( SPI2, DISABLE );

	DF_CS_1;
	DF_WP_0;

	DF_CS_0;
	spi_tx( 0x50 );
	DF_CS_1;
	delay(3);
	DF_CS_0;
	spi_tx( 0x01 );
	spi_tx( 0x00 );
	DF_CS_1;

	//delay(3);
	//DF_CS_0;
	//spi_tx( DBSY );
	//DF_CS_1;
	sst25_info( );
	//rt_sem_init( &sem_dataflash, "sem_df", 0, RT_IPC_FLAG_FIFO );
	//rt_sem_release( &sem_dataflash );
}