PP2CAN Visual Studio API
(CZ verze 0.1 )
Celé API je zastřešeno třídou PP_MCP2510 název je odvozen od parallel port - MCP2510. Tato třída pak obsahuje metody pro komunikaci se zařízením PP2CAN. Rozhraní je schodné pro všechny varianty, tzn. high speed, low speed i single wire. K vytvoření objektu PP2CAN slouží konstruktor:
PP_MCP2510(WORD address, CAN_SPEED speed, void (*error_function)(int err_code, const char * error_string), void (*msg_receiver)(MCP2510Msg *msg),int HW_Version, bool OneShotMode /*= false*/, bool PassiveMode /*= false*/ );
parametry:
address | adresa paralelního portu, v praxi se používají hodnoty: 0x378, 0x278, 0x3BC | |
speed | nastavení komunikační rychlosti pro CAN, enum CAN_SPEED definován v pp2can.h, má tento tvar | |
enum CAN_SPEED {
SPEED_20k, |
||
*error_function | ukazatel na funkci pro zpracování chybových hlášení, možno použít NULL, není však doporučeno | |
*msg_receiver | ukazatel na funkci pro zpracování přijatých zpráv, možno použít NULL, avšak doporučuje se vytvořit pro zpracování samostatné vlákno a provést vyčítání pomocí metod GET_LENGTH a GET. | |
HW_Version | typ použitého HW,
v pp2can.h jsou uvedeny tyto definice:
#define HW_HIGH_SPEED_0
0 |
|
OneShotMode | Je-li true, není při selhání odeslání zprávy prováděn pokus u znovuodeslání | |
PassiveMode | Zařízení pouze přijímá zprávy, odeslání není možno | |
Po vytvoření objektu je zařízení nainicializováno, je provedeno nastavení komunikační rychlosti a filtry zpráv jsou nastaveny na příjem všech standardních i rozšířených zpráv. Zařízení přijímá zprávy. Doporučuje se nepoužívat volání funkce msg_receiver a provádět vyčtení zpráv prostřednictvím volání funkcí GET_LENGTH (zjištění počtu zpráv v přijímacím bufferu) a GET(vyčte zprávu z přijímacím bufferu).
PP_MCP2510 * port = NULL;
..
..
// vytvoreni portu
port = new PP_MCP2510(0x378, SPEED_100k, WriteErrorText, NULL, HW_HIGH_SPEED_1 ,
false, false);
// povoluji cteni TEC a REC
port->READ_RX_ERROR(true);
port->READ_TX_ERROR(true);
..
..
// zruseni portu
delete port;
Máme aplikaci v MFC a ta obsahuje prvek CListBox o výšce 5 řádků. Dále bude-li pm_list globální ukazatel na tento prvek, můžeme chybová a další hlášení zapisovat takto:
static void MyDialog::WriteErrorText(int
error_code,const char *text)
{
if(pm_list==NULL) return;
pm_list->AddString((LPCTSTR)text);
int index = pm_list->GetCount();
if(index>5) pm_list->SetTopIndex(index-5);
};
Jsou definovány tyto chybové kódy:
Error Code | Text |
0 | ERROR: Device PP2CAN not connect |
1 | WARNING: MCP2510 - Receive Buffer 1 Overflow Flag |
2 | WARNING: MCP2510 - Receive Buffer 0 Overflow Flag |
3 | WARNING: MCP2510 - Bus-Off Error Flag |
4 | WARNING: MCP2510 - Transmit Error-Passive Flag |
5 | WARNING: MCP2510 - Receive Error-Passive Flag |
6 | WARNING: MCP2510 - Transmit Error Warning Flag |
7 | WARNING: MCP2510 - Receive Error Warning Flag |
8 | WARNING: MCP2510 - RESET |
9 | ERROR: MCP2510 - Mode |
Je-li třeba provést změnu komunikační rychlosti nebo filtrů zpráv, je třeba uvést zařízení do konfiguračního režimu voláním metody:
void PP_MCP2510::SET_CONFIG_MODE(void);
Po provedení změn je pak třeba provést nastavení pracovního režimu voláním:
void PP_MCP2510::SET_NORMAL_MODE(void);
Tyto metody je pak třeba uzavřít mezi voláním:
void PP_MCP2510::EnterCriticalSectionSPI(void);
a
void PP_MCP2510::LeaveCriticalSectionSPI(void);
tzn. například:
port->EnterCriticalSectionSPI();
port->SET_CONFIG_MODE();
port->LeaveCriticalSectionSPI();
port->SET_SPEED(SPEED_100k);
port->EnterCriticalSectionSPI();
port->SET_NORMAL_MODE();
port->LeaveCriticalSectionSPI();
Pro změnu komunikační rychlosti slouží tyto metody:
void PP_MCP2510::SET_SPEED(CAN_SPEED speed);
void PP_MCP2510::SET_SPEED(unsigned char tBRP, unsigned char tSJW, unsigned char
tPRSEG, unsigned char tPHSEG1, unsigned char tPHSEG2, bool tSAM);
void PP_MCP2510::SET_SPEED(unsigned char tCNF1, unsigned char tCNF2, unsigned
char tCNF3);
void PP_MCP2510::SET_SPEED_PARAM(unsigned char tBRP, unsigned char tSJW,
unsigned char tPRSEG, unsigned char tPHSEG1, unsigned char tPHSEG2, bool tSAM);
void PP_MCP2510::RESTART(CAN_SPEED speed, bool
suspend_comunication)
První metoda má jako parametr enum CAN_SPEED, v případě že je použita hodnota SPEED_USR je nutno provést nejprve volání funkce SET_SPEED_PARAM. Druhá a funkce provede je vlastně sloučení volání SET_SPEED_PARAM a první funkce s parametrem SPEED_USR. Třetí je pak obdobou druhé, parametry jsou však uvedeny v jiném formátu, podrobnosti lze najít v dokumentaci k MCP2510/2515.
Upřednostňujte však metodu RESTART. Parametr suspend_comunication na true:
port->RESTART(SPEED_250k, true);
nebo
port->RESTART(SPEED_250k);
nebo
port->SET_SPEED_PARAM(BRP, SJW,
PRSEG, PHSEG1, PHSEG2, SAM);
port->RESTART(SPEED_USR);
U varianty PP2CAN SiWi (Single Wire) je možno používat i metody:
bool PP_MCP2510::SiWi_ENABLE_PIN(bool state);
bool PP_MCP2510::SiWi_GET_ENABLE_PIN(bool &state);
Tyto metody jsou určeny k ovládání/čtení stavu signálu ENABLE pro nastavení normal/high speed módu. U variant zařízení high a low speed nemají tyto metody žádnou odezvu.
K odeslání zprávy je určena metoda:
int PP_MCP2510::SEND(MCP2510Msg &data);
Funkce zároveň vrací aktuální velikost bufferu zpráv pro odeslání. Jako parametr má funkce referenci na strukturu MCP2510Msg. Tato struktura je obrazem bufferu řadiče MCP2510/2515, je definována v pp2can.h a má tento tvar:
typedef union { |
Metoda void PP_MCP2510::SEND_LENGTH(void) vrací délku fronty zpráv čekajících na odeslání.
Pro usnadnění vyplnění dat v této struktuře a zároveň pro zpětné dekódování dat z této struktury při příjmu jsou určeny tyto metody:
bool PP_MCP2510::MSG_get_ID(unsigned char *data,
unsigned __int16 &Id1, unsigned __int32 &Id2);
bool PP_MCP2510::MSG_get_ID(unsigned char *data, unsigned __int16 *Id1, unsigned
__int32 *Id2);
void PP_MCP2510::MSG_set_ID(unsigned char *data, unsigned __int16 Id1, unsigned
__int32 Id2);
void PP_MCP2510::MSG_set_ID(unsigned char *data, unsigned __int16 Id1);
bool PP_MCP2510::MSG_set_DLC(unsigned char *data, bool RTR, unsigned char length);
void PP_MCP2510::MSG_get_DLC(unsigned char *data, bool &RTR, unsigned char &length);
MSG_get_ID je určena k získání identifikátoru ve formátu standardní a rozšířené části. Pokud funkce vrací true, jedná se o zprávu s rozšířeným identifikátorem, v opačném případě pak jde o funkci se standardním identifikátorem. Varianta MSG_set_ID s parametry Id1 a Id2 nastavuje hodnotu rozšířeného (29-bitového) identifkátoru, varianta pouze s Id1 pak standardní (11-bitový) identifikátor. Délku zprávy a příznak rtr čteme/nastavujeme pomocí metod MSG_get_DLC/MSG_set_DLC.
Fragment kódu s odesláním zprávy se standardním identifikátorem 1537, délkou dat (DLC) 4, data nastavena na hodnoty 1,2,3 a 4:
MCP2510Msg msg;
// nastaveni standardniho
11-bitoveho identifikatoru
port->MSG_set_ID(&msg.bytes[0], 1537);
// nastaveni rtr na false,
delka zpravy 4
port->MSG_set_DLC(&msg.bytes[0], false, 4);
// vyplneni dat
msg.item.data[0] = 1;
msg.item.data[1] = 2;
msg.item.data[2] = 3;
msg.item.data[3] = 4;
// odeslani
(ulozeni do bufferu k odeslani)
port->SEND(msg);
Odeslání
zprávy žádosti o data (RTR),
rozšířený 29-bitový identifikátor (St: 1427, Ext: 145548):
MCP2510Msg msg;
// nastaveni rozsireneho 29-bitoveho
identifikatoru
port->MSG_set_ID(&msg.bytes[0], 1427,145548);
// nastaveni rtr na true,
delka zpravy 0
port->MSG_set_DLC(&msg.bytes[0], true, 0);
// odeslani
(ulozeni do bufferu k odeslani)
port->SEND(msg);
Odeslání
zprávy se standardním
11-bitovým identifikátorem 513, v datové části uložena hodnota 123567 typu
signed __int32 od DB1, v DB0 hodnota 120:
signed __int value = 123567;
signed __int *p;
MCP2510Msg msg;
// nastaveni standardního
11-bitoveho identifikatoru
port->MSG_set_ID(&msg.bytes[0], 513);
// nastaveni rtr na false,
delka zpravy 5 (DB0 + sizeof(signed __int32)=4)
port->MSG_set_DLC(&msg.bytes[0], false, 5);
// nastavim DB0 na 120
msg.item.data[0] = 120;
// vlozim hodnotu typu signed __int32
p=(signed __int *)&msg.item.data[1];
*p = value;
// odeslani
(ulozeni do bufferu k odeslani)
port->SEND(msg);
Následující fragmet kódu demonstruje postup při čtení přijaté zprávy, obsah zprávy pak vypisuje na standardní výstup:
MCP2510Msg *data =NULL;
unsigned __int16 Id1;
unsigned __int32 Id2;
bool rtr;
unsigned char length;
..
..
// je-li v bufferu nejaka zprava
while(port->GET_LENGTH()>0)
{
// a byla-li vyctena, provedu dekodovani
if(port->GET(&data))
{
// rozsireny identifikator
if(port->MSG_get_ID(&data->bytes[0],Id1,Id2))
cout << "Ext
" << (unsigned int)Id1 << '\t' << (unsigned int)Id2 << endl;
// standardni identifikator
else
cout << "St " << (unsigned int)Id1 << '\t' << "0" << endl;
// zjistim delku zpravy a priznak rtr (remote transfer request)
port->MSG_get_DLC(&data->bytes[0],rtr,length);
// datova zprava
if(!rtr)
{
cout << (unsigned
int)length << endl;
// vypisu data
for(int
i=0;i<8;i++)
{
cout << (unsigned int)data->item.data[i] << '\t';
}
cout << endl;
}
// rtr - zadost o data
else
{
cout << "rtr-"
<< (unsigned int)length << endl;
}
// musim smazat - volani funkce API, ne delete !!!
port->DELETE_MSG(data);
}
}
..
..
Ke čtení TEC (Transmit Error Counter) a REC (Receive Error Counter) jsou určeny metody:
unsigned char PP_MCP2510::READ_TX_ERROR(void);
void PP_MCP2510::READ_TX_ERROR(bool enable);
unsigned char PP_MCP2510::READ_RX_ERROR(void);
void PP_MCP2510::READ_RX_ERROR(bool enable);
Metody READ_TX_ERROR(bool enable) a void READ_RX_ERROR(bool enable) povolují nebo zakazují čtení registrů TEC a REC. V případě, že je povoleno jejich čtení, je možno získat jejich hodnotu voláním unsigned char READ_TX_ERROR(void) nebo unsigned char READ_RX_ERROR(void).
Dále je možno zjistit počet restartů CAN řadiče v důsledku nastavení příznaku Bus-off apod. voláním metody:
unsigned int PP_MCP2510::GET_RST(void);
V následujícím textu budou uvedeny metody, které je možno použít pouze mezi voláním EnterCriticalSectionSPI a LeaveCriticalSectionSPI. Jejich použití je však možné pouze v ojedinělých případech a jejich volání se v praxi nepoužívá ani nedoporučuje. Nicméně jsou uživateli přístupné a popis je uveden pouze pro úplnost.
unsigned char PP_MCP2510::STATUS(void);
void PP_MCP2510::SEND_MESSAGE(unsigned char TX_buffer,
unsigned char *data);
void PP_MCP2510::GET_MESSAGE(unsigned char RX_buffer, unsigned char *data);
unsigned char PP_MCP2510::GET_TX_ERROR(void);
unsigned char PP_MCP2510::GET_RX_ERROR(void);
STATUS - vyčtení stavu řadiče (ve kterých bufferech je přijata zpráva a které jsou prázdné a je je možno použít k odeslání zprávy), popis v dokumentaci k MCP2510/2515.
SEND_MESSAGE - vloží zprávu k odeslání do řadiče MCP2510/2515 mimo vlákno pro komunikaci s HW PP2CAN. Parametr TX_buffer může mít hodnoty 0, 1 nebo 2. Použití společně s metodou STATUS.
GET_MESAGE - vyčtení přijaté zprávy, Parametr RX_buffer může mít hodnoty 0 nebo 1. Použití společně s metodou STATUS.
GET_TX_ERROR - vyčtení TEC
GET_RX_ERROR - vyčtení REC