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

📄 rs232.c

📁 Sirf/Centrality公司GPS平台AtlasIII芯片AT640的Nboot源码
💻 C
字号:
#include "def.h"
#include "at4x0f.h"
#include <cspregs.h>
#include "debug.h"
#include "rs232.h"
#include "nand.h"
#include "..\inc\loader.h"

#include <string.h>

extern DWORD g_nCurImg;
extern DWORD g_nNandCS;

struct _serial_msg {
		uchar  status;
		uchar  char_in;
		uchar  type;
		uchar  subtype;
		uchar  sequence;
		uchar  cmd_code;
		uchar  cmd_reg;
		uchar  baudrate;
		uchar  length_low;
		uchar  packet_length;
		uchar  write_length;
		unsigned short data_length;
		unsigned short checksum;		
		};
typedef struct _serial_msg SERIALMSG;

#define P_MAX_PACKET_DATA		128
#define P_MAX_PACKET_LENGTH		(P_MAX_PACKET_DATA+6)


/* Communication internal status */
#define STATUS_IDLE				0
#define STATUS_WAIT_PACKET		1
#define STATUS_WAIT_ACK			2
#define STATUS_SENDING_DATA		3


SERIALMSG	g_msg;
uchar		g_serialBuf[SERIAL_BUF_LEN];
uchar		g_serialPkt[P_MAX_PACKET_LENGTH];
ulong		g_iHead;
ulong		g_iTail;

static int _fCheckSum;
static int _fReadingCmd;
static int _fReadingDatabody;
static int _fReadingChecksum;
static int _fReadingCmdData;
static int _fErrorPacket;
static int _fWriteImage;

#define _pSerialPacket		(g_serialPkt)
#define _pSerialData		(_pSerialPacket + 4)

extern unsigned char * pCurImgCache;
extern unsigned int g_iCurImgLength;
extern unsigned int iCurImgTransfered;

extern int g_bNandDbgMuted;

void Rs232Init()
{
#ifdef DEBUG_UART_PORT
	INT_RISC_MASK |= INT_MASK_SERIAL_0;
	UART_INT_STATUS = UART_INT_MASK_ALL;
	UART_INT_ENABLE = UART_INT_RX_DONE_MASK;
#else // DEBUG_UART_PORT
	INT_RISC_MASK |= INT_MASK_SERIAL_7_6_5_4;
	USP5_INT_STATUS = USP_INT_MASK_ALL;
	USP5_INT_ENABLE = USP_INT_RX_DONE_MASK;
#endif // DEBUG_UART_PORT
	memset(&g_msg, 0, sizeof(SERIALMSG));
	g_iHead = g_iTail = 0;
	g_bNandDbgMuted = 1;
}

void Rs232GetChars()
{
}

void _Handle_ErrorPacket()
{
	if (_fErrorPacket == 0)
	{
		DbgPutChar(P_NAK);
		_fErrorPacket = 1;
	}
	g_msg.status = STATUS_IDLE;
	g_msg.sequence = 0;
}

void _Handle_CmdSetReg()
{
	ulong lVal;

	lVal = _pSerialData[3];
	lVal <<= 8;
	lVal += _pSerialData[2];
	lVal <<= 8;
	lVal += _pSerialData[1];
	lVal <<= 8;
	lVal += _pSerialData[0];

	g_msg.status = STATUS_IDLE;

	switch (g_msg.cmd_reg)
	{
	case P_CMD_CUR_IMG_TYPE:
		g_nCurImg = lVal;
		break;
	case P_CMD_NAND_CS:
		g_nNandCS = lVal;
		FMD_Init();
		break;
	case P_CMD_CUR_IMG_LENGTH:
		iCurImgTransfered = 0;
		g_iCurImgLength = lVal;
		break;
	}
	DbgPutChar(P_ACK);
	return;
}

void _Handle_CmdAction()
{
	g_msg.status = STATUS_IDLE;
	DbgPutChar(P_ACK);	/* Send out ACK first */

	switch (g_msg.cmd_reg)
	{
	case P_ACTION_WRITE_IMG:
		NandWriteCurImg();
		break;
	case P_ACTION_UPDATE_TOC:
		NandWriteToc();
		break;
	case P_ACTION_OPEN_DATA_PIPE:
		_fWriteImage = 1;
		break;
	case P_ACTION_CLOSE_DATA_PIPE:
		_fWriteImage = 0;
		break;
	}
	DbgPutChar(P_ENQ);
	return;

}

void _Handle_PacketCmd()
{
	switch (g_msg.cmd_code)
	{
	case P_CMD_SET_REG:
		_Handle_CmdSetReg();
		break;

	case P_CMD_ACTION:
		_Handle_CmdAction();
		break;
	}
}

void _Handle_PacketIn()
{
	switch (g_msg.type)
	{
	case P_DATA_UNFINISHED:
		DbgPutChar(P_ACK);
		memcpy((pCurImgCache+iCurImgTransfered), _pSerialData, (g_msg.packet_length - 4));
		iCurImgTransfered += g_msg.packet_length - 4;

		g_msg.status = STATUS_IDLE;
		break;

	case P_DATA:
		DbgPutChar(P_ACK);
		g_msg.status = STATUS_IDLE;
		g_msg.sequence = 0;
		break;

	case P_CMD:
		_Handle_PacketCmd();
		break;
	}
}

void _Read_Idle()
{
	uchar in;

	in = g_msg.char_in;
	switch (in)
	{
	case P_DATA_UNFINISHED:
	case P_DATA:
	case P_CMD:
		g_msg.type = in;
		g_msg.packet_length = 1;
		g_msg.checksum = 0;
		_fCheckSum = 0;
		g_msg.status = STATUS_WAIT_PACKET;
		if (in == P_CMD)
		{
			_fReadingCmd = 1;
			_fReadingCmdData = 0;
		}
		else
		{
			_fReadingCmd = 0;
		}
		_fReadingDatabody = 0;
		_fReadingChecksum = 0;
		return;

	case P_NUL:
		if (_fErrorPacket == 0)
		{
			DbgPutChar(P_NAK);
		}
		return;

	}
	_Handle_ErrorPacket();
}

int _Read_WaitPacket_Databody()
{
	uchar in;

	// data body 
	in = g_msg.char_in;

	// Add check sum first 
	g_msg.checksum += in;
	g_msg.data_length --;

	if (g_msg.data_length == 0)
		_fReadingChecksum = 1;

	if (_fReadingCmd)
	{
		if (_fReadingCmdData)
		{	// save command data
			if (g_msg.packet_length < P_MAX_PACKET_DATA)
			{
				_pSerialData[g_msg.packet_length] = in;
				g_msg.packet_length ++;
			}
		}
		else
		{
			if (g_msg.packet_length == 4)
			{
				if (in > P_CMD_GET_VDATA)		return 0;		/* cmd code is between 0 - 4 */

				g_msg.cmd_code = in;
				g_msg.packet_length ++;
			}
			else /* if (g_msg.packet_length == 5) */
			{
				g_msg.cmd_reg = in; 
				_fReadingCmdData = 1;
				g_msg.packet_length -= 5;
			}
		}
	}
	else
	{
		_pSerialPacket[g_msg.packet_length] = in;
		g_msg.packet_length ++;
	}

	return 1;
}

int _Read_WaitPacket_Checksum()
{
	if (_fCheckSum == 0)
	{
		g_msg.checksum -= g_msg.char_in;
		if ((g_msg.checksum & 0xff) != 0)
			return 0;
		_fCheckSum = 1;
	}
	else
	{
		g_msg.checksum >>= 8;
		g_msg.checksum -= g_msg.char_in;
		if (g_msg.checksum != 0)
			return 0;
		_fCheckSum = 0;

		// All data packet finished, now handle it 
		_fErrorPacket = 0;
		_Handle_PacketIn();
	}
	return 1;
}

void _Read_WaitPacket()
{
	uchar in;

	if (_fReadingDatabody)
	{
		if (_fReadingChecksum == 0)
		{
			if (_Read_WaitPacket_Databody() == 0)
				goto Error;
		}
		else
		{
			if (_Read_WaitPacket_Checksum() == 0)
				goto Error;
		}
	}
	else
	{
		in = g_msg.char_in;
		switch (g_msg.packet_length)
		{
		case 1:
			if (_fReadingCmd)
			{
				if (in != P_CMD_FIRST && in != P_CMD_NORMAL)
					goto Error;
			}
			else
			{
				if (in != g_msg.sequence)
					goto Error;
				g_msg.sequence ++;
			}
			g_msg.subtype = in;
			break;

		case 2:
			g_msg.length_low = in;
			break;

		case 3:
			g_msg.data_length = in;
			g_msg.data_length <<= 8;
			g_msg.data_length += g_msg.length_low;
			if (g_msg.data_length > P_MAX_DATA_LENGTH)
				goto Error;
			if (g_msg.data_length == 0)
				_fReadingChecksum = 1;
			_fReadingDatabody = 1;
			break;
		}
		g_msg.packet_length ++;
	}
	return;

Error:
	_Handle_ErrorPacket();
}

void _Read_WaitAck()
{
	switch (g_msg.char_in)
	{
	case P_ACK:
		g_msg.status = STATUS_IDLE;
		return;

	case P_DC1:
		_fErrorPacket = 1;
		_Handle_ErrorPacket();
		return;
	}
	/* Send NAK */
	DbgPutChar(P_NAK);
}

void Rs232ProcessChar(uchar in)
{
	g_msg.char_in = in;
	switch (g_msg.status)
	{
	case STATUS_WAIT_PACKET:
		_Read_WaitPacket();
		break;

	case STATUS_IDLE:
		_Read_Idle();
		break;

	case STATUS_WAIT_ACK:
		_Read_WaitAck();
		break;
	}
}

void DoRS232(void)
{
	Rs232Init();
	while(1)
	{
		while(g_iHead != g_iTail)
		{
			Rs232ProcessChar(g_serialBuf[g_iHead]);
			g_iHead ++;
			g_iHead &= SERIAL_BUF_AND;
		}
	}
}


⌨️ 快捷键说明

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