/* * Copyright 2016, yichip Semiconductor(shenzhen office) * All Rights Reserved. * * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Yichip Semiconductor; * the contents of this file may not be disclosed to third parties, copied * or duplicated in any form, in whole or in part, without the prior * written permission of Yichip Semiconductor. */ #include "yc11xx_spi.h" #include #include #include "yc11xx_gpio.h" #include "systick.h" #include #include "yc11xx_uart.h" void delay(uint16_t X) { int i,j; for(i=0; i>16); Soft_SPI_Write((addr & 0xff00)>>8); Soft_SPI_Write((addr & 0xff)); GPIO_SetOut(23,1); //拉高CS片选信号线 } //页写入函数 void Soft_SPIFlashPageWrite(uint8_t *Writebuffer, uint32_t Writeaddr, uint16_t NumberbiteToWrite) { GPIO_SetOut(23,0); //拉低CS片选信号线 Soft_SPI_Write(0x06); //写使能指令 GPIO_SetOut(23,1); //拉高CS片选信号线 GPIO_SetOut(23,0); //拉低CS片选信号线 Soft_SPI_Write(0x02); //写页写入指令 Soft_SPI_Write((Writeaddr & 0xff0000)>>16); Soft_SPI_Write((Writeaddr & 0xff00)>>8); Soft_SPI_Write((Writeaddr & 0xff)); if(NumberbiteToWrite > 256) { NumberbiteToWrite = 256; } while(NumberbiteToWrite--) { Soft_SPI_Write(*Writebuffer); Writebuffer++; } GPIO_SetOut(23,1); //拉高CS片选信号线 } //读Flash函数,支持多字节一直读 void Soft_SPIFlashRead(uint8_t *Readbuffer, uint32_t Readaddr, uint16_t NumberbiteToRead) { GPIO_SetOut(23,0); //拉低CS片选信号线 delay(5); Soft_SPI_Write(0x06); //写使能指令 GPIO_SetOut(23,1); //拉高CS片选信号线 GPIO_SetOut(23,0); //拉低CS片选信号线 Soft_SPI_Write(0x03); Soft_SPI_Write((Readaddr & 0xff0000)>>16); Soft_SPI_Write((Readaddr & 0xff00)>>8); Soft_SPI_Write((Readaddr & 0xff)); while(NumberbiteToRead--) { *Readbuffer = Soft_SPI_Read(); Readbuffer++; } GPIO_SetOut(23,1); //拉高CS片选信号线 } uint32_t Soft_SPIFlashIDRead(void) { uint32_t temp; uint8_t temp1,temp2,temp3; GPIO_SetOut(23,0); //拉低CS片选信号线 Soft_SPI_Write(0x9f); temp1=Soft_SPI_Read(); temp2=Soft_SPI_Read(); temp3=Soft_SPI_Read(); printf("temp1=%x\n temp2=%x\n temp3=%x\n",temp1,temp2 ,temp3 ); temp= (temp1 << 16) | (temp2 << 8) | temp3; printf("temp is %x",temp); GPIO_SetOut(23,1); //拉高CS片选信号线 return temp; } //#define YC1121B typedef struct { uint8_t Ctrl; uint8_t Dealy; uint16_t TxLen; uint16_t TxAddr; uint16_t RxAddr; uint16_t RxLen; } Spix_RegDef; void SPI_Init(SPI_InitTypeDef* SPI_InitStruct) { #define SPI_AUTO_INCR_ADDR ((uint8_t)1<<6) register uint16_t SpixCtrl = 0; Spix_RegDef * SpiAdr = NULL; void *Ptr = NULL; /*check parameter*/ _ASSERT(SPI_InitStruct != NULL); _ASSERT(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); _ASSERT(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); _ASSERT(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); _ASSERT(IS_SPI_BAUDSPEED(SPI_InitStruct->SPI_BaudSpeed)); _ASSERT(IS_SPI_TXLen(SPI_InitStruct->SPI_TXLen)); _ASSERT(IS_SPI_RXLen(SPI_InitStruct->SPI_RXlen)); SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); /*set spi control*/ SpixCtrl = SPI_InitStruct->SPI_BaudSpeed | \ SPI_InitStruct->SPI_CPOL | \ SPI_InitStruct->SPI_CPHA | \ SPI_AUTO_INCR_ADDR; HWRITE((uint32_t)&SpiAdr->Ctrl, SpixCtrl); #ifdef YC1121B /*set spi delay between read and write*/ HWRITE((uint32_t)&SpiAdr->Dealy, 0x0a); /*init spi tx buff*/ HW_REG_16BIT((uint32_t)&SpiAdr->TxAddr, 0x4f00); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, 0); /*init spi tx buff*/ HW_REG_16BIT((uint32_t)&SpiAdr->RxAddr, 0x4f80); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 0); #else /*set spi delay between read and write*/ HWRITE((uint32_t)&SpiAdr->Dealy, 0xfa); /*init spi tx buff*/ Ptr = malloc(SPI_InitStruct->SPI_TXLen); HW_REG_16BIT((uint32_t)&SpiAdr->TxAddr,(uint32_t) Ptr); _ASSERT(Ptr != NULL); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, 0); Ptr = NULL; /*init spi tx buff*/ Ptr = malloc(SPI_InitStruct->SPI_RXlen); HW_REG_16BIT((uint32_t)&SpiAdr->RxAddr,(uint32_t) Ptr); _ASSERT(Ptr != NULL); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 0); #endif } void SPI_DeInit(void) { Spix_RegDef * SpiAdr = NULL; SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); free((void *)((uint32_t)SpiAdr->RxAddr)); free((void *)((uint32_t)SpiAdr->TxAddr)); } #define START_SPI_DMA 0x02 //start spi dma #define CHECK_SPI_DMA_DONE 0x40 //check spi dma is done void Spi_SendReceDataToBuff(uint8_t *txdata,int txlen,uint8_t *rxbuf,int rxlen) { volatile int j; HWRITEW(CORE_SPID_TXADDR ,(int)txdata ); HWRITEW(CORE_SPID_TXLEN , txlen); HWRITEW(CORE_SPID_RXADDR , (int)rxbuf); HWRITEW(CORE_SPID_RXLEN , rxlen); HWRITE(CORE_DMA_START , 2); for(j = 0;j < 20;j++); while(!(HREAD(CORE_DMA_STATUS) & 0x40) ); } void SPI_SendData(uint16_t Data) { Spix_RegDef * SpiAdr = NULL; uint8_t * SpiTxPtr = NULL; SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); #ifdef YC1121B SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #else SpiTxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #endif *SpiTxPtr = Data; HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, 1); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 0); HWRITE(CORE_DMA_START, START_SPI_DMA); while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); } uint16_t SPI_ReadRegister(uint16_t RegAdr) { Spix_RegDef * SpiAdr = NULL; uint8_t * SpiRxPtr = NULL; uint8_t * SpiTxPtr = NULL; SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); #ifdef YC1121B SpiRxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->RxAddr)); SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #else SpiRxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->RxAddr)); SpiTxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #endif *SpiTxPtr =RegAdr; HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, 1); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 1); HWRITE(CORE_DMA_START, START_SPI_DMA); while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); return *SpiRxPtr; } void SPI_SendDataFromBuff(uint8_t *Buff, uint16_t Len) { Spix_RegDef * SpiAdr = NULL; uint8_t * SpiTxPtr = NULL; _ASSERT(Len); _ASSERT(Buff != NULL); SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); #ifdef YC1121B SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #else SpiTxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #endif memcpy(SpiTxPtr, Buff, Len); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, Len); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 0); HWRITE(CORE_DMA_START, START_SPI_DMA); while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); } void SPI_SendDataFromBuffWithoutDMAdone(uint8_t *Buff, uint16_t Len) { Spix_RegDef * SpiAdr = NULL; uint8_t * SpiTxPtr = NULL; _ASSERT(Len); _ASSERT(Buff != NULL); SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); #ifdef YC1121B SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #else SpiTxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); #endif memcpy(SpiTxPtr, Buff, Len); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, Len); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, 0); HWRITE(CORE_DMA_START, START_SPI_DMA); // while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); } uint32_t test; void SPI_ReceiveDataToBuff(uint8_t *TxBuff, uint16_t TxLen, uint8_t *RxBuff, uint16_t RxLen) { uint8_t j; Spix_RegDef * SpiAdr = NULL; uint8_t * SpiTxPtr = NULL; uint8_t * SpiRxPtr = NULL; test++; _ASSERT(TxLen); _ASSERT(TxBuff != NULL); _ASSERT(RxBuff != NULL); SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); HWRITE((uint32_t)&SpiAdr->Dealy, 0x8a); #ifdef YC1121B SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); SpiRxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->RxAddr)); #else SpiTxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); SpiRxPtr = (uint8_t *) reg_map_m0(HR_REG_16BIT((uint32_t)&SpiAdr->RxAddr)); #endif memcpy(SpiTxPtr, TxBuff, TxLen); HW_REG_16BIT((uint32_t)&SpiAdr->RxAddr, (uint32_t)RxBuff); HW_REG_16BIT((uint32_t)&SpiAdr->TxAddr, (uint32_t)TxBuff); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, TxLen); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, RxLen); HWRITE(CORE_DMA_START, START_SPI_DMA); for(j = 0;j < 20;j++); while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); memcpy(RxBuff, SpiRxPtr, RxLen); } void SPI_ReceiveDataToBuff2(uint8_t *TxBuff, uint16_t TxLen, uint8_t *RxBuff, uint16_t RxLen) { Spix_RegDef * SpiAdr = NULL; uint8_t * SpiTxPtr = NULL; uint8_t * SpiRxPtr = NULL; _ASSERT(TxLen); _ASSERT(TxBuff != NULL); _ASSERT(RxBuff != NULL); SpiAdr = (Spix_RegDef *)(reg_map(CORE_SPID_CTRL)); HWRITE((uint32_t)&SpiAdr->Dealy, 0x0a); SpiTxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->TxAddr)); SpiRxPtr = (uint8_t *) reg_map(HR_REG_16BIT((uint32_t)&SpiAdr->RxAddr)); // memcpy(SpiTxPtr, TxBuff, TxLen); HW_REG_16BIT((uint32_t)&SpiAdr->RxAddr, (uint32_t)RxBuff); HW_REG_16BIT((uint32_t)&SpiAdr->TxAddr, (uint32_t)TxBuff); HW_REG_16BIT((uint32_t)&SpiAdr->TxLen, TxLen); HW_REG_16BIT((uint32_t)&SpiAdr->RxLen, RxLen); HWRITE(CORE_DMA_START, START_SPI_DMA); // while(!(HREAD(CORE_DMA_STATUS) & CHECK_SPI_DMA_DONE)); // memcpy(RxBuff, SpiRxPtr, RxLen); } bool SPI_WaitDone(void) { if(!(HREAD(CORE_DMA_STATUS) & (CHECK_SPI_DMA_DONE))) { return true; } return false; }