Subversion Repositories NaviCtrl

Compare Revisions

Ignore whitespace Rev 832 → Rev 833

/trunk/MobileMenu.c
0,0 → 1,259
/*#######################################################################################*/
/* !!! THIS IS NOT FREE SOFTWARE !!! */
/*#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 2008 Ingo Busker, Holger Buss
// + Nur für den privaten Gebrauch / NON-COMMERCIAL USE ONLY
// + FOR NON COMMERCIAL USE ONLY
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + eindeutig als Ursprung verlinkt werden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung oder Nutzung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permitted
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * porting the sources to other systems or using the software on other systems (except hardware from www.mikrokopter.de) is not allowed
//
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <stdlib.h>
#include "91x_lib.h"
#include "main.h"
#include "led.h"
#include "ubx.h"
#include "GPS.h"
#include "timer1.h"
#include "compass.h"
#include "spi_slave.h"
#include "MobileMenu.h"
#include "uart0.h"
#include "uart1.h"
#include "ncmag.h"
#include "logging.h"
#include "settings.h"
#include "sdc.h"
#include "analog.h"
#include "canbus.h"
#include "triggerlog.h"
#include "CamCtrl.h"
#include "eeprom.h"
 
u8 MobileDispPtr = 0;
 
MobileDataRequest_t MobileDataRequest;
MobileDataInfo_t MobileDataInfo;
Mobile_t Mobile;
 
#define ML_SEND 0x0001 // show sendbutton
#define ML_SLIDER 0x0002
#define ML_WHEEL 0x0004
#define ML_EDIT 0x0008
 
 
MobileLabel_t MobileLabel[MOBILE_MAX_MENU] =
{
//{ 123456789012345678901 Min Max Default Decimals 1234567890123456
{ "Status " , 0, 1000, 200, 0, " ", {"SAT ","CAMERA","MAGNET"," "," "},0,0}, // 0
{ "Second Menu " , -100, 100, 50, 1, "Slider + Send ", {"-10 ","+10 ","-1 ","+1 ","Store "},2,ML_SEND | ML_SLIDER}, // 1
{ "Third Menu " , 10, 40, 20, 2, "Wheel ", {" "," "," "," ","Take "},1,ML_WHEEL}, // 2
{ "All Characters " , 0, 256, 20, 3, "Edit + Send ", {" "," "," "," "," "},3,ML_EDIT |ML_SEND} // 3
};
 
 
 
void Mobile_Putchar(char c)
{
if(MobileDispPtr < M_DISPLAYBUFFSIZE) Mobile.DisplayBuff[MobileDispPtr++] = c;
}
 
 
void Mobile_Putchar_INV(char c)
{
if(MobileDispPtr < M_DISPLAYBUFFSIZE) Mobile.DisplayBuff[MobileDispPtr++] = c | 0x80;
}
 
void Mobile_Putchar_BLINK(char c)
{
if(MenuBlinkBit) Mobile_Putchar_INV(c); else Mobile_Putchar(c);
}
 
void Mobile_Clear(void)
{
u8 i;
for( i = 0; i < M_DISPLAYBUFFSIZE; i++) Mobile.DisplayBuff[i] = ' ';
}
 
// Display with 20 characters in 4 lines
void MobileMenuUpdate(u8 item, u8 Keys, s16 Value)
{
static u32 tmp,tmp2,tmp3;
s32 i1,i2;
u8 sign;
Mobile_Clear();
switch(item)
{
// Version Info
case 0:
{
static u8 show = 0;
// Mobile_printfxy(0,0,"++ Mobile Menu ++");
 
// Mobile_printfxy_BLINK(10,3,"BLINK");
 
// Mobile_printfxy(0,1,"HW V%d.%d SW V%d.%02d%c", UART_VersionInfo.HWMajor/10, UART_VersionInfo.HWMajor%10, VERSION_MAJOR, VERSION_MINOR, 'a'+ VERSION_PATCH);
// if(FC.StatusFlags3 & FC_STATUS3_REDUNDANCE_AKTIVE) Mobile_printfxy(19,1,"R");
/*
NaviData.Current
s16 Altimeter_5cm; // hight according to air pressure
s16 Variometer; // climb(+) and sink(-) rate
u16 FlyingTime; // in seconds
u16 GroundSpeed; // speed over ground in cm/s (2D)
s16 Heading; // current flight direction in ° as angle to north
s8 AngleNick; // current Nick angle in 1°
s8 AngleRoll; // current Rick angle in 1°
u8 FCStatusFlags; // Flags from FC see main.c FC_STATUS_xxx
u8 NCFlags; // Flags from NC see main.h NC_FLAG_xxx
u8 Errorcode; // 0 --> okay
u8 WP_OperatingRadius; // current WP operation radius around the Home Position in m
s16 TopSpeed; // velocity in vertical direction in cm/s
u8 TargetHoldTime; // time in s to stay at the given target, counts down to 0 if target has been reached
u8 FCStatusFlags2; // StatusFlags2 (since version 5 added)
s16 SetpointAltitude; // setpoint for altitude
u8 Gas; // current gas (thrust)
 
NaviData.GroundSpeed
NaviData.
NaviData.
NaviData.
 
NaviData.
NaviData.SatsInUse
 
 
*/
if(FC.StatusFlags & FC_STATUS_LOWBAT)
{
Mobile_printfxy_BLINK(0,0," %2i.%1iV ",FC.BAT_Voltage/10, FC.BAT_Voltage%10)
Mobile_printfxy_BLINK(0,1," %2i:%02i ",NaviData.FlyingTime/60,NaviData.FlyingTime%60)
Mobile_printfxy_BLINK(0,2," %5i ",NaviData.UsedCapacity)
}
else
{
Mobile_printfxy(0,0," %2i.%1iV ",FC.BAT_Voltage/10, FC.BAT_Voltage%10)
Mobile_printfxy(0,1," %2i:%02i ",NaviData.FlyingTime/60,NaviData.FlyingTime%60);
Mobile_printfxy(0,2," %5i ",NaviData.UsedCapacity);
}
if(Parameter.GlobalConfig & FC_CFG_HOEHENREGELUNG)
{
if(FC.StatusFlags2 & FC_STATUS2_ALTITUDE_CONTROL) Mobile_printfxy_INV(10,0,"ALT:%4im %c", (int16_t)(NaviData.Altimeter_5cm/20),FromFC_VarioCharacter)
else Mobile_printfxy(10,0,"ALT:%4im ", (int16_t)(NaviData.Altimeter_5cm/20))
}
else Mobile_printfxy(10,0,"ALT:---- ");
 
Mobile_printfxy(10,1,"DIR: %3d%c",NaviData.CompassHeading,'`');
if(FC.StatusFlags2 & FC_STATUS2_CAREFREE) Mobile_printfxy_INV(20,1,"C") else Mobile_printfxy(20,1," ");
 
Mobile_printfxy(12,2,"I:%2i.%1iA ",NaviData.Current/10, NaviData.Current%10);
 
Mobile_printfxy(8,0,":");
Mobile_printfxy(8,1,":");
Mobile_printfxy(8,2,":");
 
if(Keys & KEY1) show = 0;
if(Keys & KEY2) show = 1;
if(Keys & KEY3) show = 2;
switch(show)
{
case 0:
Mobile_printfxy(0,3,"S:%2d %2im/s HM:%3dm %c",NaviData.SatsInUse,NaviData.GroundSpeed/100,NaviData.HomePositionDeviation.Distance_dm/10,NC_GPS_ModeCharacter);
break;
case 1:
if(TrigLogging.CountExternal) Mobile_printfxy(0,3,"HotShoe:%4u ",TrigLogging.CountExternal-1)
else Mobile_printfxy(0,3,"No HotShoe");
break;
case 2:
Mobile_printfxy(0,3,"MAG:%3u%% incl:%2d`(%2i)",EarthMagneticField,EarthMagneticInclination,EarthMagneticInclinationTheoretic);
break;
}
 
Mobile_printfxy_BLINK(0,4,"%s",NaviData_HoTT_Text.HoTT_DisplayText);
}
break;
case 1:
Mobile_printfxy(0,0,"Testpage %i ",item);
Mobile_printfxy(0,1," KEY: 0x%02x ",Keys);
Mobile_printfxy(0,2," Load: %5i ",tmp2);
Mobile_printfxy(0,3," Temp: %5i ",tmp);
 
if(Keys & KEY5) tmp2 = tmp;
if(Keys & KEY4) tmp++;
if(Keys & KEY3) tmp--;
if(Keys & KEY2) tmp += 10;
if(Keys & KEY1) tmp -= 10;
if(Keys & COPY) tmp2 = Value;
Mobile.ReturnValue = tmp2;
break;
case 2:
Mobile_printfxy(0,0,"Testpage %i ",item);
Mobile_printfxy(0,1,"CNT: %5u ",tmp3++);
Mobile_printfxy(0,2,"KEY: %02x ",Keys);
Mobile_printfxy(0,4,"VALUE: %5i ",Value);
if(Keys & COPY) tmp3 = Value;
Mobile.ReturnValue = tmp3;
break;
case 3:
{
static u16 offset = 20, tmp;
// Mobile_printfxy(0,0,"Testpage %i %c",item,33);
for(sign = 0; sign < 21*5; sign++) Mobile.DisplayBuff[sign] = sign + ' ';
 
// if(Keys & COPY) offset = Value;
}
break;
 
default:
Mobile_printfxy(0,0,"Not used ");
//MaxMenuItem = MenuItem - 1;
break;
}
Mobile.Index = item; // this menu item was processed
 
}
/trunk/MobileMenu.h
0,0 → 1,84
#ifndef _M_MENU_H
#define _M_MENU_H
 
#include "printf_P.h"
#define MOBILE_COMPATIBLITY 1
 
#define MOBILE_LABLE 0 // Name of the Menu
#define MOBILE_MENU 1
#define MOBILE_INFO 2
 
#define M_DISPLAYBUFFSIZE (5*21)
 
#define MOBILE_MAX_MENU 4
 
#define KEY1 0x01
#define KEY2 0x02
#define KEY3 0x04
#define KEY4 0x08
#define KEY5 0x10
#define COPY 0x80
 
extern u8 MobileDispPtr;
void Mobile_Putchar(char c);
void Mobile_Putchar_BLINK(char c);
void Mobile_Putchar_INV(char c);
void Mobile_Clear(void);
void MobileMenuUpdate(u8 item, u8 Keys, s16 Value);
 
#define Mobile_printfxy(x,y,format, args...) { MobileDispPtr = (y) * 21 + (x); _printf_P(&Mobile_Putchar, format , ## args);}
#define Mobile_printf(format, args...) { _printf_P(&Mobile_Putchar, format , ## args);}
#define Mobile_printfxy_INV(x,y,format, args...) { MobileDispPtr = (y) * 21 + (x); _printf_P(&Mobile_Putchar_INV, format , ## args);}
#define Mobile_printfxy_BLINK(x,y,format, args...) { MobileDispPtr = (y) * 21 + (x); _printf_P(&Mobile_Putchar_BLINK, format , ## args);}
 
// MobileLabel.LayoutOptions
#define ML_SEND 0x0001 // show sendbutton
#define ML_SLIDER 0x0002
#define ML_WHEEL 0x0004
#define ML_EDIT 0x0008
 
 
typedef struct // MOBILE_LABLE - answer from NC to PC
{
char MenuLabel[21];
s16 Min;
s16 Max;
s16 Default;
unsigned char Decimals;
char ValueLabel[16];
char ButtonLabel[5][6]; // "\0" ==> nicht anzeigen 5 Button mit 6 Zeichen
unsigned char Layout;
u16 LayoutOptions; // Bitcodiert
} __attribute__((packed)) MobileLabel_t;
 
typedef struct // MOBILE_MENU - from PC to NC
{
unsigned char MenuItem; // PC wants this Menu
u16 Value; // the s16 Value for use in Menu
unsigned char Event; // bit coded [0x01 .. 0x10] - Buttons, [0x80] = Write Value
} __attribute__((packed)) MobileDataRequest_t;
 
 
typedef struct// MOBILE_INFO - answer from NC to PC
{
unsigned char Count;
u16 CheckSumLable;
unsigned char Compatibel;
} __attribute__((packed)) MobileDataInfo_t;
 
 
typedef struct // MOBILE_MENU - answer from NC to PC
{
u8 Index;
char DisplayBuff[M_DISPLAYBUFFSIZE];
s16 ReturnValue;
} __attribute__((packed)) Mobile_t ;
 
 
extern MobileDataRequest_t MobileDataRequest;
extern MobileDataInfo_t MobileDataInfo;
extern Mobile_t Mobile;
extern MobileLabel_t MobileLabel[MOBILE_MAX_MENU];
 
#endif // M_MENU_H
 
/trunk/main.c
123,6 → 123,7
u32 ShowNoFlyzoneErrorMessage = 0;
u8 ShowCalibrationErrorMessage = 0;
u8 TryAgain_UBX_Setup = 0;
u8 MenuBlinkBit;
//----------------------------------------------------------------------------------------------------
void SCU_Config(void)
{
645,7 → 646,7
if(CheckDelay(TimerSecond)) // one second Timer
{
TimerSecond += 1000;
 
if(MenuBlinkBit) MenuBlinkBit = 0; else MenuBlinkBit = 1;
if(FC.StatusFlags & FC_STATUS_FLY)
{
NaviData.FlyingTime++; // we want to count the battery-time
/trunk/main.h
14,7 → 14,7
 
#define VERSION_MAJOR 2
#define VERSION_MINOR 19
#define VERSION_PATCH 2
#define VERSION_PATCH 4
// 0 = A
// 1 = B
// 2 = C
388,6 → 388,7
#define OEM_NAME_LENGHT 16
extern u8 OEM_String[OEM_NAME_LENGHT+1];
extern u8 TryAgain_UBX_Setup;
extern u8 MenuBlinkBit;
 
#define CHECK_ONLY 0
#define GET_LICENSE 1
/trunk/uart1.c
84,6 → 84,7
#include "eeprom.h"
#include "triggerlog.h"
#include "settings.h"
#include "MobileMenu.h"
 
#define LIC_CMD_READ_LICENSE 1
#define LIC_CMD_WRITE_LICENSE 2
132,6 → 133,10
u8 UART1_Request_FTP = FALSE;
u8 UART1_Request_LicenseString = FALSE;
u8 UART1_Request_PPM_Channels = FALSE;
u8 UART1_Request_MobileLabel = 0xff;
u8 UART1_Request_MobileMenu = 0;
u8 UART1_Request_MobileInfo = 0;
 
u8 LastTransmittedFCStatusFlags2 = 0;
u8 UART1_ExternalControlConfirmFrame = FALSE;
u8 Send_NMEA_RMC = FALSE;
235,6 → 240,7
u32 UART1_MotorData_Interval = 0; // in ms
u32 UART1_Display_Timer = 0;
u32 UART1_Display_Interval = 0; // in ms
u32 UART1_MobileMenu_Timer = 0;
u32 NMEA_Timer = 0;
u32 NMEA_Interval = 0;// in ms
 
528,6 → 534,23
case NC_ADDRESS: // own Slave Address
switch(SerialMsg.CmdID)
{
case 'n':// request for the labels of the analog debug outputs
switch(SerialMsg.pData[0])
{
case MOBILE_LABLE:
UART1_Request_MobileLabel = SerialMsg.pData[1];
if(UART1_Request_MobileLabel > MOBILE_MAX_MENU) UART1_Request_MobileLabel > MOBILE_MAX_MENU;
break;
case MOBILE_MENU:
UART1_Request_MobileMenu = 1;
memcpy(&MobileDataRequest.MenuItem, &SerialMsg.pData[1],sizeof(MobileDataRequest)); // copy
break;
case MOBILE_INFO:
UART1_Request_MobileInfo = 1;
break;
}
break;
 
case 't': // request for the GPS time
UART1_Request_SystemTime = TRUE;
break;
705,7 → 728,7
UART1_Request_DebugLabel = SerialMsg.pData[0];
if(UART1_Request_DebugLabel > 31) UART1_Request_DebugLabel = 31;
break;
case 'b': // submit extern control
memcpy(&ExternControl, SerialMsg.pData, sizeof(ExternControl));
UART1_ConfirmFrame = ExternControl.Frame;
1341,7 → 1364,8
UART1_Display_Interval = 0;
UART1_MotorData_Interval = 0;
UART1_NaviData_Timer = SetDelay(500);
UART1_AboTimeOut = SetDelay(100);
UART1_AboTimeOut = SetDelay(1000);
UART1_MobileMenu_Timer = 0;
TransmitNavigationData(0,1); // clear the CRC values
}
//if(UART1_NaviData_MaxBytes > 150) UART1_NaviData_MaxBytes = 150;
1409,6 → 1433,46
MKProtocol_CreateSerialFrame(&UART1_tx_buffer, 'A', NC_ADDRESS, 2, &UART1_Request_DebugLabel, sizeof(UART1_Request_DebugLabel), (u8 *) ANALOG_LABEL[UART1_Request_DebugLabel], 16);
UART1_Request_DebugLabel = 0xFF;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ Mobile menu
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
else if((UART1_Request_MobileInfo) && (UART1_tx_buffer.Locked == FALSE)) // Infos
{
u8 cmd = MOBILE_INFO;
MobileDataInfo.Count = MOBILE_MAX_MENU;
MobileDataInfo.Compatibel = MOBILE_COMPATIBLITY;
MobileDataInfo.CheckSumLable = CRC16((unsigned char*)(&MobileLabel[0].MenuLabel[0]), sizeof(MobileLabel)); // update crc for the structure
MKProtocol_CreateSerialFrame(&UART1_tx_buffer, 'N', NC_ADDRESS, 2, &cmd ,1, &MobileDataInfo, sizeof(MobileDataInfo));
UART1_Request_MobileInfo = 0;
}
else if((UART1_Request_MobileLabel != 0xFF) && (UART1_tx_buffer.Locked == FALSE)) // Lables
{
u8 cmd = MOBILE_LABLE;
MKProtocol_CreateSerialFrame(&UART1_tx_buffer, 'N', NC_ADDRESS, 3, &cmd ,1, &UART1_Request_MobileLabel, sizeof(UART1_Request_MobileLabel), (u8 *) &MobileLabel[UART1_Request_MobileLabel].MenuLabel[0], sizeof(MobileLabel_t));
UART1_Request_MobileLabel = 0xFF;
}
else if((((UART1_Request_MobileMenu) && CheckDelay(UART1_MobileMenu_Timer)) || (UART1_Request_MobileMenu == 1)) && (UART1_tx_buffer.Locked == FALSE)) // menu
{
u8 cmd = MOBILE_MENU, event;
static u16 lastcrc = 0;
u16 crc;
event = MobileDataRequest.Event;
MobileMenuUpdate(MobileDataRequest.MenuItem,event,MobileDataRequest.Value);
MobileDataRequest.Event = 0;
//++++ has the data changed ? +++++
crc = CRC16((unsigned char*)(&Mobile), sizeof(Mobile_t));
DebugOut.Analog[16] = crc;
if(crc != lastcrc || UART1_Request_MobileMenu == 1)
{
MKProtocol_CreateSerialFrame(&UART1_tx_buffer, 'N', NC_ADDRESS, 2, &cmd ,1, &Mobile, sizeof(Mobile_t));
lastcrc = crc;
DebugOut.Analog[17]++;
}
//+++++++++++++++++++++++++++++++++
if(++UART1_Request_MobileMenu >= 16) UART1_Request_MobileMenu = 0;
else UART1_MobileMenu_Timer = SetDelay(500);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
else if(UART1_ExternalControlConfirmFrame && (UART1_tx_buffer.Locked == FALSE))
{
MKProtocol_CreateSerialFrame(&UART1_tx_buffer, 'B', NC_ADDRESS, 1,(u8 *)&UART1_ExternalControlConfirmFrame, sizeof(UART1_ExternalControlConfirmFrame));