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 + -
显示快捷键?