PMD_Status pmdSendSpi(PMD_Chunk* chunk) { calAssertTrue(PMD_isTypeSpi(chunk->pmdIfx)); if (chunk->pmdIfx == ptrIf1) { ptrIf1TxChunk = chunk; HAL_StatusTypeDef status; // Enable the chunk receipt if (SPI_IF1_USE_DMA == 1) { status = HAL_SPI_Transmit_DMA(spiTxHandle, ptrIf1TxChunk->data, CHUNK_LENGTH); } else { status = HAL_SPI_Transmit_IT(spiTxHandle, ptrIf1TxChunk->data, CHUNK_LENGTH); } return halStatusToPmdStatus(status); } return PMD_ERROR; }
/* void hal_nrf_write_multibyte_reg(uint8_t reg, const uint8_t *pbuf, uint8_t length) { uint8_t memtype; uint8_t volatile dummy; memtype = *(uint8_t*)(&pbuf); CSN_LOW(); HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)®, (uint8_t *)&dummy, 1, 5000); if (memtype == 0x00U) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else if (memtype == 0x01U) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else if (memtype == 0xFEU) { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } else { const uint8_t *buf = (const uint8_t *)pbuf; NRF_WRITE_MULTIBYTE_REG_COMMON_BODY } CSN_HIGH(); } */ void hal_nrf_write_multibyte_reg(uint8_t reg, const uint8_t *pbuf, uint8_t length) { uint8_t *p = (uint8_t *)pbuf; while(SPI_busy); //waiting last tx finished while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY); CSN_LOW(); HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)®, spi_rx, 1, 5000); // address if( (uint32_t)pbuf < 0x20000000 ){ while(1); } if(HAL_SPI_Transmit_DMA(&SpiHandle, (uint8_t *)pbuf, length) != HAL_OK) //32 bytes data { while(1); PRINTF("SPI DMA ERROR\r\n") } SPI_busy = true; /*while(length--){ if(HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t *)p++, (uint8_t *)dummy, 1, 5000) != HAL_OK) { PRINTF("SPI DMA ERROR\r\n") } soft_delay(100); }*/ #ifdef DEBUG_NRF PRINTF("SPI DMA started") #endif /* CSN_HIGH(); #ifdef DEBUG_NRF PRINTF("SPI DMA finished") #endif */ }
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size) { SPI_HandleTypeDef* hspi = &spiHandle[spiDeviceByInstance(Instance)].Handle; DMA_HandleTypeDef* hdma = &dmaHandle[spiDeviceByInstance(Instance)].Handle; hdma->Instance = Stream; hdma->Init.Channel = Channel; hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; hdma->Init.PeriphInc = DMA_PINC_DISABLE; hdma->Init.MemInc = DMA_MINC_ENABLE; hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma->Init.Mode = DMA_NORMAL; hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; hdma->Init.PeriphBurst = DMA_PBURST_SINGLE; hdma->Init.MemBurst = DMA_MBURST_SINGLE; hdma->Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_DeInit(hdma); HAL_DMA_Init(hdma); __HAL_DMA_ENABLE(hdma); __HAL_SPI_ENABLE(hspi); /* Associate the initialized DMA handle to the spi handle */ __HAL_LINKDMA(hspi, hdmatx, (*hdma)); // DMA TX Interrupt dmaSetHandler(DMA2_ST1_HANDLER, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)spiDeviceByInstance(Instance)); // SCB_CleanDCache_by_Addr((uint32_t) pData, Size); HAL_SPI_Transmit_DMA(hspi, pData, Size); //HAL_DMA_Start(&hdma, (uint32_t) pData, (uint32_t) &(Instance->DR), Size); return hdma; }
int writetospi_dma ( uint16 headerLength, const uint8 *headerBuffer, uint32 bodylength, const uint8 *bodyBuffer ) { int stat ; #ifdef SAFE_DMA_AND_BUFF if ((headerLength + bodylength) > MAX_DMABUF_SIZE) { return DWT_ERROR; } #endif stat = decamutexon() ; memcpy(&tmp_buf[0], headerBuffer, headerLength); memcpy(&tmp_buf[headerLength], bodyBuffer, bodylength); port_SPI3_set_chip_select(); HAL_SPI_Transmit_DMA(&hspi3, tmp_buf, headerLength+bodylength); while(DMA_TX_CH->NDTR !=0); //pool until last clock from SPI_RX while((SPI3->SR & (1 << 1)) == 0); // wait while TXE flag is 0 (TX is not empty) //while((SPI3->SR & (1 << 7)) != 0); // wait while BSY flag is 1 (SPI is busy) port_SPI3_clear_chip_select(); //PORT_SPI_SET_CS_FAST decamutexoff(stat); return DWT_SUCCESS; }
//void spi_postSpi2Semaphore(void) //{ // // post (make available) spi2 semaphore // // spi2Semaphore = 1; //} void spi_readWrite(SPI_HandleTypeDef SpiH, uint8_t* rxBuf, uint8_t* txBuf, int cnt) { //HAL_SPI_TransmitReceive(&SpiHandle, txBuf, rxBuf, cnt, 1000); //HAL_SPI_Transmit(&SpiHandle, txBuf, cnt, 1); HAL_SPI_Transmit_DMA(&SpiHandle, txBuf, cnt); // //High, second edge // //We're going to bitbang it for now, I guess // HAL_GPIO_WritePin(SPI1_SCK.port, SPI1_SCK.pin, 0); // HAL_GPIO_WritePin(LCD_NSS.port, LCD_NSS.pin, 0); // int i, j; // for(i = 0; i < cnt; i++) // { // for(j = 0; j < 8; j++) // { // HAL_GPIO_WritePin(SPI1_MOSI.port, SPI1_MOSI.pin, (txBuf[i] >> (7 - j)) & 1); // HAL_GPIO_WritePin(SPI1_SCK.port, SPI1_SCK.pin, 0); // HAL_GPIO_WritePin(SPI1_SCK.port, SPI1_SCK.pin, 1); // } // } // HAL_GPIO_WritePin(LCD_NSS.port, LCD_NSS.pin, 1); }
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size) { SPIDevice device = spiDeviceByInstance(Instance); spiHardwareMap[device].hdma.Instance = Stream; spiHardwareMap[device].hdma.Init.Channel = Channel; spiHardwareMap[device].hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; spiHardwareMap[device].hdma.Init.PeriphInc = DMA_PINC_DISABLE; spiHardwareMap[device].hdma.Init.MemInc = DMA_MINC_ENABLE; spiHardwareMap[device].hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; spiHardwareMap[device].hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; spiHardwareMap[device].hdma.Init.Mode = DMA_NORMAL; spiHardwareMap[device].hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; spiHardwareMap[device].hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; spiHardwareMap[device].hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; spiHardwareMap[device].hdma.Init.MemBurst = DMA_MBURST_SINGLE; spiHardwareMap[device].hdma.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_DeInit(&spiHardwareMap[device].hdma); HAL_DMA_Init(&spiHardwareMap[device].hdma); __HAL_DMA_ENABLE(&spiHardwareMap[device].hdma); __HAL_SPI_ENABLE(&spiHardwareMap[device].hspi); /* Associate the initialized DMA handle to the spi handle */ __HAL_LINKDMA(&spiHardwareMap[device].hspi, hdmatx, spiHardwareMap[device].hdma); // DMA TX Interrupt dmaSetHandler(spiHardwareMap[device].dmaIrqHandler, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)device); //HAL_CLEANCACHE(pData,Size); // And Transmit HAL_SPI_Transmit_DMA(&spiHardwareMap[device].hspi, pData, Size); return &spiHardwareMap[device].hdma; }
void processCommand(){ uint32_t lengthTxData = 0; uint32_t addr = 0; uint32_t i; uint32_t temp; //At minimun resent length of trame and command name (minimun header) //Data_buffer_Transmit[0] = 0; //Low byte of length set in sendAndWaitIfNotReadyAndValidCommand before send //Data_buffer_Transmit[1] = 0; // High byte of length set in sendAndWaitIfNotReadyAndValidCommand before send Data_buffer_Transmit[2] = rx_raw_Frame[2]; //at minimum, answer is Low byte of command Data_buffer_Transmit[3] = rx_raw_Frame[3]; //at minimum, answer is Hight byte of command switch (lowHighByteToInt(rx_raw_Frame[2],rx_raw_Frame[3]) ){ case FPGA_COMMAND : receiveRawDataFromFPGABySPI[2] = LOBYTE(FPGA_DATA); receiveRawDataFromFPGABySPI[3] = HIBYTE(FPGA_DATA); HAL_SPI_Receive_DMA(&hspi1, *(&receiveRawDataFromFPGABySPI) + 4, 8186 ); //Offset + 4 lenght & command type lengthTxData = lowHighByteToInt(rx_raw_Frame[0],rx_raw_Frame[1]); //resend same length to receive the answer of SPI COMMAND //Cs low to start spi HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,0); HAL_SPI_Transmit_DMA(&hspi3,*(&rx_raw_Frame)+4, lengthTxData-4); break; case LOOPBACK : //Copy frame in tx buffer to send the same thing just a loopback for testing purpose memcpy (Data_buffer_Transmit,rx_raw_Frame,rx_raw_FrameLen); mustValidCommandAfterSend = 1; sendUSB(Data_buffer_Transmit,rx_raw_FrameLen); //endProcessCommandAllowReceiveAgain(); //sendAndWaitIfNotReady(rx_raw_FrameLen); break; case LED1 : Data_buffer_Transmit[4] = rx_raw_Frame[4]; //resend value of led lengthTxData = 4+1; //increment length because send a value of led HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,rx_raw_Frame[4] & 1 ); //Change value of led //sendAndWaitIfNotReadyAndValidCommand(lengthTxData); //If you don't want answer just endProcessCommandAllowReceiveAgain(); break; case LED2 : Data_buffer_Transmit[4] = rx_raw_Frame[4] ; //resend value of led lengthTxData = 4 + 1; //increment length because send a value of led HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,rx_raw_Frame[4] & 1 );//Change value of led //sendAndWaitIfNotReadyAndValidCommand(lengthTxData); //If you don't want answer just endProcessCommandAllowReceiveAgain(); break; case START_FPGA : HAL_SPI_DeInit(&hspi2); //Nce FPGA enable HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,0); //short pulse nconfig on release reconfigure fpga //HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,0); Delay(1000); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,1); Delay(5000); //Restart SPI1 to receive data from FPGA __SPI1_RELEASE_RESET(); MX_SPI1_Init(); endProcessCommandAllowReceiveAgain(); break; case STOP_FPGA : //Stop SPI1 ( receive data from FPGA) //To avoid some problem, when reset fpga (upload) 100ns pulse generate fake edge and shift (1bit) the reveived data __SPI1_FORCE_RESET(); //HAL_SPI_MspDeInit(&hspi1); //Nce FPGA disable HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,1); //nconfig on release reconfigure fpga HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,0); Delay(5000); //wait to be sure that the fpga was stopped MX_SPI2_Init(); sFLASH_READID(); //Must read ID to wake up the memory Delay(5000); //HAL_SPI_MspInit(&hspi1); endProcessCommandAllowReceiveAgain(); break; case ERASE_FIRMWARE : Data_buffer_Transmit[4] = 1; lengthTxData = 4 + 1; //increment length because send a value (1=ok) //sFLASH_ERASE_BULK(); //slow replaced by just erasing 2 sectors sFLASH_ERASE(); mustValidCommandAfterSend = 1; sendUSB(Data_buffer_Transmit,lengthTxData); break; case READ_PAGE_FIRMWARE : if (rx_raw_Frame[6] <= 31) {//Just check number of page if not less than 31 do nothing lengthTxData = (uint32_t)rx_raw_Frame[6] * 256; Data_buffer_Transmit[4] = rx_raw_Frame[4]; //low byte Number of the first page Data_buffer_Transmit[5] = rx_raw_Frame[5]; //high byte Number of the first page Data_buffer_Transmit[6] = rx_raw_Frame[6]; //Nb of page addr=lowHighByteToInt(rx_raw_Frame[4],rx_raw_Frame[5])*256; sFLASH_Read(*(&Data_buffer_Transmit)+7,addr,lengthTxData); mustValidCommandAfterSend = 1; sendUSB(Data_buffer_Transmit,lengthTxData+7); }else{ Data_buffer_Transmit[2] = LOBYTE(COMMAND_NOT_FOUND); Data_buffer_Transmit[3] = HIBYTE(COMMAND_NOT_FOUND); mustValidCommandAfterSend = 1; sendUSB(Data_buffer_Transmit,4); } break; case WRITE_PAGE_FIRMWARE : //Data_buffer_Transmit[4] = rx_raw_Frame[4]; //low byte Number of the first page //Data_buffer_Transmit[5] = rx_raw_Frame[5]; //high byte Number of the first page //Data_buffer_Transmit[6] = rx_raw_Frame[6]; //Nb of page (31 max) addr=lowHighByteToInt(rx_raw_Frame[4],rx_raw_Frame[5])*256; for (int i=0;i< rx_raw_Frame[6];i++){ sFLASH_WritePage(*(&rx_raw_Frame)+7+i*256,addr+i*256,256); } endProcessCommandAllowReceiveAgain(); break; case GET_VERSION_NUMBER : lengthTxData = 18; memcpy(&Data_buffer_Transmit[4],&versionNumber,lengthTxData); mustValidCommandAfterSend = 1; sendUSB(Data_buffer_Transmit,lengthTxData+4); break; default: //mustValidCommandAfterSend = 1; //sendAndWaitIfNotReady(lengthTxData); //If you don't want answer just endProcessCommandAllowReceiveAgain(); } }
static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { HAL_StatusTypeDef state; rt_size_t message_length, already_send_length; rt_uint16_t send_length; rt_uint8_t *recv_buf; const rt_uint8_t *send_buf; RT_ASSERT(device != RT_NULL); RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus->parent.user_data != RT_NULL); RT_ASSERT(message != RT_NULL); struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus); SPI_HandleTypeDef *spi_handle = &spi_drv->handle; struct stm32_hw_spi_cs *cs = device->parent.user_data; if (message->cs_take) { HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET); } LOG_D("%s transfer prepare and start", spi_drv->config->bus_name); LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d", spi_drv->config->bus_name, (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length); message_length = message->length; recv_buf = message->recv_buf; send_buf = message->send_buf; while (message_length) { /* the HAL library use uint16 to save the data length */ if (message_length > 65535) { send_length = 65535; message_length = message_length - 65535; } else { send_length = message_length; message_length = 0; } /* calculate the start address */ already_send_length = message->length - send_length - message_length; send_buf = (rt_uint8_t *)message->send_buf + already_send_length; recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length; /* start once data exchange in DMA mode */ if (message->send_buf && message->recv_buf) { if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)) { state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length); } else { state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length, 1000); } } else if (message->send_buf) { if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) { state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length); } else { state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, 1000); } } else { memset((uint8_t *)recv_buf, 0xff, send_length); if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG) { state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length); } else { state = HAL_SPI_Receive(spi_handle, (uint8_t *)recv_buf, send_length, 1000); } } if (state != HAL_OK) { LOG_I("spi transfer error : %d", state); message->length = 0; spi_handle->State = HAL_SPI_STATE_READY; } else { LOG_D("%s transfer done", spi_drv->config->bus_name); } /* For simplicity reasons, this example is just waiting till the end of the transfer, but application may perform other tasks while transfer operation is ongoing. */ while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY); } if (message->cs_release) { HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET); } return message->length; }