spi_sample_slave.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 433 行 · 第 1/2 页

C
433
字号
		
		if(chk_dma0_finish()==NG)
		{
			put_wvalue(DMACMSK0, 0x1);			/* channel mask */
			led_pt = LED_2;						/* turn on LED error */
			return NG;
		}
		
		put_wvalue(DMACMSK0, 0x1);				/* channel mask */
		tbyte = 0;
	}
	return OK;
}

/******************************************************************/
/*  SPI-Data receive                                              */
/*  Function : spi_receiv (Slave)                                 */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  OK/NG                                       */
/******************************************************************/
int spi_receiv(void)
{
	end_flag = 0;
	
	set_wbit(SPCR0, SPCR0_TFIE);	/* SPI interrupt available */
	
	while(end_flag!=1)
		;	/* Waiting for SPI transfer finishing */
	
	clr_wbit(SPCR0, (UWORD)SPCR0_TFIE);	/* SPI interrupt stop */
	
	if(err_status!=NO_ERR)
		return NG;
	
	return OK;
}

/******************************************************************/
/*  Get received data                                             */
/*  Function : get_receiv_data (Slave)                            */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  OK/NG                                       */
/******************************************************************/
int get_receiv_data(void)
{
	UWORD get_data;
	UWORD fifo_byte;
	
	get_data = get_wvalue(SPSR0);
	fifo_byte = ((get_data & SPSR0_RFD)>>0xB);
	
	put_wvalue(DMACCINT1, 0xFF);		/* end status clear */
	put_wvalue(DMACSIZ1, fifo_byte);	/* number of transmission */
	put_wvalue(DMACMSK1, 0x0);			/* channel mask cancel */
	
	if(chk_dma1_finish()==NG)
	{
		put_wvalue(DMACMSK1, 0x1);			/* channel mask */
		led_pt = LED_3;						/* turn on LED error */
		return NG;
	}
	
	put_wvalue(DMACMSK1, 0x1);				/* channel mask */
	return OK;
}

/******************************************************************/
/*  Check for end of DMA0 transfer                                */
/*  Function : chk_dma0_finish                                    */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  OK/NG                                       */
/******************************************************************/
int chk_dma0_finish(void)
{
	UWORD get_data;
	
	while((get_wvalue(DMASTA)&DMASTA_STA0)==DMASTA_STA0)
		;	/* Waiting for DMA data transfer finishing */
	
	get_data = get_wvalue(DMAINT);
	
	if((get_data & DMAINT_ISTA0)==DMAINT_ISTA0)
		return NG;
	
	return OK;
}

/******************************************************************/
/*  Check for end of DMA1 transfer                                */
/*  Function : chk_dma1_finish                                    */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  OK/NG                                       */
/******************************************************************/
int chk_dma1_finish(void)
{
	UWORD get_data;
	
	while((get_wvalue(DMASTA)&DMASTA_STA1)==DMASTA_STA1)
		;	/* Waiting for DMA data transfer finishing */
		
	get_data = get_wvalue(DMAINT);
	
	if((get_data & DMAINT_ISTA1)==DMAINT_ISTA1)
		return NG;
	
	return OK;
}

/******************************************************************/
/*  Compare received data                                         */
/*  Function : cmp_data_fn                                        */
/*      Parameters                                                */
/*          Input  :  received data, compare data, data size      */
/*          Output :  OK/NG                                       */
/******************************************************************/
int cmp_data_fn(UBYTE *r_data, UBYTE *c_data, int n)
{
	UBYTE *rp = r_data;
	UBYTE *cp = c_data;
	
	for( ; 0<n; ++rp, ++cp, --n)
		if(*rp != *cp)
			return NG;
	return OK;
}

/****************************************************************************/
/*  Registration of IRQ Handler                                             */
/*  Function : reg_irq_handler                                              */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note : Initialize of IRQ needs to be performed before this process.     */
/****************************************************************************/
void reg_irq_handler(void)
{
	/* register IRQ handlers into handler table */
	IRQ_HANDLER_TABLE[INT_SPI0] = spi_handler;

	/* setup interrupt level */
	set_wbit(ILC1, ILC1_ILR13 & ILC_INT_LV7);	/* spi handler(nIRQ[13]) -> level7 */

	return;
}

/*****************************************************************************/
/*  SPI interrupt handler                                                    */
/*      Function : spi_handler(void)                                         */
/*          Parameters                                                       */
/*              Input  : Nothing                                             */
/*              Output : Nothing                                             */
/*****************************************************************************/
void spi_handler(void)
{
	UWORD tmpSPSR0 = get_wvalue(SPSR0);
	
	put_wvalue(SPSR0, tmpSPSR0);	/* SPI interruption factor clear */
	
	if(((tmpSPSR0 & SPSR0_ORF)==SPSR0_ORF)||((tmpSPSR0 & SPSR0_MDF)==SPSR0_MDF))
	{
		err_status = SPI_ERR;
		led_pt = LED_1;						/* turn on LED error */
	}
	
	end_flag = 1;
    return;
}

/******************************************************************/
/*  setup dmac                                                    */
/*  Function : setup_dmac                                         */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void setup_dmac(void)
{
	/* CH0 */
	put_wvalue(DMACMSK0, 0x1);		/* channel mask */
	
	/**************************************************
	   DMACTMOD0_ARQ	auto request
	   DMACTMOD0_TSIZ	byte
	   DMACTMOD0_SDP	source address increment
	   DMACTMOD0_DDP	destination address fixation
	   DMACTMOD0_BRQ	burst mode
	   DMACTMOD0_IML	interruption mask cancel
	**************************************************/
	put_wvalue(DMACTMOD0, 0x9);
	
	put_wvalue(DMACCINT0, 0x0);			/* DMACCINT0 clear */
	put_wvalue(DMACDAD0, SPDWR0);		/* destination address */
	
	/* CH1 */
	put_wvalue(DMACMSK1, 0x1);		/* channel mask */
	
	/**************************************************
	   DMACTMOD0_ARQ	auto request
	   DMACTMOD0_TSIZ	byte
	   DMACTMOD0_SDP	source address fixation
	   DMACTMOD0_DDP	destination address increment
	   DMACTMOD0_BRQ	burst mode
	   DMACTMOD0_IML	interruption mask cancel
	**************************************************/
	put_wvalue(DMACTMOD1, 0x11);
	
	put_wvalue(DMACCINT1, 0x0);			/* DMACCINT1 clear */
	put_wvalue(DMACSAD1, SPDRR0);		/* destination address */
	
	return;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?