⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_isr.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
字号:

//
//      Copyright (c) Renesas Technology Corp. 2002-2003 All Rights Reserved.
//
//      OEM Adaptation Layer
//
//----------------------------------------------------------------------------
//
//  FILE      : SPI_ISR.C
//  CREATED   : 2002.01.31
//  MODIFIED  : 2003.08.06
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS HS7751RSTC01H (S1-E, ITS-DS5)
//  TARGET OS : Microsoft(R) Windows(R) CE .NET 4.2
//  NOTES     : 
//  HISTORY   :
//					2002.9.26
//					- Released for HS7751RSTC01H (S1-E, ITS-DS5)


#include <windows.h>
#include <s1e.h>
#include <HD64404.H>
#include <oalintr.h>
#include <drv_glob.h>

// Mode
#define SPI_MODE_TRANSMIT	0x0001	// This operates in the transmitting mode.
#define SPI_MODE_RECEIVE	0x0002	// This operates in the receiving mode.
#define SPI_MODE_MASTER		0x0004	// This operates in the master mode.
#define SPI_MODE_GENERATE	0x0008	// 
#define SPI_MODE_BUFFER1	0x0100	// The buffer 1 is transmitting.
#define SPI_MODE_BUFFER2	0x0200	// The buffer 2 is transmitting.
#define SPI_MODE_BUF1EXIST	0x1000	// Effective data exists in a buffer 1.
#define SPI_MODE_BUF2EXIST	0x2000	// Effective data exists in a buffer 1.
// Status
#define SPI_STAT_RX_EXIST	0x0001	// Receiving data exists.
#define SPI_STAT_RX_FULL	0x0002	// Receiving data buffer is full.(overrun occured)
#define SPI_STAT_RX_OVERRUN	0x0004	// Overrun error occurred
#define SPI_STAT_TX_EMPTY	0x0100	// Transmit buffer is empty.
#define SPI_STAT_TRANSMITTED 0x0200	// Data transmission was completed.


typedef struct _SPI_TABLE {
	unsigned short volatile Mode;			// Transmit and receive mode
	unsigned short volatile Status;			// Transmit and receive status
	unsigned short volatile RxRptr;			// reading pointer of receive buffer
	unsigned short volatile RxWptr;			// Receive data pointer
	unsigned short volatile TxRptr1;
	unsigned short volatile TxWptr1;
	unsigned short volatile TxRptr2;
	unsigned short volatile TxWptr2;
	unsigned char  volatile dummy[0x100 - (16)];
	unsigned char  volatile RxBuff[0x1000];
	unsigned char  volatile TxBuff1[0x100];
	unsigned char  volatile TxBuff2[0x100];
} *PSPI_TABLE;

#define SPI0_WORK_OFFSET	0x00000000
#define SPI1_WORK_OFFSET	0x00002000
#define SPI2_WORK_OFFSET	0x00004000

#define 	TXFU	0x00000400
#define 	RXEM	0x00000020
#define 	RXOO	0x00000010
#define 	RXOW	0x00000008

#define 	CR		0x00000000
#define 	SR		0x00000004
#define 	SCR		0x00000008
#define 	TBR		0x0000000C
#define 	RBR		0x00000010

#define 	DEEP_FIFOS	8

#define Read(reg)		(*(volatile unsigned long * const)(reg))
#define Write(reg, val)	(*(volatile unsigned long * const)(reg)) = (val)

int	SPI0_ISR(void)
{
PSPI_TABLE pSpi = (PSPI_TABLE)(HSPI_BUFFER_BASE);
DWORD dwBuf, i = 0;
WORD  wSysIntr = SYSINTR_NOP;
DWORD dwDeepFifos = DEEP_FIFOS;

	while( !(Read(SPI0_BASE+SR) & RXEM) ){
		dwBuf = Read(SPI0_BASE+RBR);
		i++;
		if ( (pSpi -> Mode & (SPI_MODE_TRANSMIT | SPI_MODE_RECEIVE)) == SPI_MODE_RECEIVE ){
			if ( !(pSpi -> Status & SPI_STAT_RX_FULL) ){
				pSpi -> RxBuff[pSpi -> RxWptr++] = (BYTE)dwBuf;
				pSpi -> RxWptr &= 0x0fff;
				wSysIntr = SYSINTR_SPI0;
				if ( pSpi -> RxWptr == pSpi -> RxRptr ){
					pSpi -> Status |= SPI_STAT_RX_FULL;
				}
			}
		}
	}
	if ( i )
		dwDeepFifos = i;

	if ( Read(SPI0_BASE+SR) & (RXOO|RXOW) ){
		if ( Read(SPI0_BASE+SR) & RXOO ){
			pSpi -> Status |= SPI_STAT_RX_OVERRUN;
		}
		Write(SPI0_BASE+SR, 0);
	}
	if ( pSpi -> Mode & (SPI_MODE_GENERATE | SPI_MODE_MASTER) ){
		i = 0;
		while( !(Read(SPI0_BASE+SR) & TXFU) ){
			if ( pSpi -> Mode & SPI_MODE_TRANSMIT && !(pSpi -> Status & SPI_STAT_TRANSMITTED) ){
				if ( pSpi -> Mode & SPI_MODE_BUFFER1 ){
					if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff1[pSpi -> TxRptr1++]);
						if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
							pSpi -> TxRptr1 = 0;
							pSpi -> TxWptr1 = 0;
							wSysIntr = SYSINTR_SPI0;
							if ( pSpi -> Mode & SPI_MODE_BUF2EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER2;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER1|SPI_MODE_BUF2EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER1;
							}
						}
					}
				}else if ( pSpi -> Mode & SPI_MODE_BUFFER2 ){
					if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff2[pSpi -> TxRptr2++]);
						if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
							pSpi -> TxRptr2 = 0;
							pSpi -> TxWptr2 = 0;
							wSysIntr = SYSINTR_SPI0;
							if ( pSpi -> Mode & SPI_MODE_BUF1EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER1;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER2|SPI_MODE_BUF1EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER2;
							}
						}
					}
				}
			}else if ( pSpi -> Mode & SPI_MODE_GENERATE ){
				dwBuf = 0x000000ff;
			}
			Write(SPI0_BASE+TBR, dwBuf);
			i++;
			if ( i >= dwDeepFifos ){
				break;
			}
		}
	}

	return wSysIntr;
}


int	SPI1_ISR(void)
{
PSPI_TABLE pSpi = (PSPI_TABLE)(HSPI_BUFFER_BASE+SPI1_WORK_OFFSET);
DWORD dwBuf, i = 0;
WORD  wSysIntr = SYSINTR_NOP;
DWORD dwDeepFifos = DEEP_FIFOS;

	while( !(Read(SPI1_BASE+SR) & RXEM) ){
		dwBuf = Read(SPI1_BASE+RBR);
		i++;
		if ( (pSpi -> Mode & (SPI_MODE_TRANSMIT | SPI_MODE_RECEIVE)) == SPI_MODE_RECEIVE ){
			if ( !(pSpi -> Status & SPI_STAT_RX_FULL) ){
				pSpi -> RxBuff[pSpi -> RxWptr++] = (BYTE)dwBuf;
				pSpi -> RxWptr &= 0x0fff;
				wSysIntr = SYSINTR_SPI1;
				if ( pSpi -> RxWptr == pSpi -> RxRptr ){
					pSpi -> Status |= SPI_STAT_RX_FULL;
				}
			}
		}
	}
	if ( i )
		dwDeepFifos = i;

	if ( Read(SPI1_BASE+SR) & (RXOO|RXOW) ){
		if ( Read(SPI1_BASE+SR) & RXOO ){
			pSpi -> Status |= SPI_STAT_RX_OVERRUN;
		}
		Write(SPI1_BASE+SR, 0);
	}
	if ( pSpi -> Mode & (SPI_MODE_GENERATE | SPI_MODE_MASTER) ){
		i = 0;
		while( !(Read(SPI1_BASE+SR) & TXFU) ){
			if ( pSpi -> Mode & SPI_MODE_TRANSMIT && !(pSpi -> Status & SPI_STAT_TRANSMITTED) ){
				if ( pSpi -> Mode & SPI_MODE_BUFFER1 ){
					if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff1[pSpi -> TxRptr1++]);
						if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
							pSpi -> TxRptr1 = 0;
							pSpi -> TxWptr1 = 0;
							wSysIntr = SYSINTR_SPI1;
							if ( pSpi -> Mode & SPI_MODE_BUF2EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER2;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER1|SPI_MODE_BUF2EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER1;
							}
						}
					}
				}else if ( pSpi -> Mode & SPI_MODE_BUFFER2 ){
					if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff2[pSpi -> TxRptr2++]);
						if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
							wSysIntr = SYSINTR_SPI1;
							pSpi -> TxRptr2 = 0;
							pSpi -> TxWptr2 = 0;
							if ( pSpi -> Mode & SPI_MODE_BUF1EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER1;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER2|SPI_MODE_BUF1EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER2;
							}
						}
					}
				}
			}else if ( pSpi -> Mode & SPI_MODE_GENERATE ){
				dwBuf = 0x000000ff;
			}
			Write(SPI1_BASE+TBR, dwBuf);
			i++;
			if ( i >= dwDeepFifos ){
				break;
			}
		}
	}

	return wSysIntr;
}

#if ENABLE_HSPI2
int	SPI2_ISR(void)
{
PSPI_TABLE pSpi = (PSPI_TABLE)(HSPI_BUFFER_BASE+SPI2_WORK_OFFSET);
DWORD dwBuf, i = 0;
WORD  wSysIntr = SYSINTR_NOP;
DWORD dwDeepFifos = DEEP_FIFOS;

	while( !(Read(SPI2_BASE+SR) & RXEM) ){
		dwBuf = Read(SPI2_BASE+RBR);
		i++;
		if ( (pSpi -> Mode & (SPI_MODE_TRANSMIT | SPI_MODE_RECEIVE)) == SPI_MODE_RECEIVE ){
			if ( !(pSpi -> Status & SPI_STAT_RX_FULL) ){
				pSpi -> RxBuff[pSpi -> RxWptr++] = (BYTE)dwBuf;
				pSpi -> RxWptr &= 0x0fff;
				wSysIntr = SYSINTR_SPI2;
				if ( pSpi -> RxWptr == pSpi -> RxRptr ){
					pSpi -> Status |= SPI_STAT_RX_FULL;
				}
			}
		}
	}
	if ( i )
		dwDeepFifos = i;

	if ( Read(SPI2_BASE+SR) & (RXOO|RXOW) ){
		if ( Read(SPI2_BASE+SR) & RXOO ){
			pSpi -> Status |= SPI_STAT_RX_OVERRUN;
		}
		Write(SPI2_BASE+SR, 0);
	}
	if ( pSpi -> Mode & (SPI_MODE_GENERATE | SPI_MODE_MASTER) ){
		i = 0;
		while( !(Read(SPI2_BASE+SR) & TXFU) ){
			if ( pSpi -> Mode & SPI_MODE_TRANSMIT && !(pSpi -> Status & SPI_STAT_TRANSMITTED) ){
				if ( pSpi -> Mode & SPI_MODE_BUFFER1 ){
					if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff1[pSpi -> TxRptr1++]);
						if ( pSpi -> TxRptr1 == pSpi -> TxWptr1 ){
							pSpi -> TxRptr1 = 0;
							pSpi -> TxWptr1 = 0;
							wSysIntr = SYSINTR_SPI2;
							if ( pSpi -> Mode & SPI_MODE_BUF2EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER2;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER1|SPI_MODE_BUF2EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER1;
							}
						}
					}
				}else if ( pSpi -> Mode & SPI_MODE_BUFFER2 ){
					if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
						dwBuf = 0x000000ff;
					}else{
						dwBuf = (DWORD)(pSpi -> TxBuff2[pSpi -> TxRptr2++]);
						if ( pSpi -> TxRptr2 == pSpi -> TxWptr2 ){
							pSpi -> TxRptr2 = 0;
							pSpi -> TxWptr2 = 0;
							wSysIntr = SYSINTR_SPI2;
							if ( pSpi -> Mode & SPI_MODE_BUF1EXIST ){
								pSpi -> Mode |= SPI_MODE_BUFFER1;
								pSpi -> Mode &= ~(SPI_MODE_BUFFER2|SPI_MODE_BUF1EXIST);
							}else{
								i = DEEP_FIFOS;
								pSpi -> Status |= SPI_STAT_TRANSMITTED;
								pSpi -> Mode &= ~SPI_MODE_BUFFER2;
							}
						}
					}
				}
			}else if ( pSpi -> Mode & SPI_MODE_GENERATE ){
				dwBuf = 0x000000ff;
			}
			Write(SPI2_BASE+TBR, dwBuf);
			i++;
			if ( i >= dwDeepFifos ){
				break;
			}
		}
	}

	return wSysIntr;
}
#endif

⌨️ 快捷键说明

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