#include "hal_spi.h" #include "hc32_ll_dma.h" #include "hc32_ll_aos.h" #include "hc32_ll_interrupts.h" void bsp_spi_init(void); void bsp_spi_deinit(void); void bsp_spi_active(void); void bsp_spi_inactive(void); int32_t bsp_spi_trans(const uint8_t *pu8TxBuf, uint32_t u32Size); int32_t bsp_spi_receive(uint8_t *pu8RxBuf, uint32_t u32Size); /******************************************************************************* * Local variable definitions ('static') ******************************************************************************/ stc_w25qxx_ll_t m_stcW25qxxLL = { .Delay = DDL_DelayMS, .Init = bsp_spi_init, .DeInit = bsp_spi_deinit, .Active = bsp_spi_active, .Inactive = bsp_spi_inactive, .Trans = bsp_spi_trans, .Receive = bsp_spi_receive, }; void bsp_spi_active(void) { BSP_SPI_CS_ACTIVE(); } void bsp_spi_inactive(void) { BSP_SPI_CS_INACTIVE(); } void bsp_spi_init(void) { stc_gpio_init_t stcGpioInit; stc_spi_init_t stcSpiInit; stc_spi_delay_t stcSpiDelayCfg; // (void)GPIO_StructInit(&stcGpioInit); // stcGpioInit.u16PinDrv = PIN_HIGH_DRV; // (void)GPIO_Init(BSP_SPI_SCK_PORT, BSP_SPI_SCK_PIN, &stcGpioInit); // (void)GPIO_Init(BSP_SPI_MOSI_PORT, BSP_SPI_MOSI_PIN, &stcGpioInit); // (void)GPIO_Init(BSP_SPI_MISO_PORT, BSP_SPI_MISO_PIN, &stcGpioInit); // // GPIO_SetDebugPort(GPIO_PIN_TDI, DISABLE); // stcGpioInit.u16PinDir = PIN_DIR_OUT; // stcGpioInit.u16PinState = PIN_STAT_SET; // (void)GPIO_Init(BSP_SPI_CS_PORT, BSP_SPI_CS_PIN, &stcGpioInit); GPIO_SetDebugPort(GPIO_PIN_TDI, DISABLE); GPIO_SetFunc(BSP_SPI_CS_PORT, BSP_SPI_CS_PIN, BSP_SPI_CS_PIN_FUNC); GPIO_SetFunc(BSP_SPI_SCK_PORT, BSP_SPI_SCK_PIN, BSP_SPI_SCK_PIN_FUNC); GPIO_SetFunc(BSP_SPI_MOSI_PORT, BSP_SPI_MOSI_PIN, BSP_SPI_MOSI_PIN_FUNC); GPIO_SetFunc(BSP_SPI_MISO_PORT, BSP_SPI_MISO_PIN, BSP_SPI_MISO_PIN_FUNC); /* Clear initialize structure */ (void)SPI_StructInit(&stcSpiInit); (void)SPI_DelayStructInit(&stcSpiDelayCfg); /* Configure peripheral clock */ FCG_Fcg1PeriphClockCmd(BSP_SPI_PERIPH_CLK, ENABLE); /* SPI De-initialize */ SPI_DeInit(BSP_SPI_UNIT); /* Configuration SPI structure */ stcSpiInit.u32WireMode = SPI_4_WIRE; stcSpiInit.u32TransMode = SPI_FULL_DUPLEX; stcSpiInit.u32MasterSlave = SPI_MASTER; stcSpiInit.u32ModeFaultDetect = SPI_MD_FAULT_DETECT_DISABLE; stcSpiInit.u32Parity = SPI_PARITY_INVD; stcSpiInit.u32SpiMode = SPI_MD_0; stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV4; stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT; stcSpiInit.u32FirstBit = SPI_FIRST_MSB; (void)SPI_Init(BSP_SPI_UNIT, &stcSpiInit); stcSpiDelayCfg.u32IntervalDelay = SPI_INTERVAL_TIME_8SCK; stcSpiDelayCfg.u32ReleaseDelay = SPI_RELEASE_TIME_8SCK; stcSpiDelayCfg.u32SetupDelay = SPI_SETUP_TIME_1SCK; (void)SPI_DelayTimeConfig(BSP_SPI_UNIT, &stcSpiDelayCfg); SPI_Cmd(BSP_SPI_UNIT, ENABLE); // stc_spi_init_t stcSpiInit; // /* Configure Port */ // GPIO_SetFunc(BSP_SPI_CS_PORT, BSP_SPI_CS_PIN, BSP_SPI_CS_PIN_FUNC); // GPIO_SetFunc(BSP_SPI_SCK_PORT, BSP_SPI_SCK_PIN, BSP_SPI_SCK_PIN_FUNC); // GPIO_SetFunc(BSP_SPI_MOSI_PORT, BSP_SPI_MOSI_PIN, BSP_SPI_MOSI_PIN_FUNC); // GPIO_SetFunc(BSP_SPI_MISO_PORT, BSP_SPI_MISO_PIN, BSP_SPI_MISO_PIN_FUNC); // /* Configuration SPI */ // FCG_Fcg1PeriphClockCmd(BSP_SPI_PERIPH_CLK, ENABLE); // SPI_StructInit(&stcSpiInit); // stcSpiInit.u32WireMode = SPI_4_WIRE; // stcSpiInit.u32TransMode = SPI_FULL_DUPLEX; // stcSpiInit.u32MasterSlave = SPI_MASTER; // stcSpiInit.u32Parity = SPI_PARITY_INVD; // stcSpiInit.u32SpiMode = SPI_MD_0; // stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV96; // stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT; // stcSpiInit.u32FirstBit = SPI_FIRST_MSB; // stcSpiInit.u32FrameLevel = SPI_1_FRAME; // (void)SPI_Init(BSP_SPI_UNIT, &stcSpiInit); // SPI_Cmd(BSP_SPI_UNIT, ENABLE); } void bsp_spi_deinit(void) { /* SPI De-initialize */ SPI_DeInit(BSP_SPI_UNIT); } int32_t bsp_spi_trans(const uint8_t *pu8TxBuf, uint32_t u32Size) { return SPI_Trans(BSP_SPI_UNIT, pu8TxBuf, u32Size, BSP_SPI_TIMEOUT); } int32_t bsp_spi_receive(uint8_t *pu8RxBuf, uint32_t u32Size) { return SPI_Receive(BSP_SPI_UNIT, pu8RxBuf, u32Size, BSP_SPI_TIMEOUT); } void bsp_w25qxx_init(void) { (void)W25QXX_Init(&m_stcW25qxxLL); } void BSP_W25QXX_DeInit(void) { (void)W25QXX_DeInit(&m_stcW25qxxLL); } int32_t BSP_W25QXX_Write(uint32_t u32Addr, const uint8_t *pu8Data, uint32_t u32NumByteToWrite) { uint32_t u32TempSize; uint32_t u32AddrOfst = 0UL; int32_t i32Ret = LL_ERR_INVD_PARAM; DDL_ASSERT((u32Addr + u32NumByteToWrite) <= W25Q64_MAX_ADDR); if ((pu8Data != NULL) && (u32NumByteToWrite > 0UL)) { while (u32NumByteToWrite != 0UL) { if (u32NumByteToWrite >= W25Q64_PAGE_SIZE) { u32TempSize = W25Q64_PAGE_SIZE; } else { u32TempSize = u32NumByteToWrite; } i32Ret = W25QXX_PageProgram(&m_stcW25qxxLL, u32Addr, (const uint8_t *)&pu8Data[u32AddrOfst], u32TempSize); if (i32Ret != LL_OK) { break; } u32NumByteToWrite -= u32TempSize; u32AddrOfst += u32TempSize; u32Addr += u32TempSize; } } return i32Ret; } 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_PageProgram(&m_stcW25qxxLL,WriteAddr,pBuffer,NumByteToWrite); if(NumByteToWrite==pageremain)break;//写入结束了 else //NumByteToWrite>pageremain { pBuffer+=pageremain; WriteAddr+=pageremain; NumByteToWrite-=pageremain; //减去已经写入了的字节数 if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节 else pageremain=NumByteToWrite; //不够256个字节了 } } } uint8_t flash_data_buffer[4096]; void spi_flash_write(uint32_t WriteAddr,uint8_t* pBuffer,uint16_t NumByteToWrite) { uint32_t secpos; uint16_t secoff; uint16_t secremain; uint16_t i; secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16 secoff=WriteAddr%4096;//在扇区内的偏移 secremain=4096-secoff;//扇区剩余空间大小 if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节 while(1) { BSP_W25QXX_Read(secpos*4096,flash_data_buffer,4096); for(i=0;i4096)secremain=4096; //下一个扇区还是写不完 else secremain=NumByteToWrite; //下一个扇区可以写完了 } } } int32_t spi_flash_read(uint32_t u32Addr, uint8_t *pu8Data, uint32_t u32NumByteToRead) { DDL_ASSERT((u32Addr + u32NumByteToRead) <= W25Q64_MAX_ADDR); return W25QXX_ReadData(&m_stcW25qxxLL, u32Addr, pu8Data, u32NumByteToRead); } int32_t BSP_W25QXX_Read(uint32_t u32Addr, uint8_t *pu8Data, uint32_t u32NumByteToRead) { DDL_ASSERT((u32Addr + u32NumByteToRead) <= W25Q64_MAX_ADDR); return W25QXX_ReadData(&m_stcW25qxxLL, u32Addr, pu8Data, u32NumByteToRead); } int32_t BSP_W25QXX_EraseSector(uint32_t u32Addr) { DDL_ASSERT(u32Addr < W25Q64_MAX_ADDR); return W25QXX_EraseSector(&m_stcW25qxxLL, u32Addr); } int32_t BSP_W25QXX_EraseChip(void) { return W25QXX_EraseChip(&m_stcW25qxxLL); }