uint8_t SPI_TransRecieve(uint8_t data){ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_SendData8(SPI1,data); // while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_ReceiveData8(SPI1); SPI_I2S_ClearFlag(SPI1, SPI_I2S_FLAG_RXNE); }
void Init_SPI3(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI3); GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI3); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); SPI_I2S_DeInit(SPI3); /* SPI3 ----------------------------------------------------*/ 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_16; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI3, &SPI_InitStructure); //SPI_SSOutputCmd(SPI3,ENABLE); //исправить на ENABLE SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE); SPI_Cmd(SPI3, ENABLE); //SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSSInternalSoft_Set); // не мультимастерная топология NVIC_EnableIRQ(SPI3_IRQn); //прерывания от SPI }
/** \brief read [size] byte from [offset] to [buffer] * * \param offset uint32_t unit : byte * \param buffer uint8_t* * \param size uint32_t unit : byte * \return uint32_t byte for read * */ uint32_t sst25vfxx_read(uint32_t offset,uint8_t * buffer,uint32_t size) { uint32_t index; spi_lock(); spi_config(); //CS_LOW(); spi_readwrite( CMD_WRDI ); //CS_HIGH(); //CS_LOW(); spi_readwrite( CMD_READ); spi_readwrite( offset>>16 ); spi_readwrite( offset>>8 ); spi_readwrite( offset ); #if SPI_FLASH_USE_DMA for(index=0; index<size/DMA_BUFFER_SIZE; index++) { DMA_RxConfiguration((rt_uint32_t)_spi_flash_buffer, DMA_BUFFER_SIZE); SPI_I2S_ClearFlag(SPI1, SPI_I2S_FLAG_RXNE); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE); while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET); SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE); rt_memcpy(buffer,_spi_flash_buffer,DMA_BUFFER_SIZE); buffer += DMA_BUFFER_SIZE; } #else for(index=0; index<size; index++) { *buffer++ = spi_readwrite(0xFF); } #endif //CS_HIGH(); spi_unlock(); return size; }
void spi_txrx(uint8_t* bufTx, uint8_t lenbufTx, spi_return_t returnType, uint8_t* bufRx, uint8_t maxLenBufRx, spi_first_t isFirst, spi_last_t isLast) { #ifdef SPI_IN_INTERRUPT_MODE // disable interrupts NVIC_RESETPRIMASK(); #endif // register spi frame to send spi_vars.pNextTxByte = bufTx; spi_vars.numTxedBytes = 0; spi_vars.txBytesLeft = lenbufTx; spi_vars.returnType = returnType; spi_vars.pNextRxByte = bufRx; spi_vars.maxRxBytes = maxLenBufRx; spi_vars.isFirst = isFirst; spi_vars.isLast = isLast; // SPI is now busy spi_vars.busy = 1; // lower CS signal to have slave listening if (spi_vars.isFirst==SPI_FIRST) { GPIO_ResetBits(GPIOA, GPIO_Pin_4); } #ifdef SPI_IN_INTERRUPT_MODE // implementation 1. use a callback function when transaction finishes // write first byte to TX buffer SPI_I2S_SendData(SPI2,*spi_vars.pNextTxByte); // re-enable interrupts NVIC_SETPRIMASK(); #else // implementation 2. busy wait for each byte to be sent // send all bytes while (spi_vars.txBytesLeft>0) { // write next byte to TX buffer SPI_I2S_SendData(SPI2,*spi_vars.pNextTxByte); // busy wait on the interrupt flag while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET); // clear the interrupt flag SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_RXNE); // save the byte just received in the RX buffer switch (spi_vars.returnType) { case SPI_FIRSTBYTE: if (spi_vars.numTxedBytes==0) { *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI2); } break; case SPI_BUFFER: *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI2); spi_vars.pNextRxByte++; break; case SPI_LASTBYTE: *spi_vars.pNextRxByte = SPI_I2S_ReceiveData(SPI2); break; } // one byte less to go spi_vars.pNextTxByte++; spi_vars.numTxedBytes++; spi_vars.txBytesLeft--; } // put CS signal high to signal end of transmission to slave if (spi_vars.isLast==SPI_LAST) { GPIO_SetBits(GPIOA, GPIO_Pin_4); } // SPI is not busy anymore spi_vars.busy = 0; #endif }