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

📄 usbirqfunc.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//   File:      UsbIrqFunc.c
//   Contents:  Process IRQ-control commands received from the USB host.
//		Both internal IRQ (LV24xxx interrupt - script) and external interrupt
//		(external RDS demodulator) are handled in thid file
//
//   Copyright (c) 2004 ItoM Semiconductor. All rights reserved
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "common.h"
#include "Lv24Ekit.h"

#ifdef USE_USB
#include "Usb3wCmd.h"
#endif	//USB_USB
// ==============================================================================
#ifdef USE_IRQSCRIPT 	// The whole file can be discarded if interrupt is not used
// ==============================================================================

//////////////////////////////////////////////////////////////////////
// IRQ-script opcode
//////////////////////////////////////////////////////////////////////
#define ISO_IRQID	0x01	// Assign handler ID.		Syntax: Opcode, byIrqId, byReserved
#define ISO_WRITE3W_D	0x02	// Write 3W direct.		Syntax: Opcode, byAddress, byData (byData is immediate data)
#define ISO_WRITE3W_I	0x03	// Write 3W indirect.		Syntax: Opcode, byAddress, byStorage
#define ISO_READ3W	0x04	// Read 3W.			Syntax: Opcode, byAddress, byStorage
#define ISO_CHKMASK_L	0x05	// Check mask, true if low.	Syntax: Opcode, byStorage, byMask
#define ISO_CHKMASK_H	0x06	// Check mask, true if set.	Syntax: Opcode, byStorage, byMask
#define ISO_OR_MASK	0x07	// OR storage with mask.	Syntax: Opcode, byStorage, byOrMask
#define ISO_AND_MASK	0x08	// AND storage with mask.	Syntax: Opcode, byStorage, byAndMask
#define ISO_STORE_BUF	0x09	// Store register to buffer.Syntax: Opcode, byAddress, byBufId

#define ISO_READ3W_D	0x0A	// Read 3W direct		Syntax: Opcode, byAddress, byIndexInDirectBuffer
#define ISO_POLL_H	0x0B	// Wait until bit(s) high	Syntax: Opcode, byAddress, byBitMask
#define ISO_POLL_L	0x0C	// Wait until bit(s) low	Syntax: Opcode, byAddress, byBitMask

#define ISO_ENDSCRIPT	0xFF	// End of script 		Syntax: Opcode, byReserved, byReserved
#define ISPARM_NA	0x00	// Not used parameter

// Special storage location in device interrupt buffer 0
#define ISWR_IRQOCC0	0	// Byte 0 of buffer 0 is meant for interrupt [0:7] occurred marks
#define ISWR_IRQOCC1	1	// Byte 1 of buffer 0 is meant for interrupt [8:15] occurred marks

// Script process status
#define SCRIPT_OK	0
#define SCRIPT_END	1
#define SCRIPT_CHK_FAIL	2

#define SCRIPT_ERROR	0xFF

// Subroutines
BYTE CopyRoundRobinBuf(PRNDBUF_ST pStRrBuf);

// Prototypes for USB-IRQ script handlers
BYTE ScNOP( BYTE byParm1, BYTE byParm2 );
BYTE ScIrqID( BYTE byParm1, BYTE byParm2 );
BYTE ScWrite3WD( BYTE byParm1, BYTE byParm2 );
BYTE ScWrite3WI( BYTE byParm1, BYTE byParm2 );
BYTE ScRead3W( BYTE byParm1, BYTE byParm2 );
BYTE ScChkMaskLow( BYTE byParm1, BYTE byParm2 );
BYTE ScChkMaskHigh( BYTE byParm1, BYTE byParm2 );
BYTE ScOrMask( BYTE byParm1, BYTE byParm2 );
BYTE ScAndMask( BYTE byParm1, BYTE byParm2 );
BYTE ScStoreBuf( BYTE byParm1, BYTE byParm2 );
BYTE ScRead3WD(BYTE byParm1, BYTE byParm2);
BYTE ScPollHi(BYTE byParm1, BYTE byParm2);
BYTE ScPollLo(BYTE byParm1, BYTE byParm2);

typedef BYTE (*SCRIPT_COMMAND_FUNC)(BYTE,BYTE);	// Script op-code execution-function
static SCRIPT_COMMAND_FUNC ScriptCommandTable[] = 
{
	ScNOP,		// Opcode 0
	ScIrqID,	// Opcode 1
	ScWrite3WD,	// Opcode 2
	ScWrite3WI,	// Opcode 3
	ScRead3W,	// Opcode 4
	ScChkMaskLow,	// Opcode 5
	ScChkMaskHigh,	// Opcode 6
	ScOrMask,	// Opcode 7
	ScAndMask,	// Opcode 8
	ScStoreBuf,	// Opcode 9
	ScRead3WD,	// opcode 10
	ScPollHi,	// opcode 11
	ScPollLo,	// opcode 12
};
#define SCRIPT_COMMAND_FUNC_MAX (sizeof(ScriptCommandTable)/(sizeof(ScriptCommandTable[0])-1))

BYTE UsbIrqControl()
{
	// Interrupt comtrol from USB
	// General input buffer format: <Command><Action><optional parameters><...>
	BYTE byLen, byTmp;
	WORD wLen;

	byLen = 0;			// Default length to be returned
	switch (g_ReceiveBuf[1])	// Examine the action byte for handling the command
	{
		// ---- Interface IRQ handling ------
		case RCA_INFIRQ_ENABLE:	// Reset our administration and enable the external RDS-interrupt
			g_stExtIrq.byW = 0;	// Reset the write pointer
			g_stExtIrq.byR = 0;	// Reset the read pointer
			g_stExtIrq.byF = 0;	// Reset the filled count
			g_byRdsBitCnt = 0;	// Reset the received RDS bit counter
			// fall through to enable the external interrupt
		case RCA_INFIRQ_RESUME:	// Just enable the external RDS-interrupt
			byTmp = _I45CR;
			byTmp &= 0xF0;	// Don't touch INT5 setting, clear INT4 setting (disable INT4)
			byTmp |= 0x09;	// Don't touch INT5 setting, enable INT4 - rising edge trigger
			_I45CR = byTmp;
			break;

		case RCA_INFIRQ_SUSPEND:	// Just disable the external RDS-interrupt
		case RCA_INFIRQ_DISABLE:	// Disable the external RDS-interrupt
			byTmp = _I45CR;
			byTmp &= 0xF0;	// Don't touch INT5 setting, clear INT4 setting	(disable INT4)
			_I45CR = byTmp;
			break;

		case RCA_INFIRQ_GETDATA:	// Return our RDS-data
			// Received format <RC_IRQ_CONTROL_CMD><GetData-action><BufId>
			// Reply format <Cmd><ByteCnt=n><byte0><byte1><...><byte n>

			// For interface interrupt - we don't care about the buffer ID, just send the only buffer back
			byLen = CopyRoundRobinBuf(&g_stExtIrq);
			break;
		// ---- End Interface IRQ handling ------

		// ---- Device IRQ handling ------
		case RCA_DEVIRQ_ENABLE:		// Enable device IRQ		// No reply
			// Reset data available flag of buffer 0
			g_byaIrqBuf0[ISWR_IRQOCC0] = 0;
			g_byaIrqBuf0[ISWR_IRQOCC1] = 0;
			// Fall through
		case RCA_DEVIRQ_RESUME:		// Resume device IRQ		// No reply
			// Reset the administration for buffer 1 (Device RDS buffer)
			g_stIrqBuf1.byW = 0;	// The write pointer
			g_stIrqBuf1.byR = 0;	// The read pointer
			g_stIrqBuf1.byF = 0;	// The byte filled count
			Enable3wIrq(TRUE);
			g_ReplyBuf[1] = 0; 	// No error
			break;

		case RCA_DEVIRQ_DISABLE:	// Disable device IRQ		// No reply
		case RCA_DEVIRQ_SUSPEND:	// Suspend device IRQ		// No reply
			Enable3wIrq(FALSE);
			g_ReplyBuf[1] = 0; 	// No error
			break;

		case RCA_DEVIRQ_GETDATA:	// Get device IRQ data
			// Received format <RC_IRQ_CONTROL_CMD><GetData-action><BufId>
			// Reply format <Cmd><ByteCnt=n><byte0><byte1><...><byte n>

			// Return the requested buffer (specified by buffer ID)
			if (g_ReceiveBuf[2]==0) // Buffer 0 requested
			{
				if (g_byaIrqBuf0[ISWR_IRQOCC0] || g_byaIrqBuf0[ISWR_IRQOCC1] ) // Does interrupt occur?
				{
					// Copy the buffer 0 to reply packet
					g_ReplyBuf[1] = MAXLEN_IRQBUF_0;	// Number of IRQ data byte
					for (byTmp=0; byTmp<MAXLEN_IRQBUF_0; byTmp++)
						g_ReplyBuf[2+byTmp] = g_byaIrqBuf0[byTmp];
					byLen = MAXLEN_IRQBUF_0 + 2;	// Total byte of the USB-reply packet

					// Clear data available flag
					g_byaIrqBuf0[ISWR_IRQOCC0] = 0;
					g_byaIrqBuf0[ISWR_IRQOCC1] = 0;
				}
			}
			else if (g_ReceiveBuf[2]==1) // Buffer 1 requested
			{
				byLen = CopyRoundRobinBuf(&g_stIrqBuf1);
			}

			if (byLen==0)	// Not suported buffer ID or no data
			{
				g_ReplyBuf[1]=0;	// 0 byte filled
				byLen = 2;
			}
			break;

		case RCA_DEVIRQ_INSTALL:	// Install interrupt handler script // See below
			// We received the script in small packets in following format
			//		ReceiveBuf[0] = RC_IRQ_CONTROL_CMD	- command
			//		ReceiveBuf[1] = RCA_DEVIRQ_INSTALL	- sub command
			//		ReceiveBuf[2] = Low byte of the script's length
			//		ReceiveBuf[3] = High byte of the script's length
			//		ReceiveBuf[4] = low byte of current offset 
			//		ReceiveBuf[5] = High byte of current offset 
			//		ReceiveBuf[6] = Number of byte in this packet
			// We reply in format:
			//		ReplyBuf[0] = RC_IRQ_CONTROL_CMD		- command
			//		ReplyBuf[1] = RCA_DEVIRQ_INSTALL		- sub command
			//		ReplyBuf[2] = Low byte of the script's length
			//		ReplyBuf[3] = High byte of the script's length
			//		ReplyBuf[4] = low byte of current offset 
			//		ReplyBuf[5] = High byte of current offset 
			//		ReplyBuf[6] = Number of byte received in this packet
			//		ReplyBuf[7] = Error code (0=no error)
			{
				WORD wCur;

				// Prepare the reply buffer
				for (byTmp=0; byTmp<7; byTmp++)
					g_ReplyBuf[byTmp] = g_ReceiveBuf[byTmp];
				g_ReplyBuf[7] = 0;	// No error yet

				// Determine length of the script
				wLen = MAKEWORD(g_ReceiveBuf[2], g_ReceiveBuf[3]);	// Script's length
				if (wLen > MAX_IRQSCRIPT_LEN)
				{
					g_ReplyBuf[7] = 1;	// Script length error
					g_ReplyBuf[8] = LSB(MAX_IRQSCRIPT_LEN);	// Return the max. size as extra info
					g_ReplyBuf[9] = MSB(MAX_IRQSCRIPT_LEN);
					byLen = 10;	// Number of byte to be returned
				}
				else
				{
					// Determine current offset in the script
					wCur = MAKEWORD(g_ReceiveBuf[4], g_ReceiveBuf[5]);
					// Copy the script portion
					for (byTmp=7; byTmp<g_ReceiveBuf[6]+7; byTmp++)
					{
						g_byaIrqScript[wCur] = 	g_ReceiveBuf[byTmp];
						wCur++;
					}

					// Mark script is installed when we have enough bytes
					if (wCur==wLen)
						g_byLvIrqFlg |= IFL_USBIRQ_INSTALLED;
					byLen = 8;	// Number of byte to be returned
				}
			}
			break;

		case RCA_DEVIRQ_REMOVE:		// Remove interrupt handler script  // No reply
			g_byLvIrqFlg &= (~IFL_USBIRQ_INSTALLED);
			break;

		//case RCA_DEVIRQ_SETCB:	// Set callback			// NA: for USB-uC
		case RCA_DEVIRQ_SETBUF:		// Set IRQ data buffer
			// We receive the buffer info to USB-uC following format
			//		ReceiveBuf[0] = RC_IRQ_CONTROL_CMD	- command
			//		ReceiveBuf[1] = RCA_DEVIRQ_SETBUF		- sub command
			//		ReceiveBuf[2] = Buffer ID
			//		ReceiveBuf[3] = low byte of buffer size
			//		ReceiveBuf[4] = High byte of buffer size
			// We reply in format:
			//		ReplyBuf[0] = RC_IRQ_CONTROL_CMD		- command
			//		ReplyBuf[1] = RCA_DEVIRQ_SETBUF		- sub command
			//		ReplyBuf[2] = Buffer ID
			//		ReplyBuf[3] = low byte of buffer size
			//		ReplyBuf[4] = High byte of buffer size
			//		ReplyBuf[5] = Error code (0=no error)
				
			// Prepare the reply buffer
			for (byTmp=0; byTmp<5; byTmp++)
				g_ReplyBuf[byTmp] = g_ReceiveBuf[byTmp];
			g_ReplyBuf[5] = 0;	// No error yet

			wLen = MAKEWORD(g_ReceiveBuf[3], g_ReceiveBuf[4]);	// Requested buffer's length
			// Check buffer ID, we only support buffer 0 and 1
			if (g_ReceiveBuf[2] == 0) // Buffer 0 requested
			{
				if (wLen > MAXLEN_IRQBUF_0)
				{
					g_ReplyBuf[5] = 1;	// Buffer length error
				}
			}
			else if (g_ReceiveBuf[2] == 1) // Buffer 1 requested

⌨️ 快捷键说明

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