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

📄 usbirqfunc.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
			{
				if (wLen > MAXLEN_IRQRNDBUF)
				{
					g_ReplyBuf[5] = 1;	// Buffer length error
				}
			}
			else
			{
				g_ReplyBuf[5] = 2;	// Buffer ID error
			}
			byLen = 6;	// Number of byte to be returned
			break;

		case RCA_DEVIRQ_MOD_SBUF:	// Modify scratch buffer (buffer 0)
			// We receive the buffer info to USB-uC following format
			//		ReceiveBuf[0] = RC_IRQ_CONTROL_CMD	- command
			//		ReceiveBuf[1] = RCA_DEVIRQ_MOD_SBUF	- sub command
			//		ReceiveBuf[2] = length of modify-script in byte
			//		ReceiveBuf[3] = NA
			//		ReceiveBuf[4+i*2] = Index i in the scratch buffer to be modified
			//		ReceiveBuf[5+i*2] = Value for index i (i=0...n)
			// We reply in format:
			//		ReplyBuf[0] = RC_IRQ_CONTROL_CMD	- command
			//		ReplyBuf[1] = RCA_DEVIRQ_MOD_SBUF	- sub command
			//		ReplyBuf[2] = length of modify-script in byte
			//		ReplyBuf[3] = Error code (0=no error)
			// Prepare the reply buffer
			for (byTmp=0; byTmp<3; byTmp++)
				g_ReplyBuf[byTmp] = g_ReceiveBuf[byTmp];
			g_ReplyBuf[3] = 0;	// No error yet

			// Modify the buffer 0 according to the modify-script
			for (byTmp=4; byTmp<(g_ReceiveBuf[2]+4); byTmp+=2)
				g_byaIrqBuf0[g_ReceiveBuf[byTmp]] = g_ReceiveBuf[byTmp+1];
			byLen = 4;	// Number of byte to be returned
			break;

		default:		// Do nothing
			break;
	} // EndSwitch
	return(byLen);
} // End UsbIrqControl

BYTE UsbExecScript()
{
	// Execute the passed along script command
	//I:<cmd><ScriptLength=n><Script data 0><Reply length=m><...><Script data n-1>
	//O:<cmd><Return length=m><Return data 0><...><Return data m-1>
	UsbLvIrqProcess(&g_ReceiveBuf[3]);
	g_ReplyBuf[1] = g_ReceiveBuf[2]; // Data count to be returned (specified by host)
	return(2+g_ReplyBuf[1]);	// total byte to be send back
} // End UsbExecScript

void ExtRdsIntHandler()
{
	// External RDS interrupt handling (invoke when INT4 occurred)
	// Somehow, the host wants RDS data in format (after 16 bits):
	//	 RdsBit_0..RdsBit_7 - RdsBit_8..RdsBit_15 (RdsBit_0 is the first received bit)
	// In the buffer we have:
	//	low byte [7:0]: RdsBit[0:7]
	//	High byte[7:0]: RdsBit[8:15]
	// The buffer is filled with 2 bytes each time
	BYTE byTmp;

	// Check buffer space, no data filling if out of space
	if (g_stExtIrq.byF < MAXLEN_IRQRNDBUF)
	{
		// determine filling low byte/high byte
		if (g_byRdsBitCnt < 8)
			byTmp = g_stExtIrq.byW;		// Fill low byte
		else
			byTmp = g_stExtIrq.byW + 1;	// Fill high byte

		// Make room to shift the data in
		g_stExtIrq.byBuf[byTmp] <<= 1;

		// Read RDS data level and patch it into the buffer
		// 	After first 8 bit, RdsBit_0 becomes DataBit_7
		// 	After next 8 bit, RdsBit_8 becomes DataBit_15
		if (EXRDS_PORT & EXRDS_DATA_PIN_BM) // Data is high
			g_stExtIrq.byBuf[byTmp] |= 1;	

		// Advance to next bit
		g_byRdsBitCnt++;

		// Mark we received 2 bytes when we have enough bits
		if (g_byRdsBitCnt == 16) 
		{
			g_stExtIrq.byW += 2;	// Adjust the write pointer
			g_stExtIrq.byF += 2;	// Adjust the byte count

			// Wrap the write pointer to 0 when it goes beyond the buffer
			if (g_stExtIrq.byW >= MAXLEN_IRQRNDBUF)
				g_stExtIrq.byW = 0;

			// Reset the bit counter for next time
			g_byRdsBitCnt = 0;
		}
	} // EndIf buffer size check
} // End ExtRdsIntHandler

BYTE CopyRoundRobinBuf(PRNDBUF_ST pStRrBuf)
{
	// Copy the data from the specified round robin buffer to the USB-reply buffer.
	// The reply buffer is filled until maximal USB packet count reached in followinf format:
	//	Reply[0]: Command
	//	Reply[1]: Number of byte in this packet (=n)
	//	Reply[2]: Data byte 0
	//	Reply[2+n-1]: data byte n
	// The byte filled counter is compensated after the copying
	BYTE byLen;

	// Determine number of byte to be filled in the reply buffer
	if ( pStRrBuf->byF < (USB_REPLY_PACKET_SIZE-2) )	// The 2 first bytes are meant for command and byte count
		g_ReplyBuf[1] = pStRrBuf->byF;
	else
		g_ReplyBuf[1] = (USB_REPLY_PACKET_SIZE-2);

	// Copy data
	for (byLen=0; byLen<g_ReplyBuf[1]; byLen++)
	{
		// Copy current byte at read pointer
		g_ReplyBuf[2+byLen] = pStRrBuf->byBuf[pStRrBuf->byR];
			
		// Move the read pointer to next byte
		pStRrBuf->byR++;

		// Wrap the read pointer to the begin if it goes beyond the buffer
		if (pStRrBuf->byR == MAXLEN_IRQRNDBUF)
			pStRrBuf->byR = 0;
	}
			
	// Last step: update the byte count
	// The read pointer is laready updated in the copy loop
	// This should be done with interrupt free
	if (byLen != 0)
		pStRrBuf->byF -= byLen;

	return(byLen+2);	// Return number of byte filled in reply packet
} // End CopyRoundRobinBuf

void UsbLvIrqProcess(PBYTE pbyScript)
{
	BYTE byReturn;

	// Run the IRQ handling script
	while ( pbyScript[0] != ISO_ENDSCRIPT )
	{
		if ( pbyScript[0] <= SCRIPT_COMMAND_FUNC_MAX )
		{
			byReturn = ScriptCommandTable[pbyScript[0]](pbyScript[1],pbyScript[2]);
			if ( byReturn != SCRIPT_OK )
			{
				if ( byReturn == SCRIPT_CHK_FAIL )
				{
					// Skip till next ID
					while ( (pbyScript[0] != ISO_ENDSCRIPT) && (pbyScript[0] != ISO_IRQID) )
					{
						pbyScript+=3;
					}
					continue;
				}
			}
		}
		pbyScript+=3;
	}
} // End UsbLvIrqProcess

BYTE ScNOP( BYTE byParm1, BYTE byParm2 )
{
	byParm1;
	byParm2;
	return( SCRIPT_OK );
}

BYTE ScIrqID( BYTE byParm1, BYTE byParm2 )
{
	byParm1;
	byParm2;
	return( SCRIPT_OK );
}

BYTE ScWrite3WD( BYTE byParm1, BYTE byParm2 )
{
	UsbWrite3wV3V4(byParm2, byParm1);	// Low/High
	return( SCRIPT_OK );
}

BYTE ScWrite3WI( BYTE byParm1, BYTE byParm2 )
{
	UsbWrite3wV3V4(g_byaIrqBuf0[byParm2], byParm1);	// Low/High
	return( SCRIPT_OK );
}

BYTE ScRead3W( BYTE byParm1, BYTE byParm2 )
{
	g_byaIrqBuf0[byParm2] = UsbRead3wV3V4(byParm1);
	return( SCRIPT_OK );
}

BYTE ScChkMaskLow( BYTE byParm1, BYTE byParm2 )
{
	if( g_byaIrqBuf0[byParm1] & byParm2 )
		return( SCRIPT_CHK_FAIL );
	else
		return( SCRIPT_OK );
}

BYTE ScChkMaskHigh( BYTE byParm1, BYTE byParm2 )
{
	if( g_byaIrqBuf0[byParm1] & byParm2 )
		return( SCRIPT_OK );
	else
		return( SCRIPT_CHK_FAIL );
}

BYTE ScOrMask( BYTE byParm1, BYTE byParm2 )
{
	g_byaIrqBuf0[byParm1] |= byParm2;
	return( SCRIPT_OK );
}

BYTE ScAndMask( BYTE byParm1, BYTE byParm2 )
{
	g_byaIrqBuf0[byParm1] &= byParm2;
	return( SCRIPT_OK );
}

BYTE ScStoreBuf( BYTE byParm1, BYTE byParm2 )
{
	BYTE byTmp;

	if( byParm2 == 1 ) // Only buffer 1 is supported !
	{
		byTmp = UsbRead3wV3V4(byParm1);	// Read register to clear interrupt
		if (g_stIrqBuf1.byF < MAXLEN_IRQRNDBUF)
		{
			g_stIrqBuf1.byBuf[g_stIrqBuf1.byW] = byTmp;
			g_stIrqBuf1.byW++;
			if (g_stIrqBuf1.byW == MAXLEN_IRQRNDBUF)
				g_stIrqBuf1.byW = 0;
			g_stIrqBuf1.byF++;
		}
		return( SCRIPT_OK );
	}
	else
		return( SCRIPT_ERROR );
}
BYTE ScRead3WD(BYTE byParm1, BYTE byParm2)
{
	g_ReplyBuf[2 + byParm2] = UsbRead3wV3V4(byParm1);
	return(SCRIPT_OK);
}

BYTE ScPollHi(BYTE byParm1, BYTE byParm2)
{
	while ( (UsbRead3wV3V4(byParm1) & byParm2) != byParm2 );
	return(SCRIPT_OK);
}

BYTE ScPollLo(BYTE byParm1, BYTE byParm2)
{
	while ( (UsbRead3wV3V4(byParm1) & byParm2) != 0 );
	return(SCRIPT_OK);
}
// ==============================================================================
#endif //USE_IRQSCRIPT 	// The whole file can be discarded if interrupt is not used
// ==============================================================================

⌨️ 快捷键说明

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