motorcontroldemo_028/Vsrc/CANOpenUDfuncs.c
2019-07-29 08:18:57 +03:00

407 lines
13 KiB
C

/* ==================================================================================
Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
//File name: CANOpenUDfuncs.c
//Description: Â ôàéë âûíåñåíû ôóíêöèè äðàéâåðà CANOpen îïðåäåëÿåìûå ïîëüçîâàòåëåì (êîëáýê ôóíêöèè, ôóíêöèè èíèöèàëèçàöèè è ò.ï.)
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 2017_02_08
//=====================================================================================*/
#include "DSP.h"
#include "co_ODvars.h"
#include "CANOpen_drv.h"
#include "main.h"
//! Òàáëèöà ñ íàñòðîéêàìè ñêîðîñòåé CAN äëÿ ìèêðîêîíòðîëëåðîâ ôèðìû ÍÈÈÝÒ. Ðàñêîììåíòèòü íóæíîå.
// Âíîñèòü èçìåíåíèß â íèæåîïèñàííûå ïåðåìåííûå è ìàññèâû ÇÀÏÐÅÙÅÍÎ!!!
//! Ìèêðîêîíòðîëëåð Ê1921ÂÊ01Ò
/*
// kb/s: 125 50 125 250 500 1000
TCANSpeedTableOptions canSpeedTable = { {1, 1, 1, 0, 0, 0 }, \
{9, 24, 9, 39, 19, 9 }, \
{6, 6, 6, 6, 6, 6 }, \
{1, 1, 1, 1, 1, 1 }, \
{1, 1, 1, 1, 1 , 1 }, \
};
// ^- íàñòðîéêà íà 125, ò.ê. 10 kb/s íå ðåàëèçóåìî
*/
//! Ìèêðîêîíòðîëëåð Ê1921ÂÊ028
// kb/s: 125 50 125 250 500 1000
TCANSpeedTableOptions canSpeedTable = { {1, 1, 1, 1, 0, 0 }, \
{19, 49, 19, 9, 39, 19}, \
{6, 6, 6, 6, 6, 6 }, \
{1, 1, 1, 1, 1, 1 }, \
{1, 1, 1, 1, 1 , 1 }, \
};
// ^- íàñòðîéêà íà 125, ò.ê. 10 kb/s íå ðåàëèçóåìî
//! Ìèêðîêîíòðîëëåð Ê1921ÂÊ035
/*
// kb/s: 125 50 125 250 500 1000
TCANSpeedTableOptions canSpeedTable = { {1, 1, 1, 0, 0, 0 }, \
{9, 24, 9, 39, 19, 9 }, \
{6, 6, 6, 6, 6, 6 }, \
{1, 1, 1, 1, 1, 1 }, \
{1, 1, 1, 1, 1 , 1 }, \
};
// ^- íàñòðîéêà íà 125, ò.ê. 10 kb/s íå ðåàëèçóåìî
*/
//**********************************************************************************************************************************************************************************************************
//ôóíêöèÿ èíèöèàëèçàöèè Gpio CAN1
#ifdef CAN_1_ENABLE
void co_CAN1GpioInit()
{
#ifdef HW_MOTORCONTROLBOARD
// CAN0: C12 / C13
GPIOC->ALTFUNCNUM1_bit.PIN12 = 1; // CAN0_TX
GPIOC->ALTFUNCNUM1_bit.PIN13 = 1; // CAN0_RX
GPIOC->ALTFUNCSET = GPIO_PIN_12 | GPIO_PIN_13;
#endif
#ifdef HW_VECTORCARD_SIMULATOR
// CAN0: C12 / C13
GPIOC->ALTFUNCNUM1_bit.PIN12 = 1; // CAN0_TX
GPIOC->ALTFUNCNUM1_bit.PIN13 = 1; // CAN0_RX
GPIOC->ALTFUNCSET = GPIO_PIN_12 | GPIO_PIN_13;
#endif
}
#endif //CAN_1_ENABLE
//ôóíêöèÿ èíèöèàëèçàöèè Gpio CAN2
#ifdef CAN_2_ENABLE
void co_CAN2GpioInit()
{
#ifdef HW_MOTORCONTROLBOARD
// CAN1: C14 / C15
GPIOC->ALTFUNCNUM1_bit.PIN14 = 1; // CAN0_TX
GPIOC->ALTFUNCNUM1_bit.PIN15 = 1; // CAN0_RX
GPIOC->ALTFUNCSET = GPIO_PIN_14 | GPIO_PIN_15;
#endif
#ifdef HW_VECTORCARD_SIMULATOR
// CAN1: C14 / C15
GPIOC->ALTFUNCNUM1_bit.PIN14 = 1; // CAN0_TX
GPIOC->ALTFUNCNUM1_bit.PIN15 = 1; // CAN0_RX
GPIOC->ALTFUNCSET = GPIO_PIN_14 | GPIO_PIN_15;
#endif
}
#endif //CAN_2_ENABLE
//**********************************************************************************************************************************************************************************************************
//Ôóíêöèè ðàáîòû ñ ýíåðãîíåçàâèñèìîé ïàìÿòüþ (â êà÷åñòâå ïàìÿòè ìîæåò èñïîëüçîâàòüñÿ êàê ïîëüçîâàòåëüñêàÿ ôëýø íà áîðòó MCU,
// òàê è âíåøíå ïîäêëþ÷àåìàÿ, íàïðèìåð ÷åðåç SPI, eeprom).
//Ôóíêöèè èñïîëüçóþòñÿ äðàéâåðîì CANopen ïðè ñîõðàíåíèè è âîññòàíîâëåíèè ïàðàìåòðîâ ñëîâàðÿ îáúåêòîâ
//Ñ òî÷êè çðåíèÿ äðàéâåðà CANOpen ôóíêöèè ðåàëèçóþò ïîáàéòîâîå ÷òåíèå è çàïèñü èç/â ÝíÎÇÓ
void co_UserMemoryRead (const T_UserMemoryContext *p)
{
UserMem.MemStartAddr = p->MemStartAddr;
UserMem.MCUStartAddr = p->MCUStartAddr;
UserMem.data_length = p->data_length;
UserMem.read(&UserMem);
}
void co_UserMemoryWrite (const T_UserMemoryContext *p)
{
UserMem.MemStartAddr = p->MemStartAddr;
UserMem.MCUStartAddr = p->MCUStartAddr;
UserMem.data_length = p->data_length;
UserMem.write(&UserMem);
}
//**********************************************************************************************************************************************************************************************************
//ôóíêöèÿ, êîòîðàÿ âûçûâàåòñÿ äðàéâåðîì CANOpen ïðè íåîáõîäèìîñòè îòïðàâêè CAN ñîîáùåíèÿ âî âíåøíèé èíòåðôåéñ
//âíóòðü ôóíêöèè ïîëüçîâàòåëåì äîëæåí áûòü âñòàâëåí âûçîâ ñîîòâåòñòâóþùåé ôóíêöèè, îñóùåñòâëÿþùåé ïåðåäà÷ó CAN ïàêåòà
void co_CANToExtInterface_Send(TZCanMsg* MSG, Uint16 tag_CANnum)
{
CANtoRS.write(MSG,&CANtoRS);
}
//êîëáýêè ïî ïðèåìó PDO
void co_RPDO1_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
case 2:
{
PDO_cntr2++;
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO2_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO3_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO4_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO5_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO6_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO7_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
void co_RPDO8_Callback(Uint16 nodeID, Uint16 tag_CANnum)
{
/*
switch(nodeID)
{
case 1:
{
//îáðàáàòûâàåì êàê-íèáóäü...
break;
}
default:
break;
}
*/
}
//!Îáðàùåíèå ïî CANopen ê ÷àñàì ðåàëüíîãî âðåìåíè.
//!Åñëè ïðîèñõîäèò çàïèñü â ïàðàìåòð [5139h.01h] Òåêóù. çíà÷.×àñû ðåàëüíîãî âðåìåíè,
//òî âûçûâàåòñÿ callback_RTC - òàì óñòàíàâëèâàåòñÿ çàïðîñ íà êîððåêöèþ ÷àñîâ.
void callback_RTC(Uint16 par, Uint16 tag_CANnum) {
if (par == 1) {
RTCclock.setTimeFlag = 1; //ïðîèçîøëà çàïèñü â ÷àñû
}
}
//!Îáðàùåíèå ê ïåðåìåííîé dlog.next_value_var ñ äàííûìè öèôðîâîãî îñöèëëîãðàôà.
//!Ñóùåñòâóåò ñïåöèàëüíûé èíòåðôåéñ, ïîçâîëÿþùèé àâòîìàòèçèðîâàòü ñ÷èòûâàíèå îññöèëëîãðàôèðóåìûõ ïåðåìåííûõ
//!ìîäóëÿ TDataLog. Ýòà ôóíêöèÿ âûçûâàåòñÿ ïðè îáðàùåíèè ê ïåðåìåííîé, ÷åðåç êîòîðóþ âîçìîæíî ñ÷èòàòü çàïèñàííûå
//!îñöèëëîãðàììû. Çàïèñü â ýòó ïåðåìåííóþ óñòàíàâëèâàåò òðåáóåìûé íîìåð áóôåðà (îäèí è 4õ) è íîìåð èçâëåêàåìîé òî÷êè.
//!Ïðè ÷òåíèè æå â ýòó ïåðåìåííóþ âûäâèãàòþòñÿ ñàìè îòîñöèëëîãðàôôèðîâàííûå äàííûå.
void callback_dlog(Uint16 par, Uint16 tag_CANnum) {
//åñëè çàïèñü, òî óñòàíîâèì áóôåð íà íóæíóþ òî÷êó
if (par == 1) {
//â ïåðåìåííóþ next_value_var çàïèñûâàåòñß æåëàåìîå ñìåùåíèå, íîìåð áóôåðà, èç êîòîðîãî õîòèì ÷èòàòü,
//à òàê æå ðàçðåæèâàíèå
dlog.buff_num = (long)((dlog.next_value_var >> 24) & 3); //èçâëåêàåòñß íîìåð áóôåðà
#if DLOG_DATA_SIZE == 32
dlog.highPartOfValue = (int)((dlog.next_value_var >> 26) & 1); // îòäàâàòü ñòàðøóþ ÷àñòü 32-áèòíîãî çíà÷åíèÿ?
#endif
dlog.Rcounter = (dlog.next_value_var >> 16) & 0xFF; //êàêóþ òî÷êó íàäî îòäàâàòü
//ïðîâåðßåì õîòßò ëè èñïîëüçîâàòü áëî÷íóþ ïåðåäà÷ó
if ((dlog.next_value_var & 0xffff) == 1) {
//õîòßò, ãîâîðèì îá ýòîì èíòåðôåéñó áëî÷íîé ïåðåäà÷è
#ifdef CAN_1_ENABLE
if (co1_vars.co_blockTransferCommand == CANBT_INTERFACE_FREE)
co1_vars.co_blockTransferCommand = CANBT_INTERFACE_DATALOG1;
#endif
#ifdef CAN_2_ENABLE
if (co2_vars.co_blockTransferCommand == CANBT_INTERFACE_FREE)
co2_vars.co_blockTransferCommand = CANBT_INTERFACE_DATALOG1;
#endif
}
#if DLOG_DATA_SIZE == 32
if ((dlog.next_value_var & 0xffff) == 2) {
#ifdef CAN_1_ENABLE
if (co1_vars.co_blockTransferCommand == CANBT_INTERFACE_FREE)
co1_vars.co_blockTransferCommand = CANBT_INTERFACE_DATALOG2;
#endif
#ifdef CAN_2_ENABLE
if (co2_vars.co_blockTransferCommand == CANBT_INTERFACE_FREE)
co2_vars.co_blockTransferCommand = CANBT_INTERFACE_DATALOG2;
#endif
}
#endif // DLOG_DATA_SIZE == 32
}
//âûäâèãàåì äàííûå:
#if DLOG_DATA_SIZE == 16
switch (dlog.buff_num) { //òåêóùèé íîìåð áóôåðà
case 0: {
dlog.next_value_var = dlog.dl_buffer1_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
break;
}
case 1: {
dlog.next_value_var = dlog.dl_buffer2_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
break;
}
case 2: {
dlog.next_value_var = dlog.dl_buffer3_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
break;
}
case 3: {
dlog.next_value_var = dlog.dl_buffer4_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
break;
}
default: { //åñëè â buff_num ÷òî-òî íå òî, ïî-äåôîëòó ïóñòü ïåðâûé áóôåð
dlog.next_value_var = dlog.dl_buffer1_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
break;
}
}
//äàííûå òîëüêî â íèæíåé ÷àñòè
dlog.next_value_var &= 0xFFFF;
dlog.next_value_var |= (((unsigned long) dlog.Rcounter) << 16); //â âåðõíåé ÷àñòè ñëîâà Rcounter äëß êîíòðîëß
dlog.next_value_var |= (((unsigned long) dlog.buff_num) << 24); //â âåðõíåé ÷àñòè ñëîâà (åùå âûøå) buff_num äëß êîíòðîëß
dlog.Rcounter++; //êàêóþ òî÷êó îòäàåì. èíêðåìåíòèðóåòñß ñàìî ïîñëå ÷òåíèß òåêóùåé òî÷êè.
dlog.Rcounter &= 0xFF; //ïî êðóãó. íè÷åãî ñòðàøíîãî, ïåðåä ÷òåíèåì îáíóëßþ. ñì. çàïèñü
#endif
#if DLOG_DATA_SIZE == 32
int32 val32;
int varSizeIs16;
switch (dlog.buff_num) { //òåêóùèé íîìåð áóôåðà
default:
case 0: {
val32 = dlog.dl_buffer1_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
varSizeIs16 = (int)(dlog.object1Info.varSize == 16);
break;
}
case 1: {
val32 = dlog.dl_buffer2_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
varSizeIs16 = (int)(dlog.object2Info.varSize == 16);
break;
}
case 2: {
val32 = dlog.dl_buffer3_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
varSizeIs16 = (int)(dlog.object3Info.varSize == 16);
break;
}
case 3: {
val32 = dlog.dl_buffer4_adr[(dlog.Rcounter + dlog.first_point_written) & 0xFF];
varSizeIs16 = (int)(dlog.object4Info.varSize == 16);
break;
}
}
dlog.next_value_var = (dlog.highPartOfValue != 0 ? val32 >> 16 : val32) & 0x0000FFFF;
dlog.next_value_var |= ((Uint32)dlog.Rcounter) << 16;
dlog.next_value_var |= ((Uint32)dlog.buff_num) << 24;
dlog.next_value_var |= ((Uint32)dlog.highPartOfValue) << 26;
dlog.next_value_var |= ((Uint32)varSizeIs16) << 27;
if ((dlog.highPartOfValue != 0) || varSizeIs16)
{
// Ïðè ñëåäóþùåì çàïðîñå îòäàäèì ìëàäøóþ ÷àñòü ñëåäóþùåé òî÷êè.
dlog.Rcounter++;
dlog.Rcounter &= 0xFF;
dlog.highPartOfValue = 0;
}
else
{
// Ïðè ñëåäóþùåì çàïðîñå îòäàäèì ñòàðøóþ ÷àñòü ýòîé æå òî÷êè.
dlog.highPartOfValue = 1;
}
#endif
}