Esempio n. 1
0
int spiReadWrite16(SPI_TypeDef *SPIx,uint8_t *rbuf, const uint16_t *tbuf, int cnt, uint16_t speed) {
  int i;
  
  SPIx->CR1 = (SPIx->CR1&~SPI_BaudRatePrescaler_256)|speed;
  SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);

  for (i = 0; i < cnt; i++){
    if (tbuf) {
      //      printf("data=0x%4x\n\r",*tbuf);
      SPI_I2S_SendData16(SPIx,*tbuf++);
    } 
    else {
      SPI_I2S_SendData16(SPIx,0xffff);
    }
    while (SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_RXNE) == RESET);
    if (rbuf) {
      *rbuf++ = SPI_I2S_ReceiveData16(SPIx);
    } 
    else {
      SPI_I2S_ReceiveData16(SPIx);
    }
  }
  SPI_DataSizeConfig(SPIx, SPI_DataSize_8b);

  return i;
}
Esempio n. 2
0
u16 send_strobe (u8 strobe) {
 	// drop the css and wait until chip is ready
	drop_css();
	while(miso_high());

	// switch mode to 8 bit
	SPI_DataSizeConfig(SPI1,SPI_DataSize_8b);

	// send the strobe
	SPI1->DR = strobe;

	// wait until no longer busy
	while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY) == SET);

	// wait until there is data in the read register
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

	// read the data
	t = SPI1->DR;

	// switch to 16 bit and release spi
	SPI_DataSizeConfig(SPI1,SPI_DataSize_16b);
	raise_css();

	return t;
}
Esempio n. 3
0
int xchng_datablock(SPI_TypeDef *SPIx, int half, const void *tbuf, void *rbuf, unsigned count) {
  if (count > 4) {  
    if (half) SPI_DataSizeConfig(SPI2, SPI_DataSize_16b);
    if (!tbuf) {
      dmaRcvBytes(SPI2, rbuf, count, half);
    } else if (!rbuf) {
      dmaTxBytes(SPI2, tbuf, count, half);
    } else {
      dmaExgBytes(SPI2, rbuf, tbuf, count, half);
    }
    SPI_DataSizeConfig(SPI2, SPI_DataSize_8b);
  } else {
    if (half) {
      spiReadWrite16(SPI2, rbuf, tbuf, count, SPI_FAST);
    } else {
      spiReadWrite(SPI2 , rbuf, tbuf ,count , SPI_FAST);
    }
  }
}
float Get_FlowRate(uint8_t uiChannel)
{
  uint16_t uiDataOut;
  uint8_t uiSamplingTime;
  float fVoltageFlow[10];
  fVoltageFlowRate = 0;
  
  if ((SPI2->CR1 & 0x0800) == 0x0000)
  {
    /* 
      if Datasize is equal 8bits, then reconfig to 16 bits
      Reconfig Size Data for DAC 
    */
    SPI_DataSizeConfig(SPI2, SPI_DataSize_16b);
  }
  
  /* Check Channel inpit of signal of ADC IC */
  if (uiChannel == CH0 | uiChannel == OxygenFlowRate)
  {
    uiDataOut = 0xD000;                                                         // Command for ADC channel 0
  }
  else if (uiChannel == CH1 | uiChannel == AirFlowRate)
  {
    uiDataOut = 0xF000;                                                         // Command for ADC channel 1
  }
  
  /* Sampling 10 samples */
  for(uiSamplingTime = 0; uiSamplingTime < 10; uiSamplingTime++)
  {
    /* Part Send data out */
    GPIO_ResetBits(ADC_MCP_NSS_Port, ADC_MCP_NSS_Pin);                          // Set NSS is Low
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI2, 0x01);                                               // Send Start bit (logic '1')
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
    
    /* Enable the Rx buffer not empty interrupt */
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI2, uiDataOut<<1);                                       // Send data out shift left 1
    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
    uiFlowRate = SPI_I2S_ReceiveData(SPI2);                                     // Receive Data from MCP3202
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
    GPIO_SetBits(ADC_MCP_NSS_Port, ADC_MCP_NSS_Pin);                            // Set NSS Pin is High
    
    uiFlowRate = uiFlowRate & 0x0FFF;
    fVoltageFlow[uiSamplingTime] = (uiFlowRate * 5.0)/4096;                     // Convert Digital Value to Voltage 
    
    /* Average  value */
    fVoltageFlowRate = fVoltageFlowRate + fVoltageFlow[uiSamplingTime];
  }
  fVoltageFlowRate = fVoltageFlowRate / (uiSamplingTime + 1);
    
  return fVoltageFlowRate;
  
}
Esempio n. 5
0
int spiReadWrite16(SPI_TypeDef *SPIx, uint16_t *rbuf, const uint16_t *tbuf, int cnt, uint16_t speed) {
  int i;
  SPIx->CR1 = (SPIx->CR1 & ~SPI_BaudRatePrescaler_256) | speed;
  SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);
  if ((cnt > 4) && !(cnt & 3)) {
    i =  xchng_datablock(SPIx, 1, tbuf, rbuf , cnt);
  }
  else {
    for (i = 0; i < cnt; i++){
      SPI_I2S_SendData16(SPIx, tbuf ? *tbuf++ : 0xffff);
      while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
      if (rbuf) {
    *rbuf++ = SPI_I2S_ReceiveData16(SPIx);
      } else {
    SPI_I2S_ReceiveData16(SPIx);
      }
    }
  }
  SPI_DataSizeConfig(SPIx, SPI_DataSize_8b);
  return i;
}
Esempio n. 6
0
/**
  * @brief  Lee vía SPI múltiples datos de 16 bits.
	* @param  SPIx: Especifica el SPI a utilizar.
	* @param  pRData: Especifica el puntero de los datos leídos del dispositivo SPI.
	* @param	pSize: Cantidad de datos que se va a leer.
  * @retval Ninguno.
  */
void SPI_ReadMultiple16(SPI_TypeDef* SPIx, uint16_t* pRData, uint8_t pSize){
	/* SPI - 16 bits data */
	SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);
	
	while(pSize--){
		while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
		/* Fill output buffer with data */
		SPI_I2S_SendData(SPIx, 0xFFFF);
		/* Wait for transmission to complete */
		while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
		/* Return data from buffer */
		*pRData++ = (uint16_t)SPI_I2S_ReceiveData(SPIx);
	}
}
Esempio n. 7
0
/**
  * @brief  Escribe vía SPI un dato de 16 bits.
	* @param  SPIx: Especifica el SPI a utilizar.
	* @param  data: Especifica el dato a enviar.
  * @retval El dato enviado (Si la transmisión es un éxito).
  */
uint16_t SPI_Write16(SPI_TypeDef* SPIx, uint16_t data){
	
	/* SPI - 16 bits data */
	SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);
	
	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
	/* Fill output buffer with data */
	SPI_I2S_SendData(SPIx, data);
	/* Wait for transmission to complete */
	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
	/* Return data from buffer */
	return (uint16_t)SPI_I2S_ReceiveData(SPIx);

}
Esempio n. 8
0
/**
  * @brief  Escribe vía SPI múltiples datos de 8 bits.
	* @param  SPIx: Especifica el SPI a utilizar.
	* @param  pTData: Especifica el puntero de los datos a enviar.
	* @param  pRData: Especifica el puntero de los datos receptados si la transmisión ha sido un éxito.
	* @param	pSize: Cantidad de datos que se va a enviar.
  * @retval Ninguno.
  */
void SPI_WriteMultiple8(SPI_TypeDef* SPIx, const uint8_t* pTData, uint8_t* pRData, uint8_t pSize){
	/* SPI - 8 bits data */
	SPI_DataSizeConfig(SPIx, SPI_DataSize_8b);
	
	while(pSize--){
		while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
		/* Fill output buffer with data */
		SPI_I2S_SendData(SPIx, *pTData++);
		/* Wait for transmission to complete */
		while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
		/* Return data from buffer */
		if(pRData) *pRData++ = (uint8_t)SPI_I2S_ReceiveData(SPIx);
		else SPI_I2S_ReceiveData(SPIx);
	}
}
Esempio n. 9
0
void St7735r::write16(bool is_data, const uint16_t * data, uint16_t length) {

	SPI_DataSizeConfig(_spi.base(), SPI_DataSize_16b );

	_pin_rs.set(is_data ? Bit_SET : Bit_RESET);
	_pin_ss.set(Bit_RESET);
//	_spi.write16(data, length);

	_dma.setMemoryToConf((uint32_t) &data, DMA_MemoryDataSize_HalfWord,
			DMA_MemoryInc_Enable );
	_dma.setTransferToConf(length, DMA_DIR_PeripheralDST);
	_dma.initWithConf();
	_dma.run();

	_pin_ss.set(Bit_SET);
}
Esempio n. 10
0
int spiReadWrite(SPI_TypeDef * SPIx, uint8_t * rbuf, 
                        const uint8_t * tbuf, int cnt, enum spiSpeed speed) 
{
    SPI_DataSizeConfig(SPIx, SPI_DataSize_8b);
    int i;
    SPIx->CR1 = (SPIx->CR1 & ~SPI_BaudRatePrescaler_256) | speeds[speed];
    
    for(i = 0; i < cnt; i++) {
        if(tbuf) {
            SPI_I2S_SendData(SPIx, *tbuf++);
        } else {
            SPI_I2S_SendData(SPIx, 0xff);
        }
        while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
        if(rbuf) {
            *rbuf++ = SPI_I2S_ReceiveData(SPIx);
        } else {
            SPI_I2S_ReceiveData(SPIx);
        }
    }
    return i;
}
Esempio n. 11
0
/* Envía un valor de 16 bits, count veces */
uint16_t SPI_DMA_SendHalfWord(SPI_TypeDef* SPIx, uint16_t value, uint16_t count){
	
	uint16_t dummy = value;
	uint32_t tmp;
	
	/* 16 bits */
	SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);
	
	/* Establece el tamaño de 16 bits al bus de datos a transmitir */
	SPI_DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	SPI_DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	
	/* Configura la dirección del Periférico y la cantidad de bytes a escribir */
	SPI_DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->DR));
	SPI_DMA_InitStruct.DMA_BufferSize = count;
	
	/*********************** TRANSMIT ****************************/
	/* Configura el TX DMA */
	SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_TX; /* Memory to Peripheral */
	SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&dummy;
	SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
	
	/* Clear TX DMA1 FLAG y comienza la transmisión */
	if(SPIx == SPI1){	
		DMA_ClearFlag(SPI1_TX_DMA_CHANNEL_FLAG); /* SPI1 */
		DMA_Init(SPI1_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	else if(SPIx == SPI2){	
		DMA_ClearFlag(SPI2_TX_DMA_CHANNEL_FLAG); /* SPI2 */
		DMA_Init(SPI2_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#if defined(L152RE)
	else{	
		DMA_ClearFlag(SPI3_TX_DMA_CHANNEL_FLAG); /* SPI3 */
		DMA_Init(SPI3_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#endif
	/*************** RECEIVE TO CLEAR BUFFER *****************/
	/* Configura el RX DMA */
	SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_RX; /* Peripheral to Memory */
	SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&tmp;
	SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
	
	/* Clear RX DMA1 FLAG y comienza la transmisión */
	if(SPIx == SPI1){	
		DMA_ClearFlag(SPI1_RX_DMA_CHANNEL_FLAG); /* SPI1 */
		DMA_Init(SPI1_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	else if(SPIx == SPI2){	
		DMA_ClearFlag(SPI2_RX_DMA_CHANNEL_FLAG); /* SPI2 */
		DMA_Init(SPI2_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#if defined(L152RE)
	else{	
		DMA_ClearFlag(SPI3_RX_DMA_CHANNEL_FLAG); /* SPI3 */
		DMA_Init(SPI3_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#endif
	/************************ HABILITACIÓN **************************/
	if(SPIx == SPI1){
		
		DMA_Cmd(SPI1_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI1_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI1_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI1));
	
		DMA_Cmd(SPI1_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI1_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
		
	}
	else if(SPIx == SPI2){
		
		DMA_Cmd(SPI2_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI2_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI2_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI2));
	
		DMA_Cmd(SPI2_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI2_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
		
	}
	#if defined(L152RE)
	else{
		DMA_Cmd(SPI3_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI3_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI3_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI3));
	
		DMA_Cmd(SPI3_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI3_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
	}
	#endif
	return (uint16_t)tmp;
}
Esempio n. 12
0
/* Envía y recibe datos de 8 bits (SPI-DMA) */
uint8_t SPI_DMA_Transmit8(SPI_TypeDef* SPIx, const uint8_t* pTData, uint8_t* pRData, uint16_t pSize){
	uint32_t Dummy = 0xFF;
	
	/* Establece el tamaño de 8 bits al bus de datos a transmitir */
	SPI_DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	SPI_DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	
	/* Configura la dirección del Periférico y la cantidad de bytes a escribir */
	SPI_DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->DR));
	SPI_DMA_InitStruct.DMA_BufferSize = pSize;
	
	/* 8 bits */
	SPI_DataSizeConfig(SPIx, SPI_DataSize_8b);
	
	/*********************** TRANSMIT ****************************/
	/* Configura el TX DMA */
	SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_TX; /* Memory to Peripheral */
	
	if(pTData){
		SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)pTData;
		SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
	}else{
		SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&Dummy;
		SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
	}
	
	/* Clear TX DMA1 FLAG y comienza la transmisión */
	if(SPIx == SPI1){
		DMA_ClearFlag(SPI1_TX_DMA_CHANNEL_FLAG); /* SPI1 */
		DMA_Init(SPI1_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	else if(SPIx == SPI2){	
		DMA_ClearFlag(SPI2_TX_DMA_CHANNEL_FLAG); /* SPI2 */
		DMA_Init(SPI2_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#if defined(L152RE)
	else{	
		DMA_ClearFlag(SPI3_TX_DMA_CHANNEL_FLAG); /* SPI3 */
		DMA_Init(SPI3_TX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#endif
	
	/************************** RECEIVE ****************************/
	/* Configura el RX DMA */
	SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_RX; /* Peripheral to Memory */

	if(pRData){
		SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)pRData;
		SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
	}else{
		SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&Dummy;
		SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
	}
	
	/* Clear RX DMA1 FLAG y comienza la transmisión */
	if(SPIx == SPI1){
		DMA_ClearFlag(SPI1_RX_DMA_CHANNEL_FLAG); /* SPI1 */
		DMA_Init(SPI1_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	else if(SPIx == SPI2){	
		DMA_ClearFlag(SPI2_RX_DMA_CHANNEL_FLAG); /* SPI2 */
		DMA_Init(SPI2_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#if defined(L152RE)
	else{	
		DMA_ClearFlag(SPI3_RX_DMA_CHANNEL_FLAG); /* SPI3 */
		DMA_Init(SPI3_RX_DMA_CHANNEL,&SPI_DMA_InitStruct);
	}
	#endif
	
	/************************ HABILITACIÓN **************************/
	if(SPIx == SPI1){
		DMA_Cmd(SPI1_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI1_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI1_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI1));
	
		DMA_Cmd(SPI1_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI1_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
	}
	else if(SPIx == SPI2){
		DMA_Cmd(SPI2_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI2_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI2_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI2));
	
		DMA_Cmd(SPI2_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI2_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
		
	}
	#if defined(L152RE)
	else{
		DMA_Cmd(SPI3_TX_DMA_CHANNEL,ENABLE);
		DMA_Cmd(SPI3_RX_DMA_CHANNEL,ENABLE);
		
		SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
	
		while ((DMA_GetFlagStatus(SPI3_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI3));
	
		DMA_Cmd(SPI3_TX_DMA_CHANNEL,DISABLE);
		DMA_Cmd(SPI3_RX_DMA_CHANNEL,DISABLE);
		
		CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
	}
	#endif
	
	return 1;
}
Esempio n. 13
0
void CMasterSPIHardware::num_of_bit_set(UI num_of_bit)
{
	SPI_DataSizeConfig(_spi, (num_of_bit - 1) << 8);
}
Esempio n. 14
0
int spi_read_write16(SPI_TypeDef* SPIx,uint16_t *rbuf, const uint16_t *wbuf, int cnt, uint16_t speed) {
	DMA_Channel_TypeDef* DMAy_Channelx_RX=0;
	DMA_Channel_TypeDef* DMAy_Channelx_TX=0;
	uint16_t dummy[] = { 0xFFFF }; /* dummy if rbuf or wbuf empty */
	uint32_t dmaflag;
	int i;

	assert_param(IS_SPI_BAUDRATE_PRESCALER(speed));

	SPIx->CR1 = (SPIx->CR1 & ~SPI_BaudRatePrescaler_256) | speed;
	SPI_DataSizeConfig(SPIx, SPI_DataSize_16b);
	

	if (cnt>4) {
		if (SPIx == SPI1) {
			DMAy_Channelx_RX = DMA1_Channel2;  // see RM0008: Table 78. Summary of DMA1 requests for each channel
			DMAy_Channelx_TX = DMA1_Channel3;  // see RM0008: Table 78. Summary of DMA1 requests for each channel
			if (rbuf) {
				dmaflag = DMA1_FLAG_TC2;
			} else {
				dmaflag = DMA1_FLAG_TC3;
			}
		} else 	if (SPIx == SPI2) {
			DMAy_Channelx_RX = DMA1_Channel4;  // see RM0008: Table 78. Summary of DMA1 requests for each channel
			DMAy_Channelx_TX = DMA1_Channel5;  // see RM0008: Table 78. Summary of DMA1 requests for each channel
			if (rbuf) {
				dmaflag = DMA1_FLAG_TC4;
			} else {
				dmaflag = DMA1_FLAG_TC5;
			}
		}

		DMA_InitTypeDef DMA_InitStructure;

		/* SPIx_Tx_DMA_Channel (triggered by SPIx Rx event) Config */
		DMA_DeInit(DMAy_Channelx_RX);
		DMA_DeInit(DMAy_Channelx_TX);

		DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
		DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->DR));
		DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
		DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
		DMA_InitStructure.DMA_BufferSize = cnt;
		DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
		DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
		DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

		/* RX */
		if (rbuf) {
			DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rbuf;
			DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		} else {
			DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dummy;
			DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
		}
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
		DMA_Init(DMAy_Channelx_RX, &DMA_InitStructure);

		/* TX */
		if (wbuf) {
			DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)wbuf;
			DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		} else {
			DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)dummy;
			DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
		}
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
		DMA_Init(DMAy_Channelx_TX, &DMA_InitStructure);

		/* enable SPIx DMA TX,RX request */
		SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx|SPI_I2S_DMAReq_Rx, ENABLE);

		/* send Buffer */
		DMA_Cmd(DMAy_Channelx_TX, ENABLE);
		DMA_Cmd(DMAy_Channelx_RX, ENABLE);
	
		while (DMA_GetFlagStatus(dmaflag)==RESET);

		/* disable SPIx DMA */
		DMA_Cmd(DMAy_Channelx_TX, DISABLE);
		DMA_Cmd(DMAy_Channelx_RX, DISABLE);

		SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx|SPI_I2S_DMAReq_Rx, DISABLE);
	} else {	
		for (i = 0; i < cnt; i++) {
			while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
			if (wbuf) {
				SPI_I2S_SendData(SPIx, *wbuf++);
			} else {
				SPI_I2S_SendData(SPIx, 0xFF);
			}
			while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET); // Receive buffer not empty flag.
			if (rbuf) {
				*rbuf++ = SPI_I2S_ReceiveData(SPIx);
			} else {
				SPI_I2S_ReceiveData(SPIx); // dump data
			}
		}
	}
	
	return i;
}