📄 smt.c
字号:
/*
$Workfile: smt.c $
$Revision: 1.1 $
$Date: May 17 2006 01:58:46 $
*/
//******************************************************************
//
// Copyright (C) 2003. GENESIS MICROCHIP INC.
// All rights reserved. No part of this program may be reproduced
//
// Genesis Microchip Inc., 165 Commerce Valley Dr. West
// Thornhill, Ontario, Canada, L3T 7V8
//
//================================================================
//
// MODULE: smt.c
//
//******************************************************************
#include "inc\all.h"
#include "system\mcu186.h"
#if USE_SMT
#if DEBUG_MSG
#define DEBUG_APPTEST 0
#define DEBUG_APPTEST_EXTENDED 1
#include <stdlib.h>
#include <embedded.h>
#include <mem.h>
#include ".\AppsTest\appstest.h"
#if DEBUG_APPTEST && DEBUG_MSG
#define msg(a,b) gm_Print((const char far *)a,b)
#else
#define msg(a,b)
#endif
//NOTE: do not use gm_Print to debug SMT is serial handler is used for SMT
// Support SMT
#if DEBUG_SMT && DEBUG_MSG
#define msgs(a,b) gm_Print((const char far *)a,b)
#else
#define msgs(a,b)
#endif
#if DEBUG_SMT
BYTE SMTDebug[100]; // TODO: WHY 100 ??
BYTE SMTCnt=0;
BYTE SMTCNT(void)
{
SMTCnt++;
if (SMTCnt > 100) // TODO: WHY 100 ??
SMTCnt = 0;
return SMTCnt;
}
#else
BYTE tmpSMTDebug; //to achieve code consistence, waste 1 byte if DEBUG_SMT is not turned on
#endif
SMT_TransactionStruct_t SMT_TransArray[MAX_TRANSACTION_NUMBER];
gmt_MsgStruct OutMsg;
BYTE OldEvOdd = 0xFF;
//******************************************************************************
// Sample of Hi-Lewel SMT function:
//******************************************************************************
//
// FUNCTION : void RamWrite(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use,
// BYTE EvOdd, BYTE YesNoMoreData, BYTE MsgLen)
// USAGE : This function recieve data from PC, copy it to RAM amd send response to PC
//
// INPUT : BYTE CurrentTransNumber = number of current transaction in the
// transaction array SMT_TransArray[]
// BYTE msgpkt[] = msgpkt array from SMT message
// contains: in the first message of RAM_WRITE command:
// BYTES
// 0 = low byte of command (== 0xB)
// 1 = hi byte of command (== 0)
// 2 = low byte of address (Start address of RAM)
// 3 = hi byte of address (Start address of RAM)
// 4 = low byte of Data Size
// 6 = hi byte of Data Size
// 7.. = Data
// This only for first message!!!
// For other messages: 0,1,.. - Data bytes!
// BYTE comm_use = SERIAL_USE or DDC2BI_USE
// BYTE EvOdd = Even/Odd message count
// BYTE YesNoMoreData = More Data Pending flag from first byte of
// SMT message header
// BYTE MsgLen = Length of current message
// OUTPUT : None
//
//******************************************************************************
void RamWrite(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd, BYTE YesNoMoreData, BYTE MsgLen)
{
BYTE B_Count;
BYTE B_DataStart;
msgs("RamWrite()",0);
if(SMT_TransArray[CurrentTransNumber].B_CurCmd == IDLE_CMD)
{
SMT_TransArray[CurrentTransNumber].B_CurCmd = RAM_WRITE_CMD;
SMT_TransArray[CurrentTransNumber].Bp_Buff = (BYTE far *)(DWORD)((msgpkt[3] << 8) | msgpkt[2]);
SMT_TransArray[CurrentTransNumber].BuffSize = (msgpkt[5] << 8) | msgpkt[4];
SMT_TransArray[CurrentTransNumber].W_Count = 0;
msgs("RamWrite() Bp_Buff 0x%x (Address)",(WORD) SMT_TransArray[CurrentTransNumber].Bp_Buff);
msgs("RamWrite() BuffSize %d bytes",SMT_TransArray[CurrentTransNumber].BuffSize);
msgs("RamWrite() Recieved %d bytes",SMT_TransArray[CurrentTransNumber].W_Count);
B_DataStart = 6;
}
else
{
B_DataStart = 0;
}
for(B_Count = B_DataStart; B_Count < (MsgLen - 5); B_Count++)
{
SMT_TransArray[CurrentTransNumber].Bp_Buff[SMT_TransArray[CurrentTransNumber].W_Count] = msgpkt[B_Count];
msgs("RamWrite() Byte = 0x%X ",msgpkt[B_Count]);
SMT_TransArray[CurrentTransNumber].W_Count++;
}
msgs("RamWrite() Recieved %d bytes",SMT_TransArray[CurrentTransNumber].W_Count);
if(YesNoMoreData != YES_NO_MORE_DATA)
{
if(SMT_TransArray[CurrentTransNumber].W_Count != SMT_TransArray[CurrentTransNumber].BuffSize)
{
SMT_SendReTransmit(SMT_TransArray[CurrentTransNumber].ID, comm_use, EvOdd, 100);
msgs("ERROR: Recived %d bytes. It is != that must be recived.",SMT_TransArray[CurrentTransNumber].W_Count);
return;
}
else
{
msgs("Recieve completed TransID = %d ",SMT_TransArray[CurrentTransNumber].ID);
}
SMT_TransArray[CurrentTransNumber].B_CurCmd = IDLE_CMD;
}
// Sending response:
OutMsg.len = 6;
OutMsg.cmd = SMT_Message;
OutMsg.BUF[0] = EvOdd;
OutMsg.BUF[1] = SMT_TransArray[CurrentTransNumber].ID;
OutMsg.BUF[2] = ACK; // I use ACK for example.
gm_CommsSendReply((gmt_MsgStruct far*)&OutMsg, comm_use);
}
//******************************************************************************
// Sample of Hi-Lewel SMT function:
//******************************************************************************
//
// FUNCTION : void RamRead(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
// USAGE : This function read data from RAM and send it to PC
//
// INPUT : BYTE CurrentTransNumber = number of current transaction in the
// transaction array SMT_TransArray[]
// BYTE msgpkt[] = msgpkt array from SMT message
// contains: in the first message of RAM_WRITE command:
// BYTES
// 0 = low byte of command (== 0xC)
// 1 = hi byte of command (== 0)
// 2 = low byte of address (Start address of RAM)
// 3 = hi byte of address (Start address of RAM)
// 4 = low byte of Data Size
// 6 = hi byte of Data Size
// This only for first message!!!
// For other messages: None!
// BYTE comm_use = SERIAL_USE or DDC2BI_USE
// BYTE EvOdd = Even/Odd message count
// OUTPUT : None
//
//******************************************************************************
void RamRead(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
{
BYTE B_Count;
BYTE B_CurrentMaxLen;
BYTE B_YesNoMoreData = 0;
BYTE B_MsgLen;
msgs("RamRead()",0);
if(comm_use == SERIAL_USE)
B_CurrentMaxLen = 255;
else
B_CurrentMaxLen = 10; // 120;
if(SMT_TransArray[CurrentTransNumber].B_CurCmd == IDLE_CMD)
{
SMT_TransArray[CurrentTransNumber].B_CurCmd = RAM_READ_CMD;
SMT_TransArray[CurrentTransNumber].Bp_Buff = (BYTE far *)(DWORD)((msgpkt[3] << 8) | msgpkt[2]);
SMT_TransArray[CurrentTransNumber].BuffSize = (msgpkt[5] << 8) | msgpkt[4];
SMT_TransArray[CurrentTransNumber].W_Count = 0;
if(SMT_TransArray[CurrentTransNumber].BuffSize < (B_CurrentMaxLen - 5))
{
B_MsgLen = SMT_TransArray[CurrentTransNumber].BuffSize + 5;
}
else
{
B_MsgLen = B_CurrentMaxLen;
B_YesNoMoreData = YES_NO_MORE_DATA;
}
msgs("Bp_Buff: 0x%x", (WORD) SMT_TransArray[CurrentTransNumber].Bp_Buff);
msgs("BuffSize: 0x%x", SMT_TransArray[CurrentTransNumber].BuffSize);
}
else
{
if((SMT_TransArray[CurrentTransNumber].BuffSize - SMT_TransArray[CurrentTransNumber].W_Count) < (B_CurrentMaxLen - 5))
{
B_MsgLen = (SMT_TransArray[CurrentTransNumber].BuffSize - SMT_TransArray[CurrentTransNumber].W_Count) + 5;
}
else
{
B_MsgLen = B_CurrentMaxLen;
B_YesNoMoreData = YES_NO_MORE_DATA;
}
}
// Sending response:
OutMsg.len = B_MsgLen;
OutMsg.cmd = SMT_Message;
OutMsg.BUF[0] = EvOdd | B_YesNoMoreData;
OutMsg.BUF[1] = SMT_TransArray[CurrentTransNumber].ID;
for(B_Count = 2; B_Count < (B_MsgLen - 3); B_Count++)
{
OutMsg.BUF[B_Count] = SMT_TransArray[CurrentTransNumber].Bp_Buff[(SMT_TransArray[CurrentTransNumber].W_Count + B_Count - 2)];
//msg("Sended byte = 0x%X",OutMsg.BUF[B_Count]);
}
SMT_TransArray[CurrentTransNumber].W_Count += B_Count - 2;
gm_CommsSendReply((gmt_MsgStruct far*)&OutMsg, comm_use);
if(B_YesNoMoreData != YES_NO_MORE_DATA)
{
SMT_TransArray[CurrentTransNumber].B_CurCmd = IDLE_CMD;
msgs("RamRead Completed",0);
}
else
{
msgs("RamRead continue",0);
}
}
//******************************************************************************
// Sample of Hi-Lewel SMT function:
//******************************************************************************
//
// FUNCTION : void RegisterRead(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
// USAGE : This function read data from register and send it to PC
//
// INPUT : BYTE CurrentTransNumber = number of current transaction in the
// transaction array SMT_TransArray[]
// BYTE msgpkt[] = msgpkt array from SMT message
// contains: in the first message of RAM_WRITE command:
// BYTES
// 0 = low byte of command (== 0xD)
// 1 = hi byte of command (== 0)
// 2 = low byte of address (Register address)
// 3 = hi byte of address (Register address)
// BYTE comm_use = SERIAL_USE or DDC2BI_USE
// BYTE EvOdd = Even/Odd message count
// OUTPUT : None
//
//******************************************************************************
void RegisterRead(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
{
WORD W_RegAddr;
BYTE B_RegData;
W_RegAddr = (msgpkt[3] << 8) | msgpkt[2];
B_RegData = gm_ReadRegByte(W_RegAddr);
msgs("RegisterRead() Addr = 0x%X ",W_RegAddr);
msgs("RegisterRead() Data = 0x%X",B_RegData);
// Sending response:
OutMsg.len = 7;
OutMsg.cmd = SMT_Message;
OutMsg.BUF[0] = EvOdd;
OutMsg.BUF[1] = SMT_TransArray[CurrentTransNumber].ID;
OutMsg.BUF[2] = B_RegData; //& 0xFF
// OutMsg.BUF[3] = (B_RegData >> 8) & 0xFF;
gm_CommsSendReply((gmt_MsgStruct far*)&OutMsg, comm_use);
}
//******************************************************************************
// Sample of Hi-Lewel SMT function:
//******************************************************************************
//
// FUNCTION : void RegisterWrite(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
// USAGE : This function recieve data from PC write it to register and
// response send it to PC
//
// INPUT : BYTE CurrentTransNumber = number of current transaction in the
// transaction array SMT_TransArray[]
// BYTE msgpkt[] = msgpkt array from SMT message
// contains: in the first message of RAM_WRITE command:
// BYTES
// 0 = low byte of command (== 0xD)
// 1 = hi byte of command (== 0)
// 2 = low byte of address (Register address)
// 3 = hi byte of address (Register address)
// 4 = low byte of Data
// 5 = hi byte of Data
// BYTE comm_use = SERIAL_USE or DDC2BI_USE
// BYTE EvOdd = Even/Odd message count
// OUTPUT : None
//
//******************************************************************************
void RegisterWrite(BYTE CurrentTransNumber, BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
{
WORD W_RegAddr;
WORD B_RegData;
W_RegAddr = (msgpkt[3] << 8) | msgpkt[2];
B_RegData = msgpkt[4]; //(msgpkt[5] << 8) | msgpkt[4];
gm_WriteRegByte(W_RegAddr, B_RegData);
msgs("RegisterWrite() Addr = 0x%X ", W_RegAddr);
msgs("RegisterWrite() Data = 0x%X",B_RegData);
// Sending response:
OutMsg.len = 5;
OutMsg.cmd = SMT_Message;
OutMsg.BUF[0] = EvOdd;
OutMsg.BUF[1] = SMT_TransArray[CurrentTransNumber].ID;
gm_CommsSendReply((gmt_MsgStruct far*)&OutMsg, comm_use);
}
//******************************************************************************
// SMT functions:
//******************************************************************************
//******************************************************************************
//
// FUNCTION : void SMT_OpenTransaction(BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
// USAGE : This function open transaction and send response to PC
//
// INPUT : BYTE msgpkt[] = msgpkt array from SMT message
// BYTE comm_use = SERIAL_USE or DDC2BI_USE
// BYTE EvOdd = Even/Odd message count
// OUTPUT : None
//
//******************************************************************************
void SMT_OpenTransaction(BYTE msgpkt[], BYTE comm_use, BYTE EvOdd)
{
WORD W_Port;
WORD W_Index;
BYTE CurrentTransNumber;
BYTE B_Count;
static BYTE B_LastId = 0xFF;
//Initiate SMT_TransArray if it is first transaction.
//TODO: Initiator must be modified if more possible transaction statuses are added
if((SMT_TransArray[0].B_Status!=TRANSACTION_CLOSED) &&
(SMT_TransArray[0].B_Status!=TRANSACTION_OPENED))
{
for(B_Count =0; B_Count <MAX_TRANSACTION_NUMBER; B_Count++)
{
SMT_TransArray[B_Count].ID = 0xFF;
SMT_TransArray[B_Count].B_Status = TRANSACTION_CLOSED;
}
}
// Look for vacant transaction context
for(B_Count =0; B_Count <MAX_TRANSACTION_NUMBER; B_Count++)
{
if(SMT_TransArray[B_Count].B_Status == TRANSACTION_CLOSED) //.ID == 0)
{
CurrentTransNumber = B_Count;
break;
}
}
// Handle no vacant context situation
if(B_Count == MAX_TRANSACTION_NUMBER)
{
// Send Failed
msgs("ERROR: No Vacant Transaction",0);
SMT_SendFailed(comm_use, EvOdd, GENERIC_ER);
return;
}
//extract port number from received packet
//and check port's valdidity
W_Port = ((WORD)msgpkt[0] << 8) | (WORD)msgpkt[1]; // orginal setting
// W_Port = ((WORD)msgpkt[1] << 8) | (WORD)msgpkt[0]; // for testing only
if(W_Port >= MAX_SMTPORT)
{
msgs("Port 0x%X is invalid ",W_Port);
SMT_SendFailed(comm_use, EvOdd, GENERIC_ER);
return;
}
//look for port entry in the handlers LUT
for(W_Index =0; SMT_Port2HandlerTable[W_Index].PortID != MAX_SMTPORT; W_Index++)
{
if(SMT_Port2HandlerTable[W_Index].PortID == W_Port)
{
if(SMT_Port2HandlerTable[W_Index].Fp_SMT_MsgHandler != NULL_PTR)
{
msgs("Port 0x%X is supported",W_Port);
break;
}
else
{
msgs("Port 0x%X is not supported",W_Port);
SMT_SendFailed(comm_use, EvOdd, GENERIC_ER);
return;
}
}
}
if(W_Index == MAX_SMTPORT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -