替换掉NO_OS逻辑和代码中的SPI部分

本文介绍了一种针对AD9361的SPI接口设计,详细阐述了如何使用状态机实现SPI读写操作,以及如何将此设计移植到NO-OS环境下,减少对ZYNQ硬件外设的依赖,实现代码的可移植性。

在纯粹逻辑的配置中我写一个外设,进行SPI接口的读写。几乎是跟AD9361定制的SPI接口:发送三个字节,接收到一个字节。这个小控制器为了简单,只实现对一个AD9361寄存器的读写。我打算将这个一直到NO-OS那套软件硬件代码里面这样减少对ZYNQ硬件外设的依赖,使得这套C代码更容易移植。

关于AD9361中SPI的时序,在接口手册上明确写了,并给出了波形和时序。

这里贴出来部分这个控制器的部分VERILOG代码:



module spi_ad9361_if#(parameter cnt_bit=2)(
        input clk,rst,
        output reg spi_mosi,spi_clk,spi_csn,
        input spi_miso,
        input [23:0] din,
        output reg [7:0] dout=0 ,
        input valid ,
        output reg  ready
    );  
 

                
    initial {spi_mosi,spi_clk,spi_csn,ready} = 0 ;
    reg [7:0]st = 0 ;
    wire is_delay_state =1;
    reg [1:0]  c = 0 ;always @ (posedge clk) if (is_delay_state) c<=c+1;else c<=0;
    wire sync =  c == 2'b11 ;

    reg [23:0]  reg24=0 ;
    reg [7:0]   reg8=0;

    always@(posedge clk)if (rst)st<=0;else
    case (st)
        0  : begin st <= 1 ;  ready<=0;  spi_csn<=1;  spi_clk<=0; end
        1  : if (valid)begin st<=2;  ready<=0;end
        2  : begin reg24<=din ; st <= 100 ;end
        100 : if (sync) begin st <= 200; spi_csn<=0;spi_clk<=0; end //spi_csn=0;
        200 : if (sync) begin st <= 201 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  201 : if (sync) begin st <= 202 ; spi_clk<=0;           end  // bit 23
        202 : if (sync) begin st <= 203 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  203 : if (sync) begin st <= 204 ; spi_clk<=0;           end  // bit 22
        204 : if (sync) begin st <= 205 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  205 : if (sync) begin st <= 206 ; spi_clk<=0;           end  // bit 21
        206 : if (sync) begin st <= 207 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  207 : if (sync) begin st <= 208 ; spi_clk<=0;           end  // bit 20
        208 : if (sync) begin st <= 209 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  209 : if (sync) begin st <= 210 ; spi_clk<=0;           end  // bit 19
        210 : if (sync) begin st <= 211 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  211 : if (sync) begin st <= 212 ; spi_clk<=0;           end  // bit 18
 //此处删节
        240 : if (sync) begin st <= 241 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  241 : if (sync) begin st <= 242 ; spi_clk<=0; reg8[3] <= spi_miso;   end  // bit 3
        242 : if (sync) begin st <= 243 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  243 : if (sync) begin st <= 244 ; spi_clk<=0; reg8[2] <= spi_miso;   end  // bit 2
        244 : if (sync) begin st <= 245 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  245 : if (sync) begin st <= 246 ; spi_clk<=0; reg8[1] <= spi_miso;   end  // bit 1
        246 : if (sync) begin st <= 247 ; spi_clk<=1;   spi_mosi<=reg24[23];      reg24[23:0]<={reg24[23:0],1'b0} ;    end  247 : if (sync) begin st <= 248 ; spi_clk<=0; reg8[0] <= spi_miso;   end  // bit 0
        248 : if (sync) begin st <= 249 ; spi_csn<=1;       end
        249 : if (sync) begin st <= 250 ;       end
        250 : begin st<=251;ready<=1;dout<=reg8;end
        251 : st<=1;
        default st <= 0 ;
    endcase

endmodule

 

很显然这是一个聪明人用本办法写的状态机。运行效果非常好。

做成AXI_LITE接口时候顺便加上了其他一些对外AD9361控制的信号,不使用情况下可以悬空就行。

这里的控制也非常简洁。对应操作这部分SPI控制器的代码如下:


#define CFG_SPI_ACC_ADDR  0X43C00000

unsigned char cfg_spi_acc(unsigned int cmd){ //added by liwei
unsigned int r;
*(volatile unsigned int * ) CFG_SPI_ACC_ADDR = cmd ;
while(1){
	r = *(volatile unsigned int * )CFG_SPI_ACC_ADDR ;
	if (r&(1<<31))break;
}
return r&0xff ;
}

这里读和写都是这个函数。执行写操作时候,忽略返回数值就可以。

 

 

接下来我们看SDK项目里面要移植的接口部分。

 

我们先实现通过此SPI控制器对单个AD9361寄存器的读写实现:


/**
 * SPI register read.
 * @param spi
 * @param reg The register address.
 * @return The register value or negative error code in case of failure.
 */
int32_t ad9361_spi_read(struct spi_device *spi, uint32_t reg)
{
    unsigned int cmd ;
    cmd = AD_READ | AD_CNT(1) | AD_ADDR(reg);
    cmd<<=8;
    return  0xff & cfg_spi_acc(cmd);
}

 


/**
 * SPI register write.
 * @param spi
 * @param reg The register address.
 * @param val The value of the register.
 * @return 0 in case of success, negative error code otherwise.
 */
int32_t ad9361_spi_write(struct spi_device *spi,
			 uint32_t reg, uint32_t val)
{

	int32_t  cmd;

	cmd = AD_WRITE | AD_CNT(1) | AD_ADDR(reg);
	cmd <<=8;
	cmd |= val&0xff;

	if (reg==6)	printf("lw:reg[%d]=0x%02x\n",reg,(unsigned char )val);
	if (reg==7)	printf("lw:reg[%d]=0x%02x\n",reg,(unsigned char )val);

cfg_spi_acc(cmd);

#ifdef _DEBUG
	dev_dbg(&spi->dev, "%s: reg 0x%"PRIX32" val 0x%X", __func__, reg, buf[2]);
#endif

	return 0;
}

移植后的代码非常简洁明了。

 

原来的SDK代码里面实现了连续对多个寄存器进行读写,而我们这里只有对一个寄存进行读写的控制器外设,所以要现在C语言层面把对多个寄存器进行读写的代码转换成调用对一个寄存器进行读写的实现。

读9316的接口文档,可以看到关于连续多寄存器写的描述。在我们采用的是MSB方式先(就是SPI 先传输字节的最高位 Most Signifiaenr Bit )的情况下 ,寄存器地址是递减的,如果要写从8开始的三个寄存器,就是依次写8,7,6。这点一定注意!

 

/**
 * SPI multiple bytes register write.
 * @param spi
 * @param reg The register address.
 * @param tbuf The data buffer.
 * @param num The number of bytes to read.
 * @return 0 in case of success, negative error code otherwise.
 */
static int32_t ad9361_spi_writem(struct spi_device *spi,
				 uint32_t reg, uint8_t *tbuf, uint32_t num)
{
	uint8_t buf[10];
	int32_t ret;
	uint16_t cmd;
	int32_t i;
	if (num > MAX_MBYTE_SPI)
		return -EINVAL;

	for(i=0;i<num;++i)
		ad9361_spi_write( spi,  reg - i ,tbuf[i]);

#ifdef _DEBUG
	{

		for (i = 0; i < num; i++)
			dev_dbg(&spi->dev, "Reg 0x%"PRIX32" val 0x%X", reg--, tbuf[i]);
	}
#endif

	return 0;
}

 

ad9361_spi_writem这个函数是对多个寄存器进行写。ad9361_spi_write这个函数是对个寄存器进行写。我们将读多个寄存器的连续写改成了调用ad9361_spi_write函数多多个寄存器的分别写。 这里注意的是连续写方式下,是先写高地址的寄存,所以这里的索引变量i作为减数。

 

/**
 * SPI multiple bytes register read.
 * @param spi
 * @param reg The register address.
 * @param rbuf The data buffer.
 * @param num The number of bytes to read.
 * @return 0 in case of success, negative error code otherwise.
 */
int32_t ad9361_spi_readm(struct spi_device *spi, uint32_t reg,
			 uint8_t *rbuf, uint32_t num)
{

	int32_t i;

	for(i=0;i<num;++i)	rbuf[i]=ad9361_spi_read(spi,reg-i);

#ifdef _DEBUG
	{
		for (i = 0; i < num; i++)
			dev_dbg(&spi->dev, "%s: reg 0x%"PRIX32" val 0x%X",
				__func__, reg--, rbuf[i]);
	}
#endif

	return 0;
}

这里的ad9361_spi_readm,我们改成了多次调用ad9361_spi_read来实现。注意在原来的SDK代码里面ad9361_spi_read的实现是调用ad9361_spi_readm实现的,可以这样做的道理很简单一个就是多个的特例嘛。我这里已经修改了ad9361_spi_read代码成了驱动自己的控制器。

 

这些工作都做完了之后,从新编译运行,一切OK!

 

运行单音测试选取一路组成波形。完全OK.

 

 

 

/* Copyright © 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. All Rights Reserved. Dept.:ACEC File:AcecType.h Description: descript information REQ IDs: show the handle requirement IDs History: 2014-3-1, 1306104, original / #include “Spi2.h” #include “spi_config.h” #include “int_index.h” #include “user_timer.h” #include “bsp_var.h” // / L O C A L D A T A D E F I N I T I O N S / /*/ //#if USE_SPI > 0 #define DSPI(x) DSPI_##x #define RD_SPISR(SPI2) (DSPI_1.SR.R) #define RD_SPIDR(SPI2) (DSPI_1.POPR.R & SPI2_BitWidth_Mask) #define WR_SPIDR(SPI2,x,y) (DSPI_1.PUSHR.R = ((y>0)?((x & SPI2_BitWidth_Mask)+(SPI2_PUSHR_cs_Mask))😦(x & SPI2_BitWidth_Mask)+(SPI2_PUSHR_cs_Mask)+0x88000000u))) #define CLR_SPISR_TFFF(SPI2) (DSPI_1.SR.B.TFFF = 0x01) #define CLR_SPISR_RFDF(SPI2) (DSPI_1.SR.B.RFDF = 0x01) #define CLR_SPI_TFFF_IE(SPI2) (DSPI_1.RSER.B.TFFFRE = 0x00) #define CLR_SPI_RFDF_IE(SPI2) (DSPI_1.RSER.B.RFDFRE = 0x00) #define SET_SPI_TFFF_IE(SPI2) (DSPI_1.RSER.B.TFFFRE = 0x01) #define SET_SPI_RFDF_IE(SPI2) (DSPI_1.RSER.B.RFDFRE = 0x01) #define SPISR_TCF_MASK (0x80000000u) #define SPISR_TFFF_MASK (0x02000000u) #define SPISR_RFDF_MASK (0x00020000u) /==========================================================================/ /* L O C A L F U N C T I O N S P R O T O T Y P E S / /==========================================================================*/ static void SPI2_TFFF_Handler(void); static void SPI2_RFDF_Handler(void); static void SPI2_ChannelConfigure(U1 DevNum); static void SPI2_ShiftBytes(void); static void SPI2_IntEn_FirstTx(void); /static void WR_SPIDR_SPI2(U1 data,U1 lastbyteflg);/ static U4 SPI2_PUSHR_cs_Mask; static U4 SPI2_BitWidth_Mask; /==========================================================================/ /* F U N C T I O N S / /==========================================================================/ / Function: SPI2_Init Param< void >: Param< void >: Return< void >: Discription: Note: REQ IDs: / void SPI2_Init(void) { U1 i; DSPI_1.MCR.B.MDIS = 1u; / make sure module is disabled */ (void)BSP_INTC_IntReg(&SPI2_TFFF_Handler,INTC_INDEX_SPI1_TFFF,1); (void)BSP_INTC_IntReg(&SPI2_RFDF_Handler,INTC_INDEX_SPI1_RFDF,2); /* MS_EN / / MCR description: MSTR[31]:0-slave mode; 1-master mode CONT_SCKE[30]: 0 DCONF[29:28]: 00 FRZ[27]: 0 MTFE[26]: 0 PCSSE[25]: 0 ROOE[24]: 0 Reserve[23-22]: 00 PCSISn[21:16]: CS0_x - CS5_x 0-inactive state is low, 1-inactive state is high Reserve[15] MDIS[14]:0-enalbe module,1-disable module DIS_TXF[13]:0-TxFIFO enable,1-TxFIFO disable DIS_RXF[12]:0-RxFIFO enable,1-RxFIFO disable CLR_TXF[11]: write 1 clear TXFIFO,write 0 no use CLR_RXF[10]: write 1 clear RXFIFO,write 0 no use SMPL_PT[9:8]: 00 reserve[7:1]:0000000 HALT[0]:0-start transfer,1-stop transfer / DSPI_1.MCR.R = 0x803F0C01u; / init MCR for master ,FIFO Enable*/ /DSPI_1.MCR.R = 0x803F3C01u;/ /* init MCR for master ,FIFO Disable*/ for(i=0;i<SPI_NUM_OF_DEV;i++) { if(SPI2 == spi_dev_cfg[i].IfcHandle) { SPI2_ChannelConfigure(i); } } } /* Function: SPI2_Deinit Param< void >: Param< void >: Return< void >: Discription: Note: REQ IDs: / void SPI2_Deinit(void) { DSPI_1.MCR.B.MDIS = 1u; / make sure module is disabled */ } /* Function: SPI2_CommRun Param< void >: Param< void >: Return< void >: Discription: start spi communication Note: REQ IDs: / void SPI2_CommRun(U1 DevNum) { #if OS_CRITICAL_METHOD == 3 / Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U1 tu1_err; U2 tu2_tempLen; U1 CsChannel = spi_dev_cfg[DevNum].CsChannel; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI2]); if(ERR_OK != spi_ifc_CfgCheck(pspi_ifc_r,DevNum))/debug check/ { DBG_MSG(DBG_EN,“SPI2 ifc access error\r\n”); pspi_ifc_r->u1Err = ERR_ACCESS; } else if(SPI_ERR_CRITICAL < pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt --; pspi_ifc_r->u1Err = ERR_FAIL; } else { U2 SPI2_totalLen = pspi_ifc_r->u2TotalLen; pspi_ifc_r->u2TxLen = 0; pspi_ifc_r->u2RxLen = 0; pspi_ifc_r->u2TxSize += pspi_ifc_r->u2TxOffset; pspi_ifc_r->u2RxSize += pspi_ifc_r->u2RxOffset; pspi_ifc_r->u1Err = ERR_OK; SPI2_PUSHR_cs_Mask = (0x00010000UL<<CsChannel)+(((U4)CsChannel)<<(28)); SPI2_BitWidth_Mask = SPIBitWidthMaskTab[spi_dev_cfg[DevNum].BitWidth-4]; DSPI_1.MCR.B.CLR_TXF = 0x01;/clear tx fifo/ DSPI_1.MCR.B.CLR_RXF = 0x01;/clear rx fifo/ OSSemSet(pspi_ifc_r->pOsEventSemFinishFlag,0,&tu1_err); /make sure there is no data in rx-fifo/ (void)RD_SPIDR(SPI2); CLR_SPISR_RFDF(SPI2); (void)RD_SPIDR(SPI2); CLR_SPISR_RFDF(SPI2); if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(0); } DSPI_1.MCR.B.HALT = 0x0;/*exit halt,goto running mode */ if(TRUE == pspi_ifc_r->IntEn) { if(0 == (SPISR_TFFF_MASK & RD_SPISR(SPI2))) { SPI2_IntEn_FirstTx(); } else { OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI2); SET_SPI_TFFF_IE(SPI2); OS_EXIT_CRITICAL(); } /*wait end*/ if(TRUE == OSRunning) { tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { OSSemPend(pspi_ifc_r->pOsEventSemFinishFlag,SPI_HW_TIMEOUT,&tu1_err); if(0 != tu1_err)/*pend time out*/ { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { CLR_SPI_RFDF_IE(SPI2); CLR_SPI_TFFF_IE(SPI2); tu1_err = 2; /*time out*/ tu2_tempLen = pspi_ifc_r->u2TxLen; } else if(DSPI_1.SR.B.RFOF) { CLR_SPI_RFDF_IE(SPI2); CLR_SPI_TFFF_IE(SPI2); DSPI_1.SR.B.RFOF = 1; tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 2; /*rx fifo overflow*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 0; /*continue*/ } OS_EXIT_CRITICAL(); } else { OS_ENTER_CRITICAL(); tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); } } } else { USER_TIMER temptimer; tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { reset_usertime(&temptimer); while (get_usertime(&temptimer) < (UT_1US*1000*SPI_HW_TIMEOUT)) { OS_ENTER_CRITICAL(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); /*break;*/ } else if(ERR_OK != pspi_ifc_r->u1Err) { CLR_SPI_RFDF_IE(SPI2); CLR_SPI_TFFF_IE(SPI2); tu1_err = 2;/*fail*/ OS_EXIT_CRITICAL(); /*break;*/ } else { OS_EXIT_CRITICAL(); } if(0 != tu1_err) { break; } } if(0 == tu1_err) { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { tu1_err = 3;/*time out*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; } OS_EXIT_CRITICAL(); } } } if(1 != tu1_err) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI2].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } else { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } } else { OS_ENTER_CRITICAL(); CLR_SPI_RFDF_IE(SPI2); CLR_SPI_TFFF_IE(SPI2); OS_EXIT_CRITICAL(); SPI2_ShiftBytes(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } else { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI2].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } } if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(1); } /*stop comm*/ DSPI_1.MCR.B.HALT = 0x1; /*enter halt,goto stop mode */ } } /* Function: SPI2_TFFF_Handler Param< void >: Param< void >: Return< void >: Discription: Transmit FIFO Fill Interrupt Note: REQ IDs: */ static U1 SPI2_GetTransData(U4 *pdata) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI2]); if(pspi_ifc_r->u2TxLen < (pspi_ifc_r->u2TxHeadSize)) { *pdata = (U4)(pspi_ifc_r->u2TxHead[pspi_ifc_r->u2TxLen]); } else if((pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxSize) && (pspi_ifc_r->u2TxLen >= pspi_ifc_r->u2TxOffset)) { if(0x000000FF < SPI2_BitWidth_Mask) { *pdata = (U4)(pspi_ifc_r->pu2TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } else { *pdata = (U4)(pspi_ifc_r->pu1TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } } else { *pdata = 0x0000FFFFul; } pspi_ifc_r->u2TxLen++; if(pspi_ifc_r->u2TxLen == pspi_ifc_r->u2TotalLen) /tx finish/ { ret = 1; } else { ret = 0;/It isn’t the Endian-unit in the queue/ } return ret; } static U1 SPI2_SetReceiveData(U4 data) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI2]); if((pspi_ifc_r->u2RxLen >= pspi_ifc_r->u2RxOffset) && (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2RxSize)) { if(0x000000FF < SPI2_BitWidth_Mask) { pspi_ifc_r->pu2RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U2)data; } else { pspi_ifc_r->pu1RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U1)data; } } else { } pspi_ifc_r->u2RxLen ++; if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) /*comm finish*/ { if(TRUE == OSRunning) { (void)OSSemPost(spi_ifc_r[SPI2].pOsEventSemFinishFlag); } ret = 1; } else { ret = 0; } return ret; } /* Function: SPI2_TFFF_Handler Param< void >: Param< void >: Return< void >: Discription: Transmit FIFO Fill Interrupt Note: REQ IDs: */ static void SPI2_TFFF_Handler(void) { U4 spisr; U4 data; U1 cnt = 0; spisr = (U4)RD_SPISR(SPI2); while ((cnt++ < 4) && (0 != (SPISR_TFFF_MASK & spisr))) { /tx fifo empty/ if(0 == SPI2_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI2,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI2); } else/*It is the Endian-unit in the queue*/ { CLR_SPI_TFFF_IE(SPI2);/*disable TCF interrupt*/ WR_SPIDR(SPI2,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI2); break; } spisr = (U4)RD_SPISR(SPI2); } } /* Function: SPI2_RFDF_Handler Param< void >: Param< void >: Return< void >: Discription: Receive FIFO Drain Interrupt Note: REQ IDs: */ static void SPI2_RFDF_Handler(void) { U4 spisr; U4 data; spisr = (U4)RD_SPISR(SPI2); while(0 != (SPISR_RFDF_MASK & spisr)) { /rx fifo is not empty/ data = RD_SPIDR(SPI2); CLR_SPISR_RFDF(SPI2); if(0 != SPI2_SetReceiveData(data))/It is the Endian-unit in the queue/ { CLR_SPI_RFDF_IE(SPI2);/*disable RFDF-interrupt */ } else/It isn’t the Endian-unit in the queue/ { } spisr = (U4)RD_SPISR(SPI2); } } /* Function: SPI2_IntEn_FirstTx Param< void >: Param< void >: Return< void >: Discription: Note: REQ IDs: / static void SPI2_IntEn_FirstTx(void) { #if OS_CRITICAL_METHOD == 3 / Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U4 data; if(0 == SPI2_GetTransData(&data)) /It isn’t the Endian-unit in the queue/ { WR_SPIDR(SPI2,data,0);/write the Nor Endian Byte/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI2);/enable RFDF interrupt/ SET_SPI_TFFF_IE(SPI2);/enable TCF interrupt/ OS_EXIT_CRITICAL(); } else/It is the Endian-unit in the queue/ { WR_SPIDR(SPI2,data,1);/write the Endian Byte/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI2);/enable RFDF interrupt/ OS_EXIT_CRITICAL(); } } /* Function: SPI2_ShiftBytes Param< void >: Param< void >: Return< void >: Discription: Note: REQ IDs: */ static void SPI2_ShiftBytes(void) { USER_TIMER temptimer; U1 timeout_flag = 0; U4 data; U4 spisr; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI2]); reset_usertime(&temptimer); while (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); spisr = RD_SPISR(SPI2); if(0 != (SPISR_RFDF_MASK & spisr))/Rx fifo is not empty/ { data = RD_SPIDR(SPI2); CLR_SPISR_RFDF(SPI2); (void)SPI2_SetReceiveData(data); /*comm finish*/ reset_usertime(&temptimer); } if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TotalLen) { if((0 != (SPISR_TFFF_MASK & spisr)) || (pspi_ifc_r->u2TxLen == 0)) { /*tx fifo is not full*/ if(0 != (SPISR_TFFF_MASK & spisr)) { CLR_SPISR_TFFF(SPI2); } if(0 == SPI2_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI2,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI2); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI2,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI2); } reset_usertime(&temptimer); } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } } /* Function: SPI2_ChannelConfigure Param< void >: Param< void >: Return< void >: Discription: Note: REQ IDs: */ static void SPI2_ChannelConfigure(U1 DevNum) { U4 tu4_n; U1 tu1_i; U1 tu1_cs_channel; tu1_cs_channel = spi_dev_cfg[DevNum].CsChannel; DSPI_1.CTAR[tu1_cs_channel].R = 0x38000000ul;/default value/ if((spi_dev_cfg[DevNum].BitWidth > 16) || (spi_dev_cfg[DevNum].BitWidth < 4)) { DSPI_1.CTAR[tu1_cs_channel].B.FMSZ = (U4)7; /* Configure data as 8 bits / } else { DSPI_1.CTAR[tu1_cs_channel].B.FMSZ = (U4)(spi_dev_cfg[DevNum].BitWidth-1); / Configure data as 4~16 bits */ } tu4_n = ((peri_set2_clk + spi_dev_cfg[DevNum].Baudrate) - 1) / spi_dev_cfg[DevNum].Baudrate; for(tu1_i=0; tu1_i<60; tu1_i++) { if(SPI_BAUD_CMP[tu1_i] >= tu4_n) { break; } } DSPI_1.CTAR[tu1_cs_channel].B.PBR = SPI_BR_PARA[tu1_i][0]; DSPI_1.CTAR[tu1_cs_channel].B.BR = SPI_BR_PARA[tu1_i][1]; DSPI_1.CTAR[tu1_cs_channel].B.CPOL = ((spi_dev_cfg[DevNum].IdleLevelHighEn>0)?1:0); DSPI_1.CTAR[tu1_cs_channel].B.CPHA = ((spi_dev_cfg[DevNum].SampleEvenEdgeEn>0)?1:0); DSPI_1.CTAR[tu1_cs_channel].B.LSBFE = ((spi_dev_cfg[DevNum].LSB_FirstEnable>0)?1:0); DSPI_1.CTAR[tu1_cs_channel].B.PCSSCK = SPI_BR_PARA[tu1_i][0]; DSPI_1.CTAR[tu1_cs_channel].B.CSSCK = SPI_BR_PARA[tu1_i][1]; DSPI_1.CTAR[tu1_cs_channel].B.PASC = SPI_BR_PARA[tu1_i][0]; DSPI_1.CTAR[tu1_cs_channel].B.ASC = SPI_BR_PARA[tu1_i][1]; /DSPI_1.MCR.B.HALT = 0x0;/ } //#endif /* (APP_HW_VERSION_AB802_0_0 != APP_HW_VERSION) / //#endif / USE_SPI > 0 / 这是spi2.c / Copyright © 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. All Rights Reserved. Dept.:ACEC File:AcecType.h Description: descript information REQ IDs: show the handle requirement IDs History: 2014-3-1, 1306104, original */ #ifndef SPI2_H #define SPI2_H #include “includes.h” #include “bsp_cfg.h” #include “Config.h” extern void SPI2_Init(void); extern void SPI2_Deinit(void); extern void SPI2_CommRun(U1 DevNum); #endif 这是Spi2.h,将其中的ucos相关函数替换为裸机可用,不依靠ucos底层,不删去文件中的头文件部分内容,可以增加,修改后的文件名称不作改变,将修改后的完整代码发出
01-07
/* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #include "Spi0.h" #include "spi_config.h" #include "int_index.h" #include "user_timer.h" #include "bsp_var.h" /*==========================================================================*/ /* L O C A L D A T A D E F I N I T I O N S */ /*==========================================================================*/ #if USE_SPI > 0 #if (APP_HW_VERSION_AB802_0_0 != APP_HW_VERSION) /* #define SPISR(SPI0) DSPI_0.SR.R #define SPIDR(SPI0) DSPI_0.POPR.R */ #define DSPI(x) DSPI_##x #define RD_SPISR(SPI0) (DSPI_0.SR.R) #define RD_SPIDR(SPI0) (DSPI_0.POPR.R & SPI0_BitWidth_Mask) #define WR_SPIDR(SPI0,x,y) (DSPI_0.PUSHR.R = ((y>0)?((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)):((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)+0x88000000u))) #define CLR_SPISR_TFFF(SPI0) (DSPI_0.SR.B.TFFF = 0x01) #define CLR_SPISR_RFDF(SPI0) (DSPI_0.SR.B.RFDF = 0x01) #define CLR_SPI_TFFF_IE(SPI0) (DSPI_0.RSER.B.TFFFRE = 0x00) #define CLR_SPI_RFDF_IE(SPI0) (DSPI_0.RSER.B.RFDFRE = 0x00) #define SET_SPI_TFFF_IE(SPI0) (DSPI_0.RSER.B.TFFFRE = 0x01) #define SET_SPI_RFDF_IE(SPI0) (DSPI_0.RSER.B.RFDFRE = 0x01) #define SPISR_TCF_MASK (0x80000000u) #define SPISR_TFFF_MASK (0x02000000u) #define SPISR_RFDF_MASK (0x00020000u) /*==========================================================================*/ /* L O C A L F U N C T I O N S P R O T O T Y P E S */ /*==========================================================================*/ static void SPI0_TFFF_Handler(void); static void SPI0_RFDF_Handler(void); static void SPI0_ChannelConfigure(U1 DevNum); static void SPI0_ShiftBytes(void); static void SPI0_IntEn_FirstTx(void); /*static void WR_SPIDR_SPI0(U1 data,U1 lastbyteflg);*/ static U4 SPI0_PUSHR_cs_Mask; static U4 SPI0_BitWidth_Mask; /*==========================================================================*/ /* F U N C T I O N S */ /*==========================================================================*/ /* * Function: SPI0_Init * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void SPI0_Init(void) { U1 i; DSPI_0.MCR.B.MDIS = 1u; /* make sure module is disabled */ (void)BSP_INTC_IntReg(&SPI0_TFFF_Handler,INTC_INDEX_SPI0_TFFF,1); (void)BSP_INTC_IntReg(&SPI0_RFDF_Handler,INTC_INDEX_SPI0_RFDF,2); /* MS_EN */ /* MCR description: MSTR[31]:0-slave mode; 1-master mode CONT_SCKE[30]: 0 DCONF[29:28]: 00 FRZ[27]: 0 MTFE[26]: 0 PCSSE[25]: 0 ROOE[24]: 0 Reserve[23-22]: 00 PCSISn[21:16]: CS0_x - CS5_x 0-inactive state is low, 1-inactive state is high Reserve[15] MDIS[14]:0-enalbe module,1-disable module DIS_TXF[13]:0-TxFIFO enable,1-TxFIFO disable DIS_RXF[12]:0-RxFIFO enable,1-RxFIFO disable CLR_TXF[11]: write 1 clear TXFIFO,write 0 no use CLR_RXF[10]: write 1 clear RXFIFO,write 0 no use SMPL_PT[9:8]: 00 reserve[7:1]:0000000 HALT[0]:0-start transfer,1-stop transfer */ DSPI_0.MCR.R = 0x803F0C01u; /* init MCR for master ,FIFO Enable*/ /*DSPI_0.MCR.R = 0x803F3C01u;*/ /* init MCR for master ,FIFO Disable*/ for(i=0;i<SPI_NUM_OF_DEV;i++) { if(SPI0 == spi_dev_cfg[i].IfcHandle) { SPI0_ChannelConfigure(i); } } } /* * Function: SPI0_Deinit * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void SPI0_Deinit(void) { DSPI_0.MCR.B.MDIS = 1u; /* make sure module is disabled */ } /* * Function: SPI0_CommRun * Param< void >: * Param< void >: * Return< void >: * Discription: start spi communication * Note: * REQ IDs: */ void SPI0_CommRun(U1 DevNum) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U1 tu1_err; U2 tu2_tempLen; U1 CsChannel = spi_dev_cfg[DevNum].CsChannel; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI0]); if(ERR_OK != spi_ifc_CfgCheck(pspi_ifc_r,DevNum))/*debug check*/ { DBG_MSG(DBG_EN,"spi0 ifc access error\r\n"); pspi_ifc_r->u1Err = ERR_ACCESS; } else if(SPI_ERR_CRITICAL < pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt --; pspi_ifc_r->u1Err = ERR_FAIL; } else { U2 spi0_totalLen = pspi_ifc_r->u2TotalLen; pspi_ifc_r->u2TxLen = 0; pspi_ifc_r->u2RxLen = 0; pspi_ifc_r->u2TxSize += pspi_ifc_r->u2TxOffset; pspi_ifc_r->u2RxSize += pspi_ifc_r->u2RxOffset; pspi_ifc_r->u1Err = ERR_OK; SPI0_PUSHR_cs_Mask = (0x00010000UL<<CsChannel)+(((U4)CsChannel)<<(28)); SPI0_BitWidth_Mask = SPIBitWidthMaskTab[spi_dev_cfg[DevNum].BitWidth-4]; DSPI_0.MCR.B.CLR_TXF = 0x01;/*clear tx fifo*/ DSPI_0.MCR.B.CLR_RXF = 0x01;/*clear rx fifo*/ OSSemSet(pspi_ifc_r->pOsEventSemFinishFlag,0,&tu1_err); /*make sure there is no data in rx-fifo*/ (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(0); } DSPI_0.MCR.B.HALT = 0x0;/*exit halt,goto running mode */ if(TRUE == pspi_ifc_r->IntEn) { if(0 == (SPISR_TFFF_MASK & RD_SPISR(SPI0))) { SPI0_IntEn_FirstTx(); } else { OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0); SET_SPI_TFFF_IE(SPI0); OS_EXIT_CRITICAL(); } /*wait end*/ if(TRUE == OSRunning) { tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { OSSemPend(pspi_ifc_r->pOsEventSemFinishFlag,SPI_HW_TIMEOUT,&tu1_err); if(0 != tu1_err)/*pend time out*/ { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); tu1_err = 2; /*time out*/ tu2_tempLen = pspi_ifc_r->u2TxLen; } else if(DSPI_0.SR.B.RFOF) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); DSPI_0.SR.B.RFOF = 1; tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 2; /*rx fifo overflow*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 0; /*continue*/ } OS_EXIT_CRITICAL(); } else { OS_ENTER_CRITICAL(); tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); } } } else { USER_TIMER temptimer; tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { reset_usertime(&temptimer); while (get_usertime(&temptimer) < (UT_1US*1000*SPI_HW_TIMEOUT)) { OS_ENTER_CRITICAL(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); /*break;*/ } else if(ERR_OK != pspi_ifc_r->u1Err) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); tu1_err = 2;/*fail*/ OS_EXIT_CRITICAL(); /*break;*/ } else { OS_EXIT_CRITICAL(); } if(0 != tu1_err) { break; } } if(0 == tu1_err) { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { tu1_err = 3;/*time out*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; } OS_EXIT_CRITICAL(); } } } if(1 != tu1_err) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI0].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } else { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } } else { OS_ENTER_CRITICAL(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); OS_EXIT_CRITICAL(); SPI0_ShiftBytes(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } else { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI0].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } } if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(1); } /*stop comm*/ DSPI_0.MCR.B.HALT = 0x1; /*enter halt,goto stop mode */ } } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static U1 SPI0_GetTransData(U4 *pdata) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if(pspi_ifc_r->u2TxLen < (pspi_ifc_r->u2TxHeadSize)) { *pdata = (U4)(pspi_ifc_r->u2TxHead[pspi_ifc_r->u2TxLen]); } else if((pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxSize) && (pspi_ifc_r->u2TxLen >= pspi_ifc_r->u2TxOffset)) { if(0x000000FF < SPI0_BitWidth_Mask) { *pdata = (U4)(pspi_ifc_r->pu2TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } else { *pdata = (U4)(pspi_ifc_r->pu1TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } } else { *pdata = 0x0000FFFFul; } pspi_ifc_r->u2TxLen++; if(pspi_ifc_r->u2TxLen == pspi_ifc_r->u2TotalLen) /*tx finish*/ { ret = 1; } else { ret = 0;/*It isn't the Endian-unit in the queue*/ } return ret; } static U1 SPI0_SetReceiveData(U4 data) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if((pspi_ifc_r->u2RxLen >= pspi_ifc_r->u2RxOffset) && (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2RxSize)) { if(0x000000FF < SPI0_BitWidth_Mask) { pspi_ifc_r->pu2RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U2)data; } else { pspi_ifc_r->pu1RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U1)data; } } else { } pspi_ifc_r->u2RxLen ++; if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) /*comm finish*/ { if(TRUE == OSRunning) { (void)OSSemPost(spi_ifc_r[SPI0].pOsEventSemFinishFlag); } ret = 1; } else { ret = 0; } return ret; } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static void SPI0_TFFF_Handler(void) { U4 spisr; U4 data; U1 cnt = 0; spisr = (U4)RD_SPISR(SPI0); while ((cnt++ < 4) && (0 != (SPISR_TFFF_MASK & spisr))) { /*tx fifo empty*/ if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { CLR_SPI_TFFF_IE(SPI0);/*disable TCF interrupt*/ WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); break; } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_RFDF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Receive FIFO Drain Interrupt * Note: * REQ IDs: */ static void SPI0_RFDF_Handler(void) { U4 spisr; U4 data; spisr = (U4)RD_SPISR(SPI0); while(0 != (SPISR_RFDF_MASK & spisr)) { /*rx fifo is not empty*/ data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != SPI0_SetReceiveData(data))/*It is the Endian-unit in the queue*/ { CLR_SPI_RFDF_IE(SPI0);/*disable RFDF-interrupt */ } else/*It isn't the Endian-unit in the queue*/ { } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_IntEn_FirstTx * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_IntEn_FirstTx(void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U4 data; if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ SET_SPI_TFFF_IE(SPI0);/*enable TCF interrupt*/ OS_EXIT_CRITICAL(); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ OS_EXIT_CRITICAL(); } } /* * Function: SPI0_ShiftBytes * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ShiftBytes(void) { USER_TIMER temptimer; U1 timeout_flag = 0; U4 data; U4 spisr; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI0]); reset_usertime(&temptimer); while (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); spisr = RD_SPISR(SPI0); if(0 != (SPISR_RFDF_MASK & spisr))/*Rx fifo is not empty*/ { data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)SPI0_SetReceiveData(data); /*comm finish*/ reset_usertime(&temptimer); } if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TotalLen) { if((0 != (SPISR_TFFF_MASK & spisr)) || (pspi_ifc_r->u2TxLen == 0)) { /*tx fifo is not full*/ if(0 != (SPISR_TFFF_MASK & spisr)) { CLR_SPISR_TFFF(SPI0); } if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); } reset_usertime(&temptimer); } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } } /* * Function: SPI0_ChannelConfigure * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ChannelConfigure(U1 DevNum) { U4 tu4_n; U1 tu1_i; U1 tu1_cs_channel; tu1_cs_channel = spi_dev_cfg[DevNum].CsChannel; DSPI_0.CTAR[tu1_cs_channel].R = 0x38000000ul;/*default value*/ if((spi_dev_cfg[DevNum].BitWidth > 16) || (spi_dev_cfg[DevNum].BitWidth < 4)) { DSPI_0.CTAR[tu1_cs_channel].B.FMSZ = (U4)7; /* Configure data as 8 bits */ } else { DSPI_0.CTAR[tu1_cs_channel].B.FMSZ = (U4)(spi_dev_cfg[DevNum].BitWidth-1); /* Configure data as 4~16 bits */ } tu4_n = ((peri_set2_clk + spi_dev_cfg[DevNum].Baudrate) - 1) / spi_dev_cfg[DevNum].Baudrate; for(tu1_i=0; tu1_i<60; tu1_i++) { if(SPI_BAUD_CMP[tu1_i] >= tu4_n) { break; } } DSPI_0.CTAR[tu1_cs_channel].B.PBR = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[tu1_cs_channel].B.BR = SPI_BR_PARA[tu1_i][1]; DSPI_0.CTAR[tu1_cs_channel].B.CPOL = ((spi_dev_cfg[DevNum].IdleLevelHighEn>0)?1:0); DSPI_0.CTAR[tu1_cs_channel].B.CPHA = ((spi_dev_cfg[DevNum].SampleEvenEdgeEn>0)?1:0); DSPI_0.CTAR[tu1_cs_channel].B.LSBFE = ((spi_dev_cfg[DevNum].LSB_FirstEnable>0)?1:0); DSPI_0.CTAR[tu1_cs_channel].B.PCSSCK = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[tu1_cs_channel].B.CSSCK = SPI_BR_PARA[tu1_i][1]; DSPI_0.CTAR[tu1_cs_channel].B.PASC = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[tu1_cs_channel].B.ASC = SPI_BR_PARA[tu1_i][1]; /*DSPI_0.MCR.B.HALT = 0x0;*/ } #else /* #define SPISR(SPI0) DSPI_2.SR.R #define SPIDR(SPI0) DSPI_2.POPR.R */ #define DSPI(x) DSPI_##x #define RD_SPISR(SPI0) (DSPI_2.SR.R) #define RD_SPIDR(SPI0) (DSPI_2.POPR.R & SPI0_BitWidth_Mask) #define WR_SPIDR(SPI0,x,y) (DSPI_2.PUSHR.R = ((y>0)?((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)):((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)+0x88000000u))) #define CLR_SPISR_TFFF(SPI0) (DSPI_2.SR.B.TFFF = 0x01) #define CLR_SPISR_RFDF(SPI0) (DSPI_2.SR.B.RFDF = 0x01) #define CLR_SPI_TFFF_IE(SPI0) (DSPI_2.RSER.B.TFFFRE = 0x00) #define CLR_SPI_RFDF_IE(SPI0) (DSPI_2.RSER.B.RFDFRE = 0x00) #define SET_SPI_TFFF_IE(SPI0) (DSPI_2.RSER.B.TFFFRE = 0x01) #define SET_SPI_RFDF_IE(SPI0) (DSPI_2.RSER.B.RFDFRE = 0x01) #define SPISR_TCF_MASK (0x80000000u) #define SPISR_TFFF_MASK (0x02000000u) #define SPISR_RFDF_MASK (0x00020000u) /*==========================================================================*/ /* L O C A L F U N C T I O N S P R O T O T Y P E S */ /*==========================================================================*/ static void SPI0_TFFF_Handler(void); static void SPI0_RFDF_Handler(void); static void SPI0_ChannelConfigure(U1 DevNum); static void SPI0_ShiftBytes(void); static void SPI0_IntEn_FirstTx(void); /*static void WR_SPIDR_SPI0(U1 data,U1 lastbyteflg);*/ static U4 SPI0_PUSHR_cs_Mask; static U4 SPI0_BitWidth_Mask; /*==========================================================================*/ /* F U N C T I O N S */ /*==========================================================================*/ /* * Function: SPI0_Init * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void SPI0_Init(void) { U1 i; DSPI_2.MCR.B.MDIS = 1u; /* make sure module is disabled */ (void)BSP_INTC_IntReg(&SPI0_TFFF_Handler,INTC_INDEX_SPI2_TFFF,1); (void)BSP_INTC_IntReg(&SPI0_RFDF_Handler,INTC_INDEX_SPI2_RFDF,2); /* MS_EN */ /* MCR description: MSTR[31]:0-slave mode; 1-master mode CONT_SCKE[30]: 0 DCONF[29:28]: 00 FRZ[27]: 0 MTFE[26]: 0 PCSSE[25]: 0 ROOE[24]: 0 Reserve[23-22]: 00 PCSISn[21:16]: CS0_x - CS5_x 0-inactive state is low, 1-inactive state is high Reserve[15] MDIS[14]:0-enalbe module,1-disable module DIS_TXF[13]:0-TxFIFO enable,1-TxFIFO disable DIS_RXF[12]:0-RxFIFO enable,1-RxFIFO disable CLR_TXF[11]: write 1 clear TXFIFO,write 0 no use CLR_RXF[10]: write 1 clear RXFIFO,write 0 no use SMPL_PT[9:8]: 00 reserve[7:1]:0000000 HALT[0]:0-start transfer,1-stop transfer */ DSPI_2.MCR.R = 0x803F0C01u; /* init MCR for master ,FIFO Enable*/ /*DSPI_2.MCR.R = 0x803F3C01u;*/ /* init MCR for master ,FIFO Disable*/ for(i=0;i<SPI_NUM_OF_DEV;i++) { if(SPI0 == spi_dev_cfg[i].IfcHandle) { SPI0_ChannelConfigure(i); } } } /* * Function: SPI0_Deinit * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void SPI0_Deinit(void) { DSPI_2.MCR.B.MDIS = 1u; /* make sure module is disabled */ } /* * Function: SPI0_CommRun * Param< void >: * Param< void >: * Return< void >: * Discription: start spi communication * Note: * REQ IDs: */ void SPI0_CommRun(U1 DevNum) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U1 tu1_err; U2 tu2_tempLen; U1 CsChannel = spi_dev_cfg[DevNum].CsChannel; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI0]); if(ERR_OK != spi_ifc_CfgCheck(pspi_ifc_r,DevNum))/*debug check*/ { DBG_MSG(DBG_EN,"spi0 ifc access error\r\n"); pspi_ifc_r->u1Err = ERR_ACCESS; } else if(SPI_ERR_CRITICAL < pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt --; pspi_ifc_r->u1Err = ERR_FAIL; } else { U2 spi0_totalLen = pspi_ifc_r->u2TotalLen; pspi_ifc_r->u2TxLen = 0; pspi_ifc_r->u2RxLen = 0; pspi_ifc_r->u2TxSize += pspi_ifc_r->u2TxOffset; pspi_ifc_r->u2RxSize += pspi_ifc_r->u2RxOffset; pspi_ifc_r->u1Err = ERR_OK; SPI0_PUSHR_cs_Mask = (0x00010000UL<<CsChannel)+(((U4)CsChannel)<<(28)); SPI0_BitWidth_Mask = SPIBitWidthMaskTab[spi_dev_cfg[DevNum].BitWidth-4]; DSPI_2.MCR.B.CLR_TXF = 0x01;/*clear tx fifo*/ DSPI_2.MCR.B.CLR_RXF = 0x01;/*clear rx fifo*/ OSSemSet(pspi_ifc_r->pOsEventSemFinishFlag,0,&tu1_err); /*make sure there is no data in rx-fifo*/ (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(0); } DSPI_2.MCR.B.HALT = 0x0;/*exit halt,goto running mode */ if(TRUE == pspi_ifc_r->IntEn) { if(0 == (SPISR_TFFF_MASK & RD_SPISR(SPI0))) { SPI0_IntEn_FirstTx(); } else { OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0); SET_SPI_TFFF_IE(SPI0); OS_EXIT_CRITICAL(); } /*wait end*/ if(TRUE == OSRunning) { tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { OSSemPend(pspi_ifc_r->pOsEventSemFinishFlag,SPI_HW_TIMEOUT,&tu1_err); if(0 != tu1_err)/*pend time out*/ { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); tu1_err = 2; /*time out*/ tu2_tempLen = pspi_ifc_r->u2TxLen; } else if(DSPI_2.SR.B.RFOF) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); DSPI_2.SR.B.RFOF = 1; tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 2; /*rx fifo overflow*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; tu1_err = 0; /*continue*/ } OS_EXIT_CRITICAL(); } else { OS_ENTER_CRITICAL(); tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); } } } else { USER_TIMER temptimer; tu1_err = 0; tu2_tempLen = 0; while(0 == tu1_err) { reset_usertime(&temptimer); while (get_usertime(&temptimer) < (UT_1US*1000*SPI_HW_TIMEOUT)) { OS_ENTER_CRITICAL(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { tu1_err = 1;/*finished*/ OS_EXIT_CRITICAL(); /*break;*/ } else if(ERR_OK != pspi_ifc_r->u1Err) { CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); tu1_err = 2;/*fail*/ OS_EXIT_CRITICAL(); /*break;*/ } else { OS_EXIT_CRITICAL(); } if(0 != tu1_err) { break; } } if(0 == tu1_err) { OS_ENTER_CRITICAL(); if(tu2_tempLen == pspi_ifc_r->u2RxLen) { tu1_err = 3;/*time out*/ } else { tu2_tempLen = pspi_ifc_r->u2RxLen; } OS_EXIT_CRITICAL(); } } } if(1 != tu1_err) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI0].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } else { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } } else { OS_ENTER_CRITICAL(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); OS_EXIT_CRITICAL(); SPI0_ShiftBytes(); if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) { if(5 <= pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt -= 5; } else { pspi_ifc_r->u1ErrCnt = 0; } } else { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } spi_ifc_cfg[SPI0].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } } if(0 != spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(1); } /*stop comm*/ DSPI_2.MCR.B.HALT = 0x1; /*enter halt,goto stop mode */ } } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static U1 SPI0_GetTransData(U4 *pdata) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if(pspi_ifc_r->u2TxLen < (pspi_ifc_r->u2TxHeadSize)) { *pdata = (U4)(pspi_ifc_r->u2TxHead[pspi_ifc_r->u2TxLen]); } else if((pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxSize) && (pspi_ifc_r->u2TxLen >= pspi_ifc_r->u2TxOffset)) { if(0x000000FF < SPI0_BitWidth_Mask) { *pdata = (U4)(pspi_ifc_r->pu2TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } else { *pdata = (U4)(pspi_ifc_r->pu1TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } } else { *pdata = 0x0000FFFFul; } pspi_ifc_r->u2TxLen++; if(pspi_ifc_r->u2TxLen == pspi_ifc_r->u2TotalLen) /*tx finish*/ { ret = 1; } else { ret = 0;/*It isn't the Endian-unit in the queue*/ } return ret; } static U1 SPI0_SetReceiveData(U4 data) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if((pspi_ifc_r->u2RxLen >= pspi_ifc_r->u2RxOffset) && (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2RxSize)) { if(0x000000FF < SPI0_BitWidth_Mask) { pspi_ifc_r->pu2RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U2)data; } else { pspi_ifc_r->pu1RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U1)data; } } else { } pspi_ifc_r->u2RxLen ++; if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) /*comm finish*/ { if(TRUE == OSRunning) { (void)OSSemPost(spi_ifc_r[SPI0].pOsEventSemFinishFlag); } ret = 1; } else { ret = 0; } return ret; } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static void SPI0_TFFF_Handler(void) { U4 spisr; U4 data; U1 cnt = 0; spisr = (U4)RD_SPISR(SPI0); while ((cnt++ < 4) && (0 != (SPISR_TFFF_MASK & spisr))) { /*tx fifo empty*/ if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { CLR_SPI_TFFF_IE(SPI0);/*disable TCF interrupt*/ WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); break; } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_RFDF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Receive FIFO Drain Interrupt * Note: * REQ IDs: */ static void SPI0_RFDF_Handler(void) { U4 spisr; U4 data; spisr = (U4)RD_SPISR(SPI0); while(0 != (SPISR_RFDF_MASK & spisr)) { /*rx fifo is not empty*/ data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != SPI0_SetReceiveData(data))/*It is the Endian-unit in the queue*/ { CLR_SPI_RFDF_IE(SPI0);/*disable RFDF-interrupt */ } else/*It isn't the Endian-unit in the queue*/ { } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_IntEn_FirstTx * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_IntEn_FirstTx(void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U4 data; if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ SET_SPI_TFFF_IE(SPI0);/*enable TCF interrupt*/ OS_EXIT_CRITICAL(); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ OS_EXIT_CRITICAL(); } } /* * Function: SPI0_ShiftBytes * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ShiftBytes(void) { USER_TIMER temptimer; U1 timeout_flag = 0; U4 data; U4 spisr; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI0]); reset_usertime(&temptimer); while (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); spisr = RD_SPISR(SPI0); if(0 != (SPISR_RFDF_MASK & spisr))/*Rx fifo is not empty*/ { data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)SPI0_SetReceiveData(data); /*comm finish*/ reset_usertime(&temptimer); } if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TotalLen) { if((0 != (SPISR_TFFF_MASK & spisr)) || (pspi_ifc_r->u2TxLen == 0)) { /*tx fifo is not full*/ if(0 != (SPISR_TFFF_MASK & spisr)) { CLR_SPISR_TFFF(SPI0); } if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); } reset_usertime(&temptimer); } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } } /* * Function: SPI0_ChannelConfigure * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ChannelConfigure(U1 DevNum) { U4 tu4_n; U1 tu1_i; U1 tu1_cs_channel; tu1_cs_channel = spi_dev_cfg[DevNum].CsChannel; DSPI_2.CTAR[tu1_cs_channel].R = 0x38000000ul;/*default value*/ if((spi_dev_cfg[DevNum].BitWidth > 16) || (spi_dev_cfg[DevNum].BitWidth < 4)) { DSPI_2.CTAR[tu1_cs_channel].B.FMSZ = (U4)7; /* Configure data as 8 bits */ } else { DSPI_2.CTAR[tu1_cs_channel].B.FMSZ = (U4)(spi_dev_cfg[DevNum].BitWidth-1); /* Configure data as 4~16 bits */ } tu4_n = ((peri_set2_clk + spi_dev_cfg[DevNum].Baudrate) - 1) / spi_dev_cfg[DevNum].Baudrate; for(tu1_i=0; tu1_i<60; tu1_i++) { if(SPI_BAUD_CMP[tu1_i] >= tu4_n) { break; } } DSPI_2.CTAR[tu1_cs_channel].B.PBR = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.BR = SPI_BR_PARA[tu1_i][1]; DSPI_2.CTAR[tu1_cs_channel].B.CPOL = ((spi_dev_cfg[DevNum].IdleLevelHighEn>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.CPHA = ((spi_dev_cfg[DevNum].SampleEvenEdgeEn>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.LSBFE = ((spi_dev_cfg[DevNum].LSB_FirstEnable>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.PCSSCK = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.CSSCK = SPI_BR_PARA[tu1_i][1]; DSPI_2.CTAR[tu1_cs_channel].B.PASC = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.ASC = SPI_BR_PARA[tu1_i][1]; /*DSPI_2.MCR.B.HALT = 0x0;*/ } #endif /* (APP_HW_VERSION_AB802_0_0 != APP_HW_VERSION) */ #endif /* USE_SPI > 0 */ 这是spi0.c /* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #ifndef _SPI0_H_ #define _SPI0_H_ #include "includes.h" #include "bsp_cfg.h" #include "Config.h" extern void SPI0_Init(void); extern void SPI0_Deinit(void); extern void SPI0_CommRun(U1 DevNum); #endif 这是Spi0.h,将其中的ucos相关函数替换为裸机可用,不依靠ucos底层,不删去文件中的头文件部分内容,可以增加,修改后的文件名称不作改变,将修改后的完整代码发出
最新发布
01-07
/* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #include "api_ad7190.h" #include "Spi_config.h" #include "bsp_cfg.h" /*==========================================================================*/ /* L O C A L D A T A D E F I N I T I O N S */ /*==========================================================================*/ StatusType ad7190_comm_Pend(void) { StatusType retVal = ERR_OK; U1 tu1_err; if(OSRunning == TRUE) { OSSemPend(spi_ifc_r[spi_dev_cfg[SPI_DEV_AD7190].IfcHandle].pOsEventSem,0,&tu1_err); if(OS_NO_ERR != tu1_err) { DBG_MSG(DBG_EN,"ad7190_comm_Pend error\r\n"); retVal = ERR_FAIL; } else { } } else { } return retVal; } /* * Function: mc25lc256_comm_Post * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void ad7190_comm_Post(void) { if(OSRunning == TRUE) { //OSTimeDly(2); (void)OSSemPost(spi_ifc_r[spi_dev_cfg[SPI_DEV_AD7190].IfcHandle].pOsEventSem); } else { } } /* * Function: AD7190_Write * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ StatusType AD7190_Write(U2 addr,U1 databuff[],U2 datalen) { StatusType retVal = ERR_OK; spi_ifc_handle tu1_ifc = spi_dev_cfg[SPI_DEV_AD7190].IfcHandle; (void)addr; /*if(ERR_OK == spi_ifc_Pend(tu1_ifc))*/ if(1) { spi_ifc_r[tu1_ifc].IntEn = AD7190_INT_EN; spi_ifc_r[tu1_ifc].u2TxHeadSize = 0; /*Head*/ spi_ifc_r[tu1_ifc].pu1TxBuff = databuff; /*TxBuff*/ spi_ifc_r[tu1_ifc].pu2TxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2TxOffset = 0; spi_ifc_r[tu1_ifc].u2TxSize = datalen; spi_ifc_r[tu1_ifc].pu1RxBuff = (U1*)0; /*RxBuff*/ spi_ifc_r[tu1_ifc].pu2RxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2RxOffset = 0; spi_ifc_r[tu1_ifc].u2RxSize = 0; spi_ifc_r[tu1_ifc].u2TotalLen = datalen; spi_ifc_cfg[tu1_ifc].pfSpiCommRun(SPI_DEV_AD7190); if(ERR_OK != spi_ifc_r[tu1_ifc].u1Err) { retVal = ERR_FAIL; } /* spi_ifc_Post(tu1_ifc);*/ } else { retVal = ERR_ACCESS; } return retVal; } /* * Function: AD7190_Write_byte * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ StatusType AD7190_Write_byte(U1 bytedata) { StatusType retVal = ERR_OK; spi_ifc_handle tu1_ifc = spi_dev_cfg[SPI_DEV_AD7190].IfcHandle; /*if(ERR_OK == spi_ifc_Pend(tu1_ifc))*/ if(1) { spi_ifc_r[tu1_ifc].IntEn = AD7190_INT_EN; spi_ifc_r[tu1_ifc].u2TxHead[0] = (U2)bytedata; spi_ifc_r[tu1_ifc].u2TxHeadSize = 1; /*Head*/ spi_ifc_r[tu1_ifc].pu1TxBuff = (U1*)0; /*TxBuff*/ spi_ifc_r[tu1_ifc].pu2TxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2TxOffset = 0; spi_ifc_r[tu1_ifc].u2TxSize = 0; spi_ifc_r[tu1_ifc].pu1RxBuff = (U1*)0; /*RxBuff*/ spi_ifc_r[tu1_ifc].pu2RxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2RxOffset = 0; spi_ifc_r[tu1_ifc].u2RxSize = 0; spi_ifc_r[tu1_ifc].u2TotalLen = 1; spi_ifc_cfg[tu1_ifc].pfSpiCommRun(SPI_DEV_AD7190); if(ERR_OK != spi_ifc_r[tu1_ifc].u1Err) { retVal = ERR_FAIL; } /* spi_ifc_Post(tu1_ifc);*/ } else { retVal = ERR_ACCESS; } return retVal; } /* * Function: AD7190_Read * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ StatusType AD7190_Read(U1 databuff[],U2 datalen) { StatusType retVal = ERR_OK; spi_ifc_handle tu1_ifc = spi_dev_cfg[SPI_DEV_AD7190].IfcHandle; /*if(ERR_OK == spi_ifc_Pend(tu1_ifc))*/ if(1) { spi_ifc_r[tu1_ifc].IntEn = AD7190_INT_EN; spi_ifc_r[tu1_ifc].u2TxHead[0] = (U2)databuff[0]; spi_ifc_r[tu1_ifc].u2TxHeadSize = 1; /*Head*/ spi_ifc_r[tu1_ifc].pu1TxBuff = (U1*)0; /*TxBuff*/ spi_ifc_r[tu1_ifc].pu2TxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2TxOffset = 0; spi_ifc_r[tu1_ifc].u2TxSize = 0; spi_ifc_r[tu1_ifc].pu1RxBuff = (U1*)databuff; /*RxBuff*/ spi_ifc_r[tu1_ifc].pu2RxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2RxOffset = 1; spi_ifc_r[tu1_ifc].u2RxSize = datalen; spi_ifc_r[tu1_ifc].u2TotalLen = datalen+1; /*Total Length*/ spi_ifc_cfg[tu1_ifc].pfSpiCommRun(SPI_DEV_AD7190); if(ERR_OK != spi_ifc_r[tu1_ifc].u1Err) { retVal = ERR_FAIL; } /* spi_ifc_Post(tu1_ifc);*/ } else { retVal = ERR_ACCESS; } return retVal; } /* * Function: AD7190_Read_byte * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ StatusType AD7190_Read_byte(U1 *pbytedata) { StatusType retVal = ERR_OK; spi_ifc_handle tu1_ifc = spi_dev_cfg[SPI_DEV_AD7190].IfcHandle; /*if(ERR_OK == spi_ifc_Pend(tu1_ifc))*/ if(1) { spi_ifc_r[tu1_ifc].IntEn = AD7190_INT_EN; spi_ifc_r[tu1_ifc].u2TxHeadSize = 0; /*Head*/ spi_ifc_r[tu1_ifc].pu1TxBuff = (U1*)0; /*TxBuff*/ spi_ifc_r[tu1_ifc].pu2TxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2TxOffset = 0; spi_ifc_r[tu1_ifc].u2TxSize = 0; spi_ifc_r[tu1_ifc].pu1RxBuff = pbytedata; /*RxBuff*/ spi_ifc_r[tu1_ifc].pu2RxBuff = (U2*)0; spi_ifc_r[tu1_ifc].u2RxOffset = 0; spi_ifc_r[tu1_ifc].u2RxSize = 1; spi_ifc_r[tu1_ifc].u2TotalLen = 1; /*Total Length*/ spi_ifc_cfg[tu1_ifc].pfSpiCommRun(SPI_DEV_AD7190); if(ERR_OK != spi_ifc_r[tu1_ifc].u1Err) { retVal = ERR_FAIL; } /* spi_ifc_Post(tu1_ifc);*/ } else { retVal = ERR_ACCESS; } return retVal; } 这是api_ad7190.c /* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #ifndef _API_AD7190_H_ #define _API_AD7190_H_ #include "includes.h" #include "Config.h" StatusType ad7190_comm_Pend(void); void ad7190_comm_Post(void); StatusType AD7190_Read(U1 databuff[],U2 datalen); StatusType AD7190_Write_byte(U1 bytedata); StatusType AD7190_Write(U2 addr,U1 databuff[],U2 datalen); StatusType AD7190_Read_byte(U1 *pbytedata); #endif 这是api_ad7190.h,将其中的ucos相关函数替换为裸机可用,不依靠ucos底层,不删去文件中的头文件部分内容,可以增加,修改后的文件名称不作改变,将修改后的完整代码发出
01-06
/* * Copyright (c) 2014, SHENZHEN HANGSHENG ELECTRONICS Co., Ltd. * All Rights Reserved. * Dept.: ACEC * File: Spi0.c * Description: SPI0 driver for NXP DSPI module, adapted for bare-metal use * History: * 2014-3-1, 1306104, original * 2025-04-05, Modified for bare-metal (no uCOS) */ #include "Spi0.h" #include "spi_config.h" #include "int_index.h" #include "user_timer.h" #include "bsp_var.h" #if USE_SPI > 0 #if (APP_HW_VERSION_AB802_0_0 != APP_HW_VERSION) /* === 寄存器映射宏定义(基于 DSPI_0)=== */ #define DSPI(x) DSPI_##x /* 读写状态和数据寄存器 */ #define RD_SPISR(SPI0) (DSPI_0.SR.R) #define RD_SPIDR(SPI0) (DSPI_0.POPR.R & SPI0_BitWidth_Mask) #define WR_SPIDR(SPI0, x, y) (DSPI_0.PUSHR.R = ((y > 0) ? \ ((x & SPI0_BitWidth_Mask) + SPI0_PUSHR_cs_Mask) : \ ((x & SPI0_BitWidth_Mask) + SPI0_PUSHR_cs_Mask + 0x88000000u))) #define CLR_SPISR_TFFF(SPI0) (DSPI_0.SR.B.TFFF = 0x01) #define CLR_SPISR_RFDF(SPI0) (DSPI_0.SR.B.RFDF = 0x01) #define CLR_SPI_TFFF_IE(SPI0) (DSPI_0.RSER.B.TFFFRE = 0x00) #define CLR_SPI_RFDF_IE(SPI0) (DSPI_0.RSER.B.RFDFRE = 0x00) #define SET_SPI_TFFF_IE(SPI0) (DSPI_0.RSER.B.TFFFRE = 0x01) #define SET_SPI_RFDF_IE(SPI0) (DSPI_0.RSER.B.RFDFRE = 0x01) /* 中断标志掩码 */ #define SPISR_TCF_MASK (0x80000000u) #define SPISR_TFFF_MASK (0x02000000u) #define SPISR_RFDF_MASK (0x00020000u) /*==========================================================================*/ /* L O C A L F U N C T I O N S P R O T O T Y P E S */ /*==========================================================================*/ static void SPI0_TFFF_Handler(void); static void SPI0_RFDF_Handler(void); static void SPI0_ChannelConfigure(U1 DevNum); static void SPI0_ShiftBytes(void); static void SPI0_IntEn_FirstTx(void); /* 全局变量:CS 片选与位宽掩码 */ static U4 SPI0_PUSHR_cs_Mask; static U4 SPI0_BitWidth_Mask; /*==========================================================================*/ /* F U N C T I O N S */ /*==========================================================================*/ /* * Function: SPI0_Init * Description: 初始化 SPI0 控制器 */ void SPI0_Init(void) { U1 i; /* Disable module before configuration */ DSPI_0.MCR.B.MDIS = 1u; /* Register interrupt handlers */ (void)BSP_INTC_IntReg(&SPI0_TFFF_Handler, INTC_INDEX_SPI0_TFFF, 1); (void)BSP_INTC_IntReg(&SPI0_RFDF_Handler, INTC_INDEX_SPI0_RFDF, 2); /* Master mode, FIFOs enabled, HALT=1 initially */ DSPI_0.MCR.R = 0x803F0C01u; /* Enable FIFOs, clear on reset */ /* Configure each device's CTAR register */ for(i = 0; i < SPI_NUM_OF_DEV; i++) { if(SPI0 == spi_dev_cfg[i].IfcHandle) { SPI0_ChannelConfigure(i); } } } /* * Function: SPI0_Deinit * Description: 停用 SPI 模块 */ void SPI0_Deinit(void) { DSPI_0.MCR.B.MDIS = 1u; } /* * Function: SPI0_CommRun * Description: 启动一次 SPI 数据通信(支持中断和轮询模式) */ void SPI0_CommRun(U1 DevNum) { U1 tu1_err = 0; U2 tu2_tempLen = 0; U1 CsChannel = spi_dev_cfg[DevNum].CsChannel; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); /* --- 参数合法性检查 --- */ if(ERR_OK != spi_ifc_CfgCheck(pspi_ifc_r, DevNum)) { DBG_MSG(DBG_EN, "spi0 ifc access error\r\n"); pspi_ifc_r->u1Err = ERR_ACCESS; return; } if(SPI_ERR_CRITICAL < pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt--; pspi_ifc_r->u1Err = ERR_FAIL; return; } /* --- 初始化传输状态 --- */ pspi_ifc_r->u2TxLen = 0; pspi_ifc_r->u2RxLen = 0; pspi_ifc_r->u2TxSize += pspi_ifc_r->u2TxOffset; pspi_ifc_r->u2RxSize += pspi_ifc_r->u2RxOffset; pspi_ifc_r->u1Err = ERR_OK; /* 设置 CS 掩码和位宽掩码 */ SPI0_PUSHR_cs_Mask = (0x00010000UL << CsChannel) + (((U4)CsChannel) << 28); SPI0_BitWidth_Mask = SPIBitWidthMaskTab[spi_dev_cfg[DevNum].BitWidth - 4]; /* 清空 FIFO */ DSPI_0.MCR.B.CLR_TXF = 1; DSPI_0.MCR.B.CLR_RXF = 1; /* 清除残留接收数据 */ (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); /* 拉低片选 */ if(spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(0); } /* 退出 HALT 模式,开始传输 */ DSPI_0.MCR.B.HALT = 0; if(TRUE == pspi_ifc_r->IntEn) { /* 中断模式 */ if(0 == (SPISR_TFFF_MASK & RD_SPISR(SPI0))) { SPI0_IntEn_FirstTx(); } else { __disable_irq(); SET_SPI_RFDF_IE(SPI0); SET_SPI_TFFF_IE(SPI0); __enable_irq(); } /* 轮询等待完成(裸机下无法阻塞任务) */ USER_TIMER timer; reset_usertime(&timer); while(pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); /* 超时判断 */ if(get_usertime(&timer) > (UT_1US * 1000 * SPI_HW_TIMEOUT)) { tu1_err = 2; /* Timeout */ break; } /* 错误提前终止 */ if(pspi_ifc_r->u1Err != ERR_OK) { tu1_err = 2; break; } } /* 关闭中断 */ __disable_irq(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); __enable_irq(); } else { /* 轮询模式 */ __disable_irq(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); __enable_irq(); SPI0_ShiftBytes(); } /* --- 传输结果判定 --- */ if(tu1_err || (pspi_ifc_r->u2RxLen != pspi_ifc_r->u2TotalLen)) { if(255 > pspi_ifc_r->u1ErrCnt) pspi_ifc_r->u1ErrCnt++; spi_ifc_cfg[SPI0].pfSpiInit(); /* Re-init if needed */ pspi_ifc_r->u1Err = ERR_FAIL; } else { if(5 <= pspi_ifc_r->u1ErrCnt) pspi_ifc_r->u1ErrCnt -= 5; else pspi_ifc_r->u1ErrCnt = 0; } /* 拉高片选 */ if(spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(1); } /* 进入 HALT 模式 */ DSPI_0.MCR.B.HALT = 1; } /* * Function: SPI0_GetTransData * Description: 获取下一个要发送的数据字节/字 */ static U1 SPI0_GetTransData(U4 *pdata) { spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxHeadSize) { *pdata = (U4)(pspi_ifc_r->u2TxHead[pspi_ifc_r->u2TxLen]); } else if((pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxSize) && (pspi_ifc_r->u2TxLen >= pspi_ifc_r->u2TxOffset)) { if(0x000000FF < SPI0_BitWidth_Mask) { *pdata = (U4)(pspi_ifc_r->pu2TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } else { *pdata = (U4)(pspi_ifc_r->pu1TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } } else { *pdata = 0xFFFFul; } pspi_ifc_r->u2TxLen++; return (pspi_ifc_r->u2TxLen == pspi_ifc_r->u2TotalLen) ? 1 : 0; } /* * Function: SPI0_SetReceiveData * Description: 存储接收到的数据 */ static U1 SPI0_SetReceiveData(U4 data) { spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if((pspi_ifc_r->u2RxLen >= pspi_ifc_r->u2RxOffset) && (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2RxSize)) { if(0x000000FF < SPI0_BitWidth_Mask) { pspi_ifc_r->pu2RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U2)data; } else { pspi_ifc_r->pu1RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U1)data; } } pspi_ifc_r->u2RxLen++; return (pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) ? 1 : 0; } /* * Function: SPI0_TFFF_Handler * Description: 发送 FIFO 空中断处理程序 */ static void SPI0_TFFF_Handler(void) { U4 spisr = RD_SPISR(SPI0); U4 data; U1 cnt = 0; while ((cnt++ < 4) && (SPISR_TFFF_MASK & spisr)) { if(0 == SPI0_GetTransData(&data)) { WR_SPIDR(SPI0, data, 0); CLR_SPISR_TFFF(SPI0); } else { CLR_SPI_TFFF_IE(SPI0); WR_SPIDR(SPI0, data, 1); CLR_SPISR_TFFF(SPI0); break; } spisr = RD_SPISR(SPI0); } } /* * Function: SPI0_RFDF_Handler * Description: 接收 FIFO 满中断处理程序 */ static void SPI0_RFDF_Handler(void) { U4 spisr = RD_SPISR(SPI0); U4 data; while(SPISR_RFDF_MASK & spisr) { data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != SPI0_SetReceiveData(data)) { CLR_SPI_RFDF_IE(SPI0); /* 最后一字节,关闭中断 */ } spisr = RD_SPISR(SPI0); } } /* * Function: SPI0_IntEn_FirstTx * Description: 手动触发第一次发送并使能中断 */ static void SPI0_IntEn_FirstTx(void) { U4 data; if(0 == SPI0_GetTransData(&data)) { WR_SPIDR(SPI0, data, 0); __disable_irq(); SET_SPI_RFDF_IE(SPI0); SET_SPI_TFFF_IE(SPI0); __enable_irq(); } else { WR_SPIDR(SPI0, data, 1); __disable_irq(); SET_SPI_RFDF_IE(SPI0); __enable_irq(); } } /* * Function: SPI0_ShiftBytes * Description: 轮询模式下的全双工收发 */ static void SPI0_ShiftBytes(void) { USER_TIMER timer; U1 timeout_flag = 0; U4 data; U4 spisr; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); reset_usertime(&timer); while(pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); spisr = RD_SPISR(SPI0); /* 处理接收 FIFO */ if(spisr & SPISR_RFDF_MASK) { data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)SPI0_SetReceiveData(data); reset_usertime(&timer); /* 刷新超时计时 */ } /* 处理发送 FIFO */ if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TotalLen) { if((spisr & SPISR_TFFF_MASK) || (pspi_ifc_r->u2TxLen == 0)) { if(spisr & SPISR_TFFF_MASK) { CLR_SPISR_TFFF(SPI0); } if(0 == SPI0_GetTransData(&data)) { WR_SPIDR(SPI0, data, 0); } else { WR_SPIDR(SPI0, data, 1); } reset_usertime(&timer); } else { /* 发送缓冲区满,等待或超时 */ if(timeout_flag || get_usertime(&timer) > (UT_1US*1000*SPI_HW_TIMEOUT)) { timeout_flag = 1; pspi_ifc_r->u1Err = ERR_FAIL; break; } } } else { /* 已发送完,但未收完,继续等接收 */ if(timeout_flag || get_usertime(&timer) > (UT_1US*1000*SPI_HW_TIMEOUT)) { timeout_flag = 1; pspi_ifc_r->u1Err = ERR_FAIL; break; } } } } /* * Function: SPI0_ChannelConfigure * Description: 配置 SPI 设备通道参数(波特率、CPOL、CPHA 等) */ static void SPI0_ChannelConfigure(U1 DevNum) { U4 tu4_n; U1 tu1_i; U1 cs_ch = spi_dev_cfg[DevNum].CsChannel; /* 默认配置 */ DSPI_0.CTAR[cs_ch].R = 0x38000000ul; /* 设置帧大小 */ if(spi_dev_cfg[DevNum].BitWidth > 16 || spi_dev_cfg[DevNum].BitWidth < 4) { DSPI_0.CTAR[cs_ch].B.FMSZ = 7; // 默认 8-bit } else { DSPI_0.CTAR[cs_ch].B.FMSZ = spi_dev_cfg[DevNum].BitWidth - 1; } /* 计算波特率分频参数 */ tu4_n = ((peri_set2_clk + spi_dev_cfg[DevNum].Baudrate) - 1) / spi_dev_cfg[DevNum].Baudrate; for(tu1_i = 0; tu1_i < 60; tu1_i++) { if(SPI_BAUD_CMP[tu1_i] >= tu4_n) break; } DSPI_0.CTAR[cs_ch].B.PBR = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[cs_ch].B.BR = SPI_BR_PARA[tu1_i][1]; DSPI_0.CTAR[cs_ch].B.CPOL = (spi_dev_cfg[DevNum].IdleLevelHighEn > 0) ? 1 : 0; DSPI_0.CTAR[cs_ch].B.CPHA = (spi_dev_cfg[DevNum].SampleEvenEdgeEn > 0) ? 1 : 0; DSPI_0.CTAR[cs_ch].B.LSBFE = (spi_dev_cfg[DevNum].LSB_FirstEnable > 0) ? 1 : 0; DSPI_0.CTAR[cs_ch].B.PCSSCK = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[cs_ch].B.CSSCK = SPI_BR_PARA[tu1_i][1]; DSPI_0.CTAR[cs_ch].B.PASC = SPI_BR_PARA[tu1_i][0]; DSPI_0.CTAR[cs_ch].B.ASC = SPI_BR_PARA[tu1_i][1]; } #else /* 使用 DSPI_2 替代 DSPI_0(适用于不同硬件版本) */ #define RD_SPISR(SPI0) (DSPI_2.SR.R) #define RD_SPIDR(SPI0) (DSPI_2.POPR.R & SPI0_BitWidth_Mask) #define WR_SPIDR(SPI0,x,y) (DSPI_2.PUSHR.R = ((y>0)?((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)):((x & SPI0_BitWidth_Mask)+(SPI0_PUSHR_cs_Mask)+0x88000000u))) #define CLR_SPISR_TFFF(SPI0) (DSPI_2.SR.B.TFFF = 0x01) #define CLR_SPISR_RFDF(SPI0) (DSPI_2.SR.B.RFDF = 0x01) #define CLR_SPI_TFFF_IE(SPI0) (DSPI_2.RSER.B.TFFFRE = 0x00) #define CLR_SPI_RFDF_IE(SPI0) (DSPI_2.RSER.B.RFDFRE = 0x00) #define SET_SPI_TFFF_IE(SPI0) (DSPI_2.RSER.B.TFFFRE = 0x01) #define SET_SPI_RFDF_IE(SPI0) (DSPI_2.RSER.B.RFDFRE = 0x01) #define SPISR_TCF_MASK (0x80000000u) #define SPISR_TFFF_MASK (0x02000000u) #define SPISR_RFDF_MASK (0x00020000u) static void SPI0_TFFF_Handler(void); static void SPI0_RFDF_Handler(void); static void SPI0_ChannelConfigure(U1 DevNum); static void SPI0_ShiftBytes(void); static void SPI0_IntEn_FirstTx(void); static U4 SPI0_PUSHR_cs_Mask; static U4 SPI0_BitWidth_Mask; void SPI0_Init(void) { U1 i; DSPI_2.MCR.B.MDIS = 1u; (void)BSP_INTC_IntReg(&SPI0_TFFF_Handler, INTC_INDEX_SPI2_TFFF, 1); (void)BSP_INTC_IntReg(&SPI0_RFDF_Handler, INTC_INDEX_SPI2_RFDF, 2); DSPI_2.MCR.R = 0x803F0C01u; for(i = 0; i < SPI_NUM_OF_DEV; i++) { if(SPI0 == spi_dev_cfg[i].IfcHandle) { SPI0_ChannelConfigure(i); } } } void SPI0_Deinit(void) { DSPI_2.MCR.B.MDIS = 1u; } void SPI0_CommRun(U1 DevNum) { U1 tu1_err = 0; U2 tu2_tempLen = 0; U1 CsChannel = spi_dev_cfg[DevNum].CsChannel; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if(ERR_OK != spi_ifc_CfgCheck(pspi_ifc_r, DevNum)) { DBG_MSG(DBG_EN, "spi0 ifc access error\r\n"); pspi_ifc_r->u1Err = ERR_ACCESS; return; } if(SPI_ERR_CRITICAL < pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt--; pspi_ifc_r->u1Err = ERR_FAIL; return; } pspi_ifc_r->u2TxLen = 0; pspi_ifc_r->u2RxLen = 0; pspi_ifc_r->u2TxSize += pspi_ifc_r->u2TxOffset; pspi_ifc_r->u2RxSize += pspi_ifc_r->u2RxOffset; pspi_ifc_r->u1Err = ERR_OK; SPI0_PUSHR_cs_Mask = (0x00010000UL << CsChannel) + (((U4)CsChannel) << 28); SPI0_BitWidth_Mask = SPIBitWidthMaskTab[spi_dev_cfg[DevNum].BitWidth - 4]; DSPI_2.MCR.B.CLR_TXF = 1; DSPI_2.MCR.B.CLR_RXF = 1; (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(0); } DSPI_2.MCR.B.HALT = 0; if(TRUE == pspi_ifc_r->IntEn) { if(0 == (SPISR_TFFF_MASK & RD_SPISR(SPI0))) { SPI0_IntEn_FirstTx(); } else { __disable_irq(); SET_SPI_RFDF_IE(SPI0); SET_SPI_TFFF_IE(SPI0); __enable_irq(); } USER_TIMER timer; reset_usertime(&timer); while(pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); if(get_usertime(&timer) > (UT_1US*1000*SPI_HW_TIMEOUT)) { tu1_err = 2; break; } if(pspi_ifc_r->u1Err != ERR_OK) { tu1_err = 2; break; } } __disable_irq(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); __enable_irq(); } else { __disable_irq(); CLR_SPI_RFDF_IE(SPI0); CLR_SPI_TFFF_IE(SPI0); __enable_irq(); SPI0_ShiftBytes(); } if(tu1_err || (pspi_ifc_r->u2RxLen != pspi_ifc_r->u2TotalLen)) { if(255 > pspi_ifc_r->u1ErrCnt) pspi_ifc_r->u1ErrCnt++; spi_ifc_cfg[SPI0].pfSpiInit(); pspi_ifc_r->u1Err = ERR_FAIL; } else { if(5 <= pspi_ifc_r->u1ErrCnt) pspi_ifc_r->u1ErrCnt -= 5; else pspi_ifc_r->u1ErrCnt = 0; } if(spi_dev_cfg[DevNum].pFuncCsCtrl) { spi_dev_cfg[DevNum].pFuncCsCtrl(1); } DSPI_2.MCR.B.HALT = 1; } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static U1 SPI0_GetTransData(U4 *pdata) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if(pspi_ifc_r->u2TxLen < (pspi_ifc_r->u2TxHeadSize)) { *pdata = (U4)(pspi_ifc_r->u2TxHead[pspi_ifc_r->u2TxLen]); } else if((pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TxSize) && (pspi_ifc_r->u2TxLen >= pspi_ifc_r->u2TxOffset)) { if(0x000000FF < SPI0_BitWidth_Mask) { *pdata = (U4)(pspi_ifc_r->pu2TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } else { *pdata = (U4)(pspi_ifc_r->pu1TxBuff[pspi_ifc_r->u2TxLen - pspi_ifc_r->u2TxOffset]); } } else { *pdata = 0x0000FFFFul; } pspi_ifc_r->u2TxLen++; if(pspi_ifc_r->u2TxLen == pspi_ifc_r->u2TotalLen) /*tx finish*/ { ret = 1; } else { ret = 0;/*It isn't the Endian-unit in the queue*/ } return ret; } static U1 SPI0_SetReceiveData(U4 data) { U1 ret; spi_ifc_register *pspi_ifc_r = &(spi_ifc_r[SPI0]); if((pspi_ifc_r->u2RxLen >= pspi_ifc_r->u2RxOffset) && (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2RxSize)) { if(0x000000FF < SPI0_BitWidth_Mask) { pspi_ifc_r->pu2RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U2)data; } else { pspi_ifc_r->pu1RxBuff[pspi_ifc_r->u2RxLen - pspi_ifc_r->u2RxOffset] = (U1)data; } } else { } pspi_ifc_r->u2RxLen ++; if(pspi_ifc_r->u2RxLen == pspi_ifc_r->u2TotalLen) /*comm finish*/ { if(TRUE == OSRunning) { (void)OSSemPost(spi_ifc_r[SPI0].pOsEventSemFinishFlag); } ret = 1; } else { ret = 0; } return ret; } /* * Function: SPI0_TFFF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Transmit FIFO Fill Interrupt * Note: * REQ IDs: */ static void SPI0_TFFF_Handler(void) { U4 spisr; U4 data; U1 cnt = 0; spisr = (U4)RD_SPISR(SPI0); while ((cnt++ < 4) && (0 != (SPISR_TFFF_MASK & spisr))) { /*tx fifo empty*/ if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { CLR_SPI_TFFF_IE(SPI0);/*disable TCF interrupt*/ WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); break; } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_RFDF_Handler * Param< void >: * Param< void >: * Return< void >: * Discription: Receive FIFO Drain Interrupt * Note: * REQ IDs: */ static void SPI0_RFDF_Handler(void) { U4 spisr; U4 data; spisr = (U4)RD_SPISR(SPI0); while(0 != (SPISR_RFDF_MASK & spisr)) { /*rx fifo is not empty*/ data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); if(0 != SPI0_SetReceiveData(data))/*It is the Endian-unit in the queue*/ { CLR_SPI_RFDF_IE(SPI0);/*disable RFDF-interrupt */ } else/*It isn't the Endian-unit in the queue*/ { } spisr = (U4)RD_SPISR(SPI0); } } /* * Function: SPI0_IntEn_FirstTx * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_IntEn_FirstTx(void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif U4 data; if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ SET_SPI_TFFF_IE(SPI0);/*enable TCF interrupt*/ OS_EXIT_CRITICAL(); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ OS_ENTER_CRITICAL(); SET_SPI_RFDF_IE(SPI0);/*enable RFDF interrupt*/ OS_EXIT_CRITICAL(); } } /* * Function: SPI0_ShiftBytes * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ShiftBytes(void) { USER_TIMER temptimer; U1 timeout_flag = 0; U4 data; U4 spisr; spi_ifc_register *pspi_ifc_r; pspi_ifc_r = &(spi_ifc_r[SPI0]); reset_usertime(&temptimer); while (pspi_ifc_r->u2RxLen < pspi_ifc_r->u2TotalLen) { Feed_sw_dog(); spisr = RD_SPISR(SPI0); if(0 != (SPISR_RFDF_MASK & spisr))/*Rx fifo is not empty*/ { data = RD_SPIDR(SPI0); CLR_SPISR_RFDF(SPI0); (void)SPI0_SetReceiveData(data); /*comm finish*/ reset_usertime(&temptimer); } if(pspi_ifc_r->u2TxLen < pspi_ifc_r->u2TotalLen) { if((0 != (SPISR_TFFF_MASK & spisr)) || (pspi_ifc_r->u2TxLen == 0)) { /*tx fifo is not full*/ if(0 != (SPISR_TFFF_MASK & spisr)) { CLR_SPISR_TFFF(SPI0); } if(0 == SPI0_GetTransData(&data)) /*It isn't the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,0);/*write the Nor Endian Byte*/ CLR_SPISR_TFFF(SPI0); } else/*It is the Endian-unit in the queue*/ { WR_SPIDR(SPI0,data,1);/*write the Endian Byte*/ CLR_SPISR_TFFF(SPI0); } reset_usertime(&temptimer); } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } else { if(0 != timeout_flag) { if(255 > pspi_ifc_r->u1ErrCnt) { pspi_ifc_r->u1ErrCnt ++; } pspi_ifc_r->u1Err = ERR_FAIL; break; } else { if(get_usertime(&temptimer) > ((UT_1US*1000*SPI_HW_TIMEOUT))) { timeout_flag = 1; } } } } } /* * Function: SPI0_ChannelConfigure * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ static void SPI0_ChannelConfigure(U1 DevNum) { U4 tu4_n; U1 tu1_i; U1 tu1_cs_channel; tu1_cs_channel = spi_dev_cfg[DevNum].CsChannel; DSPI_2.CTAR[tu1_cs_channel].R = 0x38000000ul;/*default value*/ if((spi_dev_cfg[DevNum].BitWidth > 16) || (spi_dev_cfg[DevNum].BitWidth < 4)) { DSPI_2.CTAR[tu1_cs_channel].B.FMSZ = (U4)7; /* Configure data as 8 bits */ } else { DSPI_2.CTAR[tu1_cs_channel].B.FMSZ = (U4)(spi_dev_cfg[DevNum].BitWidth-1); /* Configure data as 4~16 bits */ } tu4_n = ((peri_set2_clk + spi_dev_cfg[DevNum].Baudrate) - 1) / spi_dev_cfg[DevNum].Baudrate; for(tu1_i=0; tu1_i<60; tu1_i++) { if(SPI_BAUD_CMP[tu1_i] >= tu4_n) { break; } } DSPI_2.CTAR[tu1_cs_channel].B.PBR = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.BR = SPI_BR_PARA[tu1_i][1]; DSPI_2.CTAR[tu1_cs_channel].B.CPOL = ((spi_dev_cfg[DevNum].IdleLevelHighEn>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.CPHA = ((spi_dev_cfg[DevNum].SampleEvenEdgeEn>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.LSBFE = ((spi_dev_cfg[DevNum].LSB_FirstEnable>0)?1:0); DSPI_2.CTAR[tu1_cs_channel].B.PCSSCK = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.CSSCK = SPI_BR_PARA[tu1_i][1]; DSPI_2.CTAR[tu1_cs_channel].B.PASC = SPI_BR_PARA[tu1_i][0]; DSPI_2.CTAR[tu1_cs_channel].B.ASC = SPI_BR_PARA[tu1_i][1]; /*DSPI_2.MCR.B.HALT = 0x0;*/ } #endif /* (APP_HW_VERSION_AB802_0_0 != APP_HW_VERSION) */ #endif /* USE_SPI > 0 */
01-07
/* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #include "includes.h" #include "Spi_config.h" #include "bsp_cpu.h" #include "api_esp32.h" #include "FOTON_BMS_STRATEGY_private.h" uint16_t CellVolt[CELL_VOLT_LEN]; uint16_t Batt_CellVolt[BATT_CELL_VOLT_LEN]; uint32_t MdlTemp[MDL_TEMP_LEN]; uint16_t Batt_MdlTemp[MDL_TEMP_LEN]; /*==========================================================================*/ /* L O C A L D A T A D E F I N I T I O N S */ /*==========================================================================*/ /*==========================================================================*/ /* L O C A L F U N C T I O N S P R O T O T Y P E S */ /*==========================================================================*/ /*==========================================================================*/ /* F U N C T I O N S */ /*==========================================================================*/ /* * Function: AD7988_init * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ void AD7988_init(void) { AD7988_CNV_ON(); } /* * Function: AD7988_readdata * Param< void >: * Param< void >: * Return< void >: * Discription: * Note: * REQ IDs: */ StatusType AD7988_readdata(U2 addr, U2 databuff[], U2 datalen) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif StatusType retVal = ERR_OK; spi_ifc_handle tu1_ifc; (void)addr; tu1_ifc = spi_dev_cfg[SPI_DEV_AD7988].IfcHandle; if(ERR_OK == spi_ifc_Pend(tu1_ifc)) { spi_ifc_r[tu1_ifc].IntEn = AD7988_INT_EN; spi_ifc_r[tu1_ifc].u2TxHeadSize = 0; /*Head*/ spi_ifc_r[tu1_ifc].pu1TxBuff = (U1*)0x02; /*TxBuff*/ spi_ifc_r[tu1_ifc].pu2TxBuff = (U2*)0x0A; spi_ifc_r[tu1_ifc].u2TxOffset = 0; spi_ifc_r[tu1_ifc].u2TxSize = 0x02; spi_ifc_r[tu1_ifc].pu1RxBuff = (U1*)0; /*RxBuff*/ spi_ifc_r[tu1_ifc].pu2RxBuff = databuff; spi_ifc_r[tu1_ifc].u2RxOffset = 0; spi_ifc_r[tu1_ifc].u2RxSize = datalen; spi_ifc_r[tu1_ifc].u2TotalLen = datalen + 0; /*Total Length*/ spi_ifc_cfg[tu1_ifc].pfSpiCommRun(SPI_DEV_AD7988); if(ERR_OK != spi_ifc_r[tu1_ifc].u1Err) { retVal = ERR_FAIL; } else { OS_ENTER_CRITICAL(); databuff[0] = (databuff[0]) & 0xFFFF; OS_EXIT_CRITICAL(); } spi_ifc_Post(tu1_ifc); } else { retVal = ERR_ACCESS; } return retVal; } /** * @brief SPI2 主机模式连续收发 * @param tx_data [in] 要发送的数据(如果只是接收,则传 NULL) * @param rx_data [out] 接收缓冲数组(保存从机 MISO 数据) * @param len [in] 数据个数(以 16bit 为单位,因为 BitWidth=16) * @return ERR_OK:成功;ERR_FAIL:通信失败;ERR_ACCESS:SPI总线忙 */ StatusType SPI2_Master_Transfer(U2 *tx_data, U2 *rx_data, U2 len) { #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr = 0; #endif static U2 dummy_tx[256]; U2 i; StatusType ret = ERR_OK; spi_ifc_handle ifc = SPI2; // SPI2 对应 DSPI_1 U1 devNum = SPI_DEV_AD7988; // 对应配置表中 SPI_I_CS if (ERR_OK == spi_ifc_Pend(ifc)) { spi_ifc_r[ifc].IntEn = TRUE; spi_ifc_r[ifc].u2TxHeadSize = 0; spi_ifc_r[ifc].pu2TxBuff = tx_data; spi_ifc_r[ifc].pu1TxBuff = (U1 *)0; spi_ifc_r[ifc].u2TxOffset = 0; spi_ifc_r[ifc].u2TxSize = len; spi_ifc_r[ifc].pu2RxBuff = rx_data; spi_ifc_r[ifc].pu1RxBuff = (U1 *)0; spi_ifc_r[ifc].u2RxOffset = 0; spi_ifc_r[ifc].u2RxSize = len; spi_ifc_r[ifc].u2TotalLen = len; // 片选拉低(开始通信) if (spi_dev_cfg[devNum].pFuncCsCtrl != NULL) spi_dev_cfg[devNum].pFuncCsCtrl(0); // 启动通信(产生时钟并处理FIFO) spi_ifc_cfg[ifc].pfSpiCommRun(devNum); // 片选拉高(结束通信) if (spi_dev_cfg[devNum].pFuncCsCtrl != NULL) spi_dev_cfg[devNum].pFuncCsCtrl(1); if (ERR_OK != spi_ifc_r[ifc].u1Err) ret = ERR_FAIL; spi_ifc_Post(ifc); } else { ret = ERR_ACCESS; } return ret; } #if 0 void read_vol_from_esp32(void) { static U2 tx_buffer0[ESP32_RX_LEN]; static U2 tx_buffer1[ESP32_RX_LEN]; static U2 tx_buffer2[ESP32_RX_LEN]; static U2 tx_buffer3[ESP32_RX_LEN]; static U2 tx_buffer4[ESP32_RX_LEN]; static U2 tx_buffer5[ESP32_RX_LEN]; static U2 tx_buffer6[ESP32_RX_LEN]; static U2 tx_buffer7[ESP32_RX_LEN]; static U2 rx_buffer0[ESP32_RX_LEN]; // 存放接收数据 static U2 rx_buffer1[ESP32_RX_LEN]; static U2 rx_buffer2[ESP32_RX_LEN]; static U2 rx_buffer3[ESP32_RX_LEN]; static U2 rx_buffer4[ESP32_RX_LEN]; static U2 rx_buffer5[ESP32_RX_LEN]; static U2 rx_buffer6[ESP32_RX_LEN]; static U2 rx_buffer7[ESP32_RX_LEN]; static U2 com_buffer0[COM_NO_LEN];//单放命令段 static U2 com_buffer1[COM_NO_LEN]; static U2 com_buffer2[COM_NO_LEN]; static U2 com_buffer3[COM_NO_LEN]; static U2 com_buffer4[COM_NO_LEN]; static U2 com_buffer5[COM_NO_LEN]; static U2 com_buffer6[COM_NO_LEN]; static U2 com_buffer7[COM_NO_LEN]; static U2 com_rx_buffer[COM_NO_LEN]; static U2 tx_id = 0; // 发送索引 static U1 rx_id = 0; // 接收索引 static U1 rx_value = 0; // 接收内容 static U1 half_data[ESP32_RX_LEN] = {0}; // 存放半个数据,用ID索引 static U1 group = 0; static U2 i = 0; static U2 j = 0; for(i=0;i<COM_NO_LEN;i++) { com_buffer0[i] = 0xAA00; com_buffer1[i] = 0xAA01; com_buffer2[i] = 0xAA02; com_buffer3[i] = 0xAA03; com_buffer4[i] = 0xAA04; com_buffer5[i] = 0xAA05; com_buffer6[i] = 0xAA06; com_buffer7[i] = 0xAA07; } for(tx_id=0;tx_id<ESP32_RX_LEN;tx_id++) { tx_buffer0[tx_id] = 0x0000; tx_buffer1[tx_id] = 0x0001; tx_buffer2[tx_id] = 0x0002; tx_buffer3[tx_id] = 0x0003; tx_buffer4[tx_id] = 0x0004; tx_buffer5[tx_id] = 0x0005; tx_buffer6[tx_id] = 0x0006; tx_buffer7[tx_id] = 0x0007; } #if 1 //第一包数据 if (SPI2_Master_Transfer(com_buffer0, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer0, rx_buffer0, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer0[i]== 0xAABB) { if(rx_buffer0[i+1]== 0x0000) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j] = rx_buffer0[i+j+2]; } else { MdlTemp[0] = rx_buffer0[i+18]; } } } } } } } #endif //第二包数据 if (SPI2_Master_Transfer(com_buffer1, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer1, rx_buffer1, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer1[i]== 0xAABB) { if(rx_buffer1[i+1]== 0x0001) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+16] = rx_buffer1[i+j+2]; } else { MdlTemp[1] = rx_buffer1[i+18]; } } } } } } } //第三包数据 if (SPI2_Master_Transfer(com_buffer2, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer2, rx_buffer2, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer2[i]== 0xAABB) { if(rx_buffer2[i+1]== 0x0002) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+32] = rx_buffer2[i+j+2]; } else { MdlTemp[2] = rx_buffer2[i+18]; } } } } } } } //第四包数据 if (SPI2_Master_Transfer(com_buffer3, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer3, rx_buffer3, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer3[i]== 0xAABB) { if(rx_buffer3[i+1]== 0x0003) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+48] = rx_buffer3[i+j+2]; } else { MdlTemp[3] = rx_buffer3[i+18]; } } } } } } } //第五包数据 if (SPI2_Master_Transfer(com_buffer4, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer4, rx_buffer4, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer4[i]== 0xAABB) { if(rx_buffer4[i+1]== 0x0004) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+64] = rx_buffer4[i+j+2]; } else { MdlTemp[4] = rx_buffer4[i+18]; } } } } } } } //第六包数据 if (SPI2_Master_Transfer(com_buffer5, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer5, rx_buffer5, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer5[i]== 0xAABB) { if(rx_buffer5[i+1]== 0x0005) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+80] = rx_buffer5[i+j+2]; } else { MdlTemp[5] = rx_buffer5[i+18]; } } } } } } } //第七包数据 if (SPI2_Master_Transfer(com_buffer6, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer6, rx_buffer6, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer6[i]== 0xAABB) { if(rx_buffer6[i+1]== 0x0006) { for(j = 0;j < 17;j++) { if(j < 16) { CellVolt[j+96] = rx_buffer6[i+j+2]; } else { MdlTemp[6] = rx_buffer6[i+18]; } } } } } } } //第八包数据(小电瓶) if (SPI2_Master_Transfer(com_buffer7, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer7, rx_buffer7, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer7[i]== 0xAABB) { if(rx_buffer7[i+1]== 0x0007) { for(j = 0;j < 17;j++) { if(j < 16) { Batt_CellVolt[j] = rx_buffer6[i+j+2]; } else { Batt_MdlTemp[0] = rx_buffer6[i+18]; } } } } } } } } #endif void read_vol_from_esp32(void) { static U2 tx_buffer[ESP32_RX_LEN]; static U2 rx_buffer[ESP32_RX_LEN]; // 存放接收数据 static U2 com_buffer[COM_NO_LEN];//单放命令段 static U2 com_rx_buffer[COM_NO_LEN]; static U2 tx_id = 0; // 发送索引 static U1 rx_id = 0; // 接收索引 static U1 board_num = 0; static U2 i = 0; static U2 j = 0; static U1 su1_canUpdateCnt = 1; static U1 cell_index = 0; static U1 tem_index = 0; for(board_num = 0; board_num < Z_SLAVE_NUM; board_num++) { for(i = 0; i < COM_NO_LEN; i++) { com_buffer[i] = 0xAA00 + board_num; //头部指令 } for(tx_id = 0; tx_id < ESP32_RX_LEN; tx_id++) { tx_buffer[tx_id] = 0x0000 + board_num; //填充指令作为数据包 } if (SPI2_Master_Transfer(com_buffer, com_rx_buffer, COM_NO_LEN) == ERR_OK) { delay_usertime(50); if (SPI2_Master_Transfer(tx_buffer, rx_buffer, ESP32_RX_LEN) == ERR_OK) { // 现在 rx_buffer[] 里已经有连续接收到的 ESP32_RX_LEN 个字 for (i = 0; i < ESP32_RX_LEN; i++) { if(rx_buffer[i]== RE_FLAG) //判断返回标志位 { if(rx_buffer[i+1] == 0x0000 + board_num) //判断包号 { for(j = 0;j < 18;j++) { if(j < 16) { if(board_num < Z_SLAVE_NUM - 1) { CellVolt[j + (16*board_num)] = rx_buffer[i+j+2]; } else //最大板号为小电瓶数据 单独存放 { Batt_CellVolt[j] = rx_buffer[i+j+2]; } } else { if(board_num < Z_SLAVE_NUM - 1) { MdlTemp[board_num*2] |= rx_buffer[i+18]; MdlTemp[(board_num*2)+1] |= rx_buffer[i+19]; } else { Batt_MdlTemp[0] = rx_buffer[i+18]; Batt_MdlTemp[1] = rx_buffer[i+19]; } } } } } } } } } if(su1_canUpdateCnt < 20) { su1_canUpdateCnt++; } else { su1_canUpdateCnt = 1; for(cell_index = 0; cell_index < CELL_VOLT_LEN; cell_index++) { HLd_v_CellVolt[cell_index] = CellVolt[cell_index]; } for(tem_index = 0; tem_index < MDL_TEMP_LEN; tem_index++) { HLd_t_MdlTemp[tem_index] = MdlTemp[tem_index]; } } } void SPI2_Test_MOSI(void) { // 1. 配置主机模式 DSPI_1.MCR.R = 0x80010001; // HALT=1, MSTR=1, 清FIFO DSPI_1.MCR.B.MSTR = 1; DSPI_1.MCR.B.HALT = 1; // 2. 配置 CTAR0 为 16bit,CPOL=0,CPHA=0 DSPI_1.CTAR[0].R = 0; DSPI_1.CTAR[0].B.FMSZ = 15; // 16bit DSPI_1.CTAR[0].B.CPOL = 0; DSPI_1.CTAR[0].B.CPHA = 0; DSPI_1.CTAR[0].B.PBR = 0; // 波特率分频 DSPI_1.CTAR[0].B.BR = 0; // 3. 拉低片选 SPI_I_CS(0); // 4. 退出 HALT DSPI_1.MCR.B.HALT = 0; // 5. 发送一个 0xAAAA DSPI_1.PUSHR.R = (0x0020) | (1<<16); // PCS0=1,CTAR0 // 6. 等待发送完成 while (!DSPI_1.SR.B.TCF) {} DSPI_1.SR.B.TCF = 1; // 7. 拉高片选 SPI_I_CS(1); } 这是api_esp32.c /* * Copyright (c) 2014,SHENZHEN HANGSHENG ELECTRONICS Co.,Ltd. * All Rights Reserved. * Dept.:ACEC * File:AcecType.h * Description: descript information * REQ IDs: show the handle requirement IDs * History: * 2014-3-1, 1306104, original */ #ifndef _API_ESP32_H_ #define _API_ESP32_H_ #include "includes.h" #include "Config.h" #define Z_SLAVE_NUM 8 #define COM_NO_LEN 4 #define ESP32_RX_LEN 32 #define CELL_VOLT_LEN 112 #define BATT_CELL_VOLT_LEN 16 #define MDL_TEMP_LEN 8 #define BATT_MDL_TEMP_LEN 1 #define RE_FLAG 0xAABB extern uint16_t CellVolt[CELL_VOLT_LEN]; extern uint16_t Batt_CellVolt[BATT_CELL_VOLT_LEN]; extern uint32_t MdlTemp[MDL_TEMP_LEN]; extern uint16_t Batt_MdlTemp[MDL_TEMP_LEN]; extern void AD7988_init(void); extern StatusType AD7988_readdata(U2 addr,U2 databuff[],U2 datalen); extern StatusType SPI2_Master_Transfer(U2 *tx_data, U2 *rx_data, U2 len); extern void SPI2_Test_MOSI(void); extern void read_vol_from_esp32(void); extern uint16_t CellVolt[CELL_VOLT_LEN]; #endif 这是api_esp32.h,将其中的ucos相关函数替换为裸机可用,不依靠ucos底层,不删去文件中的头文件部分内容,可以增加,修改后的文件名称不作改变,将修改后的完整代码发出
01-06
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值