📄 mcdemo.c.bak
字号:
/*
** Copyright (C)1999 KVASER AB, http://www.kvaser.com
** This code may be freely distrubuted and used if the source is indicated.
**
*/
#ifdef __WIN32__
#include <vcl.h>
#pragma hdrstop
#include <canlib.h>
#include "mainUnit.h"
#include "mcThread.h"
#include "inc\canUnit.h"
#include "util_w32.h"
#else
#include <string.h>
#include "inc\util_mc.h"
#include "inc\spi_mcp.h"
#include <pic.h>
#include <stdio.h>
#endif
#include "inc\mcDemo.h"
#include "inc\ck.h"
#include "ad.h"
//---------------------------------------------------------------------------
#ifdef __WIN32__
#pragma package(smart_init)
#endif
/*
Available functions:
There are three transmit buffes in MCP2510, but only the first one is used.
If it is in use, a message may be dropped. This could be improved.
The two receive buffers are used as a short receive queue. The are polled,
should they both be full, received messages are dropped.
Document list. Document number and Folder number are identical and fixed
Receive documents
0 Kings Document DLC = 8
Page 0. Selects Action and Communication mode.
Page 1. Provides the Base numbers, asks for a Mayor's response.
Page 2. Assigns an Envelope to a Folder.
Page 9. Change the city address.
Page 16. Partial support, enable/disable a folder by number.
2 Parameter settings DLC = 8
Page 0
line 0: 0 (page number)
line 1..2: Period to transmit the Inputs document, 1..65536, 0 no transmissions
line 3..7: 0
3 LED control DLC = 1
line 0: Bit 0..1 controls the two LEDs (RXBF0, RXBF1)
4 Request Document Inputs DLC = 0
Transmit documents
1 Mayor's Document DLC = 8
Page 0
line 0: 0
line 1: 0 (page no)
line 2..6: EAN code (LSB..MSB)
line 7: 0
Page 1
line 0: 0
line 1: 1 (page no)
line 2..6: Serial number (LSB..MSB)
line 7: 0
5 Inputs DLC = 2 RTR always enabled
line 0: Bit 0..1 Current LED status
Bit 2..4 Buttons 0..2, current value
Bit 5..7 Buttons 0..2, sticky (cleared at Tx).
line 1: Analog value, 0..255
Optional receive documents (not implemented):
KP3. Assign a City to Groups
KP4. Removing a City from Groups
KP8. CAN bus parameter setting
KP9. Change of the City physical adress
KP16. Placing a Document in a folder
KP20. Setup filters
Optional transmit documents (not implemented):
MP128
line 0: 0
line 1: 128
line 2: No of dropped transmit documents
line 3: No of lost recieve documents (if possible to detect)
The Main program
Startup:
Turn off LEDs. Initiate analogue input, button inputs etc.
Initialize the CAN communication (Baud rate etc, set up one receive
and one transmit buffer, go on line).
Check for received CAN message.
If one, handle it. May result in a message being transmitted.
Poll the buttons.
Check if a periodic transmission should be done.
*/
// --- Global variables
BANK1 canIdT folder_env[FOLDER_COUNT]; // CAN id's. Bit 31 marks Extended CAN.
// We want to be able to disable a folder but keep the envelope, so we must use this
BANK1 uchar folder_enabledMask;
BANK1 canIdT baseNo = envInvalid; // Assigned envInvalid for an invalid base number.
BANK1 uchar nodeNo = 10;
BANK1 actModesT actMode = ckFreeze;
BANK1 commModesT commMode = ckSilent;
BANK1 unsigned int txPeriod = 0;
//int canWriteFailures = 0;
BANK1 unsigned int txLastTime; // Used for periodic transmissions
BANK1 uchar LEDsave = 0; // Saves which LEDs are active
BANK1 uchar buttonsSticky = 0;
// --- Protottypes
void ckInit(void);
void checkMsg(void);
void rxKP(uchar *buf);
void txMP(uchar pageNo);
void txInputs(void);
void rxParam(uchar *buf);
BANK1 uchar mpPending = 255;
void setFolderEnable(uchar fNo, uchar f) {
if (f)
folder_enabledMask |= (1 << fNo);
else
folder_enabledMask &= ~(1 << fNo);
}
uchar checkFolderEnable(uchar fNo) {
return folder_enabledMask & (1 << fNo);
}
/* Reset the module. Will never return.
*/
void doReset(void) {
setLEDs(0);
#ifdef __WIN32__
for(;;)
Sleep(100);
#else
#endif
}
/* Perform any action that should be done when Freeze mode is entered such
* as turning off all outputs etc.
* may be called also when the mode _is_ Freeze.
*/
void doFreeze(void) {
setLEDs(0);
}
/* Perform any action that should be done when Run mode is entered.
* may be called also when the mode _is_ Run.
*/
void doRun(void) {
setLEDs(LEDsave);
}
#ifdef __WIN32__
// The "main" function will be called by a thread
void mcMain(void)
#else
// The actual main function
void main(void)
#endif
{
//uchar b;
//uchar d;
//char candata[8]={0x53,0x54,0x02,0x01,0,0,0,0};
//setupModule();
//setLEDs(0);
//canSetup();
//ckInit();
//adinitial();
#ifndef __WIN32__
//mcp_read_all();
#endif
TRISC = 0;
for (;;) {
//checkMsg();
//canWrite(0x10, candata, 8,4) ;
//printf("dddddddddddddddddd\n");
//filter();
DelayF(3000);
PORTC=0x04;
DelayF(3000);
PORTC=0xfb;
}
}
void fixMPEnv(void) {
if (baseNo == envInvalid)
folder_env[doc_MayorsDocument] = envInvalid;
else
folder_env[doc_MayorsDocument] = baseNo+nodeNo;
}
void ckInit(void) {
int i;
for (i = 0; i < FOLDER_COUNT; i++) {
folder_env[i] = envInvalid;
setFolderEnable(i, 0);
}
// Set up for the King's Page and the Mayor's Page.
setFolderEnable(doc_KingsDocument, 1);
folder_env[doc_KingsDocument] = 0;
setFolderEnable(doc_MayorsDocument, 1);
fixMPEnv();
#ifdef __WIN32__
mcThread->showCKStatus();
mcThread->showFolders();
mcThread->showModuleStatus();
#endif
}
/*
* Check if a message is received; if so, act on it.
*/
void checkMsg(void) {
ulong id;
unsigned char dlc;
unsigned char buf[8];
unsigned int flags;
canStatus stat;
int i;
stat = canRead(&id, buf, &dlc, &flags);
if (stat == canOK) {
printf("Message rcvd: id=%x, dlc=%x, {%d,%d,%d,%d,%d,%d,%d,%d...}\r\n", (int)id, dlc, buf[0], buf[1], buf[2],buf[3],buf[4], buf[5], buf[6],buf[7]);
}
}
// Extracts an Envelop number from a message; it starts at buf[0].
// The highest bit decides if it is an extended CAN id or not and is kept,
// the other two reserved or control bits are cleared.
// We support extended CAN as we must be able to detect 0x1fffffff for an
// undefined base number.
ulong extractEnvelope(uchar *buf) {
return buf[0] + ((buf[1] + ((buf[2] +((buf[3] & 0x9f) << 8)) << 8)) << 8);
}
// Handle a King's Page. In buf, there is an 8 byte message.
void rxKP(uchar *buf) {
ulong env; // Has to be long, even if we support only standard CAN.
uchar i, folderNo, enableF, cmd;
if (buf[0] == 0 || buf[0] == nodeNo) {
switch(buf[1]) {
case 0: // KP0: Selects Action and Communication mode.
if (buf[2] && buf[2] < 4)
actMode = (actModesT)buf[2];
if (buf[3] && buf[3] < 4)
commMode = (commModesT)buf[3];
switch(actMode) {
case ckReset:
#ifdef __WIN32__
// doReset() won't return, so we must show the status now.
mcThread->showCKStatus();
#endif
doReset();
break;
case ckFreeze:
doFreeze();
break;
case ckRunning:
doRun();
break;
}
canSetCommMode(commMode);
#ifdef __WIN32__
mcThread->showCKStatus();
#endif
break;
case 1: // KP1: Provides the Base numbers, asks for a Mayor's response.
env = extractEnvelope(buf+4);
if ((env & 0x1fffffff) == 0x1fffffff)
baseNo = envInvalid;
else if (env != 0)
baseNo = env;
fixMPEnv();
if (buf[2] != 0xff) {
mpPending = buf[2]; // txMP(buf[2]);
}
#ifdef __WIN32__
mcThread->showCKStatus();
mcThread->showFolders();
#endif
break;
case 2: // Assigns an Envelope to a Folder
env = extractEnvelope(buf+2);
folderNo = buf[6];
enableF = (uchar)(buf[7] & 1);
cmd = (uchar)(buf[7] >> 1); // We demand the reserved bits to be zero.
// Find the folder with envelope env. Should there be more than one
// folder with this envelope, all will not be found.
for (i = 0; i < FOLDER_COUNT; i++)
if (folder_env[i] == env)
break;
switch(cmd) {
case 0: // Keep current assignment, ignore folderNo, only regard enableF.
if (i < FOLDER_COUNT)
setFolderEnable(i, enableF);
break;
case 1: // Assign the envelope env to the folder folderNo.
// We do not allow more than one envelope per folder.
if (folderNo < FOLDER_COUNT) {
folder_env[folderNo] = env;
setFolderEnable(folderNo, enableF);
}
break;
case 3: // Transfer the envelope env to to the folder folderNo.
// The old assignment is cancelled.
if (i < FOLDER_COUNT) {
folder_env[i] = envInvalid;
setFolderEnable(i, 0);
}
if (folderNo < FOLDER_COUNT) {
folder_env[folderNo] = env;
setFolderEnable(folderNo, enableF);
}
break;
case 2: // Expel this envelope from any assignment. Folder No is ignored.
if (!enableF) { // AAE has to be 100.
if (i < FOLDER_COUNT) {
setFolderEnable(i, 0);
folder_env[i] = envInvalid;
}
}
break;
default:
break;
}
#ifdef __WIN32__
mcThread->showFolders();
#endif
break;
case 9:
nodeNo = buf[3];
fixMPEnv();
if (buf[2] != 0xff) {
mpPending = buf[2]; // txMP(buf[2]);
}
#ifdef __WIN32__
mcThread->showCKStatus();
mcThread->showFolders();
#endif
case 16:
// As the connection between folder and document is fixed, we do
// not use these fields. We just make it possible to enable/disable
// a folder without having to specify the envelope number.
folderNo = buf[2];
if (buf[4]) {
enableF = (uchar)(buf[4] & 0x40);
if (folderNo < FOLDER_COUNT)
setFolderEnable(folderNo, enableF);
#ifdef __WIN32__
mcThread->showFolders();
#endif
}
break;
default:
break;
}
}
}
void txMP(uchar pageNo) {
uchar buf[8];
buf[0] = 0;
buf[1] = pageNo;
if (commMode != ckSilent && pageNo < 2 &&
folder_env[doc_MayorsDocument] != envInvalid) {
switch(pageNo) {
case 0:
strcpy((char*)buf+2, "!EAN!"); // Clears buf[7] as well.
break;
case 1:
strcpy((char*)buf+2, "SerNo"); // Clears buf[7] as well
break;
}
if (canWrite(folder_env[doc_MayorsDocument], buf, 8, 0) != canOK)
; // canWriteFailures++;
}
}
// Read the input variables (buttons, analogue value) and transmit a message.
// Inputs DLC = 2 RTR always enabled
// line 0: Bit 0..1 Current LED status
// Bit 2..4 Buttons 0..2, current value
// Bit 5..7 Buttons 0..2, sticky (cleared at Tx).
// line 1: Analog value, 0..255
void txInputs(void) {
uchar buf[2];
if (actMode == ckRunning && commMode == ckCommunicate &&
folder_env[doc_Inputs] != envInvalid && checkFolderEnable(doc_Inputs)) {
buf[0] = (uchar)((LEDsave & 3) | (getButtons() << 2) | (buttonsSticky << 5));
buf[1] = (uchar)getAnalogue();
if (canWrite(folder_env[doc_Inputs], buf, 2, 0) == canOK)
buttonsSticky = 0;
else
; // canWriteFailures++;
}
}
// Parse a paramter setting doucument.
// Parameter settings DLC = 8
// Page 0
// line 0: 0 (page number)
// line 1: Period to transmit the Inputs document, 1..255, 0 no transmissions
// line 2..7: 0
//
void rxParam(uchar *buf) {
unsigned int pSave = txPeriod;
txPeriod = buf[1] + (buf[2] << 8);
if (pSave == 0 && txPeriod != 0) // Make sure a message is transmitted at once.
txLastTime = timerValue()-txPeriod;
#ifdef __WIN32__
mcThread->showModuleStatus();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -