spi_sample_slave.c

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

C
433
字号
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2005 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML67Q4051/ML67Q4061 series                         */
/*     Module Name  :  ML67Q4051/ML67Q4061 SPI sample program (Slave)     */
/*     File   Name  :  spi_sample_slave.c                                 */
/*     Revision     :  01.00                                              */
/*     Date         :  2005/02/17                                         */
/*                                                                        */
/**************************************************************************/
#include   "ml674061.h"
#include   "common.h"
#include   "irq.h"

#ifdef __IAR__
#include "intrinsics.h"
#endif

/* constants */
#define SPI_LED_NORMAL	LED_NORMAL_END_PATTERN	/* OK pattern */
#define SPI_END_PATTERN	0xFF	/* data-end pattern */
#define BUFF_SIZE		32
#define PORTSEL2_SPI0	0x55
#define LIMIT_SEND_DATA	12

/* functions */
int  main(void);						/* Main routine */
void init_spi(void);					/* Initialize SPI */
int  spi_main(void);					/* SPI Main routine*/
int  set_send_data(void);				/* setup for SPI send process */
int  spi_receiv(void);					/* SPI receive process */
int  get_receiv_data(void);				/* get received data */
void reg_irq_handler(void);				/* Registration of IRQ Handler */
void spi_handler(void);					/* SPI interrupt handler */
void setup_dmac(void);					/* setup for DMAC */
int  chk_dma0_finish(void);				/* DMA0 transfer finish check */
int  chk_dma1_finish(void);				/* DMA1 transfer finish check */
int  cmp_data_fn(UBYTE*, UBYTE*, int size);	/* Data compare process */

/* global variables */
unsigned  char  SPI_SendData[BUFF_SIZE];	/* Send buffer */
unsigned  char  SPI_ReceivData[BUFF_SIZE];	/* Receive buffer */
unsigned char cmp_data[BUFF_SIZE];			/* compare data */
UBYTE led_pt;							/* LED pattern */
int err_status;							/* Error status */
volatile UHWORD end_flag;				/* Flag for Program end */
UWORD tbyte;							/* Send data size */

enum err_num {		/* Error number */
	NO_ERR, 		/* No error */
	SPI_ERR,		/* SPI error */
	DMA_SEND_ERR,	/* DMA sending error */
	DMA_RECEIV_ERR,	/* DMA receiving error */
	DATA_CMP_ERR	/* Data comparison error */
};

/******************************************************************/
/*  Entry point                                                   */
/*  Function : main (Slave)                                       */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  0                                           */
/******************************************************************/
int main(void)
{
	init_irq();					/* initialize irq */
	reg_irq_handler();			/* register IRQ handlers */
	
	init_led();                 /* initialize led */
	led_on(LED_START_PATTERN);  /* light led start pattern */

	led_pt = LED_NORMAL_END_PATTERN;

	init_spi();					/* initialize spi */
	setup_dmac();				/* setup DMAC0, DMA1 */
	
	/* enable IRQ */
#ifdef __IAR__
      __enable_interrupt();
#else
    irq_en();
#endif
	
	tbyte = BUFF_SIZE;
	
	set_wbit(SPCR0, SPCR0_SPE);		/* SPI transmission start */
	/* Main of SPI data transmission and reception  */
	err_status = spi_main();
	clr_wbit(SPCR0, (UWORD)SPCR0_SPE);	/* SPI transmission unavailable */
	
#ifdef __IAR__
      __disable_interrupt();
#else
    irq_dis();
#endif

	
	if(err_status==NO_ERR)
	{	/* received data compare */
		if(cmp_data_fn(SPI_ReceivData, cmp_data, BUFF_SIZE)==NG)
		{
			err_status = DATA_CMP_ERR;
			led_pt = LED_4;		/* turn on LED error */
		}
	}
	
	led_on(led_pt);				/* turn on lower square LED */
	
	return 0;
}

/******************************************************************/
/*  Initialize SPI                                                */
/*  Function : init_spi (Slave)                                   */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_spi(void)
{
	UBYTE  i;
//	UWORD get_data, set_data;

	set_wbit(PORTSEL2, PORTSEL2_SPI0);	/* selection of a secondary function */
	
	clr_wbit(SPCR0, (UWORD)SPCR0_MSTR);	/* slave mode */
	
	set_wbit(SPCR0, SPCR0_FICLR);	/* FIFO clear */
	clr_wbit(SPCR0, (UWORD)SPCR0_FICLR);
	
	clr_wbit(SPCR0, (UWORD)SPCR0_LSBF);	/* LSB */

       //get_data = get_wvalue(SPBRR0);
       //set_data = ((get_data & 0xFFFFFC00) | 0x8); // was this value
       //put_wvalue(SPBRR0, set_data);	/* SPI0 baudrate set */

	put_wvalue(SPBRR0, 0x25008);	/* SPI0 baudrate set */

	clr_wbit(SPBRR0, (UWORD)SPBRR0_SIZE);	/* 8bit */
	
	/***********************************************************
	    Clear send_receive_buffer and err_status
	***********************************************************/
	for(i=0; i<BUFF_SIZE; i++)
	{
		SPI_SendData[i] = i;
		SPI_ReceivData[i] = SPI_END_PATTERN;
		cmp_data[i] = i;
	}
	
	err_status = NO_ERR;
	return;
}

/******************************************************************/
/*  SPI data transmission and reception                           */
/*  Function : spi_main (Slave)                                   */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  error number                                */
/******************************************************************/
int spi_main(void)
{
	put_wvalue(DMACSAD0, (UWORD)SPI_SendData);		/* DMA0 source address */
	put_wvalue(DMACDAD1, (UWORD)SPI_ReceivData);	/* DMA1 destination address */
	
	do {
		if(set_send_data()==NG)
			return DMA_SEND_ERR;
		
		if(spi_receiv()==NG)
			return SPI_ERR;
		
		if(get_receiv_data()==NG)
			return DMA_RECEIV_ERR;
		
	}while(tbyte!=0);
	
	return NO_ERR;
}

/******************************************************************/
/*  set of SPI-Data                                               */
/*  Function : set_send_data (Slave)                              */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  OK/NG                                       */
/******************************************************************/
int set_send_data(void)
{
	if(tbyte > LIMIT_SEND_DATA)
	{
		clr_wbit(SPCR0,(UWORD)0x000F0000);
		set_wbit(SPCR0,0x00040000);

		put_wvalue(DMACCINT0, 0xFF);			/* end status clear */
		put_wvalue(DMACSIZ0, LIMIT_SEND_DATA);	/* number of transmission */
		put_wvalue(DMACMSK0, 0x0);				/* channel mask cancel */
		
		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 -= LIMIT_SEND_DATA;
	}
	else
	{
		clr_wbit(SPCR0,(UWORD)0x000F0000);

		put_wvalue(DMACCINT0, 0xFF);			/* end status clear */
		put_wvalue(DMACSIZ0, tbyte);	/* number of transmission */
		put_wvalue(DMACMSK0, 0x0);		/* channel mask cancel */

⌨️ 快捷键说明

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