Subversion Repositories NaviCtrl

Compare Revisions

Ignore whitespace Rev 361 → Rev 362

/trunk/fat16.c
60,6 → 60,7
#include "fat16.h"
#include "sdc.h"
#include "uart1.h"
#include "main.h"
 
//________________________________________________________________________________________________________________________________________
// Module name: fat16.c
439,7 → 440,7
subpath = NULL;
readpointer = 0;
if(filepath[0] == '/') readpointer = 1; // ignore first '/'
while(subpath == NULL) // search the filepath until a subpath was found.
while(subpath == NULL && (SD_WatchDog)) // search the filepath until a subpath was found.
{
if(((filepath[readpointer] == 0) || (filepath[readpointer] == '/'))) // if '/' found or end of filepath reached
{
477,7 → 478,7
// start seperating the dirname from the filepath.
readpointer = 0;
if(filepath[0] == '/') readpointer = 1; // ignore first '/'
while( &filepath[readpointer] < subpath)
while( &filepath[readpointer] < subpath && (SD_WatchDog))
{
if(writepointer >= 11) return(NULL); // dirname to long
if(filepath[readpointer] == '.') // seperating dirname and extension.
825,7 → 826,7
}
fat_sector++; // continue the search in next fat sector
// repeat until the end of the fat is reached and no free cluster has been found so far
}while((fat_sector < Partition.SectorsPerFat) && (!free_cluster));
}while((fat_sector < Partition.SectorsPerFat) && (!free_cluster) && (SD_WatchDog));
return(free_cluster);
}
 
867,7 → 868,7
file->ByteOfCurrSector = 0;
file->Position = 0;
if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue);
while(file->Position < fposition) // repeat until the current position is less than target
while(file->Position < fposition && (SD_WatchDog)) // repeat until the current position is less than target
{
file->Position++; // increment file position
file->ByteOfCurrSector++; // next byte in current sector
957,7 → 958,7
}
}
}
while(repeat);
while(repeat && (SD_WatchDog));
 
return 1;
}
1164,7 → 1165,7
}
dir_sector++; // search next sector
// stop if we reached the end of the cluster or the end of the root dir
}while((dir_sector < max_dir_sector) && (!direntry_exist));
}while((dir_sector < max_dir_sector) && (!direntry_exist) && (SD_WatchDog));
 
// if we are seaching in the data area and the file not found in this cluster so take next cluster.
if(!direntry_exist && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1171,7 → 1172,7
{
end_of_directory_not_reached = GetNextCluster(file); // updates File->FirstSectorOfCurrCluster
}
}while((end_of_directory_not_reached) && (!direntry_exist)); // repeat until a next cluster exist an no
}while((end_of_directory_not_reached) && (!direntry_exist) && (SD_WatchDog)); // repeat until a next cluster exist an no
return(direntry_exist);
}
 
1341,7 → 1342,7
}
dir_sector++; // search next sector
// stop if we reached the end of the cluster or the end of the root dir
}while((dir_sector < max_dir_sector) && (!retvalue));
}while((dir_sector < max_dir_sector) && (!retvalue) && (SD_WatchDog));
 
// if we are seaching in the data area and the file not found in this cluster so take next cluster.
if(!retvalue && ( Partition.FirstDataSector <= file->FirstSectorOfCurrCluster))
1348,7 → 1349,7
{
end_of_directory_not_reached = GetNextCluster(file); // updates File->FirstSectorOfCurrCluster
}
}while((end_of_directory_not_reached) && (!retvalue));
}while((end_of_directory_not_reached) && (!retvalue) && (SD_WatchDog));
// Perhaps we are at the end of the last cluster of a directory file and have no free direntry found.
// Then we would need to add a cluster to that file and create the new direntry there.
// This code is not implemented yet, because its occurs only if more that 32*32=1024 direntries are
1389,7 → 1390,7
else file->DirectorySector = Partition.CurrentWorkingDirectory;
}
// as long as the file was not found and the remaining path is not empty
while((*path != 0) && !file_exist)
while((*path != 0) && !file_exist && (SD_WatchDog))
{ // separate dirname and subpath from filepath string
subpath = SeperateDirName(path, dirname);
if(subpath != NULL)
1451,7 → 1452,7
file->DirectorySector = 0; // start at RootDirectory with file search
file->DirectoryIndex = 0;
// as long as the file was not created and the remaining file path is not empty
while((*path != 0) && !file_created)
while((*path != 0) && !file_created && (SD_WatchDog))
{ // separate dirname and subpath from filepath string
subpath = SeperateDirName(path, dirname);
if(subpath != NULL)
1524,7 → 1525,7
// bring the path into the correct syntax
cptr = filename;
// search the whole string
while(*cptr != 0)
while(*cptr != 0 && (SD_WatchDog))
{
// replace all '\' by '/'
if(*cptr == '\\') *cptr = '/';
1848,10 → 1849,10
 
pbuff = (u8 *) buffer; // cast the void pointer to an u8 *
 
while((object_cnt < count) && success)
while((object_cnt < count) && success && (SD_WatchDog))
{
object_size = size;
while((size > 0) && success)
while((size > 0) && success && (SD_WatchDog))
{
c = fgetc_(file);
if(c != EOF)
1891,10 → 1892,10
if(file->Mode == 'r') return (0); // opened read only
pbuff = (u8 *) buffer; // cast the void pointer to an u8 *
 
while((object_cnt < count) && success)
while((object_cnt < count) && success && (SD_WatchDog))
{
object_size = size;
while((size > 0) && success)
while((size > 0) && success && (SD_WatchDog))
{
c = fputc_(*pbuff, file); // write a byte from the buffer to the opened file.
if(c != EOF)
1928,7 → 1929,7
 
if((!Partition.IsValid) || (file == NULL) || (string == NULL)) return(EOF);
if(file->Mode == 'r') return(EOF);
while((string[i] != 0)&& (c != EOF))
while((string[i] != 0)&& (c != EOF) && (SD_WatchDog))
{
c = fputc_(string[i], file);
i++;
1951,7 → 1952,7
if((!Partition.IsValid) || (file == NULL) || (string == NULL) || (length < 1)) return (0);
bytecount = length;
pbuff = string; // set write pointer to start of string
while(bytecount > 1) // read the length-1 characters from the file to the string.
while(bytecount > 1 && (SD_WatchDog)) // read the length-1 characters from the file to the string.
{
c = fgetc_(file); // read a character from the opened file.
switch(c)
2084,7 → 2085,7
}
dir_sector++; // search next sector
// stop if we reached the end of the cluster or the end of the root dir
}while((dir_sector < max_dir_sector) && (!pVolumeLabel));
}while((dir_sector < max_dir_sector) && (!pVolumeLabel) && (SD_WatchDog));
 
UnlockFilePointer(file);
return(pVolumeLabel);
2143,7 → 2144,7
SDC_GetSector(((u32) file.FirstSectorOfCurrCluster + (u32)file.SectorOfCurrCluster), file.Cache); // Read the Rootdirectory.
DirectoryEntry = (DirEntry_t *)file.Cache;
 
while((!retvalue)&&(index<16))
while((!retvalue)&&(index<16) && (SD_WatchDog))
{
i=0;
if((u8) DirectoryEntry[index].Name[0] != 0xe5) // ignore deleted items.
2207,7 → 2208,7
}
}
}
while((end_of_directory_not_reached) && (!retvalue));
while((end_of_directory_not_reached) && (!retvalue) && (SD_WatchDog));
 
return(retvalue);
}
2314,7 → 2315,7
u8 i=0;
u8 cnt=0;
 
while(dirpath[i] != 0)
while(dirpath[i] != 0 && (SD_WatchDog))
{
if(dirpath[i]=='/')
{
2344,7 → 2345,7
/* if the first character of the path is an '/' we go to the next character */
if(*cptr == '/') cptr++;
/* search end of path or subdirectory*/
while((*cptr != 0) && (*cptr != '/'))
while((*cptr != 0) && (*cptr != '/') && (SD_WatchDog))
{
*dptr = *cptr;
dptr++;
2416,11 → 2417,11
/* a pointer to the beginning of the absolute path to the cwd */
s8 * cptr = Partition.PathToCwd;
/* lets find the end of the path to the cwd */
while(*cptr != 0) cptr++;
while(*cptr != 0 && (SD_WatchDog)) cptr++;
/* if the path is terminated with an '/' */
if((*(cptr-1)) == '/') *(cptr-1)=0;
/* now lets find the beginning of the last directorientry */
while((*cptr != '/') && cptr > Partition.PathToCwd) cptr--;
while((*cptr != '/' && (SD_WatchDog)) && cptr > Partition.PathToCwd) cptr--;
/* is there one subdirectory left within the path? */
if(cptr > Partition.PathToCwd)
{
2469,7 → 2470,7
/* bring the path into the correct syntax */
cptr = path;
/* search the whole string */
while(*cptr != 0)
while(*cptr != 0 && (SD_WatchDog))
{
if(*cptr == '\\') *cptr = '/';
cptr++;
2518,7 → 2519,7
}
}
/* do this until all subdirectories have been found or a subdirectory is missing */
while(dircount && retvalue);
while(dircount && retvalue && (SD_WatchDog));
 
/* if we could not change to the specified directory we restore the actual path */
if(!retvalue)
/trunk/fifo.c
1,4 → 1,5
#include "fifo.h"
#include "main.h"
 
u8 fifo_init (fifo_t* f, u8* buffer, const u16 size, u16 putvicsource, u16 getvicsource)
{
37,7 → 38,7
 
u8 fifo_get_wait (fifo_t *f, u8 *pdata)
{
while (!f->count);
while (!f->count && (SD_WatchDog));
 
return fifo_get(f, pdata);
}
/trunk/gpx.c
134,7 → 134,7
 
if(doc == NULL) return(0);
 
while(doc->state != GPX_DOC_CLOSED) // close linestring, placemark and document before closing the file on the memorycard
while(doc->state != GPX_DOC_CLOSED && (SD_WatchDog)) // close linestring, placemark and document before closing the file on the memorycard
{
switch(doc->state)
{
467,7 → 467,7
u8 GPX_LoggGPSCoordinates(GPX_Document_t *doc,unsigned char part)
{
u8 retval = 0;
while(doc->state != GPX_DOC_TRACKSEGMENT_OPENED) // automatic create document with default filename on the card.
while(doc->state != GPX_DOC_TRACKSEGMENT_OPENED && (SD_WatchDog)) // automatic create document with default filename on the card.
{
switch(doc->state)
{
/trunk/i2c.c
238,7 → 238,6
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_NOACK;
VIC_ITCmd(I2C1_ITLine, DISABLE);
LED_GRN_OFF;
return;
}
else
247,7 → 246,6
{
// the start condition was initiated on the bus
case I2C_EVENT_MASTER_MODE_SELECT:
LED_GRN_ON;
// update current bus state variable
// jump to rx state if there is nothing to send
switch(I2C_Direction)
261,7 → 259,6
{
I2C_GenerateSTOP (I2C1, ENABLE);
VIC_ITCmd(I2C1_ITLine, DISABLE);
// LED_GRN_OFF;
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_NONE;
return;
275,7 → 272,6
default: // invalid direction
I2C_GenerateSTOP (I2C1, ENABLE);
VIC_ITCmd(I2C1_ITLine, DISABLE);
LED_GRN_OFF;
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_UNKNOWN;
return;
310,7 → 306,6
default: // unknown I2C state
// should never happen
I2C_GenerateSTOP (I2C1, ENABLE);
LED_GRN_OFF;
VIC_ITCmd(I2C1_ITLine, DISABLE);
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_UNKNOWN;
340,7 → 335,6
{ // stop communication
I2C_GenerateSTOP(I2C1, ENABLE); // generate stop condition to free the bus
VIC_ITCmd(I2C1_ITLine, DISABLE);
// LED_GRN_OFF;
I2C_State = I2C_STATE_IDLE; // ready for new actions
I2C_Error = I2C_ERROR_NONE;
}
364,7 → 358,6
I2C1_Timeout = SetDelay(I2C1_TIMEOUT);
DebugOut.Analog[15]++;
VIC_ITCmd(I2C1_ITLine, DISABLE);
// LED_GRN_OFF;
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_NONE;
return;
380,7 → 373,6
default:// unknown event
// should never happen
I2C_GenerateSTOP (I2C1, ENABLE);
LED_GRN_OFF;
VIC_ITCmd(I2C1_ITLine, DISABLE);
I2C_State = I2C_STATE_IDLE;
I2C_Error = I2C_ERROR_UNKNOWN;
/trunk/logging.c
188,7 → 188,7
do
{ // try to generate a new logfile name
logfilename = GenerateKMLLogFileName();
}while((logfilename != NULL) && fexist_(logfilename));
}while((logfilename != NULL) && fexist_(logfilename) && (SD_WatchDog));
// if logfilename exist
if(logfilename != NULL)
{
323,7 → 323,7
do
{ // try to generate a new logfile name
logfilename = GenerateGPXLogFileName();
}while((logfilename != NULL) && fexist_(logfilename));
}while((logfilename != NULL) && fexist_(logfilename) && (SD_WatchDog));
// if logfilename exist
if(logfilename != NULL)
{
/trunk/main.c
79,6 → 79,7
#include "debug.h"
#include "eeprom.h"
#include "ssc.h"
#include "sdc.h"
 
#ifdef FOLLOW_ME
u8 TransmitAlsoToFC = 0;
94,6 → 95,8
u8 StopNavigation = 0;
Param_t Parameter;
volatile FC_t FC;
volatile u32 MainWatchDog = 15000; // stop Navigation if this goes to zero
volatile u32 SD_WatchDog = 15000; // stop Logging if this goes to zero
 
s8 ErrorMSG[25];
 
330,7 → 333,7
newErrorCode = 26;
DebugOut.StatusRed |= AMPEL_NC;
}
else if(SD_LoggingError && Parameter.GlobalConfig3 & CFG3_NO_SDCARD_NO_START)
else if((SD_LoggingError || (SD_WatchDog == 0)) && Parameter.GlobalConfig3 & CFG3_NO_SDCARD_NO_START )
{
LED_RED_ON;
sprintf(ErrorMSG,"ERR:SD Logging aborted");
433,6 → 436,7
// initialize logging (needs settings)
Logging_Init();
 
LED_GRN_ON;
TimerCheckError = SetDelay(3000);
UART1_PutString("\r\n++++++++++++++++++++++++++++++++++++++++++");
UART1_PutString("\n\r Version information:");
457,9 → 461,7
LED_RED_ON;
}
#endif
 
GPS_Init();
 
// ---------- Prepare the isr driven
// set to absolute lowest priority
VIC_Config(EXTIT3_ITLine, VIC_IRQ, PRIORITY_SW);
467,9 → 469,11
VIC_ITCmd(EXTIT3_ITLine, ENABLE);
 
Debug_OK("START");
UART1_PutString("\r\n");
 
for (;;) // the endless main loop
{
MainWatchDog = 3500; // stop communication to FC after this timeout
UART0_ProcessRxData(); // process request
UART1_ProcessRxData(); // process request
USB_ProcessRxData(); // process request
494,10 → 498,14
else NCFlags &= ~NC_FLAG_NOSERIALLINK;
if(StopNavigation && (Parameter.NaviGpsModeControl >= 50) && (Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) BeepTime = 1000;
}
 
// ---------------- Logging ---------------------------------------
Logging_Update(); // could be block some time for at max. 2 seconds, therefore move time critical part of the mainloop into the ISR of timer 1
 
if(SD_WatchDog)
{
SD_WatchDog = 3000;
if(SDCardInfo.Valid == 1) Logging_Update(); // could be block some time for at max. 2 seconds, therefore move time critical part of the mainloop into the ISR of timer 1
else if(FC.StatusFlags & FC_STATUS_START) SD_LoggingError = 100;
if(!SD_WatchDog) UART1_PutString("\n\rSD-Watchdog - Logging aborted\n\r");
}
/*
// test
if(CheckDelay(ftimer))
/trunk/main.h
14,7 → 14,7
 
#define VERSION_MAJOR 0
#define VERSION_MINOR 28
#define VERSION_PATCH 2
#define VERSION_PATCH 3
// 0 = A
// 1 = B
// 2 = C
197,4 → 197,7
extern u8 ErrorCode;
extern u8 StopNavigation;
extern u8 ErrorGpsFixLost;
extern volatile u32 MainWatchDog; // stop Navigation if this goes to zero
extern volatile u32 SD_WatchDog; // stop Logging if this goes to zero
 
#endif // _MAIN_H
/trunk/sdc.c
132,22 → 132,6
#define DATA_RESPONSE_CRC_ERR 0x0B
#define DATA_RESPONSE_WRITE_ERR 0x1D
 
typedef enum
{
VER_UNKNOWN,
VER_1X,
VER_20
} SDVersion_t;
 
typedef struct
{
u8 Valid;
SDVersion_t Version; // HW-Version
u32 Capacity; // Memory capacity in bytes
u8 CID[16]; // CID register
u8 CSD[16]; // CSD register
} __attribute__((packed)) SDCardInfo_t;
 
volatile SDCardInfo_t SDCardInfo;
 
 
192,7 → 176,7
{
rsp = SSC_GetChar();
if(CheckDelay(timestamp)) break;
}while(rsp != 0xFF); // wait while card is busy (data out low)
}while(rsp != 0xFF && (SD_WatchDog)); // wait while card is busy (data out low)
return(rsp);
}
 
235,7 → 219,7
{
r1 = SSC_GetChar(); // get byte from sd-card
if (timeout++ >500) break;
}while(r1 == 0xFF); // wait for the response byte from sd-card.
}while(r1 == 0xFF && (SD_WatchDog)); // wait for the response byte from sd-card.
return(r1);
}
 
291,7 → 275,7
result = SD_ERROR_READ_DATA;
goto end;
}
}while(rsp != DATA_START_TOKEN);
}while(rsp != DATA_START_TOKEN && (SD_WatchDog));
// data start token received
for (a = 0; a < len; a++) // read the block from the SSC
{
758,6 → 742,7
sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
UART1_PutString(text);
}
 
return(result);
}
 
/trunk/sdc.h
30,6 → 30,24
SD_Result_t SDC_PutSector (u32, const u8 *);
SD_Result_t SDC_Deinit(void);
 
typedef enum
{
VER_UNKNOWN,
VER_1X,
VER_20
} SDVersion_t;
 
typedef struct
{
u8 Valid;
SDVersion_t Version; // HW-Version
u32 Capacity; // Memory capacity in bytes
u8 CID[16]; // CID register
u8 CSD[16]; // CSD register
} __attribute__((packed)) SDCardInfo_t;
 
extern volatile SDCardInfo_t SDCardInfo;
 
#endif // _SDC_H
 
 
/trunk/settings.c
61,7 → 61,9
#include "fat16.h"
#include "settings.h"
#include "uart1.h"
#include "main.h"
 
 
typedef struct
{
ParamId_t ParamId;
163,7 → 165,7
return;
}
// read all lines from file
while(fgets_(settingsline, LINE_MAX, fp) != 0)
while(fgets_(settingsline, LINE_MAX, fp) != 0 && (SD_WatchDog))
{
if ( // ignorelines starting with \r,\n,' ',';','#'
(settingsline[0] != '\n') &&
/trunk/spi_slave.c
137,16 → 137,17
SSP_ClearITPendingBit(SSP0, SSP_IT_RxFifo);
 
// while RxFIFO not empty
while (SSP_GetFlagStatus(SSP0, SSP_FLAG_RxFifoNotEmpty) == SET)
while (SSP_GetFlagStatus(SSP0, SSP_FLAG_RxFifoNotEmpty) == SET && (SD_WatchDog))
{
rxdata = SSP0->DR; // catch the received byte
// Fill TxFIFO while its not full or end of packet is reached
while (SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoNotFull) == SET)
while (SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoNotFull) == SET && (SD_WatchDog))
{
if (SPI_TxBufferIndex < SPI_TXBUFFER_LEN) // still data to send ?
{
SSP0->DR = SPI_TxBuffer[SPI_TxBufferIndex]; // send a byte
*Ptr_TxChksum += SPI_TxBuffer[SPI_TxBufferIndex]; // update checksum
if(MainWatchDog == 0) *Ptr_TxChksum += 1; // disturbe this packet to stop the communication!
SPI_TxBufferIndex++; // pointer to next byte
}
else // end of packet is reached reset and copy data to tx buffer
/trunk/ssc.c
55,6 → 55,7
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "91x_lib.h"
#include "config.h"
#include "main.h"
 
//________________________________________________________________________________________________________________________________________
// Module name: ssc.c
246,9 → 247,9
u8 SSC_GetChar (void)
{
u8 Byte = 0;
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET); // wait for space in the tx fifo
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET && (SD_WatchDog)); // wait for space in the tx fifo
SSP_SendData(SSP1, 0xFF);// send dymmy byte (0xFF) as master to receive a byte from the slave
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET); // wait for the byte to be sent
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET && (SD_WatchDog)); // wait for the byte to be sent
Byte = SSP_ReceiveData(SSP1); // read the byte transmitted from the slave
return (Byte);
}
257,9 → 258,9
void SSC_ClearRxFifo (void)
{
// wait that the tx fifo is empty
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET);
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoEmpty) != SET && (SD_WatchDog));
// then empty the rx fifo by reading all the bytes that are available
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_RxFifoNotEmpty) == SET) SSP_ReceiveData(SSP1);
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_RxFifoNotEmpty) == SET && (SD_WatchDog)) SSP_ReceiveData(SSP1);
}
//________________________________________________________________________________________________________________________________________
// Function: SSC_PutChar(u8 Byte);
273,7 → 274,7
void SSC_PutChar (u8 Byte)
{
// wait for some space in the tx fifo
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET);
while(SSP_GetFlagStatus(SSP1, SSP_FLAG_TxFifoNotFull) != SET && (SD_WatchDog));
// put the byte to send in the tx fifo
SSP_SendData(SSP1, Byte);
}
/trunk/timer1.c
57,6 → 57,7
#include "timer1.h"
#include "uart1.h"
#include "config.h"
#include "main.h"
 
u32 CountMilliseconds;
DateTime_t SystemTime;
71,7 → 72,8
TIM_ClearFlag(TIM1, TIM_FLAG_OC1); // clear irq pending bit
TIM1->OC1R += 200; // Timerfreq is 200kHz, generate an interrupt every 1ms
CountMilliseconds++;
if(SD_WatchDog) SD_WatchDog--;
if(MainWatchDog) MainWatchDog--;
// generate SW Interrupt to make a regular timing
// independent from the mainloop at the lowest IRQ priority
VIC_SWITCmd(EXTIT3_ITLine, ENABLE);
/trunk/uart1.c
604,9 → 604,10
/*****************************************************/
s16 UART1_Putchar(char c)
{
u32 timeout = 10000;
if (c == '\n') UART1_Putchar('\r');
// wait until txd fifo is not full
while (UART_GetFlagStatus(UART1, UART_FLAG_TxFIFOFull) != RESET);
while(UART_GetFlagStatus(UART1, UART_FLAG_TxFIFOFull) != RESET) if(--timeout == 0) return(0);
// transmit byte
UART_SendData(UART1, c);
#ifdef FOLLOW_ME