/trunk/fat16.c |
---|
836,7 → 836,7 |
/* */ |
/* Description: This function sets the pointer of the stream relative to the position */ |
/* specified by origin (SEEK_SET, SEEK_CUR, SEEK_END) */ |
/* Returnvalue: Is 0 if seek was successful */ |
/* Returnvalue: Is 0 if seek was successful */ |
/****************************************************************************************************************************************************/ |
s16 fseek_(File_t *file, s32 offset, s16 origin) |
{ |
843,55 → 843,61 |
s32 fposition = 0; |
s16 retvalue = 1; |
// the byteindex within a sector |
u32 byte_index = 0; |
// the sectorindex within a cluster |
u32 sector_index = 0; |
// the index of the cluster within the clusterchain inside the fat |
u32 cluster_index = 0; |
// check if the partition is valid |
if((!Partition.IsValid) || (file == NULL)) return(retvalue); |
switch(origin) |
//...................................................... |
if(origin == SEEK_SET) // Fileposition relative to the beginning of the file. |
{ |
case SEEK_SET: // Fileposition relative to the beginning of the file. |
fposition = 0; |
break; |
case SEEK_END: // Fileposition relative to the end of the file. |
fposition = (s32)file->Size; |
break; |
case SEEK_CUR: // Fileposition relative to the current position of the file. |
default: |
fposition = file->Position; |
break; |
} |
fposition = 0; |
} |
//...................................................... |
else if(origin == SEEK_END) // Fileposition relative to the end of the file. |
{ |
fposition = (s32) file->Size; |
} |
//...................................................... |
else if(origin == SEEK_CUR) // Fileposition relative to the current position of the file. |
{ |
fposition = (s32)file->Position; |
} |
fposition += offset; |
if((fposition >= 0) && (fposition <= (s32)file->Size)) // is the pointer still within the file? |
// calculate the specified fileposition according to the selected mode |
fposition += offset; // Die Absolute Dateiposition welche durch fseek angesprungen werden soll. |
// is the fileposition within the file? |
if((fposition >= 0) && (fposition <= (s32)file->Size)) // Ist die berechnete Dateiposition innerhalb der geƶffneten Datei? |
{ |
// reset file position to start of the file |
// initialize the filepointer |
file->FirstSectorOfCurrCluster = file->FirstSectorOfFirstCluster; |
file->SectorOfCurrCluster = 0; |
file->ByteOfCurrSector = 0; |
file->Position = 0; |
// has the specified file at least one valid sector attached? |
if(file->FirstSectorOfCurrCluster == SECTOR_UNDEFINED) return(retvalue); |
while(file->Position < fposition) // repeat until the current position is less than target |
{ |
file->Position++; // increment file position |
file->ByteOfCurrSector++; // next byte in current sector |
if(file->ByteOfCurrSector >= BYTES_PER_SECTOR) |
{ |
file->ByteOfCurrSector = 0; // reading at the beginning of new sector. |
file->SectorOfCurrCluster++; // continue reading in next sector |
if(file->SectorOfCurrCluster >= Partition.SectorsPerCluster) // if end of cluster is reached, the next datacluster has to be searched in the FAT. |
{ |
if(GetNextCluster(file)) // Sets the clusterpointer of the file to the next datacluster. |
{ |
file->SectorOfCurrCluster = 0; |
} |
else // the last cluster was allready reached |
{ |
file->SectorOfCurrCluster--; // jump back to the last sector in the last cluster |
file->ByteOfCurrSector = BYTES_PER_SECTOR; // set ByteOfCurrSector one byte over sector end |
} |
} |
} |
} |
} |
if(file->Position == fposition) retvalue = 0; |
// calculate the absolute number of the sector wich contains the fileposition we are looking for |
sector_index = (u32) ((u32)fposition >> 9); |
// calculate the index of the cluster containing the specified sector |
cluster_index = (u32) sector_index / Partition.SectorsPerCluster; |
// the absolute sectornumber becomes relative to the beginning of the specified cluster |
sector_index = (sector_index % Partition.SectorsPerCluster); |
// calculate the index of the byteposition the fileposition points to |
byte_index = (u32) fposition % 512; |
// parse the fat till the calculated cluster has been reached |
while(cluster_index--) GetNextCluster(file); |
// set the filepointer to the specified sector and byteposition |
file->SectorOfCurrCluster = (u8) sector_index; |
file->ByteOfCurrSector = (u16) byte_index; |
// the fileposition now equals the filepointer |
file->Position = (u32)fposition; |
// the specified fileposition has been reached |
retvalue = 0; |
} |
return(retvalue); |
} |
971,19 → 977,32 |
/* */ |
/* Returnvalue: The function returns the appened cluster number or CLUSTER_UNDEFINED of no cluster was appended. */ |
/****************************************************************************************************************************************/ |
u16 AppendCluster(File_t *file) |
{ |
u16 last_cluster, new_cluster = CLUSTER_UNDEFINED; |
u32 fat_byte_offset, sector, byte; |
Fat16Entry_t * fat; |
// s8 text[64]; |
if((!Partition.IsValid) || (file == NULL)) return(new_cluster); |
new_cluster = FindNextFreeCluster(file); // the next free cluster found on the disk. |
if(new_cluster != CLUSTER_UNDEFINED) |
{ // A free cluster was found and can be added to the end of the file. |
fseek_(file, 0, SEEK_END); // jump to the end of the file |
last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster |
{ // A free cluster was found and can be added to the end of the file. |
// is there at least one cluster appended to the file? |
if(file->FirstSectorOfLastCluster == CLUSTER_UNDEFINED) |
{ |
fseek_(file, 0, SEEK_END); // jump to the end of the file |
// remember the first sector of the last cluster |
file->FirstSectorOfLastCluster = file->FirstSectorOfCurrCluster; |
last_cluster = SectorToFat16Cluster(file->FirstSectorOfCurrCluster); // determine current file cluster |
} |
else |
{ |
last_cluster = SectorToFat16Cluster(file->FirstSectorOfLastCluster); // determine current file cluster |
} |
if(last_cluster != CLUSTER_UNDEFINED) |
{ |
// update FAT entry of last cluster |
1007,6 → 1026,8 |
Fat16_Deinit(); |
return(0); |
} |
// now the new cluster appended to the fat is the last cluster |
file->FirstSectorOfLastCluster = Fat16ClusterToSector(new_cluster); |
} |
else // last cluster of the file is undefined |
{ // then the new cluster must be the first one of the file |
1035,6 → 1056,7 |
} |
// update file info |
file->FirstSectorOfFirstCluster = Fat16ClusterToSector(new_cluster); |
file->FirstSectorOfLastCluster = file->FirstSectorOfFirstCluster; |
file->Size = 0; |
file->Position = 0; |
} |
1046,6 → 1068,7 |
return(new_cluster); |
} |
/****************************************************************************************************************************************************/ |
/* Function: DirectoryEntryExist(s8 *, u8, u8, File_t *) */ |
/* */ |
/trunk/fat16.h |
---|
25,6 → 25,7 |
{ |
u32 FirstSectorOfFirstCluster; // First sector of the first cluster of the file. |
u32 FirstSectorOfCurrCluster; // First sector of the cluster which is edited at the moment. |
u32 FirstSectorOfLastCluster; // First sector of the last cluster of the file |
u8 SectorOfCurrCluster; // The sector within the current cluster. |
u16 ByteOfCurrSector; // The byte location within the current sector. |
u8 Mode; // Mode of fileoperation (read,write) |
/trunk/fifo.c |
---|
13,7 → 13,7 |
return(1); |
} |
u8 fifo_put (fifo_t *f, const u8 data) |
u8 fifo_put(fifo_t *f, const u8 data) |
{ |
if(f->buffer == 0) return(0); |
if (f->count >= f->size) return(0); // return 0 in case of FIFO overflow. |
/trunk/fifo.h |
---|
17,6 → 17,7 |
u16 getvicsource; // IRQ source to block, during get |
} fifo_t; |
extern fifo_t UART1_rx_fifo; |
/* |
The initialization of the FIFO sets the read/write pointers etc.. |
The FIFO uses the buffer 'buf' which byte length must 'size'. |
/trunk/gpx.c |
---|
67,6 → 67,7 |
#include "main.h" |
#include "led.h" |
#include "timer2.h" |
#include "logging.h" |
//________________________________________________________________________________________________________________________________________ |
// Function: GPX_DocumentInit(GPX_Document_t *) |
115,6 → 116,7 |
} |
Logging_FCStatusFlags1 = 0; |
Logging_FCStatusFlags2 = 0; |
Logged_GPX_Counter = 0; |
return(retvalue); |
} |
301,6 → 303,7 |
{ |
case 0: |
DebugOut.Analog[19]++; |
Logged_GPX_Counter++; |
if(GPSData.Position.Latitude < 0) u8_1 = '-'; |
else u8_1 = '+'; |
i32_1 = abs(GPSData.Position.Latitude)/10000000L; |
/trunk/kml.c |
---|
59,8 → 59,8 |
#include "kml.h" |
#include "kml_header.h" |
#include "uart1.h" |
#include "logging.h" |
//________________________________________________________________________________________________________________________________________ |
// Module name: kml.c |
// Compiler used: avr-gcc 3.4.5 |
253,6 → 253,7 |
{ |
doc->state = KML_DOC_LINESTRING_OPENED; |
fwrite_((void*)KML_LINESTRING_HEADER, sizeof(KML_LINESTRING_HEADER)-1,1,doc->file); |
Logged_KML_Counter = 0; |
retvalue = 1; |
} |
} |
330,6 → 331,7 |
i2 = rel_altitude%1000L; |
sprintf(string,"%ld.%03ld",i1, i2); |
fputs_(string, doc->file); |
Logged_KML_Counter++; |
retvalue = 1; |
} |
} |
/trunk/logging.c |
---|
63,8 → 63,10 |
#include "ssc.h" |
#include "settings.h" |
#include "led.h" |
#include "logging.h" |
#define MIN_SD_INTERVAL 500 |
#define MIN_SD_INTERVAL_KML 200 |
#define MIN_SD_INTERVAL_GPX 500 |
u8 SD_LoggingError = 0; |
83,13 → 85,8 |
logfilestate_t Logging_KML(u32 LogDelay); |
logfilestate_t Logging_GPX(u32 LogDelay); |
typedef struct |
{ |
u32 KML_Interval; // the kml-log interval (0 = off) |
u32 GPX_Interval; // the gpx-log interval (0 = off) |
} LogCfg_t; |
LogCfg_t LogCfg = {500 , 1000}; |
u32 Logged_GPX_Counter = 0, Logged_KML_Counter = 0; |
//---------------------------------------------------------------------------------------------------- |
375,11 → 372,7 |
if(CheckDelay(flushtimer)) |
{ |
flushtimer = SetDelay(LOG_FLUSH_INTERVAL); |
LED_RED_ON; |
fflush_(logfile.file); |
LED_RED_OFF; |
} |
} |
} |
428,12 → 421,12 |
SD_LoggingError = 0; |
LogCfg.KML_Interval = 1000; //default |
Settings_GetParamValue(PID_KML_LOGGING, (u16*)&LogCfg.KML_Interval); // overwrite by settings value |
if(LogCfg.KML_Interval != 0 && LogCfg.KML_Interval < MIN_SD_INTERVAL) LogCfg.KML_Interval = MIN_SD_INTERVAL; |
if(LogCfg.KML_Interval != 0 && LogCfg.KML_Interval < MIN_SD_INTERVAL_KML) LogCfg.KML_Interval = MIN_SD_INTERVAL_KML; |
Logging_KML(0); // initialize |
LogCfg.GPX_Interval = 0; //default |
Settings_GetParamValue(PID_GPX_LOGGING, (u16*)&LogCfg.GPX_Interval); // overwrite by settings value |
if(LogCfg.GPX_Interval != 0 && LogCfg.GPX_Interval < MIN_SD_INTERVAL) LogCfg.GPX_Interval = MIN_SD_INTERVAL; |
if(LogCfg.GPX_Interval != 0 && LogCfg.GPX_Interval < MIN_SD_INTERVAL_GPX) LogCfg.GPX_Interval = MIN_SD_INTERVAL_GPX; |
Logging_GPX(0); // initialize |
} |
/trunk/logging.h |
---|
4,5 → 4,15 |
void Logging_Init(void); |
void Logging_Update(void); // logs the current gps position to a kml file |
extern u8 SD_LoggingError; |
extern u32 Logged_GPX_Counter, Logged_KML_Counter; |
typedef struct |
{ |
u32 KML_Interval; // the kml-log interval (0 = off) |
u32 GPX_Interval; // the gpx-log interval (0 = off) |
} LogCfg_t; |
extern LogCfg_t LogCfg; |
#endif //_LOGGING_H |
/trunk/main.c |
---|
80,6 → 80,7 |
#include "eeprom.h" |
#include "ssc.h" |
#include "sdc.h" |
#include "uart1.h" |
#ifdef FOLLOW_ME |
u8 TransmitAlsoToFC = 0; |
152,7 → 153,7 |
if(CheckDelay(SPI0_Timeout)) |
{ |
LED_RED_ON; |
LED_RED_ON; |
sprintf(ErrorMSG,"no FC communication "); |
newErrorCode = 3; |
StopNavigation = 1; |
163,7 → 164,7 |
else if(CheckDelay(I2C1_Timeout)) |
{ |
LED_RED_ON; |
sprintf(ErrorMSG,"no compass communication"); |
sprintf(ErrorMSG,"no compass communica"); |
//Reset I2CBus |
I2C1_Deinit(); |
I2C1_Init(); |
230,7 → 231,7 |
} |
else if(FC.Error[0] & FC_ERROR0_PRESSURE) |
{ |
LED_RED_ON; |
LED_RED_ON; |
sprintf(ErrorMSG,"ERR:Pressure sensor"); |
newErrorCode = 16; |
} |
257,8 → 258,8 |
LED_RED_ON; |
// if(!(Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) sprintf(ErrorMSG,"GPS disconnected "); |
// else |
{ |
sprintf(ErrorMSG,"no GPS communication "); |
{ |
sprintf(ErrorMSG,"no GPS communication"); |
UART_VersionInfo.HardwareError[0] |= NC_ERROR0_GPS_RX; |
newErrorCode = 5; |
} |
337,7 → 338,7 |
else if((SD_LoggingError || (SD_WatchDog == 0)) && Parameter.GlobalConfig3 & CFG3_NO_SDCARD_NO_START ) |
{ |
LED_RED_ON; |
sprintf(ErrorMSG,"ERR:SD Logging aborted"); |
sprintf(ErrorMSG,"ERR:SD Logging abort"); |
newErrorCode = 27; |
DebugOut.StatusRed |= AMPEL_NC; |
SD_LoggingError = 0; |
355,8 → 356,8 |
LED_RED_OFF; |
if(no_error_delay) { no_error_delay--; } |
else |
{ |
sprintf(ErrorMSG,"No Error "); |
{ |
sprintf(ErrorMSG,"No Error "); |
ErrorCode = 0; |
} |
} |
374,9 → 375,6 |
ErrorGpsFixLost = 0; |
} |
// the handler will be cyclic called by the timer 1 ISR |
// used is for critical timing parts that normaly would handled |
// within the main loop that could block longer at logging activities |
void Polling(void) |
384,19 → 382,34 |
static u8 running = 0; |
if(running) return; |
running = 1; |
LED_GRN_OFF; |
// PollingTimeout = 20; |
SPI0_UpdateBuffer(); // also calls the GPS-functions |
UART0_ProcessRxData(); // GPS process request |
UART0_TransmitTxData(); // GPS send answer |
UART1_ProcessRxData(); // PC process request |
UART1_TransmitTxData(); // PC send answer |
UART2_TransmitTxData(); // FC send answer |
CalcHeadFree(); |
LED_GRN_ON; |
// ---------------- Error Check Timing ---------------------------- |
if(CheckDelay(TimerCheckError)) |
{ |
TimerCheckError = SetDelay(1000); |
if(CheckDelay(SPI0_Timeout) && (DebugUART == UART1)) GPS_Navigation(&GPSData, &(ToFlightCtrl.GPSStick)); // process the GPS data even if the FC is not connected |
if(!CheckDelay(SPI0_Timeout) || (DebugUART == UART1)) CheckErrors(); |
if(FC.StatusFlags & FC_STATUS_FLY) NaviData.FlyingTime++; // we want to count the battery-time |
// else NaviData.FlyingTime = 0; // not the time per flight |
if(SerialLinkOkay) SerialLinkOkay--; |
if(SerialLinkOkay < 250 - 5) NCFlags |= NC_FLAG_NOSERIALLINK; // 5 seconds timeout for serial communication |
else NCFlags &= ~NC_FLAG_NOSERIALLINK; |
if(StopNavigation && (Parameter.NaviGpsModeControl >= 50) && (Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) BeepTime = 1000; |
} |
running = 0; |
} |
// the handler will be cyclic called by the timer 1 ISR |
// used is for critical timing parts that normaly would handled |
// within the main loop that could block longer at logging activities |
void EXTIT3_IRQHandler(void) |
{ |
IENABLE; |
404,11 → 417,11 |
Compass_Update(); // update compass communication |
Analog_Update(); // get new ADC values |
if(!PollingTimeout) |
{ |
PollingTimeout = 3; |
Polling(); |
} |
if(!PollingTimeout) |
{ |
PollingTimeout = 5; |
Polling(); |
} |
VIC_SWITCmd(EXTIT3_ITLine,DISABLE); // clear pending bit |
VIC_ITCmd(EXTIT3_ITLine, ENABLE); // enable irq |
497,44 → 510,23 |
Debug_OK("START"); |
UART1_PutString("\r\n"); |
Polling(); |
fifo_purge(&UART1_rx_fifo); // flush the whole fifo init buffer |
LED_GRN_ON; |
LED_RED_OFF; |
for (;;) // the endless main loop |
{ |
Polling(); |
PollingTimeout = 15; |
DebugOut.Analog[17] = CountMilliseconds; |
UART1_ProcessRxData(); // PC process request |
// UART1_TransmitTxData(); // PC send answer |
// ---------------- Error Check Timing ---------------------------- |
if(CheckDelay(TimerCheckError)) |
{ |
TimerCheckError = SetDelay(1000); |
if(CheckDelay(SPI0_Timeout) && (DebugUART == UART1)) GPS_Navigation(&GPSData, &(ToFlightCtrl.GPSStick)); // process the GPS data even if the FC is not connected |
if(!CheckDelay(SPI0_Timeout) || (DebugUART == UART1)) CheckErrors(); |
if(FC.StatusFlags & FC_STATUS_FLY) NaviData.FlyingTime++; // we want to count the battery-time |
// else NaviData.FlyingTime = 0; // not the time per flight |
if(SerialLinkOkay) SerialLinkOkay--; |
if(SerialLinkOkay < 250 - 5) NCFlags |= NC_FLAG_NOSERIALLINK; // 5 seconds timeout for serial communication |
else NCFlags &= ~NC_FLAG_NOSERIALLINK; |
if(StopNavigation && (Parameter.NaviGpsModeControl >= 50) && (Parameter.GlobalConfig & FC_CFG_GPS_AKTIV)) BeepTime = 1000; |
} |
// ---------------- Logging --------------------------------------- |
if(SD_WatchDog) |
// ---------------- Logging --------------------------------------- |
if(SD_WatchDog) |
{ |
SD_WatchDog = 10000; |
SD_WatchDog = 30000; |
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/menu.c |
---|
66,6 → 66,7 |
#include "menu.h" |
#include "uart1.h" |
#include "ncmag.h" |
#include "logging.h" |
u8 DispPtr = 0; |
s8 DisplayBuff[DISPLAYBUFFSIZE]; |
120,8 → 121,8 |
LCD_printfxy(0,3,"%s",ErrorMSG); |
} |
else |
{ |
LCD_printfxy(0,3,"(c) Buss, Busker"); |
{ |
LCD_printfxy(0,3,"(c) HiSystems GmbH"); |
LCD_printfxy(0,2,"%s",ErrorMSG); |
} |
break; |
369,7 → 370,12 |
LCD_printfxy(0,2,"UP5:%3i UP6:%3i",Parameter.User5,Parameter.User6); |
LCD_printfxy(0,3,"UP7:%3i UP8:%3i",Parameter.User7,Parameter.User8); |
break; |
case 17: // magnetic field |
case 17: // User Parameter |
LCD_printfxy(0,0,"SD-Card Logs",Parameter.User1,Parameter.User2); |
LCD_printfxy(0,1,"GPX:%4i (%3ims) ",Logged_GPX_Counter,LogCfg.GPX_Interval); |
LCD_printfxy(0,2,"KML:%4i (%3ims) ",Logged_KML_Counter,LogCfg.KML_Interval); |
break; |
case 18: // magnetic field |
if(Compass_CalState) |
{ |
LCD_printfxy(0,0,"Calibration:"); |
420,7 → 426,7 |
} |
if(Keys & KEY3)Compass_SetCalState(0); // cancel |
break; |
case 18: |
case 19: |
if(GeoMagDec < 0) sign = '-'; |
else sign = '+'; |
LCD_printfxy(0,0,"Magnetic Field"); |
/trunk/sdc.c |
---|
176,7 → 176,7 |
{ |
rsp = SSC_GetChar(); |
if(CheckDelay(timestamp)) break; |
}while(rsp != 0xFF && (SD_WatchDog)); // wait while card is busy (data out low) |
}while(rsp != 0xFF); // wait while card is busy (data out low) |
return(rsp); |
} |
219,7 → 219,7 |
{ |
r1 = SSC_GetChar(); // get byte from sd-card |
if (timeout++ >500) break; |
}while(r1 == 0xFF && (SD_WatchDog)); // wait for the response byte from sd-card. |
}while(r1 == 0xFF); // wait for the response byte from sd-card. |
return(r1); |
} |
275,7 → 275,7 |
result = SD_ERROR_READ_DATA; |
goto end; |
} |
}while(rsp != DATA_START_TOKEN && (SD_WatchDog)); |
}while(rsp != DATA_START_TOKEN); |
// data start token received |
for (a = 0; a < len; a++) // read the block from the SSC |
{ |
/trunk/spi_slave.c |
---|
193,10 → 193,6 |
memcpy((u8 *) &FromFlightCtrl, (u8 *) SPI_RxBuffer, sizeof(FromFlightCtrl)); |
SPI_RxBuffer_Request = 1; |
} |
else |
{ |
DebugOut.Analog[16]++; |
} |
// reset timeout counter on good packet |
SPI0_Timeout = SetDelay(SPI0_TIMEOUT); |
DebugOut.Analog[13]++; |
/trunk/uart1.c |
---|
280,8 → 280,6 |
static u8 abortState = 0; |
u8 c; |
IENABLE; |
if((UART_GetITStatus(UART1, UART_IT_Receive) != RESET) || (UART_GetITStatus(UART1, UART_IT_ReceiveTimeOut) != RESET) ) |
{ |
// clear the pending bits! |
352,7 → 350,8 |
} // eof DebugUart = UART1 |
} |
IDISABLE; |
VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register |
} |
362,8 → 361,8 |
void UART1_ProcessRxData(void) |
{ |
// return on forwarding uart or unlocked rx buffer |
u8 c; |
if(DebugUART != UART1) return; |
u8 c; |
// if rx buffer is not locked |
if(UART1_rx_buffer.Locked == FALSE) |
{ |
/trunk/uart1.h |
---|
136,8 → 136,8 |
extern UART_TypeDef *DebugUART; |
extern volatile u8 SerialLinkOkay; |
extern Buffer_t UART1_tx_buffer; |
extern Buffer_t UART1_rx_buffer; |
void UART1_Init(void); |
void UART1_Transmit(void); |
void UART1_TransmitTxData(void); |
/trunk/uart2.c |
---|
174,8 → 174,8 |
/********************************************************/ |
void UART2_IRQHandler(void) |
{ |
IENABLE; |
// if receive irq or receive timeout irq has occured |
if((UART_GetITStatus(UART2, UART_IT_Receive) != RESET) || (UART_GetITStatus(UART2, UART_IT_ReceiveTimeOut) != RESET) ) |
{ |
203,7 → 203,7 |
} |
} // eof receive irq or receive timeout irq |
IDISABLE; |
VIC1->VAR = 0xFF; // write any value to VIC1 Vector address register |
} |