From 495cc1df494505378977995eeb76b05f20f0b235 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 13 Jun 2010 17:49:42 +0200 Subject: import firmware from LEGO v1.29 --- AT91SAM7S256/Source/BtTest.inc | 85 +- AT91SAM7S256/Source/Functions.inl | 1219 +++++++++---- AT91SAM7S256/Source/Icons.txt | 40 +- AT91SAM7S256/Source/Mainmenu.rms | 21 +- AT91SAM7S256/Source/Submenu03.rms | 207 +-- AT91SAM7S256/Source/Submenu04.rms | 77 +- AT91SAM7S256/Source/Ui.txt | 14 +- AT91SAM7S256/Source/c_button.c | 6 +- AT91SAM7S256/Source/c_button.h | 6 +- AT91SAM7S256/Source/c_button.iom | 6 +- AT91SAM7S256/Source/c_cmd.c | 3230 +++++++++++++++++++++++++-------- AT91SAM7S256/Source/c_cmd.h | 168 +- AT91SAM7S256/Source/c_cmd.iom | 40 +- AT91SAM7S256/Source/c_cmd_alternate.c | 163 -- AT91SAM7S256/Source/c_cmd_bytecodes.h | 132 +- AT91SAM7S256/Source/c_comm.c | 76 +- AT91SAM7S256/Source/c_comm.h | 6 +- AT91SAM7S256/Source/c_comm.iom | 13 +- AT91SAM7S256/Source/c_display.c | 22 +- AT91SAM7S256/Source/c_display.h | 8 +- AT91SAM7S256/Source/c_display.iom | 8 +- AT91SAM7S256/Source/c_input.c | 1326 +++++++++++--- AT91SAM7S256/Source/c_input.h | 32 +- AT91SAM7S256/Source/c_input.iom | 104 +- AT91SAM7S256/Source/c_ioctrl.c | 6 +- AT91SAM7S256/Source/c_ioctrl.h | 6 +- AT91SAM7S256/Source/c_ioctrl.iom | 6 +- AT91SAM7S256/Source/c_loader.c | 14 +- AT91SAM7S256/Source/c_loader.h | 6 +- AT91SAM7S256/Source/c_loader.iom | 9 +- AT91SAM7S256/Source/c_lowspeed.c | 6 +- AT91SAM7S256/Source/c_lowspeed.h | 6 +- AT91SAM7S256/Source/c_lowspeed.iom | 6 +- AT91SAM7S256/Source/c_output.c | 6 +- AT91SAM7S256/Source/c_output.h | 6 +- AT91SAM7S256/Source/c_output.iom | 6 +- AT91SAM7S256/Source/c_sound.c | 8 +- AT91SAM7S256/Source/c_sound.h | 8 +- AT91SAM7S256/Source/c_sound.iom | 8 +- AT91SAM7S256/Source/c_ui.c | 174 +- AT91SAM7S256/Source/c_ui.h | 71 +- AT91SAM7S256/Source/c_ui.iom | 21 +- AT91SAM7S256/Source/d_bt.c | 7 +- AT91SAM7S256/Source/d_bt.h | 6 +- AT91SAM7S256/Source/d_bt.r | 19 +- AT91SAM7S256/Source/d_button.c | 6 +- AT91SAM7S256/Source/d_button.h | 6 +- AT91SAM7S256/Source/d_button.r | 6 +- AT91SAM7S256/Source/d_display.c | 8 +- AT91SAM7S256/Source/d_display.h | 8 +- AT91SAM7S256/Source/d_display.r | 8 +- AT91SAM7S256/Source/d_hispeed.c | 6 +- AT91SAM7S256/Source/d_hispeed.h | 6 +- AT91SAM7S256/Source/d_hispeed.r | 6 +- AT91SAM7S256/Source/d_input.c | 56 +- AT91SAM7S256/Source/d_input.h | 17 +- AT91SAM7S256/Source/d_input.r | 307 +++- AT91SAM7S256/Source/d_ioctrl.c | 63 +- AT91SAM7S256/Source/d_ioctrl.h | 6 +- AT91SAM7S256/Source/d_ioctrl.r | 315 ++-- AT91SAM7S256/Source/d_loader.c | 197 +- AT91SAM7S256/Source/d_loader.h | 17 +- AT91SAM7S256/Source/d_loader.r | 6 +- AT91SAM7S256/Source/d_lowspeed.c | 6 +- AT91SAM7S256/Source/d_lowspeed.h | 6 +- AT91SAM7S256/Source/d_lowspeed.r | 102 +- AT91SAM7S256/Source/d_output.c | 17 +- AT91SAM7S256/Source/d_output.h | 6 +- AT91SAM7S256/Source/d_output.r | 6 +- AT91SAM7S256/Source/d_sound.c | 8 +- AT91SAM7S256/Source/d_sound.h | 8 +- AT91SAM7S256/Source/d_sound.r | 8 +- AT91SAM7S256/Source/d_sound_adpcm.r | 6 +- AT91SAM7S256/Source/d_timer.c | 32 +- AT91SAM7S256/Source/d_timer.h | 12 +- AT91SAM7S256/Source/d_timer.r | 26 +- AT91SAM7S256/Source/d_usb.c | 8 +- AT91SAM7S256/Source/d_usb.h | 8 +- AT91SAM7S256/Source/d_usb.r | 8 +- AT91SAM7S256/Source/m_sched.c | 6 +- AT91SAM7S256/Source/m_sched.h | 6 +- AT91SAM7S256/Source/modules.h | 15 +- AT91SAM7S256/Source/stdconst.h | 8 +- 83 files changed, 6024 insertions(+), 2736 deletions(-) delete mode 100644 AT91SAM7S256/Source/c_cmd_alternate.c (limited to 'AT91SAM7S256/Source') diff --git a/AT91SAM7S256/Source/BtTest.inc b/AT91SAM7S256/Source/BtTest.inc index b4626ab..31d9373 100644 --- a/AT91SAM7S256/Source/BtTest.inc +++ b/AT91SAM7S256/Source/BtTest.inc @@ -2,7 +2,7 @@ #include "Test1.txt" #include "Test2.txt" - +//#define TESTPRG // If defined the test program will be included extern void BtIo(void); @@ -13,7 +13,18 @@ const char MONTH[] = "JanFebMarAprMajJunJulAugSepOktNovDec"; void GetProtocolVersion(UBYTE *String) { - sprintf((char*)String,"FW %2X.%02X",(FIRMWAREVERSION >> 8),FIRMWAREVERSION & 0x00FF); + UWORD Tmp; + + Tmp = FIRMWAREVERSION & 0x00FF; + + if (Tmp < 100) + { + sprintf((char*)String,"FW %3u.%02u",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF); + } + else + { + sprintf((char*)String,"FW Hex %2X.%02X",(FIRMWAREVERSION >> 8) & 0x00FF,Tmp & 0x00FF); + } } @@ -23,22 +34,22 @@ void GetARMBuild(UBYTE *String) UWORD Lng; char String1[4]; char String2[4]; - + String1[0] = BUILD_DATE[4]; String1[1] = BUILD_DATE[5]; String1[2] = 0; - + Tmp = (UWORD)atoi(String1); Lng = 0; Lng += sprintf((char*)&String[Lng],"BUILD "); Lng += sprintf((char*)&String[Lng],"%02u",Tmp); - + String1[0] = BUILD_DATE[0]; String1[1] = BUILD_DATE[1]; String1[2] = BUILD_DATE[2]; String1[3] = 0; String2[3] = 0; - + Tmp = 0; do { @@ -67,12 +78,12 @@ void GetAVRBuild(UBYTE *String) sprintf((char*)String,"AVR %1u.%02u",((IoFromAvr.Battery >> 13) & 3),((IoFromAvr.Battery >> 10) & 7)); } - + void GetBC4Address(UBYTE *String) { UWORD Count; UBYTE Tmp; - + Count = (UWORD)sprintf((char*)String,"ID "); for (Tmp = 0;(Tmp < (SIZE_OF_BDADDR - 1)) && (Count <= (DISPLAYLINE_LENGTH - 2));Tmp++) { @@ -145,15 +156,15 @@ const UBYTE TXT_LINE[] = "----------------"; const UBYTE TXT_TEST[] = "Timer Test Bt "; const UBYTE TXT_TIMER[] = "Reset Hold "; -const UBYTE TXT_TIMER_HOLD[] = " Continue "; +const UBYTE TXT_TIMER_HOLD[] = " Continue "; const UBYTE TXT_LAST[] = "Last UI->BT Cmd."; -const UBYTE TXT_BT_PAGE[] = "Reset List BtIo"; +const UBYTE TXT_BT_PAGE[] = "Reset List BtIo"; const UBYTE TXT_RESETTING[] = " Resetting! "; -const UBYTE TXT_BT_LIST[] = "Down ConTab Up "; -const UBYTE TXT_BT_CONN[] = "Down Update Up "; +const UBYTE TXT_BT_LIST[] = "Down ConTab Up "; +const UBYTE TXT_BT_CONN[] = "Down Update Up "; const UBYTE TXT_BTUPDATE[] = "BT update mode !"; const UBYTE TXT_DONE[] = " When done "; @@ -226,7 +237,7 @@ UBYTE TestPrg(UBYTE Dummy) static UWORD Count; static UBYTE TxtBuffer[TEXTLINES][DISPLAYLINE_LENGTH + 1]; static UBYTE State = SYSTEM_INIT; -#ifdef TESTPRG +#ifdef TESTPRG static UWORD Pointer; static UWORD InputValues[NO_OF_INPUTS]; static SWORD OutputValues[NO_OF_OUTPUTS]; @@ -246,7 +257,7 @@ UBYTE TestPrg(UBYTE Dummy) GetBC4Build(TxtBuffer[2]); GetARMBuild(TxtBuffer[3]); GetBC4Address(TxtBuffer[4]); - + pMapDisplay->pTextLines[TEXTLINE_3] = (UBYTE*)TxtBuffer[0]; pMapDisplay->pTextLines[TEXTLINE_4] = (UBYTE*)TxtBuffer[1]; pMapDisplay->pTextLines[TEXTLINE_5] = (UBYTE*)TxtBuffer[2]; @@ -257,7 +268,7 @@ UBYTE TestPrg(UBYTE Dummy) #ifdef TESTPRG SubState = 0; -#endif +#endif State = SYSTEM_UNLOCK_INIT; } break; @@ -291,19 +302,19 @@ UBYTE TestPrg(UBYTE Dummy) Count = 0; } break; - + case 3 : { State = SYSTEM_UNLOCK; } break; - + default : { Tmp = BUTTON_EXIT; } break; - + } } break; @@ -322,7 +333,7 @@ UBYTE TestPrg(UBYTE Dummy) Tmp = BUTTON_EXIT; } break; - + case 1 : { if (Tmp == BUTTON_LEFT) @@ -340,7 +351,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case 2 : { if (Tmp == BUTTON_RIGHT) @@ -357,11 +368,11 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + } } break; - + } Pointer++; if (((SubState) && (Pointer > 500)) || (Tmp == BUTTON_EXIT)) @@ -370,7 +381,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case SYSTEM_UNLOCK : { pMapDisplay->pTextLines[TEXTLINE_8] = (UBYTE*)TXT_TEST; @@ -378,7 +389,7 @@ UBYTE TestPrg(UBYTE Dummy) State = SYSTEM_PAGE; } break; - + case SYSTEM_PAGE : { switch (cUiReadButtons()) @@ -450,19 +461,19 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case TIMER_INIT : { State = TIMER_SHOW; } break; - + case TIMER_SHOW : { sprintf((char*)TxtBuffer[2]," %10lu mS ",VarsUi.CRPasskey); pMapDisplay->pTextLines[TEXTLINE_3] = TxtBuffer[2]; pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); - + switch (cUiReadButtons()) { case BUTTON_ENTER : @@ -472,7 +483,7 @@ UBYTE TestPrg(UBYTE Dummy) State = TIMER_HOLD; } break; - + case BUTTON_LEFT : { pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); @@ -489,7 +500,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case TIMER_HOLD : { switch (cUiReadButtons()) @@ -565,7 +576,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case BT_RESET : { VarsUi.BTCommand = (UBYTE)FACTORYRESET; @@ -591,7 +602,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case BT_RESETTING : { if (VarsUi.BTResult != INPROGRESS) @@ -600,7 +611,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case BT_UPDATE_FW : { if (++Timer >= 100) @@ -609,7 +620,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case BT_LIST_INIT : { sprintf((char*)TxtBuffer[0],"DeviceTable No%2u",Pointer); @@ -630,7 +641,7 @@ UBYTE TestPrg(UBYTE Dummy) State = BT_LIST; } break; - + case BT_LIST : { switch (cUiReadButtons()) @@ -688,7 +699,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case BT_CONN_INIT : { sprintf((char*)TxtBuffer[0],"Conn. Table No%2u",Pointer); @@ -713,7 +724,7 @@ UBYTE TestPrg(UBYTE Dummy) State = BT_CONN; } break; - + case BT_CONN : { switch (cUiReadButtons()) @@ -761,7 +772,7 @@ UBYTE TestPrg(UBYTE Dummy) } } break; - + case TSTPRG_INIT : { IOMapUi.Flags &= ~UI_ENABLE_STATUS_UPDATE; diff --git a/AT91SAM7S256/Source/Functions.inl b/AT91SAM7S256/Source/Functions.inl index e641409..4211137 100644 --- a/AT91SAM7S256/Source/Functions.inl +++ b/AT91SAM7S256/Source/Functions.inl @@ -20,8 +20,10 @@ const UBYTE NONVOLATILE_NAME[] = UI_NONVOLATILE; // Non volatile filename without extention const UBYTE DEFAULT_PROGRAM_NAME[] = UI_PROGRAM_DEFAULT; // On brick programming filename without extention -const UBYTE TEMP_PROGRAM_FILENAME[] = UI_PROGRAM_TEMP; // On brick programming tmp filename +const UBYTE TEMP_PROGRAM_FILENAME[] = UI_PROGRAM_TEMP; // On brick programming tmp filename without extention const UBYTE VM_PROGRAM_READER[] = UI_PROGRAM_READER; // On brick programming script reader filename without extention +const UBYTE TEMP_DATALOG_FILENAME[] = UI_DATALOG_TEMP; // On brick datalog tmp filename without extention +const UBYTE DEFAULT_DATALOG_NAME[] = UI_DATALOG_DEFAULT; // On brick datalog filename without extention const UBYTE DEFAULT_PIN_CODE[] = UI_PINCODE_DEFAULT; // Default blue tooth pin code const UBYTE TXT_INVALID_SENSOR[] = "??????????????"; // Display invalid sensor data @@ -30,317 +32,372 @@ const UBYTE TXT_INVALID_SENSOR[] = "??????????????"; // Display invalid const UBYTE SENSORTYPE[SENSORS] = // for view and datalog { - 0, // MENU_SENSOR_EMPTY - SOUND_DB, // MENU_SENSOR_SOUND_DB - SOUND_DBA, // MENU_SENSOR_SOUND_DBA - LIGHT_ACTIVE, // MENU_SENSOR_LIGHT - LIGHT_INACTIVE, // MENU_SENSOR_LIGHT_AMB - REFLECTION, // MENU_SENSOR_LIGHT_OLD - SWITCH, // MENU_SENSOR_TOUCH - 0, // MENU_SENSOR_MOTOR_DEG - 0, // MENU_SENSOR_MOTOR_ROT - ANGLE, // MENU_SENSOR_ROTATION - LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_IN - LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_CM - TEMPERATURE, // MENU_SENSOR_TEMP_C - TEMPERATURE // MENU_SENSOR_TEMP_F + 0, // MENU_SENSOR_EMPTY + SOUND_DB, // MENU_SENSOR_SOUND_DB + SOUND_DBA, // MENU_SENSOR_SOUND_DBA + LIGHT_ACTIVE, // MENU_SENSOR_LIGHT + LIGHT_INACTIVE, // MENU_SENSOR_LIGHT_AMB + SWITCH, // MENU_SENSOR_TOUCH + 0, // MENU_SENSOR_MOTOR_DEG + 0, // MENU_SENSOR_MOTOR_ROT + LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_IN + LOWSPEED_9V, // MENU_SENSOR_ULTRASONIC_CM + LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_C + LOWSPEED_9V, // MENU_SENSOR_IIC_TEMP_F + COLORFULL // MENU_SENSOR_COLOR }; const UBYTE SENSORMODE[SENSORS] = // for view and datalog { - 0, // MENU_SENSOR_EMPTY - PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DB - PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DBA - PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT - PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT_AMB - PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT_OLD - BOOLEANMODE, // MENU_SENSOR_TOUCH - 0, // MENU_SENSOR_MOTOR_DEG - 0, // MENU_SENSOR_MOTOR_ROT - ANGLESTEPSMODE, // MENU_SENSOR_ROTATION - 0, // MENU_SENSOR_ULTRASONIC_IN - 0, // MENU_SENSOR_ULTRASONIC_CM - CELSIUSMODE, // MENU_SENSOR_TEMP_C - FAHRENHEITMODE // MENU_SENSOR_TEMP_F + 0, // MENU_SENSOR_EMPTY + PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DB + PCTFULLSCALEMODE, // MENU_SENSOR_SOUND_DBA + PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT + PCTFULLSCALEMODE, // MENU_SENSOR_LIGHT_AMB + BOOLEANMODE, // MENU_SENSOR_TOUCH + 0, // MENU_SENSOR_MOTOR_DEG + 0, // MENU_SENSOR_MOTOR_ROT + 0, // MENU_SENSOR_ULTRASONIC_IN + 0, // MENU_SENSOR_ULTRASONIC_CM + 0, // MENU_SENSOR_IIC_TEMP_C + 0, // MENU_SENSOR_IIC_TEMP_F + 0 // MENU_SENSOR_COLOR }; -const UBYTE SENSORFORMAT[SENSORS][10] = +const UBYTE SENSORFORMAT[SENSORS][9] = { - "", // MENU_SENSOR_EMPTY - "%3.0f %%", // MENU_SENSOR_SOUND_DB - "%3.0f %%", // MENU_SENSOR_SOUND_DBA - "%3.0f %%", // MENU_SENSOR_LIGHT - "%3.0f %%", // MENU_SENSOR_LIGHT_AMB - "%3.0f %%", // MENU_SENSOR_LIGHT_OLD - "%1.0f", // MENU_SENSOR_TOUCH - "%8.0f `", // MENU_SENSOR_MOTOR_DEG - "%8.0f R", // MENU_SENSOR_MOTOR_ROT - "%6.0f T", // MENU_SENSOR_ROTATION - "%3.0f In", // MENU_SENSOR_ULTRASONIC_IN - "%3.0f cm", // MENU_SENSOR_ULTRASONIC_CM - "%5.1f `C", // MENU_SENSOR_TEMP_C - "%5.1f `F" // MENU_SENSOR_TEMP_F + "", // MENU_SENSOR_EMPTY + "%3.0f %%", // MENU_SENSOR_SOUND_DB + "%3.0f %%", // MENU_SENSOR_SOUND_DBA + "%3.0f %%", // MENU_SENSOR_LIGHT + "%3.0f %%", // MENU_SENSOR_LIGHT_AMB + "%1.0f", // MENU_SENSOR_TOUCH + "%8.0f `", // MENU_SENSOR_MOTOR_DEG + "%8.0f R", // MENU_SENSOR_MOTOR_ROT + "%3.0f In", // MENU_SENSOR_ULTRASONIC_IN + "%3.0f cm", // MENU_SENSOR_ULTRASONIC_CM + "%5.1f `C", // MENU_SENSOR_IIC_TEMP_C + "%5.1f `F", // MENU_SENSOR_IIC_TEMP_F + "%9.0f" // MENU_SENSOR_COLOR (no of characters) }; const float SENSORDIVIDER[SENSORS] = { - 1.0, // MENU_SENSOR_EMPTY - 1.0, // MENU_SENSOR_SOUND_DB - 1.0, // MENU_SENSOR_SOUND_DBA - 1.0, // MENU_SENSOR_LIGHT - 1.0, // MENU_SENSOR_LIGHT_AMB - 1.0, // MENU_SENSOR_LIGHT_OLD - 1.0, // MENU_SENSOR_TOUCH - 1.0, // MENU_SENSOR_MOTOR_DEG - 360.0, // MENU_SENSOR_MOTOR_ROT - 1.0, // MENU_SENSOR_ROTATION - 2.54, // MENU_SENSOR_ULTRASONIC_IN - 1.0, // MENU_SENSOR_ULTRASONIC_CM - 10.0, // MENU_SENSOR_TEMP_C - 10.0 // MENU_SENSOR_TEMP_F + 1.0, // MENU_SENSOR_EMPTY + 1.0, // MENU_SENSOR_SOUND_DB + 1.0, // MENU_SENSOR_SOUND_DBA + 1.0, // MENU_SENSOR_LIGHT + 1.0, // MENU_SENSOR_LIGHT_AMB + 1.0, // MENU_SENSOR_TOUCH + 1.0, // MENU_SENSOR_MOTOR_DEG + 360.0, // MENU_SENSOR_MOTOR_ROT + 2.54, // MENU_SENSOR_ULTRASONIC_IN + 1.0, // MENU_SENSOR_ULTRASONIC_CM + 10.0, // MENU_SENSOR_IIC_TEMP_C + 10.0, // MENU_SENSOR_IIC_TEMP_F + 1.0 // MENU_SENSOR_COLOR }; -//******* cUiSetupUltrasonic ************************************************* +#define SENSORSYNCDATA "Sync data" +#define SENSORSDATA "Sdata" +#define SENSORTIME "Time" -void cUiSetupUltrasonic(UBYTE Port) -{ - Port -= MENU_PORT_1; - pMapLowSpeed->OutBuf[Port].InPtr = 0; - pMapLowSpeed->OutBuf[Port].OutPtr = 0; - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = ULTRA_SONIC; // Device Adress - pMapLowSpeed->OutBuf[Port].InPtr++; - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = 0x41; // Function => Set command - pMapLowSpeed->OutBuf[Port].InPtr++; - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = 0x02; // Function => Set to continiues measurement - pMapLowSpeed->OutBuf[Port].InPtr++; +const UBYTE SENSORDIRNAME[SENSORS - 1][19] = +{ + "Sound Sensor", // MENU_SENSOR_SOUND_DB + "Sound Sensor", // MENU_SENSOR_SOUND_DBA + "Light Sensor", // MENU_SENSOR_LIGHT + "Light Sensor", // MENU_SENSOR_LIGHT_AMB + "Bumper", // MENU_SENSOR_TOUCH + "FP Rotation Sensor", // MENU_SENSOR_MOTOR_DEG + "FP Rotation Sensor", // MENU_SENSOR_MOTOR_ROT + "Distance Sensor", // MENU_SENSOR_ULTRASONIC_IN + "Distance Sensor", // MENU_SENSOR_ULTRASONIC_CM + "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_C + "NXT Temp Sensor", // MENU_SENSOR_IIC_TEMP_F + "Color Detector" // MENU_SENSOR_COLOR +}; - pMapLowSpeed->InBuf[Port].BytesToRx = 0; - pMapLowSpeed->ChannelState[Port] = LOWSPEED_INIT; - pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); -} +const UBYTE SENSORUNITNAME[SENSORS - 1][5] = +{ + "_dB", // MENU_SENSOR_SOUND_DB + "_dBa", // MENU_SENSOR_SOUND_DBA + "_on", // MENU_SENSOR_LIGHT + "_off", // MENU_SENSOR_LIGHT_AMB + "", // MENU_SENSOR_TOUCH + "_deg", // MENU_SENSOR_MOTOR_DEG + "_rot", // MENU_SENSOR_MOTOR_ROT + "_in", // MENU_SENSOR_ULTRASONIC_IN + "_cm", // MENU_SENSOR_ULTRASONIC_CM + "_C", // MENU_SENSOR_IIC_TEMP_C + "_F", // MENU_SENSOR_IIC_TEMP_F + "_0", // MENU_SENSOR_COLOR +}; +const UBYTE SENSORFORMAT2[SENSORS - 1][6] = +{ + "\t%.0f", // MENU_SENSOR_SOUND_DB + "\t%.0f", // MENU_SENSOR_SOUND_DBA + "\t%.0f", // MENU_SENSOR_LIGHT + "\t%.0f", // MENU_SENSOR_LIGHT_AMB + "\t%.0f", // MENU_SENSOR_TOUCH + "\t%.0f", // MENU_SENSOR_MOTOR_DEG + "\t%.0f", // MENU_SENSOR_MOTOR_ROT + "\t%.0f", // MENU_SENSOR_ULTRASONIC_IN + "\t%.0f", // MENU_SENSOR_ULTRASONIC_CM + "\t%.1f", // MENU_SENSOR_IIC_TEMP_C + "\t%.1f", // MENU_SENSOR_IIC_TEMP_F + "\t%.0f" // MENU_SENSOR_COLOR +}; -//******* cUiAskUltrasonic *************************************************** +//******* cUiWriteLowspeed *************************************************** -void cUiAskUltrasonic(UBYTE Port) +void cUiWriteLowspeed(UBYTE Port,UBYTE TxBytes,UBYTE *TxBuf,UBYTE RxBytes) { Port -= MENU_PORT_1; pMapLowSpeed->OutBuf[Port].InPtr = 0; pMapLowSpeed->OutBuf[Port].OutPtr = 0; - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = ULTRA_SONIC; // Device Adress - pMapLowSpeed->OutBuf[Port].InPtr++; - pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = 0x42; // Function => Read result 1 - pMapLowSpeed->OutBuf[Port].InPtr++; - - pMapLowSpeed->InBuf[Port].BytesToRx = 1; + while (TxBytes) + { + pMapLowSpeed->OutBuf[Port].Buf[pMapLowSpeed->OutBuf[Port].InPtr] = *TxBuf; + pMapLowSpeed->OutBuf[Port].InPtr++; + TxBuf++; + TxBytes--; + } + pMapLowSpeed->InBuf[Port].BytesToRx = RxBytes; pMapLowSpeed->ChannelState[Port] = LOWSPEED_INIT; pMapLowSpeed->State |= (COM_CHANNEL_ONE_ACTIVE << Port); } +//******* cUiReadLowspeed **************************************************** -//******* cUiReadUltrasonic ************************************************** +#define IIC_READY 0 +#define IIC_BUSY 1 +#define IIC_ERROR 2 -UBYTE cUiReadUltrasonic(UBYTE Port) +UBYTE cUiReadLowspeed(UBYTE Port,UBYTE RxBytes,UWORD *Value) { UBYTE Result; + *Value = 0; Port -= MENU_PORT_1; if ((pMapLowSpeed->ChannelState[Port] == LOWSPEED_IDLE) || (pMapLowSpeed->ChannelState[Port] == LOWSPEED_DONE)) { - Result = (UBYTE)pMapLowSpeed->InBuf[Port].Buf[pMapLowSpeed->InBuf[Port].OutPtr]; - pMapLowSpeed->InBuf[Port].OutPtr++; - if (pMapLowSpeed->InBuf[Port].OutPtr >= SIZE_OF_LSBUF) + while (RxBytes) { - pMapLowSpeed->InBuf[Port].OutPtr = 0; - } - if (Result == 0) - { - Result = 0xFF; + (*Value) <<= 8; + (*Value) |= (UWORD)(pMapLowSpeed->InBuf[Port].Buf[pMapLowSpeed->InBuf[Port].OutPtr]); + pMapLowSpeed->InBuf[Port].OutPtr++; + if (pMapLowSpeed->InBuf[Port].OutPtr >= SIZE_OF_LSBUF) + { + pMapLowSpeed->InBuf[Port].OutPtr = 0; + } + RxBytes--; } + Result = IIC_READY; } else { - Result = 0xFF; - } - - return (Result); -} - - - -//******* cUiResetSensor ***************************************************** - -void cUiResetSensor(UBYTE Port,UBYTE Sensor) // Set sensor parameters -{ - switch (Sensor) - { - case MENU_SENSOR_MOTOR_DEG : + if (pMapLowSpeed->ErrorType[Port] == LOWSPEED_CH_NOT_READY) { - pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_RESET_COUNT; + Result = IIC_ERROR; } - break; - - case MENU_SENSOR_MOTOR_ROT : - { - pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_RESET_COUNT; - } - break; - - case MENU_SENSOR_ROTATION : + else { - pMapInput->Inputs[Port - MENU_PORT_1].SensorValue = 0; + Result = IIC_BUSY; } - break; - } + + return (Result); } +//******* cUiUpdateSensor **************************************************** -//******* cUiSetupSensor ***************************************************** +#define SENSOR_SETUP 0 +#define SENSOR_ACQUIRE 3 +#define SENSOR_READ 8 +#define SENSOR_STATES 10 -void cUiSetupSensor(UBYTE Port,UBYTE Sensor) // Set sensor parameters +void cUiUpdateSensor(SWORD Time) { - switch (Sensor) + UBYTE Port; + UBYTE Sensor; + UBYTE Result; + SWORD Tmp; + + if (VarsUi.SensorReset == TRUE) { - case MENU_SENSOR_MOTOR_DEG : + for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) { - pMapOutPut->Outputs[Port - MENU_PORT_A].Mode &= ~(BRAKE | MOTORON); - pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_MODE | UPDATE_SPEED; - pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt = 0; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; } - break; + VarsUi.SensorTimer = (MIN_SENSOR_READ_TIME / SENSOR_STATES); + VarsUi.SensorState = SENSOR_SETUP; + } - case MENU_SENSOR_MOTOR_ROT : - { - pMapOutPut->Outputs[Port - MENU_PORT_A].Mode &= ~(BRAKE | MOTORON); - pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_MODE | UPDATE_SPEED; - pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt = 0; - } - break; + VarsUi.SensorTimer += Time; + if (VarsUi.SensorTimer >= (MIN_SENSOR_READ_TIME / SENSOR_STATES)) + { + VarsUi.SensorTimer -= (MIN_SENSOR_READ_TIME / SENSOR_STATES); - case MENU_SENSOR_ULTRASONIC_IN : + for (Port = MENU_PORT_1;Port < MENU_PORT_INVALID;Port++) { - pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; - cUiSetupUltrasonic(Port); - } - break; + Sensor = VarsUi.DatalogPort[Port - MENU_PORT_1]; - case MENU_SENSOR_ULTRASONIC_CM : - { - pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; - cUiSetupUltrasonic(Port); + if (Sensor != MENU_SENSOR_EMPTY) + { + if ((Sensor == MENU_SENSOR_MOTOR_DEG) || (Sensor == MENU_SENSOR_MOTOR_ROT)) + { + if (VarsUi.SensorReset == TRUE) + { + pMapOutPut->Outputs[Port - MENU_PORT_A].Mode &= ~(BRAKE | MOTORON); + pMapOutPut->Outputs[Port - MENU_PORT_A].Flags |= UPDATE_MODE | UPDATE_SPEED | UPDATE_RESET_COUNT; + pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt = 0; + } + if (VarsUi.SensorState == SENSOR_READ) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + } + else + { + pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; + pMapInput->Inputs[Port - MENU_PORT_1].SensorMode = SENSORMODE[Sensor - MENU_SENSOR_EMPTY]; + if ((Sensor == MENU_SENSOR_ULTRASONIC_IN) || (Sensor == MENU_SENSOR_ULTRASONIC_CM)) + { + if (VarsUi.SensorReset == TRUE) + { + cUiWriteLowspeed(Port,3,"\x02\x41\x02",0); + } + if (VarsUi.SensorState == SENSOR_ACQUIRE) + { + cUiWriteLowspeed(Port,2,"\x02\x42",1); + } + if (VarsUi.SensorState == SENSOR_READ) + { + Result = cUiReadLowspeed(Port,1,(UWORD*)&Tmp); + if (Result == IIC_READY) + { + if ((UBYTE)Tmp != 0xFF) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)Tmp; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + else + { + if ((Sensor == MENU_SENSOR_IIC_TEMP_C) || (Sensor == MENU_SENSOR_IIC_TEMP_F)) + { + if (VarsUi.SensorState == SENSOR_SETUP) + { + cUiWriteLowspeed(Port,3,"\x98\x01\x60",0); + } + if (VarsUi.SensorState == SENSOR_ACQUIRE) + { + cUiWriteLowspeed(Port,2,"\x98\x00",2); + } + if (VarsUi.SensorState == SENSOR_READ) + { + Result = cUiReadLowspeed(Port,2,(UWORD*)&Tmp); + if (Result == IIC_READY) + { +// if (Tmp >= -14080) + { + if (Sensor == MENU_SENSOR_IIC_TEMP_F) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)(Tmp + 4544) / 14.2); + } + else + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = (SLONG)((float)Tmp / 25.6); + } + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + } + else + { + if (Result == IIC_ERROR) + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + } + else + { + if (VarsUi.SensorState == SENSOR_READ) + { + if (pMapInput->Inputs[Port - MENU_PORT_1].InvalidData != INVALID_DATA) + { + VarsUi.DatalogSampleValue[Port - MENU_PORT_1] = pMapInput->Inputs[Port - MENU_PORT_1].SensorValue; + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = TRUE; + } + else + { + VarsUi.DatalogSampleValid[Port - MENU_PORT_1] = FALSE; + } + } + } + } + } + } } - break; - default : + VarsUi.SensorState++; + if (VarsUi.SensorState >= SENSOR_STATES) { - pMapInput->Inputs[Port - MENU_PORT_1].SensorType = SENSORTYPE[Sensor - MENU_SENSOR_EMPTY]; - pMapInput->Inputs[Port - MENU_PORT_1].SensorMode = SENSORMODE[Sensor - MENU_SENSOR_EMPTY]; + VarsUi.SensorState = SENSOR_SETUP; } - break; + VarsUi.SensorReset = FALSE; } } +//******* cUiGetCustomPctFullScale ******************************************* -//******* cUiAskSensor ******************************************************* -void cUiAskSensor(UBYTE Port,UBYTE Sensor) // Ask for sensor data +UBYTE cUiGetCustomPctFullScale(UBYTE Port,UBYTE Sensor) { - switch (Sensor) - { - case MENU_SENSOR_ULTRASONIC_IN : - { - cUiAskUltrasonic(Port); - } - break; - - case MENU_SENSOR_ULTRASONIC_CM : - { - cUiAskUltrasonic(Port); - } - break; - - default : - { - } - break; + UBYTE Result = 0; + if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) + { + Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomPctFullScale; } + + return (Result); } -//******* cUiGetSensorValue ************************************************** +//******* cUiGetCustomActiveStatus ******************************************* + -UBYTE cUiGetSensorValue(UBYTE Port,UBYTE Sensor,SLONG *Value) +UBYTE cUiGetCustomActiveStatus(UBYTE Port,UBYTE Sensor) { - UBYTE Result = FALSE; + UBYTE Result = 0; - *Value = 0L; - switch (Sensor) + if ((Sensor != MENU_SENSOR_MOTOR_DEG) && (Sensor != MENU_SENSOR_MOTOR_ROT)) { - case MENU_SENSOR_MOTOR_DEG : - { - *Value = pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt; - Result = TRUE; - } - break; - - case MENU_SENSOR_MOTOR_ROT : - { - *Value = pMapOutPut->Outputs[Port - MENU_PORT_A].TachoCnt; - Result = TRUE; - } - break; - - case MENU_SENSOR_ULTRASONIC_IN : - { - Result = cUiReadUltrasonic(Port); - if (Result != 0xFF) - { - *Value = Result; - Result = TRUE; - } - else - { - Result = FALSE; - } - } - break; - - case MENU_SENSOR_ULTRASONIC_CM : - { - Result = cUiReadUltrasonic(Port); - if (Result != 0xFF) - { - *Value = Result; - Result = TRUE; - } - else - { - Result = FALSE; - } - } - break; - - default : - { - if (pMapInput->Inputs[Port - MENU_PORT_1].InvalidData != INVALID_DATA) - { - *Value = pMapInput->Inputs[Port - MENU_PORT_1].SensorValue; - Result = TRUE; - } - } - break; - + Result = (UBYTE)pMapInput->Inputs[Port - MENU_PORT_1].CustomActiveStatus; } return (Result); @@ -350,26 +407,53 @@ UBYTE cUiGetSensorValue(UBYTE Port,UBYTE Sensor,SLONG *Value) //******* cUiPrintSensorInDisplayBuffer ************************************** -void cUiPrintSensorInDisplayBuffer(UBYTE Port,UBYTE Sensor,UBYTE Valid,SLONG Value) +#define COLORNAMES 6 + +const UBYTE COLORNAME[COLORNAMES][10] = { - SWORD Tmp; + "1. Black ", + "2. Blue ", + "3. Green ", + "4. Yellow", + "5. Red ", + "6. White " +}; + - Tmp = sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor - MENU_SENSOR_EMPTY],(float)0); - if (Valid == TRUE) +void cUiPrintSensorInDisplayBuffer(UBYTE Port) +{ + UBYTE Sensor; + float Value; + SWORD Size; + SWORD Index; + + Port -= MENU_PORT_1; + Sensor = VarsUi.DatalogPort[Port] - MENU_SENSOR_EMPTY; + Value = (float)VarsUi.DatalogSampleValue[Port] / (float)SENSORDIVIDER[Sensor]; + Size = sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],(float)0); + sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); + + if (VarsUi.DatalogSampleValid[Port] == TRUE) { - if (Tmp < sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor - MENU_SENSOR_EMPTY],(float)Value / SENSORDIVIDER[Sensor - MENU_SENSOR_EMPTY])) + if (Sensor == (MENU_SENSOR_COLOR - MENU_SENSOR_EMPTY)) { - sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Tmp,Tmp,(char*)TXT_INVALID_SENSOR); + Index = (SWORD)Value - 1; + if ((Index >= 0) && (Index < COLORNAMES)) + { + sprintf((char*)VarsUi.DisplayBuffer,(char*)COLORNAME[Index]); + } + } + else + { + if (Size < sprintf((char*)VarsUi.DisplayBuffer,(char*)SENSORFORMAT[Sensor],Value)) + { + sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Size,Size,(char*)TXT_INVALID_SENSOR); + } } - } - else - { - sprintf((char*)VarsUi.DisplayBuffer,"%*.*s",Tmp,Tmp,(char*)TXT_INVALID_SENSOR); } } - //******* cUiReleaseSensors ************************************************** void cUiReleaseSensors(void) @@ -586,7 +670,7 @@ UWORD cUiBTCommand(UBYTE Cmd,UBYTE Flag,UBYTE *pParam1,UBYTE *pParam2) //******* cUiNVxxxxx ********************************************************* -void cUiNVWriteByte(void) +void cUiNVWrite(void) { sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); VarsUi.NVTmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.NVFilename,VarsUi.SearchFilenameBuffer,&VarsUi.NVTmpLength); @@ -595,58 +679,36 @@ void cUiNVWriteByte(void) pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); pMapLoader->pFunc(DELETE,VarsUi.NVFilename,NULL,NULL); } - VarsUi.NVTmpLength = 1; + VarsUi.NVTmpLength = sizeof(NVDATA); VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENWRITE,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); } -void cUiNVWritePowerOnTimeCount(UBYTE Count) -{ - VarsUi.NVData &= ~0x07; - VarsUi.NVData |= (Count & 0x07); - cUiNVWriteByte(); -} - -UBYTE cUiNVReadPowerOnTimeCount(void) -{ - return (VarsUi.NVData & 0x07); -} -void cUiNVWriteVolumeCount(UBYTE Count) +void cUiNVRead(void) { - VarsUi.NVData &= ~0x70; - VarsUi.NVData |= ((Count << 4) & 0x70); - cUiNVWriteByte(); -} - -UBYTE cUiNVReadVolumeCount(void) -{ - return ((VarsUi.NVData >> 4) & 0x07); -} - -void cUiNVReadByte(void) -{ - VarsUi.NVData = 0xFF; + VarsUi.NVData.CheckByte = 0; sprintf((char*)VarsUi.NVFilename,"%s.%s",(char*)NONVOLATILE_NAME,(char*)TXT_SYS_EXT); VarsUi.NVTmpHandle = pMapLoader->pFunc(OPENREAD,VarsUi.NVFilename,NULL,&VarsUi.NVTmpLength); if (!(VarsUi.NVTmpHandle & 0x8000)) { - VarsUi.NVTmpLength = 1; - pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.NVTmpHandle,&VarsUi.NVData,&VarsUi.NVTmpLength); + VarsUi.NVTmpLength = sizeof(NVDATA); + pMapLoader->pFunc(READ,(UBYTE*)&VarsUi.NVTmpHandle,(UBYTE*)&VarsUi.NVData,&VarsUi.NVTmpLength); pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.NVTmpHandle,NULL,NULL); } - - if ((cUiNVReadPowerOnTimeCount() > (POWER_OFF_TIME_STEPS - 1)) || (cUiNVReadVolumeCount() > MAX_VOLUME)) + if (VarsUi.NVData.CheckByte != CHECKBYTE) { - VarsUi.NVData = 0xFF; - cUiNVWritePowerOnTimeCount(POWER_OFF_TIME_DEFAULT); - cUiNVWriteVolumeCount(MAX_VOLUME); + VarsUi.NVData.DatalogEnabled = DATALOGENABLED; + VarsUi.NVData.VolumeStep = MAX_VOLUME; + VarsUi.NVData.PowerdownCode = POWER_OFF_TIME_DEFAULT; + VarsUi.NVData.DatalogNumber = 0; + VarsUi.NVData.CheckByte = CHECKBYTE; + cUiNVWrite(); } } - //******* cUiFeedback ******************************************************** UBYTE cUiFeedback(BMPMAP *Bitmap,UBYTE TextNo1,UBYTE TextNo2,UWORD Time) // Show bimap and text @@ -728,7 +790,14 @@ UBYTE cUiFeedback(BMPMAP *Bitmap,UBYTE TextNo1,UBYTE TextNo2,UWORD Time) // } else { - VarsUi.FBText = cUiGetString(TextNo2); + if (TextNo2 == 0xFF) + { + VarsUi.FBText = VarsUi.SelectedFilename; + } + else + { + VarsUi.FBText = cUiGetString(TextNo2); + } VarsUi.FBPointer = 0; VarsUi.FBState++; } @@ -1056,7 +1125,7 @@ UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT { case MENU_INIT : // Init time counter and cursor bitmap { - VarsUi.Counter = cUiNVReadVolumeCount() + 1; + VarsUi.Counter = VarsUi.NVData.VolumeStep + 1; VarsUi.pTmp = (UBYTE*)Cursor; for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)sizeof(Cursor));VarsUi.Tmp++) @@ -1086,8 +1155,9 @@ UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT case MENU_ENTER : // Enter { - cUiNVWriteVolumeCount(VarsUi.Counter - 1); - IOMapUi.Volume = cUiNVReadVolumeCount(); + VarsUi.NVData.VolumeStep = VarsUi.Counter - 1; + cUiNVWrite(); + IOMapUi.Volume = VarsUi.NVData.VolumeStep; pMapSound->Volume = IOMapUi.Volume; Action = MENU_EXIT; } @@ -1095,7 +1165,7 @@ UBYTE cUiVolume(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_EXIT case MENU_EXIT : // Leave { - IOMapUi.Volume = cUiNVReadVolumeCount(); + IOMapUi.Volume = VarsUi.NVData.VolumeStep; } break; @@ -1140,13 +1210,12 @@ typedef struct } STRSETS; -const UBYTE PincodeFigures[] = { "0987654321" "\x7F" "abcdefghijklmnopqrstuvwxyz " }; -const UBYTE FilenameFigures[] = { "0987654321" "\x7F" "abcdefghijklmnopqrstuvwxyz " }; +const UBYTE Figures[] = { "0987654321" "\x7F" "abcdefghijklmnopqrstuvwxyz " }; const STRSETS StrSets[STRINGTYPES] = { - { TXT_GETUSERSTRING_PIN, PincodeFigures, 37, SIZE_OF_BT_PINCODE - 1, 15, 10 }, - { TXT_GETUSERSTRING_FILENAME, FilenameFigures, 37, FILENAME_LENGTH - 4 , 15, 10 } + { TXT_GETUSERSTRING_PIN, Figures, 37, SIZE_OF_BT_PINCODE - 1, 15, 10 }, + { TXT_GETUSERSTRING_FILENAME, Figures, 37, FILENAME_LENGTH - 4 , 15, 10 } }; @@ -1404,6 +1473,544 @@ void cUiDrawPortNo(UBYTE *Bitmap,UBYTE MenuIconNo,UBYTE PortNo) } +UBYTE cUiDataLogging(UBYTE Action) +{ + SBYTE TmpBuffer[DATALOGBUFFERSIZE + 1]; + + switch (Action) + { + case MENU_INIT : // Initialize all ports to empty + { +// Show select + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + +// Init ports + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; + } + } + break; + + case MENU_EXIT : // Initialize all ports to empty + { +// Show select + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + } + break; + + case MENU_TEXT : // Write text + { +// Init selected sensor and port to none + VarsUi.SelectedSensor = MENU_SENSOR_EMPTY; + VarsUi.SelectedPort = MENU_PORT_EMPTY; +// Count ports + VarsUi.Counter = 0; + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { +// Find default port to view + if (VarsUi.SelectedPort == MENU_PORT_EMPTY) + { + VarsUi.SelectedPort = VarsUi.Tmp + MENU_PORT_1; + } + VarsUi.Counter++; + } + } + if (VarsUi.Counter) + { +// Display text + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_DATALOGGING_PRESS_EXIT_TO); + pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_STOP_DATALOGGING); + + pMapDisplay->TextLinesCenterFlags |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + pMapDisplay->UpdateMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4)); + } + else + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + case MENU_RUN : // Run data logging + { + switch (VarsUi.State) + { + case 0 : // Init log + { +// Save menu text + VarsUi.MenuIconTextSave = pMapDisplay->pMenuText; + +// Delete file if exist + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(FINDFIRST,VarsUi.FilenameBuffer,VarsUi.SearchFilenameBuffer,&VarsUi.TmpLength); + if (!(VarsUi.TmpHandle & 0x8000)) + { + pMapLoader->pFunc(CLOSE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + } + +// Open file + VarsUi.TmpLength = pMapLoader->FreeUserFlash; + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(OPENWRITEDATA,VarsUi.FilenameBuffer,NULL,&VarsUi.TmpLength); + VarsUi.DatalogError = VarsUi.TmpHandle; + if (!(VarsUi.DatalogError & 0x8000)) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s\t%lu",SENSORSYNCDATA,pMapCmd->SyncTime); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->SyncTick); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu",pMapCmd->Tick); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%lu\t-1\r\n",DATALOG_DEFAULT_SAMPLE_TIME); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORSDATA); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%u_%s%s",(UWORD)(VarsUi.Tmp + 1),(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(char*)SENSORUNITNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%s",SENSORTIME); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t%s",(char*)SENSORDIRNAME[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + if (!(VarsUi.DatalogError & 0x8000)) + { + VarsUi.DatalogTimer = 0; + VarsUi.DatalogSampleTime = DATALOG_DEFAULT_SAMPLE_TIME; + VarsUi.DatalogSampleTimer = 0; + VarsUi.Timer = 0; + VarsUi.Update = TRUE; + IOMapUi.Flags |= UI_BUSY; + VarsUi.DatalogOldTick = pMapCmd->Tick; + VarsUi.SensorReset = TRUE; + VarsUi.State++; + } + else + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 4; + } + } + else + { +// File error + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 3; + } + } + break; + + case 1 : + { +// Get real time since last + VarsUi.DatalogRTC = (pMapCmd->Tick - VarsUi.DatalogOldTick); + VarsUi.DatalogOldTick = pMapCmd->Tick; +// Update all timers + VarsUi.DatalogTimer += VarsUi.DatalogRTC; + VarsUi.DatalogSampleTimer += VarsUi.DatalogRTC; + VarsUi.ReadoutTimer += VarsUi.DatalogRTC; +// Update sensor values + cUiUpdateSensor((SWORD)VarsUi.DatalogRTC); +// Check for select change + if (VarsUi.Update == TRUE) + { + VarsUi.Update = FALSE; + VarsUi.SelectedSensor = VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1]; + pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.SelectedSensor)); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = NULL; + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = NULL; + + pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_LARGE); + pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; + pMapDisplay->UpdateMask = (BITMAP_BIT(BITMAP_1) | MENUICON_BITS | SPECIAL_BIT(TOPLINE) | SPECIAL_BIT(FRAME_SELECT)); + + pMapDisplay->pBitmaps[BITMAP_2] = (BMPMAP*)VarsUi.PortBitmapLeft; + pMapDisplay->pBitmaps[BITMAP_3] = (BMPMAP*)VarsUi.PortBitmapCenter; + pMapDisplay->pBitmaps[BITMAP_4] = (BMPMAP*)VarsUi.PortBitmapRight; + + cUiDrawPortNo(VarsUi.PortBitmapCenter,MENUICON_CENTER,VarsUi.SelectedPort - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_3); + + + + if (VarsUi.Counter == 2) + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if (VarsUi.Tmp > VarsUi.SelectedPort) + { + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + } + else + { + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + } + } + if (VarsUi.Counter > 2) + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + pMapDisplay->pMenuIcons[MENUICON_RIGHT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapRight,MENUICON_RIGHT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_4); + + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp--; + if (VarsUi.Tmp <= MENU_PORT_EMPTY) + { + VarsUi.Tmp = MENU_PORT_INVALID - 1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + pMapDisplay->pMenuIcons[MENUICON_LEFT] = cUiMenuGetIconImage(cUiMenuSearchSensorIcon(VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1])); + cUiDrawPortNo(VarsUi.PortBitmapLeft,MENUICON_LEFT,VarsUi.Tmp - MENU_PORT_EMPTY); + pMapDisplay->UpdateMask |= BITMAP_BIT(BITMAP_2); + + + } + VarsUi.ReadoutTimer = DISPLAY_VIEW_UPDATE; + } +// Write sample if timeout + if (VarsUi.DatalogSampleTimer >= VarsUi.DatalogSampleTime) + { + VarsUi.DatalogSampleTimer -= VarsUi.DatalogSampleTime; + + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"%lu",VarsUi.DatalogTimer - VarsUi.DatalogSampleTime); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + for (VarsUi.Tmp = 0;(VarsUi.Tmp < DATALOGPORTS) && (!(VarsUi.DatalogError & 0x8000));VarsUi.Tmp++) + { + if (MENU_SENSOR_EMPTY != VarsUi.DatalogPort[VarsUi.Tmp]) + { + if (VarsUi.DatalogSampleValid[VarsUi.Tmp] == TRUE) + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,(char*)SENSORFORMAT2[(VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY) - 1],(float)VarsUi.DatalogSampleValue[VarsUi.Tmp] / SENSORDIVIDER[VarsUi.DatalogPort[VarsUi.Tmp] - MENU_SENSOR_EMPTY]); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + else + { + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\t-"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } + } + } + VarsUi.TmpLength = (ULONG)sprintf((char*)TmpBuffer,"\r\n"); + VarsUi.DatalogError |= pMapLoader->pFunc(WRITE,(UBYTE*)&VarsUi.TmpHandle,(UBYTE*)TmpBuffer,&VarsUi.TmpLength); + } +// Refresh display + if (++VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) + { + VarsUi.ReadoutTimer = 0; + +// Display sensor value + cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); + pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + } + +// Test for file error + if ((VarsUi.DatalogError & 0x8000)) + { + pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); + pMapDisplay->pBitmaps[BITMAP_1] = NULL; + VarsUi.State = 4; + } + +// Test for break; + switch (cUiReadButtons()) + { + case BUTTON_EXIT : + { + VarsUi.State++; + } + break; + + case BUTTON_LEFT : + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp--; + if (VarsUi.Tmp <= MENU_PORT_EMPTY) + { + VarsUi.Tmp = MENU_PORT_INVALID - 1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if ((VarsUi.Counter > 2) || (VarsUi.Tmp < VarsUi.SelectedPort)) + { + VarsUi.SelectedPort = VarsUi.Tmp; + } + VarsUi.Update = TRUE; + } + break; + + case BUTTON_RIGHT : + { + VarsUi.Tmp = VarsUi.SelectedPort; + do + { + VarsUi.Tmp++; + if (VarsUi.Tmp >= MENU_PORT_INVALID) + { + VarsUi.Tmp = MENU_PORT_1; + } + } + while (VarsUi.DatalogPort[VarsUi.Tmp - MENU_PORT_1] == MENU_SENSOR_EMPTY); + if ((VarsUi.Counter > 2) || (VarsUi.Tmp > VarsUi.SelectedPort)) + { + VarsUi.SelectedPort = VarsUi.Tmp; + } + VarsUi.Update = TRUE; + } + break; + + } + IOMapUi.Flags |= UI_RESET_SLEEP_TIMER; + } + break; + + case 2 : + { +// Close file + pMapLoader->pFunc(CROPDATAFILE,(UBYTE*)&VarsUi.TmpHandle,NULL,NULL); + +// Clean up + pMapDisplay->pMenuText = VarsUi.MenuIconTextSave; + cUiReleaseSensors(); + + IOMapUi.Flags &= ~UI_BUSY; + IOMapUi.State = RIGHT_PRESSED; + VarsUi.State = 0; + } + break; + + case 3 : // Display memory full text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + case 4 : // Display memory full text + { + if (!cUiFeedback((BMPMAP*)Fail,TXT_FB_DL_ERROR_MEMORY_FULL_1,TXT_FB_DL_ERROR_MEMORY_FULL_2,DISPLAY_SHOW_ERROR_TIME)) + { + VarsUi.State = 2; + } + } + break; + + } + } + break; + + case MENU_SAVE : // Save datalog file + { + switch (VarsUi.State) + { + case 0 : + { + VarsUi.NVData.DatalogNumber++; + if (VarsUi.NVData.DatalogNumber > MAX_DATALOGS) + { + VarsUi.NVData.DatalogNumber = 1; + } + cUiNVWrite(); + sprintf((char*)VarsUi.SelectedFilename,"%s%u.%s",(char*)UI_DATALOG_FILENAME,VarsUi.NVData.DatalogNumber,TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.State++; + } + break; + + case 1 : + { +// Rename TEMP_DATALOG_FILENAME to VarsUi.SelectedFilename(user filename) + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + VarsUi.TmpHandle = pMapLoader->pFunc(RENAMEFILE,VarsUi.FilenameBuffer,VarsUi.SelectedFilename,&VarsUi.TmpLength); + VarsUi.State++; + } + break; + + case 2 : // Display saved text + { + if (!cUiFeedback((BMPMAP*)Info,TXT_FB_DL_FILE_SAVED_INFO,0xFF,DISPLAY_SHOW_FILENAME_TIME)) + { + VarsUi.State++; + } + } + break; + + default : + { + cUiMenuPrevFile(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + break; + + } + } + break; + + case MENU_DELETE : // Delete datalog file + { + switch (VarsUi.State) + { + case 0 : + { +// Delete file if exist + sprintf((char*)VarsUi.FilenameBuffer,"%s.%s",(char*)TEMP_DATALOG_FILENAME,(char*)TXT_FILE_EXT[FILETYPE_DATALOG]); + pMapLoader->pFunc(DELETE,VarsUi.FilenameBuffer,NULL,NULL); + VarsUi.State++; + } + break; + + case 1 : + { + pMapDisplay->EraseMask |= (TEXTLINE_BIT(TEXTLINE_3) | TEXTLINE_BIT(TEXTLINE_4) | TEXTLINE_BIT(TEXTLINE_5) | MENUICON_BITS | SPECIAL_BIT(MENUTEXT)); + VarsUi.Timer = DISPLAY_SHOW_TIME; + VarsUi.State++; + } + break; + + case 2 : + { + if (++VarsUi.Timer >= DISPLAY_SHOW_TIME) + { + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_3); + VarsUi.State++; + } + } + break; + + default : + { + VarsUi.State = 0; + } + break; + + } + } + break; + + case MENU_SELECT : // Save sensor + { + pMapDisplay->pTextLines[TEXTLINE_3] = cUiGetString(TXT_VIEW_SELECT); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); + + VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; + IOMapUi.State = EXIT_PRESSED; + } + break; + + default : + { + switch (VarsUi.State) + { + case 0 : + { + if ((Action > MENU_SENSOR_EMPTY) && (Action < MENU_SENSOR_INVALID)) + { + VarsUi.SelectedSensor = Action; + } + if ((Action > MENU_PORT_EMPTY) && (Action < MENU_PORT_INVALID)) + { + VarsUi.SelectedPort = Action; + if (VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] != MENU_SENSOR_EMPTY) + { + + // Port occupied + pMapDisplay->pTextLines[TEXTLINE_4] = cUiGetString(TXT_DATALOGGING_PORT_OCCUPIED); + pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); + pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); + VarsUi.Timer = 0; + VarsUi.State++; + } + } + } + break; + + default : + { + if ((++VarsUi.Timer >= DISPLAY_SHOW_TIME) || (BUTTON_NONE != cUiReadButtons())) + { + pMapDisplay->EraseMask |= TEXTLINE_BIT(TEXTLINE_4); + cUiMenuPrev(); + IOMapUi.State = NEXT_MENU; + VarsUi.State = 0; + } + } + break; + + } + } + break; + + } + + return (VarsUi.State); +} + + //******* cUiRunning ********************************************************** void cUiRunning(UBYTE Action) @@ -2221,7 +2828,6 @@ UBYTE cUiFileDelete(UBYTE Action) } - //******* cUiView ************************************************************ UBYTE cUiView(UBYTE Action) // MENU_INIT @@ -2238,6 +2844,11 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_3); pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_3); pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_SMALL); +// Init ports + for (VarsUi.Tmp = 0;VarsUi.Tmp < DATALOGPORTS;VarsUi.Tmp++) + { + VarsUi.DatalogPort[VarsUi.Tmp] = MENU_SENSOR_EMPTY; + } } break; @@ -2250,17 +2861,18 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT if ((Action >= MENU_PORT_1) && (Action <= MENU_PORT_C)) { VarsUi.SelectedPort = Action; - IOMapUi.Flags |= UI_BUSY; + + VarsUi.DatalogPort[VarsUi.SelectedPort - MENU_PORT_1] = VarsUi.SelectedSensor; - cUiSetupSensor(VarsUi.SelectedPort,VarsUi.SelectedSensor); - cUiResetSensor(VarsUi.SelectedPort,VarsUi.SelectedSensor); + IOMapUi.Flags |= UI_BUSY; pMapDisplay->EraseMask |= SCREEN_BIT(SCREEN_LARGE); pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Display; pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); IOMapUi.Flags |= UI_REDRAW_STATUS; VarsUi.ReadoutTimer = 0;; - VarsUi.Timer = 0; VarsUi.State++; + + VarsUi.SensorReset = TRUE; } } break; @@ -2272,23 +2884,11 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT case 1 : { VarsUi.ReadoutTimer++; - VarsUi.Timer++; - if (VarsUi.Timer == MIN_SENSOR_READ_TIME) - { - // Ask sensors for data - cUiAskSensor(VarsUi.SelectedPort,VarsUi.SelectedSensor); - } - if (VarsUi.Timer >= (MIN_SENSOR_READ_TIME * 2)) - { - // Read sensor data - VarsUi.ViewSampleValid = cUiGetSensorValue(VarsUi.SelectedPort,VarsUi.SelectedSensor,&VarsUi.ViewSampleValue); - VarsUi.Timer = 0; - } - + cUiUpdateSensor(1); if (VarsUi.ReadoutTimer >= DISPLAY_VIEW_UPDATE) { VarsUi.ReadoutTimer = 0; - cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort,VarsUi.SelectedSensor,VarsUi.ViewSampleValid,VarsUi.ViewSampleValue); + cUiPrintSensorInDisplayBuffer(VarsUi.SelectedPort); pMapDisplay->pTextLines[TEXTLINE_4] = VarsUi.DisplayBuffer; pMapDisplay->TextLinesCenterFlags |= TEXTLINE_BIT(TEXTLINE_4); pMapDisplay->UpdateMask |= TEXTLINE_BIT(TEXTLINE_4); @@ -2306,7 +2906,7 @@ UBYTE cUiView(UBYTE Action) // MENU_INIT } if (VarsUi.Tmp == BUTTON_ENTER) { - cUiResetSensor(VarsUi.SelectedPort,VarsUi.SelectedSensor); + VarsUi.SensorReset = TRUE; } } break; @@ -3123,7 +3723,7 @@ UBYTE cUiBtConnect(UBYTE Action) // Select connection no and insert device { if (VarsUi.BTResult == REQPIN) { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_SOUND_EXT); + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); pMapSound->Volume = IOMapUi.Volume; pMapSound->Mode = SOUND_ONCE; pMapSound->Flags |= SOUND_UPDATE; @@ -3363,7 +3963,7 @@ UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_E { case MENU_INIT : // Init time counter and cursor bitmap { - VarsUi.Counter = cUiNVReadPowerOnTimeCount() + 1; + VarsUi.Counter = VarsUi.NVData.PowerdownCode + 1; VarsUi.pTmp = (UBYTE*)Cursor; for (VarsUi.Tmp = 0;(VarsUi.Tmp < SIZE_OF_CURSOR) && (VarsUi.Tmp < (UBYTE)sizeof(Cursor));VarsUi.Tmp++) @@ -3391,8 +3991,9 @@ UBYTE cUiPowerOffTime(UBYTE Action) // MENU_INIT,MENU_LEFT,MENU_RIGHT,MENU_E case MENU_ENTER : // Enter { - cUiNVWritePowerOnTimeCount(VarsUi.Counter - 1); - IOMapUi.SleepTimeout = PowerOffTimeSteps[cUiNVReadPowerOnTimeCount()]; + VarsUi.NVData.PowerdownCode = VarsUi.Counter - 1; + cUiNVWrite(); + IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; Action = MENU_EXIT; } break; @@ -3440,7 +4041,7 @@ UBYTE cUiBTConnectRequest(UBYTE Action) { case 0 : { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_SOUND_EXT); + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_ATTENTION_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); pMapSound->Volume = IOMapUi.Volume; pMapSound->Mode = SOUND_ONCE; pMapSound->Flags |= SOUND_UPDATE; @@ -3714,7 +4315,7 @@ FUNCTION Functions[] = // Use same index as FUNC_NO cUiVolume, cUiFileRun, cUiFileDelete, - 0, + cUiDataLogging, cUiOnBrickProgramming, 0, cUiBTConnectRequest, diff --git a/AT91SAM7S256/Source/Icons.txt b/AT91SAM7S256/Source/Icons.txt index 34218e2..0d58409 100644 --- a/AT91SAM7S256/Source/Icons.txt +++ b/AT91SAM7S256/Source/Icons.txt @@ -1,9 +1,9 @@ const ICON Icons[] = { 0x04,0x00, // Graphics Format - 0x1B,0x00, // Graphics DataSize + 0x1A,0x70, // Graphics DataSize 0x01, // Graphics Count X - 0x60, // Graphics Count Y + 0x5E, // Graphics Count Y 0x18, // Graphics Width 0x18, // Graphics Height 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -45,21 +45,21 @@ const ICON Icons[] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xE0,0x3C,0xC3,0x00,0x00,0x00,0xFF,0x10,0x10,0x82,0x6C,0x10,0x01,0xC6,0x38,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x01,0x02,0x04,0x07,0x00,0x1C,0x14,0x00,0x1C,0x05,0x08,0x04,0x1C,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xC0,0x40,0x40,0x40,0x4F,0xD0,0x50,0x50,0x49,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, + 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x30,0x48,0x48,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xC0,0x40,0x40,0x40,0x5F,0xC4,0x44,0x40,0x40,0x40,0xFC,0x04,0x07,0x05,0x05,0x05,0x07,0x04,0x04,0x07,0x00,0x00, + 0x00,0x00,0x07,0x06,0x06,0x06,0x06,0x07,0x04,0x04,0x04,0x04,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xC0,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x03,0x04,0x04,0x02,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x08,0xF0,0x00,0x00,0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x04,0x7F,0x80,0x00,0x00,0x00,0xE0,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x40,0xA0,0x60,0xA0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xC0,0x30,0x18,0x0F,0x0A,0x0D,0x1A,0x35,0xEA,0xF5,0xFA,0xFF,0xF8,0xF8,0xF0,0xE0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x06,0x04,0x08,0x08,0x08,0x04,0x06,0x01,0x03,0x07,0x07,0x07,0x07,0x03,0x01,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xF8,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x9E,0x91,0x51,0x51,0x51,0x91,0x9E,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3C,0x3C,0x3C,0x24,0x25,0x3D,0x25,0x24,0x3C,0x24,0x24,0x3F,0x00,0x00,0x00,0x00,0x00, @@ -99,8 +99,8 @@ const ICON Icons[] = 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0x10,0x10,0x90,0x50,0x70,0x50,0x70,0x50,0x90,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x1F,0x20,0x20,0x20,0x2F,0x30,0x25,0x28,0x25,0x30,0x2F,0x20,0x20,0x1F,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, - 0x00,0x00,0x00,0xF0,0x10,0xF0,0x10,0xD0,0x10,0x90,0x10,0xD0,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x5F,0x50,0x5F,0x50,0x5F,0x50,0x5C,0x50,0x5F,0x50,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, + 0x00,0x00,0x00,0xF0,0x10,0xF0,0x90,0xD0,0x90,0x10,0x10,0x10,0x10,0x10,0x50,0x10,0x10,0x10,0xF0,0x10,0xF0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x3F,0x40,0x5F,0x50,0x54,0x50,0x52,0x50,0x51,0x50,0x78,0x50,0x40,0x3F,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x1F,0x11,0x1D,0x1D,0x11,0x11,0x11,0x1F,0x10,0x10,0x10,0x0F,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -189,9 +189,9 @@ const ICON Icons[] = 0x00,0x00,0x00,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0xE0,0x20,0x20,0x20,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x03,0x00,0x00,0x03,0x02,0x82,0xCA,0xFB,0x78,0x78,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x00,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00, - 0x00,0x00,0x00,0xFF,0x00,0x92,0x00,0xFF,0x80,0xFE,0x80,0x80,0xFC,0x80,0xF0,0x80,0xFF,0x80,0x00,0xFF,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x0F,0x18,0x18,0x18,0x1A,0x18,0x18,0x1A,0x18,0x18,0x1A,0x18,0x18,0x1A,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00, + 0x00,0x00,0x08,0xFC,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x1F,0x10,0x10,0x13,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x10,0x00,0x00, 0x00,0x00,0x00,0xE0,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0xE0,0x00,0x00,0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x80,0xC0,0xA0,0x90,0x08,0x08,0x90,0xA0,0xC0,0x80,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x1F,0x10,0x10,0x1F,0x02,0x02,0x02,0x02,0x02,0x03,0x01,0x00,0x00,0x00, @@ -287,11 +287,5 @@ const ICON Icons[] = 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x08,0x09,0x08,0x08,0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0xE0,0xE0,0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x79,0x86,0x44,0x28,0x10,0x00,0x01,0x83,0x01,0x00,0x10,0x28,0x44,0xFA,0x01,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x02,0x05,0x08,0x10,0x08,0x04,0x0A,0x09,0x08,0x09,0x06,0x04,0x08,0x10,0x08,0x05,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + 0x00,0x00,0x00,0x00,0x02,0x05,0x08,0x10,0x08,0x04,0x0A,0x09,0x08,0x09,0x06,0x04,0x08,0x10,0x08,0x05,0x02,0x00,0x00,0x00 }; diff --git a/AT91SAM7S256/Source/Mainmenu.rms b/AT91SAM7S256/Source/Mainmenu.rms index f26e744..2e014fb 100644 --- a/AT91SAM7S256/Source/Mainmenu.rms +++ b/AT91SAM7S256/Source/Mainmenu.rms @@ -1,9 +1,9 @@ const UBYTE MAINMENU[] = { 0x07,0x00, // Menu Format - 0x00,0xE8, // Menu DataSize + 0x01,0x05, // Menu DataSize 0x1D, // Menu item size - 0x08, // Menu items + 0x09, // Menu items 0x18, // Menu icon Width 0x18, // Menu icon Height @@ -35,29 +35,36 @@ const UBYTE MAINMENU[] = 0x4E,0x58,0x54,0x20,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x00,0x00,0x00,0x00,0x00, 0x3C, // 3C - // View + // NXT_Datalog 0x00,0x00,0x00,0x31, // 0x00000031 + 0x01,0x84,0x00,0x00, // 0x01840000 + 0x0A,0x00,0x03,0x01, // 10 ,0 ,3 ,1 + 0x4E,0x58,0x54,0x20,0x44,0x61,0x74,0x61,0x6C,0x6F,0x67,0x00,0x00,0x00,0x00,0x00, + 0x3D, // 3D + + // View + 0x00,0x00,0x00,0x41, // 0x00000041 0x01,0x04,0x00,0x00, // 0x01040000 - 0x00,0x00,0x04,0x01, // 0 ,0 ,4 ,1 + 0x0E,0x00,0x04,0x01, // 14 ,0 ,4 ,1 0x56,0x69,0x65,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x3E, // 3E // Bluetooth - 0x00,0x00,0x00,0x41, // 0x00000041 + 0x00,0x00,0x00,0x51, // 0x00000051 0x01,0x04,0x00,0x00, // 0x01040000 0x00,0x00,0x07,0x02, // 0 ,0 ,7 ,2 0x42,0x6C,0x75,0x65,0x74,0x6F,0x6F,0x74,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x51, // 51 // Settings - 0x00,0x00,0x00,0x51, // 0x00000051 + 0x00,0x00,0x00,0x61, // 0x00000061 0x01,0x04,0x00,0x00, // 0x01040000 0x00,0x00,0x05,0x01, // 0 ,0 ,5 ,1 0x53,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x3F, // 3F // Try_Me - 0x00,0x00,0x00,0x61, // 0x00000061 + 0x00,0x00,0x00,0x71, // 0x00000071 0x01,0x04,0x00,0x00, // 0x01040000 0x00,0x00,0x06,0x01, // 0 ,0 ,6 ,1 0x54,0x72,0x79,0x20,0x4D,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/AT91SAM7S256/Source/Submenu03.rms b/AT91SAM7S256/Source/Submenu03.rms index 0dd4b6c..cb7830b 100644 --- a/AT91SAM7S256/Source/Submenu03.rms +++ b/AT91SAM7S256/Source/Submenu03.rms @@ -1,105 +1,98 @@ const UBYTE SUBMENU03[] = { 0x07,0x00, // Menu Format - 0x05,0x19, // Menu DataSize + 0x03,0xA0, // Menu DataSize 0x1D, // Menu item size - 0x2D, // Menu items + 0x20, // Menu items 0x18, // Menu icon Width 0x18, // Menu icon Height - // Sound_dB + // Temperature_`C 0x00,0x00,0x00,0x01, // 0x00000001 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0B,0x00,0x01, // 10 ,11 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, + 0x0F, // 0F + + // Temperature_`F + 0x00,0x00,0x00,0x02, // 0x00000002 + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0C,0x00,0x01, // 10 ,12 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, + 0x10, // 10 + + // Sound_dB + 0x00,0x00,0x00,0x03, // 0x00000003 + 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x02,0x00,0x01, // 10 ,2 ,0 ,1 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x02, // 02 // Sound_dBA - 0x00,0x00,0x00,0x02, // 0x00000002 + 0x00,0x00,0x00,0x04, // 0x00000004 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x03,0x00,0x01, // 10 ,3 ,0 ,1 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03, // 03 // Reflected_light - 0x00,0x00,0x00,0x03, // 0x00000003 + 0x00,0x00,0x00,0x05, // 0x00000005 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x04,0x00,0x01, // 10 ,4 ,0 ,1 0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x65,0x64,0x20,0x6C,0x69,0x67,0x68,0x74,0x00, 0x04, // 04 // Ambient_light - 0x00,0x00,0x00,0x04, // 0x00000004 + 0x00,0x00,0x00,0x06, // 0x00000006 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x05,0x00,0x01, // 10 ,5 ,0 ,1 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, 0x05, // 05 - // Light_sensor* - 0x00,0x00,0x00,0x05, // 0x00000005 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x06,0x00,0x01, // 10 ,6 ,0 ,1 - 0x4C,0x69,0x67,0x68,0x74,0x20,0x73,0x65,0x6E,0x73,0x6F,0x72,0x2A,0x00,0x00,0x00, - 0x06, // 06 - - // Temperature_`C* - 0x00,0x00,0x00,0x06, // 0x00000006 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0D,0x00,0x01, // 10 ,13 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x2A,0x00, - 0x0D, // 0D - - // Temperature_`F* - 0x00,0x00,0x00,0x07, // 0x00000007 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0E,0x00,0x01, // 10 ,14 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x2A,0x00, - 0x0E, // 0E - - // Rotation* - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0A,0x00,0x01, // 10 ,10 ,0 ,1 - 0x52,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x0A, // 0A - // Motor_Rotations - 0x00,0x00,0x00,0x09, // 0x00000009 + 0x00,0x00,0x00,0x07, // 0x00000007 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0A,0x09,0x00,0x01, // 10 ,9 ,0 ,1 + 0x0A,0x08,0x00,0x01, // 10 ,8 ,0 ,1 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x52,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, 0x09, // 09 // Motor_Degrees - 0x00,0x00,0x00,0x0A, // 0x0000000A + 0x00,0x00,0x00,0x08, // 0x00000008 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0A,0x08,0x00,0x01, // 10 ,8 ,0 ,1 + 0x0A,0x07,0x00,0x01, // 10 ,7 ,0 ,1 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x44,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, 0x08, // 08 // Touch - 0x00,0x00,0x00,0x0B, // 0x0000000B + 0x00,0x00,0x00,0x09, // 0x00000009 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x07,0x00,0x01, // 10 ,7 ,0 ,1 + 0x0A,0x06,0x00,0x01, // 10 ,6 ,0 ,1 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x07, // 07 // UltraSonic_inch - 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x00,0x00,0x00,0x0A, // 0x0000000A 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0B,0x00,0x01, // 10 ,11 ,0 ,1 + 0x0A,0x09,0x00,0x01, // 10 ,9 ,0 ,1 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, 0x0B, // 0B // UltraSonic_cm - 0x00,0x00,0x00,0x0D, // 0x0000000D + 0x00,0x00,0x00,0x0B, // 0x0000000B 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0A,0x0C,0x00,0x01, // 10 ,12 ,0 ,1 + 0x0A,0x0A,0x00,0x01, // 10 ,10 ,0 ,1 0x55,0x6C,0x74,0x72,0x61,0x53,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, 0x0C, // 0C + // Color + 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0A,0x0D,0x00,0x01, // 10 ,13 ,0 ,1 + 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11, // 11 + // Done - 0x00,0x00,0x00,0x0E, // 0x0000000E + 0x00,0x00,0x00,0x0D, // 0x0000000D 0x00,0x00,0x00,0x20, // 0x00000020 0x0A,0xEE,0x00,0x01, // 10 ,238,0 ,1 0x44,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -134,189 +127,105 @@ const UBYTE SUBMENU03[] = 0x15, // 15 // Port_A - 0x00,0x00,0x00,0x19, // 0x00000019 + 0x00,0x00,0x00,0x17, // 0x00000017 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x16, // 16 // Port_B - 0x00,0x00,0x00,0x29, // 0x00000029 + 0x00,0x00,0x00,0x27, // 0x00000027 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x17, // 17 // Port_C - 0x00,0x00,0x00,0x39, // 0x00000039 + 0x00,0x00,0x00,0x37, // 0x00000037 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x18, // 18 // Port_A - 0x00,0x00,0x00,0x1A, // 0x0000001A + 0x00,0x00,0x00,0x18, // 0x00000018 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x16,0x00,0x01, // 10 ,22 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x16, // 16 // Port_B - 0x00,0x00,0x00,0x2A, // 0x0000002A + 0x00,0x00,0x00,0x28, // 0x00000028 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x17,0x00,0x01, // 10 ,23 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x17, // 17 // Port_C - 0x00,0x00,0x00,0x3A, // 0x0000003A + 0x00,0x00,0x00,0x38, // 0x00000038 0x10,0x00,0x00,0x21, // 0x10000021 0x0A,0x18,0x00,0x01, // 10 ,24 ,0 ,1 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x17, // 17 - // Logging_time - 0x00,0x00,0x00,0x1E, // 0x0000001E - 0x00,0x00,0x03,0xE0, // 0x000003E0 - 0x0C,0xEF,0x00,0x01, // 12 ,239,0 ,1 - 0x4C,0x6F,0x67,0x67,0x69,0x6E,0x67,0x20,0x74,0x69,0x6D,0x65,0x00,0x00,0x00,0x00, - 0x38, // 38 - - // _ - 0x00,0x00,0x00,0x2E, // 0x0000002E - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - - // _ - 0x00,0x00,0x00,0x3E, // 0x0000003E - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // Logging_Rate - 0x00,0x00,0x01,0x11, // 0x00000111 - 0x00,0x00,0x03,0x68, // 0x00000368 - 0x0C,0xEF,0x00,0x01, // 12 ,239,0 ,1 - 0x4C,0x6F,0x67,0x67,0x69,0x6E,0x67,0x20,0x52,0x61,0x74,0x65,0x00,0x00,0x00,0x00, - 0x38, // 38 - - // _ - 0x00,0x00,0x02,0x11, // 0x00000211 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - // _ - 0x00,0x00,0x03,0x11, // 0x00000311 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // Logging_Rate - 0x00,0x00,0x01,0x19, // 0x00000119 - 0x00,0x00,0x03,0x68, // 0x00000368 - 0x0C,0xEF,0x00,0x01, // 12 ,239,0 ,1 - 0x4C,0x6F,0x67,0x67,0x69,0x6E,0x67,0x20,0x52,0x61,0x74,0x65,0x00,0x00,0x00,0x00, - 0x38, // 38 - - // _ - 0x00,0x00,0x02,0x19, // 0x00000219 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - - // _ - 0x00,0x00,0x03,0x19, // 0x00000319 - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // Logging_Rate - 0x00,0x00,0x01,0x1A, // 0x0000011A - 0x00,0x00,0x03,0x68, // 0x00000368 - 0x0C,0xEF,0x00,0x01, // 12 ,239,0 ,1 - 0x4C,0x6F,0x67,0x67,0x69,0x6E,0x67,0x20,0x52,0x61,0x74,0x65,0x00,0x00,0x00,0x00, - 0x38, // 38 - - // _ - 0x00,0x00,0x02,0x1A, // 0x0000021A - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x35, // 35 - - // _ - 0x00,0x00,0x03,0x1A, // 0x0000031A - 0x00,0x00,0x00,0x00, // 0x00000000 - 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36, // 36 - - // _ - 0x00,0x00,0x01,0x1E, // 0x0000011E + 0x00,0x00,0x00,0x1D, // 0x0000001D 0x00,0x00,0x10,0x00, // 0x00001000 0x0A,0xF7,0x00,0x01, // 10 ,247,0 ,1 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, // 00 // _ - 0x00,0x00,0x11,0x11, // 0x00001111 - 0x0E,0x05,0x10,0x00, // 0x0E051000 + 0x00,0x00,0x01,0x11, // 0x00000111 + 0x0D,0x05,0x10,0x00, // 0x0D051000 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, // 00 // _ - 0x00,0x00,0x11,0x19, // 0x00001119 - 0x0E,0x05,0x10,0x00, // 0x0E051000 + 0x00,0x00,0x01,0x17, // 0x00000117 + 0x0D,0x05,0x10,0x00, // 0x0D051000 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, // 00 // _ - 0x00,0x00,0x11,0x1A, // 0x0000111A - 0x0E,0x05,0x10,0x00, // 0x0E051000 + 0x00,0x00,0x01,0x18, // 0x00000118 + 0x0D,0x05,0x10,0x00, // 0x0D051000 0x0A,0xF2,0x00,0x00, // 10 ,242,0 ,0 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, // 00 // Run - 0x00,0x00,0x11,0x1E, // 0x0000111E - 0x00,0x00,0x00,0x20, // 0x00000020 + 0x00,0x00,0x01,0x1D, // 0x0000011D + 0x00,0x00,0x00,0x68, // 0x00000068 0x0A,0xF8,0x00,0x02, // 10 ,248,0 ,2 0x52,0x75,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x32, // 32 // Main_menu - 0x00,0x01,0x11,0x1E, // 0x0001111E + 0x00,0x00,0x11,0x1D, // 0x0000111D 0x00,0x02,0x20,0x00, // 0x00022000 0x0A,0xF1,0x00,0x00, // 10 ,241,0 ,0 0x4D,0x61,0x69,0x6E,0x20,0x6D,0x65,0x6E,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x37, // 37 // Save - 0x00,0x02,0x11,0x1E, // 0x0002111E + 0x00,0x00,0x21,0x1D, // 0x0000211D 0x00,0x02,0x00,0x00, // 0x00020000 0x0A,0xFA,0x00,0x02, // 10 ,250,0 ,2 0x53,0x61,0x76,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1E, // 1E + 0x1F, // 1F // Yes - 0x00,0x12,0x11,0x1E, // 0x0012111E + 0x00,0x01,0x21,0x1D, // 0x0001211D 0x00,0x00,0x20,0x20, // 0x00002020 0x0A,0xED,0x00,0x00, // 10 ,237,0 ,0 0x59,0x65,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x31, // 31 // No - 0x00,0x22,0x11,0x1E, // 0x0022111E + 0x00,0x02,0x21,0x1D, // 0x0002211D 0x00,0x08,0x00,0x24, // 0x00080024 0x00,0x00,0x00,0x00, // 0 ,0 ,0 ,0 0x4E,0x6F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/AT91SAM7S256/Source/Submenu04.rms b/AT91SAM7S256/Source/Submenu04.rms index 0bfec3e..273e456 100644 --- a/AT91SAM7S256/Source/Submenu04.rms +++ b/AT91SAM7S256/Source/Submenu04.rms @@ -1,15 +1,15 @@ const UBYTE SUBMENU04[] = { 0x07,0x00, // Menu Format - 0x02,0x9B, // Menu DataSize + 0x02,0x7E, // Menu DataSize 0x1D, // Menu item size - 0x17, // Menu items + 0x16, // Menu items 0x18, // Menu icon Width 0x18, // Menu icon Height // Sound_dB 0x00,0x00,0x00,0x01, // 0x00000001 - 0x10,0x00,0x01,0x21, // 0x10000121 + 0x10,0x00,0x00,0x21, // 0x10000021 0x0E,0x02,0x00,0x01, // 14 ,2 ,0 ,1 0x53,0x6F,0x75,0x6E,0x64,0x20,0x64,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x02, // 02 @@ -35,69 +35,62 @@ const UBYTE SUBMENU04[] = 0x41,0x6D,0x62,0x69,0x65,0x6E,0x74,0x20,0x6C,0x69,0x67,0x68,0x74,0x00,0x00,0x00, 0x05, // 05 - // Light_Sensor* + // Temperature_`C 0x00,0x00,0x00,0x05, // 0x00000005 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x06,0x00,0x01, // 14 ,6 ,0 ,1 - 0x4C,0x69,0x67,0x68,0x74,0x20,0x53,0x65,0x6E,0x73,0x6F,0x72,0x2A,0x00,0x00,0x00, - 0x06, // 06 + 0x10,0x00,0x01,0x21, // 0x10000121 + 0x0E,0x0B,0x00,0x01, // 14 ,11 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x00,0x00, + 0x0F, // 0F - // Temperature_`C* + // Temperature_`F 0x00,0x00,0x00,0x06, // 0x00000006 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0D,0x00,0x01, // 14 ,13 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x43,0x2A,0x00, - 0x0D, // 0D - - // Temperature_`F* - 0x00,0x00,0x00,0x07, // 0x00000007 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0E,0x00,0x01, // 14 ,14 ,0 ,1 - 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x2A,0x00, - 0x0E, // 0E - - // Rotation* - 0x00,0x00,0x00,0x08, // 0x00000008 - 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0A,0x00,0x01, // 14 ,10 ,0 ,1 - 0x52,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x0A, // 0A + 0x0E,0x0C,0x00,0x01, // 14 ,12 ,0 ,1 + 0x54,0x65,0x6D,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x60,0x46,0x00,0x00, + 0x10, // 10 // Motor_rotations - 0x00,0x00,0x00,0x09, // 0x00000009 + 0x00,0x00,0x00,0x07, // 0x00000007 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x09,0x00,0x01, // 14 ,9 ,0 ,1 + 0x0E,0x08,0x00,0x01, // 14 ,8 ,0 ,1 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x72,0x6F,0x74,0x61,0x74,0x69,0x6F,0x6E,0x73,0x00, 0x09, // 09 // Motor_degrees - 0x00,0x00,0x00,0x0A, // 0x0000000A + 0x00,0x00,0x00,0x08, // 0x00000008 0x00,0x00,0x00,0x20, // 0x00000020 - 0x0E,0x08,0x00,0x01, // 14 ,8 ,0 ,1 + 0x0E,0x07,0x00,0x01, // 14 ,7 ,0 ,1 0x4D,0x6F,0x74,0x6F,0x72,0x20,0x64,0x65,0x67,0x72,0x65,0x65,0x73,0x00,0x00,0x00, 0x08, // 08 // Touch - 0x00,0x00,0x00,0x0B, // 0x0000000B + 0x00,0x00,0x00,0x09, // 0x00000009 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x07,0x00,0x01, // 14 ,7 ,0 ,1 + 0x0E,0x06,0x00,0x01, // 14 ,6 ,0 ,1 0x54,0x6F,0x75,0x63,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x07, // 07 // Ultrasonic_inch - 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x00,0x00,0x00,0x0A, // 0x0000000A 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0B,0x00,0x01, // 14 ,11 ,0 ,1 + 0x0E,0x09,0x00,0x01, // 14 ,9 ,0 ,1 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x69,0x6E,0x63,0x68,0x00, 0x0B, // 0B // Ultrasonic_cm - 0x00,0x00,0x00,0x0D, // 0x0000000D + 0x00,0x00,0x00,0x0B, // 0x0000000B 0x10,0x00,0x00,0x21, // 0x10000021 - 0x0E,0x0C,0x00,0x01, // 14 ,12 ,0 ,1 + 0x0E,0x0A,0x00,0x01, // 14 ,10 ,0 ,1 0x55,0x6C,0x74,0x72,0x61,0x73,0x6F,0x6E,0x69,0x63,0x20,0x63,0x6D,0x00,0x00,0x00, 0x0C, // 0C + // Color + 0x00,0x00,0x00,0x0C, // 0x0000000C + 0x10,0x00,0x00,0x21, // 0x10000021 + 0x0E,0x0D,0x00,0x01, // 14 ,13 ,0 ,1 + 0x43,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11, // 11 + // Port_1 0x00,0x00,0x00,0x11, // 0x00000011 0x00,0x00,0x00,0x20, // 0x00000020 @@ -127,42 +120,42 @@ const UBYTE SUBMENU04[] = 0x15, // 15 // Port_A - 0x00,0x00,0x00,0x19, // 0x00000019 + 0x00,0x00,0x00,0x17, // 0x00000017 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x16, // 16 // Port_B - 0x00,0x00,0x00,0x29, // 0x00000029 + 0x00,0x00,0x00,0x27, // 0x00000027 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x17, // 17 // Port_C - 0x00,0x00,0x00,0x39, // 0x00000039 + 0x00,0x00,0x00,0x37, // 0x00000037 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x18, // 18 // Port_A - 0x00,0x00,0x00,0x1A, // 0x0000001A + 0x00,0x00,0x00,0x18, // 0x00000018 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x16,0x00,0x00, // 14 ,22 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x16, // 16 // Port_B - 0x00,0x00,0x00,0x2A, // 0x0000002A + 0x00,0x00,0x00,0x28, // 0x00000028 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x17,0x00,0x00, // 14 ,23 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x17, // 17 // Port_C - 0x00,0x00,0x00,0x3A, // 0x0000003A + 0x00,0x00,0x00,0x38, // 0x00000038 0x00,0x00,0x00,0x20, // 0x00000020 0x0E,0x18,0x00,0x00, // 14 ,24 ,0 ,0 0x50,0x6F,0x72,0x74,0x20,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/AT91SAM7S256/Source/Ui.txt b/AT91SAM7S256/Source/Ui.txt index e3f736d..6db746e 100644 --- a/AT91SAM7S256/Source/Ui.txt +++ b/AT91SAM7S256/Source/Ui.txt @@ -1,9 +1,9 @@ const TXT Ui[] = { 0x05,0x00, // Text Format - 0x03,0x63, // Text DataSize + 0x04,0x0D, // Text DataSize 0x01, // ItemsX - 0x33, // ItemsY + 0x3D, // ItemsY 0x11, // ItemCharsX 0x01, // ItemCharsY 'C','o','n','n','e','c','t','i','n','g', 0 , 0 , 0 , 0 , 0 , 0 , 0 , @@ -25,6 +25,9 @@ const TXT Ui[] = 'F','i','l','e',' ','s','a','v','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'F','i','l','e',' ','e','x','i','s','t','s', 0 , 0 , 0 , 0 , 0 , 0 , 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'S','a','v','e','d',' ','a','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'F','i','l','e',' ','e','x','i','s','t', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'o','v','e','r','w','r','i','t','e','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'F','i','l','e',' ','d','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , 'F','i','l','e','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'd','e','l','e','t','e','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , @@ -34,6 +37,11 @@ const TXT Ui[] = 'F','i','l','e',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , 'D','e','l','e','t','i','n','g',' ','a','l','l', 0 , 0 , 0 , 0 , 0 , '%','s',' ','f','i','l','e','s','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'P','r','e','s','s',' ','C','l','e','a','r',' ','t','o', 0 , 0 , 0 , + 's','t','o','p',' ','D','a','t','a','L','o','g','g','i','n','g', 0 , + 'P','o','r','t',' ','o','c','c','u','p','i','e','d','!', 0 , 0 , 0 , + 'H',':','M','M',':','S','S',':','0','0', 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'H','H',':','M','M',':','S','S', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'S','o','u','n','d', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'S','o','f','t','w','a','r','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'N','X','T', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , @@ -56,5 +64,7 @@ const TXT Ui[] = 'f','u','l','l',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , 0 , 'B','T',' ','u','n','k','n','o','w','n', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'a','d','d','r','.',' ','e','r','r','o','r','!', 0 , 0 , 0 , 0 , 0 , + 'M','e','m','o','r','y',' ','i','s', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 'f','u','l','l','!', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 'N','e','v','e','r', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; diff --git a/AT91SAM7S256/Source/c_button.c b/AT91SAM7S256/Source/c_button.c index d702dd1..3145d8f 100644 --- a/AT91SAM7S256/Source/c_button.c +++ b/AT91SAM7S256/Source/c_button.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_button.c $ // -// Version $Revision:: 16 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_button.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_button.h b/AT91SAM7S256/Source/c_button.h index abb1b2b..c33b24d 100644 --- a/AT91SAM7S256/Source/c_button.h +++ b/AT91SAM7S256/Source/c_button.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_button.h $ // -// Version $Revision:: 6 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_button.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_button.iom b/AT91SAM7S256/Source/c_button.iom index 24064a2..640a7cd 100644 --- a/AT91SAM7S256/Source/c_button.iom +++ b/AT91SAM7S256/Source/c_button.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_button.iom $ // -// Version $Revision:: 10 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_button.i $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_cmd.c b/AT91SAM7S256/Source/c_cmd.c index 9b83c14..4ce9829 100644 --- a/AT91SAM7S256/Source/c_cmd.c +++ b/AT91SAM7S256/Source/c_cmd.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 28-03-07 14:53 $ +// Revision date $Date: 24-06-09 8:53 $ // // Filename $Workfile:: c_cmd.c $ // -// Version $Revision:: 67 $ +// Version $Revision: 14 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ // // Platform C // @@ -15,7 +15,7 @@ // // File Description: // This file contains the virtual machine implementation to run bytecode -// programs compatible with LEGO MINDSTORMS NXT Software 1.0. +// programs compatible with LEGO MINDSTORMS NXT Software 2.0. // // This module (c_cmd) is also responsible for reading the system timer // (d_timer) and returning on 1 ms timer boundaries. @@ -34,6 +34,7 @@ #include "c_display.iom" #include "c_comm.iom" #include "c_lowspeed.iom" +#include "m_sched.h" #include "c_cmd.h" #include "c_cmd_bytecodes.h" @@ -41,11 +42,41 @@ #include #include #include +#include // for sqrt, abs, and trig stuff +#define VMProfilingCode 0 static IOMAPCMD IOMapCmd; static VARSCMD VarsCmd; static HEADER **pHeaders; +static ULONG gInstrsToExecute; +static SLONG gPCDelta; +#define NUM_INTERP_FUNCS 16 +#define NUM_SHORT_INTERP_FUNCS 8 +#define VAR_INSTR_SIZE 0xE +// important to cast since most args are assigned from signed value, and locals may be ULONG +#define GetDataArg(arg) ((UWORD)(arg)) +#if VMProfilingCode +static ULONG ExecutedInstrs= 0, CmdCtrlTime= 0, OverheadTime= 0, CmdCtrlCalls= 0, LeaveTime= 0, NotFirstCall= 0, LastAvgCount= 0; +static ULONG CmdCtrlClumpTime[256]; +typedef struct { + ULONG Time; + ULONG Count; + ULONG Avg; + ULONG Max; +} VMInstrProfileInfo; +static VMInstrProfileInfo InstrProfile[OPCODE_COUNT]; +static VMInstrProfileInfo SysCallProfile[SYSCALL_COUNT]; +static VMInstrProfileInfo InterpFuncProfile[NUM_INTERP_FUNCS]; +static VMInstrProfileInfo ShortInstrProfile[NUM_SHORT_OPCODE_COUNT]; +#endif + +#define cCmdDSType(Arg) (VarsCmd.pDataspaceTOC[(Arg)].TypeCode) +#define cCmdDSScalarPtr(DSElementID, Offset) (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[DSElementID].DSOffset + Offset) +#define cCmdSizeOf(TC) (TC_Size_Table[(TC)]) + +#define scalarBinopDispatchMask 0x1 +#define scalarUnop2DispatchMask 0x2 const HEADER cCmd = { @@ -67,22 +98,60 @@ const HEADER cCmd = // (the graphics implementation was split off for practical file management reasons) #include "c_cmd_drawing.inc" - // //Function pointers to sub-interpreters -//This table is indexed by arity +//This table is indexed by instr size //Unary operations can have arity of 1 or 2 (some need a destination) //All instructions taking 4 or more operands are handled as "Other" +// Table uses NoArg for illegal instr sizes such as zero and odd sizes // -static pInterp InterpFuncs[INTERP_COUNT] = +static pInterp InterpFuncs[NUM_INTERP_FUNCS] = { cCmdInterpNoArg, - cCmdInterpUnop1, - cCmdInterpUnop2, - cCmdInterpBinop, - cCmdInterpOther + cCmdInterpNoArg, + cCmdInterpNoArg, // size 2 + cCmdInterpNoArg, + cCmdInterpUnop1, // size 4 + cCmdInterpNoArg, + cCmdInterpUnop2, // size 6 general poly is cCmdInterpUnop2, scalar is cCmdInterpScalarUnop2 + cCmdInterpNoArg, + cCmdInterpBinop, // size 8, general poly is cCmdInterpBinop, scalar is cCmdInterpScalarBinop + cCmdInterpNoArg, + cCmdInterpOther, // size 10 + cCmdInterpNoArg, + cCmdInterpOther, // size 12 + cCmdInterpNoArg, + cCmdInterpOther, // size 14 + cCmdInterpNoArg +}; + +static pInterpShort ShortInterpFuncs[NUM_SHORT_INTERP_FUNCS] = +{ + cCmdInterpShortMove, + cCmdInterpShortAcquire, + cCmdInterpShortRelease, + cCmdInterpShortSubCall, + cCmdInterpShortError, + cCmdInterpShortError, + cCmdInterpShortError, + cCmdInterpShortError }; +ULONG TC_Size_Table[]= { + 0, // void + SIZE_UBYTE, + SIZE_SBYTE, + SIZE_UWORD, + SIZE_SWORD, + SIZE_ULONG, + SIZE_SLONG, + SIZE_UWORD, // array + 0, // cluster + SIZE_MUTEX, + SIZE_FLOAT +}; + + // //Function pointers to SysCall implementations //See interpreter for OP_SYSCALL @@ -94,35 +163,51 @@ static pSysCall SysCallFuncs[SYSCALL_COUNT] = cCmdWrapFileOpenAppend, cCmdWrapFileRead, cCmdWrapFileWrite, - cCmdWrapFileClose, + cCmdWrapFileClose, // 5 cCmdWrapFileResolveHandle, cCmdWrapFileRename, cCmdWrapFileDelete, cCmdWrapSoundPlayFile, - cCmdWrapSoundPlayTone, + cCmdWrapSoundPlayTone, // 10 cCmdWrapSoundGetState, cCmdWrapSoundSetState, cCmdWrapDrawText, cCmdWrapDrawPoint, - cCmdWrapDrawLine, + cCmdWrapDrawLine, // 15 cCmdWrapDrawCircle, cCmdWrapDrawRect, cCmdWrapDrawPicture, cCmdWrapSetScreenMode, - cCmdWrapReadButton, + cCmdWrapReadButton, // 20 cCmdWrapCommLSWrite, cCmdWrapCommLSRead, cCmdWrapCommLSCheckStatus, cCmdWrapRandomNumber, - cCmdWrapGetStartTick, + cCmdWrapGetStartTick, // 25 cCmdWrapMessageWrite, cCmdWrapMessageRead, cCmdWrapCommBTCheckStatus, cCmdWrapCommBTWrite, - cCmdWrapCommBTRead, + cCmdWrapCommBTRead, // 30 cCmdWrapKeepAlive, cCmdWrapIOMapRead, - cCmdWrapIOMapWrite + cCmdWrapIOMapWrite, + cCmdWrapColorSensorRead, + cCmdWrapCommBTOnOff, // 35 + cCmdWrapCommBTConnection, + cCmdWrapCommHSWrite, + cCmdWrapCommHSRead, + cCmdWrapCommHSCheckStatus, + cCmdWrapReadSemData, //40 + cCmdWrapWriteSemData, + cCmdWrapComputeCalibValue, + cCmdWrapUpdateCalibCacheInfo, + cCmdWrapDatalogWrite, + cCmdWrapDatalogGetTimes, //45 + cCmdWrapSetSleepTimeout, + cCmdWrapListFiles //47 + + // don't forget to update SYSCALL_COUNT in c_cmd.h }; // @@ -234,6 +319,39 @@ void ** IO_PTRS[2] = IO_PTRS_OUT }; +// Data used to indicate usage of motor ports, or usage requests +UBYTE gUsageSemData, gRequestSemData; + +UBYTE cCmdBTGetDeviceType(UBYTE *pCOD) +{ + ULONG COD; + UBYTE Result; + UBYTE Tmp; + + COD = 0; + for (Tmp = 0;Tmp < SIZE_OF_CLASS_OF_DEVICE;Tmp++) + { + COD <<= 8; + COD |= (ULONG)*pCOD; + pCOD++; + } + + Result = DEVICETYPE_UNKNOWN; + if ((COD & 0x00001FFF) == 0x00000804) + { + Result = DEVICETYPE_NXT; + } + if ((COD & 0x00001F00) == 0x00000200) + { + Result = DEVICETYPE_PHONE; + } + if ((COD & 0x00001F00) == 0x00000100) + { + Result = DEVICETYPE_PC; + } + + return (Result); +} //cCmdHandleRemoteCommands is the registered handler for "direct" command protocol packets //It is only intended to be called via c_comm's main protocol handler @@ -311,7 +429,7 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen) case RC_PLAY_SOUND_FILE: { - if (LOADER_ERR(pMapLoader->pFunc(FINDFIRST, (&pInBuf[2]), NULL, NULL)) != SUCCESS) + if (LOADER_ERR(LStatus = pMapLoader->pFunc(FINDFIRST, (&pInBuf[2]), NULL, NULL)) != SUCCESS) { RCStatus = ERR_RC_ILLEGAL_VAL; break; @@ -735,6 +853,159 @@ UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen) } break; + // remote-only command to read from datalog buffer + // pInBuf[1] = Remove? (bool) + case RC_DATALOG_READ: + { + if (SendResponse == TRUE) + { + RCStatus = cCmdDatalogGetSize(&Count); + pOutBuf[ResponseLen] = Count; + ResponseLen++; + + if (!IS_ERR(RCStatus) && Count > 0) + { + pData = &(pOutBuf[ResponseLen]); + RCStatus = cCmdDatalogRead(pData, Count, (pInBuf[1])); + //If cCmdDatalogRead encountered an error, there is no real data in the buffer, so clear it out (below) + if (IS_ERR(RCStatus)) + Count = 0; + else + ResponseLen += Count; + } + + //Pad remaining data bytes with zeroes + Count = MAX_DATALOG_SIZE - Count; + memset(&(pOutBuf[ResponseLen]), 0, Count); + ResponseLen += Count; + } + } + break; + case RC_DATALOG_SET_TIMES: + { + //SyncTime SLONG + memcpy((PSZ)&IOMapCmd.SyncTime, (PSZ)&(pInBuf[1]), 4); + IOMapCmd.SyncTick= dTimerReadNoPoll(); + } + break; + + case RC_BT_GET_CONN_COUNT: + if (SendResponse == TRUE) { + pOutBuf[ResponseLen]= SIZE_OF_BT_CONNECT_TABLE; + ResponseLen++; + } + break; + case RC_BT_GET_CONN_NAME: // param in is index, param out is name + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + if(i < SIZE_OF_BT_CONNECT_TABLE) { // unsigned, so guaranteed >= 0 + pOutBuf[ResponseLen] = cCmdBTGetDeviceType(pMapComm->BtConnectTable[i].ClassOfDevice); + memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtConnectTable[i].Name), SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + else { + pOutBuf[ResponseLen] = 0; + ResponseLen += SIZE_OF_BT_NAME + 2; + } + } + break; + case RC_BT_GET_CONTACT_COUNT: + if (SendResponse == TRUE) { + pOutBuf[ResponseLen]= SIZE_OF_BT_DEVICE_TABLE; + ResponseLen++; + } + break; + case RC_BT_GET_CONTACT_NAME: + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + if(i < SIZE_OF_BT_DEVICE_TABLE && (pMapComm->BtDeviceTable[i].DeviceStatus & BT_DEVICE_KNOWN)) { // unsigned, so guaranteed >= 0 + (pOutBuf[ResponseLen])= cCmdBTGetDeviceType(pMapComm->BtDeviceTable[i].ClassOfDevice); + memcpy((PSZ)(&(pOutBuf[ResponseLen+1])), (PSZ)(pMapComm->BtDeviceTable[i].Name), SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + else + { + pOutBuf[ResponseLen] = 0; + memset((PSZ)(&(pOutBuf[ResponseLen+1])), 0, SIZE_OF_BT_NAME + 1); + ResponseLen += SIZE_OF_BT_NAME + 2; + } + } + break; + case RC_SET_PROPERTY: // label/value pairs + i = pInBuf[1]; + switch(i) { + case RC_PROP_BTONOFF: { + UWORD retVal, status; + if(pInBuf[2]) + status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); + else + status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); + + RCStatus= (status == SUCCESS) ? retVal : status; + } + break; + case RC_PROP_SOUND_LEVEL: { + UBYTE volume= pInBuf[2]; + if(volume > 4) + volume= 4; + pMapSound->Volume= volume; // apparently stored in two places + pMapUi->Volume= volume; + } + break; + case RC_PROP_SLEEP_TIMEOUT: { // ulong millisecs to sleep + ULONG value; + memcpy((PSZ)&value, (PSZ)&(pInBuf[2]), 4); + pMapUi->SleepTimeout= value / 60000; + } + break; + default: + //Unknown property -- still inform client to not expect any response bytes + NXT_BREAK; + RCStatus = ERR_RC_UNKNOWN_CMD; + break; + } + break; + case RC_GET_PROPERTY: // label/value pairs + if (SendResponse == TRUE) { // get index from inbuf + i = pInBuf[1]; + switch(i) { + case RC_PROP_BTONOFF: + pOutBuf[ResponseLen]= pMapUi->BluetoothState != BT_STATE_OFF; + ResponseLen++; + break; + case RC_PROP_SOUND_LEVEL: { + pOutBuf[ResponseLen]= pMapSound->Volume; + ResponseLen++; + } + break; + case RC_PROP_SLEEP_TIMEOUT: { + ULONG value= (pMapUi->SleepTimeout * 60 * 1000); + memcpy((PSZ)&(pOutBuf[ResponseLen]), (PSZ)&value, 4); + ResponseLen += 4; + } + break; + default: + //Unknown property -- still inform client to not expect any response bytes + NXT_BREAK; + RCStatus = ERR_RC_UNKNOWN_CMD; + break; + } + } + break; + case RC_UPDATE_RESET_COUNT: + { + i = pInBuf[1]; + + //Don't do anything if illegal port specification is made + if (i >= NO_OF_OUTPUTS) + { + RCStatus = ERR_RC_ILLEGAL_VAL; + break; + } + + pMapOutPut->Outputs[i].Flags |= UPDATE_RESET_COUNT; + } + break; default: { //Unknown remote command -- still inform client to not expect any response bytes @@ -884,6 +1155,8 @@ void cCmdInit(void* pHeader) dTimerInit(); IOMapCmd.Tick = dTimerRead(); + IOMapCmd.SyncTime= 0; + IOMapCmd.SyncTick= 0; return; } @@ -891,13 +1164,113 @@ void cCmdInit(void* pHeader) void cCmdCtrl(void) { - UBYTE Continue = TRUE; NXT_STATUS Status = NO_ERR; - ULONG i; - CLUMP_ID CurrClumpID; switch (VarsCmd.VMState) { + case VM_RUN_FREE: + case VM_RUN_SINGLE: + { + #if VMProfilingCode + ULONG EnterTime= dTimerReadHiRes(), FinishTime; + CmdCtrlCalls ++; +#endif + ULONG Continue; + +#if VM_BENCHMARK + //IOMapCmd.Tick currently holds the tick from the end of last cCmdCtrl call. + //If we don't come back here before dTimerRead() increments, the m_sched loop has taken *at least* 1 ms. + if (IOMapCmd.Tick != dTimerRead()) + { + VarsCmd.OverTimeCount++; + //Record maximum magnitude of schedule loop overage, in millisecs + if (dTimerRead() - IOMapCmd.Tick > VarsCmd.MaxOverTimeLength) + VarsCmd.MaxOverTimeLength = dTimerRead() - IOMapCmd.Tick; + } + VarsCmd.CmdCtrlCount++; +#endif + //Abort current program if cancel button is pressed + if (IOMapCmd.DeactivateFlag == TRUE || pMapButton->State[BTN1] & PRESSED_EV) + { + IOMapCmd.DeactivateFlag = FALSE; + + //Clear pressed event so it doesn't get double-counted by UI + pMapButton->State[BTN1] &= ~PRESSED_EV; + + //Go to VM_RESET1 state and report abort + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_ABORT; + break; + } + + //Assert that we have an active program + NXT_ASSERT(VarsCmd.ActiveProgHandle != NOT_A_HANDLE); + + //Handle any resting clumps that are ready to awaken + cCmdCheckRestQ(IOMapCmd.Tick); // not using result, yet + //Execute from at least one clump + do + { + //Execute instructions from a clump up to INSTR_MAX, to end of millisec, + //Finishing/suspending a clump, BREAKOUT_REQ, or any errors will cause a return +#if VMProfilingCode + ULONG ClumpEnterTime= dTimerReadHiRes(); + CLUMP_ID clump= VarsCmd.RunQ.Head; +#endif + Status = cCmdInterpFromClump(); +#if VMProfilingCode + CmdCtrlClumpTime[clump] += dTimerReadHiRes() - ClumpEnterTime; +#endif + + //If RunQ and RestQ are empty, program is done, or wacko + if (!cCmdIsClumpIDSane(VarsCmd.RunQ.Head)) { + Continue = FALSE; + if(!cCmdIsClumpIDSane(VarsCmd.RestQ.Head)) { + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_OK; + } + } + else if (Status == CLUMP_SUSPEND || Status == CLUMP_DONE) + Continue = TRUE; // queue isn't empty, didn't timeout + //Only rotate RunQ on a "normal" finish, i.e. no error, clump end, or breakout request + else if (Status == ROTATE_QUEUE) { // done and suspend do their own + cCmdRotateQ(); + Continue= TRUE; + } + else if (Status == TIMES_UP) { + cCmdRotateQ(); + Continue = FALSE; + } + else if (IS_ERR(Status)) // mem error is handled in InterpFromClump if possible + { + Continue = FALSE; + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_ERROR; + } + else if (Status == STOP_REQ) + { + Continue = FALSE; + VarsCmd.VMState = VM_RESET1; + IOMapCmd.ProgStatus = PROG_OK; + } + else if (Status == BREAKOUT_REQ) + { + Continue = FALSE; + } + } while (Continue == TRUE); +#if VMProfilingCode + FinishTime= dTimerReadHiRes(); + if(NotFirstCall) + OverheadTime += EnterTime - LeaveTime; + else + NotFirstCall= 1; + CmdCtrlTime += FinishTime - EnterTime; + LeaveTime= FinishTime; +#endif + // May busy wait to postpone to 1ms schedule + while (IOMapCmd.Tick == dTimerRead()); + } + break; case VM_IDLE: { //If there's a new program to activate... @@ -922,6 +1295,10 @@ void cCmdCtrl(void) VarsCmd.VMState = VM_RUN_FREE; IOMapCmd.ProgStatus = PROG_RUNNING; VarsCmd.StartTick = IOMapCmd.Tick; + if(VarsCmd.VMState == VM_RUN_FREE) + gInstrsToExecute = 20; + else + gInstrsToExecute= 1; #if VM_BENCHMARK //Re-init benchmark @@ -942,9 +1319,9 @@ void cCmdCtrl(void) pMapUi->Flags |= (UI_DISABLE_LEFT_RIGHT_ENTER | UI_DISABLE_EXIT); } } - - break; + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time } + break; //Initialize VM internal state data and devices which must respond immediately to program ending case VM_RESET1: @@ -985,6 +1362,7 @@ void cCmdCtrl(void) VarsCmd.CommStatReset = (SWORD)BTBUSY; VarsCmd.VMState = VM_RESET2; + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time } break; @@ -1012,164 +1390,51 @@ void cCmdCtrl(void) VarsCmd.VMState = VM_IDLE; IOMapCmd.ProgStatus = PROG_IDLE; } - break; + while (IOMapCmd.Tick == dTimerRead()); // delay until scheduled time } + break; + }//END state machine switch - case VM_RUN_FREE: - case VM_RUN_SINGLE: - { + //Set tick to new value for next time 'round + IOMapCmd.Tick = dTimerReadNoPoll(); -#if VM_BENCHMARK - //IOMapCmd.Tick currently holds the tick from the end of last cCmdCtrl call. - //If we don't come back here before dTimerRead() increments, the m_sched loop has taken *at least* 1 ms. - if (IOMapCmd.Tick != dTimerRead()) - { - VarsCmd.OverTimeCount++; - //Record maximum magnitude of schedule loop overage, in millisecs - if (dTimerRead() - IOMapCmd.Tick > VarsCmd.MaxOverTimeLength) - VarsCmd.MaxOverTimeLength = dTimerRead() - IOMapCmd.Tick; - } - VarsCmd.CmdCtrlCount++; -#endif - //Abort current program if cancel button is pressed - if (IOMapCmd.DeactivateFlag == TRUE || pMapButton->State[BTN1] & PRESSED_EV) - { - IOMapCmd.DeactivateFlag = FALSE; + return; +} - //Clear pressed event so it doesn't get double-counted by UI - pMapButton->State[BTN1] &= ~PRESSED_EV; - //Go to VM_RESET1 state and report abort - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_ABORT; - break; - } +void cCmdExit(void) +{ + dTimerExit(); - //Assert that we have an active program - NXT_ASSERT(VarsCmd.ActiveProgHandle != NOT_A_HANDLE); + return; +} - //Execute from at least one clump - do - { - if (cCmdIsClumpIDSane(VarsCmd.RunQ.Head)) - { - //Stash and dequeue RunQ's head clump - CurrClumpID = VarsCmd.RunQ.Head; - - //Execute at least one instruction from current clump - //Execute up to 'Priority' instructions as long as we are in VM_FREE_RUN mode - //Finishing/suspending a clump, BREAKOUT_REQ, or any errors will also end this loop - i = 0; - do - { - //Interpret one instruction per call, advancing PC as needed - Status = cCmdInterpFromClump(CurrClumpID); -#if VM_BENCHMARK - VarsCmd.InstrCount++; -#endif +NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, + PROG_FILE_OFFSETS* pFileOffsets) +{ + ULONG i; + UBYTE * pCursor; + UWORD CurrOffset = 0; + UBYTE DepCount; + UWORD DopeVectorOffset; + UWORD FileClumpCount; + UBYTE FileMajor, FileMinor, + CompatibleMinor, CompatibleMajor, + CurrentMajor; - NXT_ASSERT(!IS_ERR(Status)); - if (IS_ERR(Status) || Status == CLUMP_DONE || Status == CLUMP_SUSPEND || Status == BREAKOUT_REQ || Status == STOP_REQ) - { - //We're done with this clump or breaking out prematurely, - //so break the multi-instruction loop - break; - } - else - { - //Count up one more instruction for this pass - i++; - } - } while (VarsCmd.VMState == VM_RUN_FREE && i < VarsCmd.pAllClumps[CurrClumpID].Priority); + NXT_ASSERT(pData != NULL); - //Only rotate RunQ on a "normal" finish, i.e. no error, clump end, or breakout request - if (!(IS_ERR(Status) || Status == CLUMP_DONE || Status == CLUMP_SUSPEND || Status == BREAKOUT_REQ)) - cCmdRotateQ(&(VarsCmd.RunQ)); - } + //Assign pCursor to point to version word inside file header + pCursor = (pData + VM_FORMAT_STRING_SIZE - 2); - //Re-evaluate conditions for stopping the dataflow scheduler - //Halt program on all errors - if (IS_ERR(Status)) - { - Continue = FALSE; - - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_ERROR; - } - else if (Status == BREAKOUT_REQ) - { - Continue = FALSE; - } - //If RunQ is empty or user requested early termination, program is done - else if (!cCmdIsClumpIDSane(VarsCmd.RunQ.Head) || Status == STOP_REQ) - { - Continue = FALSE; - - VarsCmd.VMState = VM_RESET1; - IOMapCmd.ProgStatus = PROG_OK; - } - //VM_RUN_FREE means continue executing until a new ms tick rolls over - else if (VarsCmd.VMState == VM_RUN_FREE) - { - Continue = (IOMapCmd.Tick == dTimerRead()); - } - //Otherwise execute only one pass per call - else //VarsCmd.VMState == VM_RUN_SINGLE - { - VarsCmd.VMState = VM_RUN_PAUSE; - Continue = FALSE; - } - - } while (Continue == TRUE); - - break; - } - }//END state machine switch - - //Busy wait to always maintain 1ms period - BUSY_WAIT_NEXT_MS; - - //Set tick to new value for next time 'round - IOMapCmd.Tick = dTimerRead(); - - return; -} - - -void cCmdExit(void) -{ - dTimerExit(); - - return; -} - - -NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, - PROG_FILE_OFFSETS* pFileOffsets) -{ - ULONG i; - UBYTE * pCursor; - UWORD CurrOffset = 0; - UBYTE DepCount; - UWORD DopeVectorOffset; - UWORD FileClumpCount; - UBYTE FileMajor, FileMinor, - CompatibleMinor, CompatibleMajor, - CurrentMajor; - - NXT_ASSERT(pData != NULL); - - //Assign pCursor to point to version word inside file header - pCursor = (pData + VM_FORMAT_STRING_SIZE - 2); - - //Decode version numbers into comparable bytes - FileMajor = *pCursor; - FileMinor = *(pCursor + 1); - CompatibleMajor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION >> 8); - CompatibleMinor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION); - CurrentMajor = (UBYTE)(FIRMWAREVERSION >> 8); - //CurrentMinor = (UBYTE)(FIRMWAREVERSION); + //Decode version numbers into comparable bytes + FileMajor = *pCursor; + FileMinor = *(pCursor + 1); + CompatibleMajor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION >> 8); + CompatibleMinor = (UBYTE)(VM_OLDEST_COMPATIBLE_VERSION); + CurrentMajor = (UBYTE)(FIRMWAREVERSION >> 8); + //CurrentMinor = (UBYTE)(FIRMWAREVERSION); //Return ERR_VER if file lacks proper format string or version number //!!! Only checking major version recommended for future development @@ -1280,6 +1545,8 @@ NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize, VarsCmd.RunQ.Head = NOT_A_CLUMP; VarsCmd.RunQ.Tail = NOT_A_CLUMP; + VarsCmd.RestQ.Head = NOT_A_CLUMP; + VarsCmd.RestQ.Tail = NOT_A_CLUMP; //Reset codespace pointer VarsCmd.pCodespace = (CODE_WORD*)(pData + pFileOffsets->Codespace); @@ -1325,7 +1592,9 @@ NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ TypeCode = cCmdDSType(DSElementID); - if (TypeCode == TC_CLUSTER) + if (TypeCode > TC_LAST_VALID) + return ERR_INSTR; + else if (TypeCode == TC_CLUSTER) { Count = cCmdClusterCount(DSElementID); //Advance DSElementID to sub-type @@ -1369,6 +1638,19 @@ NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ return Status; } +void cCmdRefreshActiveClump(CLUMP_ID CurrID) +{ + CLUMP_REC * clumpRecPtr= &(VarsCmd.pAllClumps[CurrID]); + + if(clumpRecPtr->clumpScalarDispatchHints & scalarBinopDispatchMask) + InterpFuncs[8]= cCmdInterpScalarBinop; + else + InterpFuncs[8]= cCmdInterpBinop; + if(clumpRecPtr->clumpScalarDispatchHints & scalarUnop2DispatchMask) + InterpFuncs[6]= cCmdInterpScalarUnop2; + else + InterpFuncs[6]= cCmdInterpUnop2; +} NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) { @@ -1427,18 +1709,18 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) pCursor = (pData + FileOffsets.Clumps); for (i = 0; i < VarsCmd.AllClumpsCount; i++) { - VarsCmd.pAllClumps[i].InitFireCount = *(UBYTE*)(pCursor + i * VM_FILE_CLUMP_REC_SIZE); - VarsCmd.pAllClumps[i].DependentCount = *(UBYTE*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 1); - VarsCmd.pAllClumps[i].CodeStart = *(UWORD*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 2); + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + clumpPtr->InitFireCount = *(UBYTE*)(pCursor + i * VM_FILE_CLUMP_REC_SIZE); + clumpPtr->DependentCount = *(UBYTE*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 1); + clumpPtr->CodeStart = *(UWORD*)(pCursor + (i * VM_FILE_CLUMP_REC_SIZE) + 2) + VarsCmd.pCodespace; //Initialize remaining CLUMP_REC fields - VarsCmd.pAllClumps[i].PC = 0; - VarsCmd.pAllClumps[i].Priority = 20; - VarsCmd.pAllClumps[i].Link = NOT_A_CLUMP; + clumpPtr->PC = clumpPtr->CodeStart; + clumpPtr->Link = NOT_A_CLUMP; //Activate any clumps with CurrFireCount of 0 - VarsCmd.pAllClumps[i].CurrFireCount = VarsCmd.pAllClumps[i].InitFireCount; - if (VarsCmd.pAllClumps[i].CurrFireCount == 0) + clumpPtr->CurrFireCount = clumpPtr->InitFireCount; + if (clumpPtr->CurrFireCount == 0) cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)i); } @@ -1446,28 +1728,89 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) pCursor += VarsCmd.AllClumpsCount * VM_FILE_CLUMP_REC_SIZE; for (i = 0; i < VarsCmd.AllClumpsCount; i++) { - if (VarsCmd.pAllClumps[i].DependentCount > 0) + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + if (clumpPtr->DependentCount > 0) { - VarsCmd.pAllClumps[i].pDependents = (CLUMP_ID*)(pCursor); + clumpPtr->pDependents = (CLUMP_ID*)(pCursor); - pCursor += (VarsCmd.pAllClumps[i].DependentCount * sizeof(CLUMP_ID)); + pCursor += (clumpPtr->DependentCount * sizeof(CLUMP_ID)); } else - VarsCmd.pAllClumps[i].pDependents = NULL; + clumpPtr->pDependents = NULL; //Patch up CodeEnd value based on CodeStart of next clump or last overall codeword if (i < (VarsCmd.AllClumpsCount - 1)) - VarsCmd.pAllClumps[i].CodeEnd = VarsCmd.pAllClumps[i+1].CodeStart - 1; + clumpPtr->CodeEnd = (clumpPtr+1)->CodeStart - 1; else - VarsCmd.pAllClumps[i].CodeEnd = VarsCmd.CodespaceCount - 1; + clumpPtr->CodeEnd = VarsCmd.CodespaceCount - 1 + VarsCmd.pCodespace; //Test for empty/insane clump code definitions - NXT_ASSERT(VarsCmd.pAllClumps[i].CodeStart < VarsCmd.pAllClumps[i].CodeEnd); + NXT_ASSERT(clumpPtr->CodeStart < clumpPtr->CodeEnd); } + // Check if the instructions within a clump are polymorphic and mark which table to dispatch from + for (i = 0; i < VarsCmd.AllClumpsCount; i++) + { // Check type on Boolean, math, ArrInit and ArrIndex, ingore GetSet I/O as these are always scalar + // do we need to check for DataArg encodings to I/O map??? GM + // Get Opcode and size of each instr, if ^^, check Arg types for Array or Cluster + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[i]; + CODE_WORD *pInstr = clumpPtr->CodeStart, *lastPC = clumpPtr->CodeEnd; + ULONG InstrSize, opCode, shortOp, isT2Agg, isT3Agg, isScalarBinop= TRUE, isScalarUnop2= TRUE; + TYPE_CODE t1, t2, t3; + ULONG instrWord; + do + { + instrWord= *(UWORD*)pInstr; + opCode= OP_CODE(pInstr); + shortOp= (instrWord>>8) & 0x0F; + InstrSize = INSTR_SIZE(instrWord); + if (InstrSize == VAR_INSTR_SIZE) + InstrSize = ((UWORD*)pInstr)[1]; + if(shortOp <= 7) // no shorts are binOps + { + t2= cCmdDSType(pInstr[2]); + isT2Agg= IS_AGGREGATE_TYPE(t2); + if(InstrSize == 8) { + t3= cCmdDSType(pInstr[3]); + isT3Agg= IS_AGGREGATE_TYPE(t3); + if(isT2Agg || isT3Agg) { + if(opCode == OP_CMP) { + UBYTE isString2, isString3; + isString2= (t2 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[2])) == TC_UBYTE; + isString3= (t3 == TC_ARRAY) && cCmdDSType(INC_ID(pInstr[3])) == TC_UBYTE; + t1= cCmdDSType(pInstr[1]); + if((!isString2 || !isString3) || t1 == TC_ARRAY) // allow strings to go scalar, don't let through element compares of bytes or Bools + isScalarBinop= FALSE; + } + else if(opCode == OP_BRCMP) + isScalarBinop= FALSE; + } + } + else if(InstrSize == 6 && isT2Agg && (opCode == OP_NOT || opCode == OP_BRTST)) + isScalarUnop2= FALSE; + } + pInstr += InstrSize/2; + } while((isScalarBinop || isScalarUnop2) && pInstr < lastPC); + if(isScalarBinop) + clumpPtr->clumpScalarDispatchHints |= scalarBinopDispatchMask; + else + clumpPtr->clumpScalarDispatchHints &= ~scalarBinopDispatchMask; + + if(isScalarUnop2) + clumpPtr->clumpScalarDispatchHints |= scalarUnop2DispatchMask; + else + clumpPtr->clumpScalarDispatchHints &= ~scalarUnop2DispatchMask; + + } //Programs with no active clumps constitutes an activation error if (VarsCmd.RunQ.Head == NOT_A_CLUMP) return (ERR_FILE); + else + { + // now that we know which clumps are scalar and poly, refresh dispatch table to match head + cCmdRefreshActiveClump(VarsCmd.RunQ.Head); + + } //Initialize dataspace with default values from file //!!! This would be a good place to enforce check against potentially @@ -1491,6 +1834,13 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) //Copy Dynamic defaults from file memmove(VarsCmd.pDataspace + VarsCmd.DSStaticSize, pData + FileOffsets.DSDefaults + FileOffsets.DynamicDefaults, FileOffsets.DynamicDefaultsSize); + // fix memmgr links. old files contain unused backPtrs, we now use these to store backLink + DV_INDEX prev= NOT_A_DS_ID; + for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) { + DV_ARRAY[i].BackLink= prev; + prev= i; + } + //Verify the MemMgr ended up where we said it would if ((UBYTE *)VarsCmd.MemMgr.pDopeVectorArray != VarsCmd.pDataspace + DV_ARRAY[0].Offset) { @@ -1510,9 +1860,27 @@ NXT_STATUS cCmdActivateProgram(UBYTE * pFileName) } } + //Initialize datalog queue + VarsCmd.DatalogBuffer.ReadIndex = 0; + VarsCmd.DatalogBuffer.WriteIndex = 0; + for (j = 0; j < DATALOG_QUEUE_DEPTH; j++) + { + VarsCmd.DatalogBuffer.Datalogs[j] = NOT_A_DS_ID; + } + + // now that we've loaded program, prime memmgr dopevectors based upon number of handles in ds. + ULONG numHandles= DV_ARRAY[0].Count/2; + if(numHandles > 200) + numHandles= 200; + Status = cCmdGrowDopeVectorArray(numHandles); + if (cCmdVerifyMemMgr() != TRUE) return (ERR_FILE); + gUsageSemData= 0; + gRequestSemData= 0; + // preload all calibration coefficients into mem + cCmdLoadCalibrationFiles(); return (Status); } @@ -1541,8 +1909,6 @@ void cCmdDeactivateProgram() VarsCmd.RunQ.Head = NOT_A_CLUMP; VarsCmd.RunQ.Tail = NOT_A_CLUMP; - VarsCmd.ScratchPC = 0; - VarsCmd.CallerClump = NOT_A_CLUMP; if (VarsCmd.ActiveProgHandle != NOT_A_HANDLE) { @@ -1561,7 +1927,7 @@ void cCmdDeactivateProgram() tmp = i; //Close file if (*(VarsCmd.FileHandleTable[i]) != 0) - pMapLoader->pFunc(CLOSE, &tmp, NULL, NULL); + pMapLoader->pFunc(CROPDATAFILE, &tmp, NULL, NULL); } //Clear FileHandleTable @@ -1646,6 +2012,8 @@ void cCmdEnQClump(CLUMP_Q * Queue, CLUMP_ID NewClump) Queue->Head = NewClump; Queue->Tail = NewClump; + if(Queue == &(VarsCmd.RunQ)) + cCmdRefreshActiveClump(NewClump); } //Otherwise, tack onto the end else @@ -1679,18 +2047,21 @@ void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump) //If we just removed the last clump, patch up the queue's tail if (Queue->Head == NOT_A_CLUMP) Queue->Tail = NOT_A_CLUMP; + else if(Queue == &(VarsCmd.RunQ)) + cCmdRefreshActiveClump(Queue->Head); } //Else, look through rest of list looking for a link to our clump else { do { - LinkID = VarsCmd.pAllClumps[CurrID].Link; + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[CurrID]; + LinkID = clumpPtr->Link; //If we find a link to our clump, patch up predecessor's link - if (VarsCmd.pAllClumps[CurrID].Link == Clump) + if (clumpPtr->Link == Clump) { - VarsCmd.pAllClumps[CurrID].Link = VarsCmd.pAllClumps[Clump].Link; + clumpPtr->Link = VarsCmd.pAllClumps[Clump].Link; VarsCmd.pAllClumps[Clump].Link = NOT_A_CLUMP; //If we just removed the tail, patch tail @@ -1707,10 +2078,11 @@ void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump) //Rotate head to tail and advance head for given Queue -void cCmdRotateQ(CLUMP_Q * Queue) +void cCmdRotateQ() { CLUMP_ID CurrID; CLUMP_REC * pClumpRec; + CLUMP_Q * Queue = &VarsCmd.RunQ; //Make sure Queue is sane NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); @@ -1730,6 +2102,10 @@ void cCmdRotateQ(CLUMP_Q * Queue) pClumpRec->Link = CurrID; Queue->Tail = CurrID; + // reinit clump info + CurrID= Queue->Head; + cCmdRefreshActiveClump(Queue->Head); + //Make sure we didn't make any really stupid mistakes NXT_ASSERT(cCmdIsQSane(Queue) == TRUE); } @@ -1798,9 +2174,10 @@ UBYTE cCmdIsQSane(CLUMP_Q * Queue) // Mutex queuing functions // -NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex, CLUMP_ID Clump) +NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex) { NXT_STATUS Status = NO_ERR; + CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below NXT_ASSERT(Mutex != NULL && cCmdIsClumpIDSane(Clump)); @@ -1825,8 +2202,11 @@ NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex, CLUMP_ID Clump) } -NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex, CLUMP_ID Clump) +NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex) { +#if WIN_DEBUG || defined(ARM_DEBUG) + CLUMP_ID Clump= VarsCmd.RunQ.Head; +#endif NXT_ASSERT(Mutex != NULL); //!!! don't actually need to pass in Owner clump, but provides nice error checking for now // Might want to return an error/warning if we see a Release on an free mutex, though... @@ -1847,6 +2227,36 @@ NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex, CLUMP_ID Clump) return (NO_ERR); } +// No instruction to do this yet, but put current clump to sleep until awakeTime occurs +NXT_STATUS cCmdSleepClump(ULONG time) +{ + CLUMP_ID Clump= VarsCmd.RunQ.Head; // save off before queue changes below + CLUMP_REC * pClump = &(VarsCmd.pAllClumps[Clump]); + cCmdDeQClump(&(VarsCmd.RunQ), Clump); + cCmdEnQClump(&(VarsCmd.RestQ), Clump); + pClump->awakenTime= time; + return CLUMP_SUSPEND; +} + +UBYTE cCmdCheckRestQ(ULONG currTime) +{ + UBYTE awakened= FALSE; + CLUMP_ID curr, next; + CLUMP_REC * pClump; + curr= VarsCmd.RestQ.Head; + while(curr != NOT_A_CLUMP) { + pClump= &(VarsCmd.pAllClumps[curr]); + next= pClump->Link; + if(pClump->awakenTime <= currTime) { + pClump->awakenTime= 0; // not necessary, but for debugging identification + cCmdDeQClump(&(VarsCmd.RestQ), curr); + cCmdEnQClump(&(VarsCmd.RunQ), curr); + awakened= TRUE; + } + curr= next; + } + return awakened; +} NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End) { @@ -1891,8 +2301,9 @@ NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump) NXT_ASSERT(cCmdIsClumpIDSane(Clump)); NXT_ASSERT(cCmdIsClumpIDSane(TargetClump)); - VarsCmd.pAllClumps[TargetClump].CurrFireCount--; - if (VarsCmd.pAllClumps[TargetClump].CurrFireCount == 0) + CLUMP_REC *clumpPtr= &VarsCmd.pAllClumps[TargetClump]; + clumpPtr->CurrFireCount--; + if (clumpPtr->CurrFireCount == 0) cCmdEnQClump(&(VarsCmd.RunQ), TargetClump); return (NO_ERR); @@ -1914,25 +2325,31 @@ UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump) void cCmdInitPool(void) { ULONG i; + ULONG *poolPtr; //VarsCmd.Pool is a UBYTE pointer to ULONG array //This was done to enforce portable alignment. VarsCmd.Pool = (UBYTE*)(IOMapCmd.MemoryPool); - for (i = 0; i < (POOL_MAX_SIZE / 4); i++) - ((SLONG*)(POOL_START))[i] = 0xDEADBEEF; + for (i = (POOL_MAX_SIZE / 4), poolPtr= (ULONG*)&(POOL_START)[0]; i>0; i--, poolPtr++) + *poolPtr = 0xDEADBEEF; VarsCmd.PoolSize = 0; } +#if VMProfilingCode +ULONG memMgrTime= 0; +#endif NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount) { NXT_STATUS Status = NO_ERR; UWORD DVIndex; UWORD OldCount; UWORD i; - +#if VMProfilingCode + ULONG enterTime= dTimerReadHiRes(); +#endif NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); //Only arrays are valid here @@ -1942,9 +2359,15 @@ NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCo DVIndex = cCmdGetDVIndex(DSElementID, Offset); OldCount = DV_ARRAY[DVIndex].Count; + if(OldCount == NewCount) + goto allocExit; Status = cCmdDVArrayAlloc(DVIndex, NewCount); + if (Status < NO_ERR) - return Status; + goto allocExit; + + if(!IS_AGGREGATE_TYPE(cCmdDSType(INC_ID(DSElementID)))) + goto allocExit; if (OldCount > NewCount) { @@ -1953,22 +2376,25 @@ NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCo { Status = cCmdFreeSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); if (IS_ERR(Status)) - return Status; + goto allocExit; } } else if (OldCount < NewCount) { //Alloc dope vectors for sub-arrays. Set up DVIndexes - for (i = OldCount; i < NewCount; i++) + for (i = OldCount; i < NewCount; i++) { Status = cCmdAllocSubArrayDopeVectors(INC_ID(DSElementID), ARRAY_ELEM_OFFSET(DVIndex, i)); if (IS_ERR(Status)) - return Status; + goto allocExit; } } NXT_ASSERT(cCmdVerifyMemMgr()); - +allocExit: +#if VMProfilingCode + memMgrTime += dTimerReadHiRes() - enterTime; +#endif return Status; } @@ -2044,11 +2470,13 @@ NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount) VarsCmd.PoolSize += ArraySize; VarsCmd.DataspaceSize += ArraySize; - //Move Array Data - memmove(pData, VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, (UWORD)(DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count)); - //!!! Clear mem so we make sure we don't reference stale data. Not strictly needed. - memset(VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, 0xFF, (UWORD)(DV_ARRAY[DVIndex].ElemSize * DV_ARRAY[DVIndex].Count)); - + //Move old Array Data to new allocation + if(OldCount) + memmove(pData, VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); + //!!! Clear mem so old mem doesn't contain stale data. Not strictly needed. +#if WIN_DEBUG || defined(ARM_DEBUG) + memset(VarsCmd.pDataspace + DV_ARRAY[DVIndex].Offset, 0xFF, (UWORD)(DV_ARRAY[DVIndex].ElemSize * OldCount)); +#endif //Update dope vector DV_ARRAY[DVIndex].Offset = pData - VarsCmd.pDataspace; DV_ARRAY[DVIndex].Count = NewCount; @@ -2094,7 +2522,7 @@ NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) // It'd be nice to not have to recalculate it. ElemSize = cCmdCalcArrayElemSize((DS_ELEMENT_ID)(DSElementID + i)); DVIndexOffset = VarsCmd.pDataspaceTOC[DSElementID + i].DSOffset + Offset; - Status = cCmdAllocDopeVector(&DVIndex, ElemSize, DVIndexOffset); + Status = cCmdAllocDopeVector(&DVIndex, ElemSize); if (IS_ERR(Status)) return Status; @@ -2156,7 +2584,7 @@ NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset) } -NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr) +NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize) { NXT_STATUS Status = NO_ERR; @@ -2168,11 +2596,14 @@ NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr) return Status; } - NXT_ASSERT(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID); + if(VarsCmd.MemMgr.FreeHead == NOT_A_DS_ID) + return ERR_MEM; //Remove DV from free list *pIndex = VarsCmd.MemMgr.FreeHead; - VarsCmd.MemMgr.FreeHead = DV_ARRAY[VarsCmd.MemMgr.FreeHead].Link; + VarsCmd.MemMgr.FreeHead = DV_ARRAY[*pIndex].Link; + if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= NOT_A_DS_ID; //Add DV to tail of MemMgr list Status = cCmdMemMgrInsertAtTail(*pIndex); @@ -2180,7 +2611,6 @@ NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr) DV_ARRAY[*pIndex].Offset = NOT_AN_OFFSET; DV_ARRAY[*pIndex].ElemSize = ElemSize; DV_ARRAY[*pIndex].Count = 0; - DV_ARRAY[*pIndex].BackPtr = BackPtr; NXT_ASSERT(cCmdVerifyMemMgr()); @@ -2196,7 +2626,7 @@ NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr) NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex) { NXT_STATUS Status = NO_ERR; - DV_INDEX i; + DV_INDEX prev, post; //Bounds check NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); @@ -2205,33 +2635,33 @@ NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex) DV_ARRAY[DVIndex].Count = 0; DV_ARRAY[DVIndex].ElemSize = 0; DV_ARRAY[DVIndex].Offset = NOT_AN_OFFSET; - DV_ARRAY[DVIndex].BackPtr = NOT_AN_OFFSET; //Remove from MemMgr list if (DVIndex == VarsCmd.MemMgr.Head) { VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; + if(VarsCmd.MemMgr.Head != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; } else { - //Walk MemMgr list to find previous. - //!!! Could speed this up if MemMgr list were doubly linked - for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) - { - if (DV_ARRAY[i].Link == DVIndex) - { - DV_ARRAY[i].Link = DV_ARRAY[DVIndex].Link; - if (DVIndex == VarsCmd.MemMgr.Tail) - VarsCmd.MemMgr.Tail = i; - break; - } - } + // patchup middle or end of list. + prev= DV_ARRAY[DVIndex].BackLink; + post= DV_ARRAY[DVIndex].Link; + NXT_ASSERT(prev != NOT_A_DS_ID); + + DV_ARRAY[prev].Link = post; + if(post != NOT_A_DS_ID) + DV_ARRAY[post].BackLink= prev; + if (DVIndex == VarsCmd.MemMgr.Tail) + VarsCmd.MemMgr.Tail = prev; //Make sure we found the previous DV, otherwise this DV was not in the the list (already freed?) - NXT_ASSERT(i != NOT_A_DS_ID); } - //Push on to free list + //Push onto free list DV_ARRAY[DVIndex].Link = VarsCmd.MemMgr.FreeHead; + DV_ARRAY[DVIndex].BackLink = NOT_A_DS_ID; + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink= DVIndex; VarsCmd.MemMgr.FreeHead = DVIndex; NXT_ASSERT(cCmdVerifyMemMgr()); @@ -2291,7 +2721,9 @@ NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewNodesCount) DV_ARRAY[i].Offset = 0xFFFF; DV_ARRAY[i].ElemSize = 0; DV_ARRAY[i].Count = 0; - DV_ARRAY[i].BackPtr = 0xFFFF; + DV_ARRAY[i].BackLink = NOT_A_DS_ID; + if(VarsCmd.MemMgr.FreeHead != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.FreeHead].BackLink = i; DV_ARRAY[i].Link = VarsCmd.MemMgr.FreeHead; VarsCmd.MemMgr.FreeHead = i; } @@ -2304,13 +2736,6 @@ NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewNodesCount) return Status; } -NXT_STATUS cCmdCompactDopeVectorArray(void) -{ - //!!! Not implemented. Needs BackPtr support. - NXT_BREAK; - return ERR_ARG; -} - UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID) { @@ -2348,7 +2773,7 @@ UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID) NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex) { - DV_INDEX i; + DV_INDEX prev, post; //Bounds check NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); @@ -2357,26 +2782,25 @@ NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex) if (DVIndex == VarsCmd.MemMgr.Tail) return NO_ERR; - if (DVIndex == VarsCmd.MemMgr.Head) + if (DVIndex == VarsCmd.MemMgr.Head) { VarsCmd.MemMgr.Head = DV_ARRAY[DVIndex].Link; + DV_ARRAY[VarsCmd.MemMgr.Head].BackLink= NOT_A_DS_ID; + } else { - //Walk MemMgr list to find previous. - //!!! Could speed this up if MemMgr list were doubly linked - for (i = VarsCmd.MemMgr.Head; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) - { - if (DV_ARRAY[i].Link == DVIndex) - { - DV_ARRAY[i].Link = DV_ARRAY[DVIndex].Link; - break; - } - } - //Make sure we found the previous DV, otherwise this DV was not in the the list - NXT_ASSERT(i != NOT_A_DS_ID); + // connect to middle or end of list. + prev= DV_ARRAY[DVIndex].BackLink; + post= DV_ARRAY[DVIndex].Link; + NXT_ASSERT(prev != NOT_A_DS_ID); + DV_ARRAY[prev].Link = post; + if(post != NOT_A_DS_ID) + DV_ARRAY[post].BackLink= prev; } DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; - DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; + DV_ARRAY[DVIndex].BackLink = VarsCmd.MemMgr.Tail; + if(VarsCmd.MemMgr.Tail != NOT_A_DS_ID) + DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; VarsCmd.MemMgr.Tail = DVIndex; NXT_ASSERT(cCmdVerifyMemMgr()); @@ -2391,8 +2815,9 @@ NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex) NXT_ASSERT(DVIndex < DV_ARRAY[0].Count); DV_ARRAY[VarsCmd.MemMgr.Tail].Link = DVIndex; - VarsCmd.MemMgr.Tail = DVIndex; + DV_ARRAY[DVIndex].BackLink= VarsCmd.MemMgr.Tail; DV_ARRAY[DVIndex].Link = NOT_A_DS_ID; + VarsCmd.MemMgr.Tail = DVIndex; NXT_ASSERT(cCmdVerifyMemMgr()); @@ -2402,7 +2827,7 @@ NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex) UBYTE cCmdVerifyMemMgr() { - DV_INDEX i; + DV_INDEX i, prev, post; UWORD CurrOffset = 0; UWORD PrevOffset = 0; UWORD DVCount = 0; @@ -2420,12 +2845,21 @@ UBYTE cCmdVerifyMemMgr() PrevOffset = CurrOffset; } - if (DV_ARRAY[i].Link == NOT_A_DS_ID && i != VarsCmd.MemMgr.Tail) + prev= DV_ARRAY[i].BackLink; + post= DV_ARRAY[i].Link; + if (post == NOT_A_DS_ID && i != VarsCmd.MemMgr.Tail) + return FALSE; + else if(prev == NOT_A_DS_ID && i != VarsCmd.MemMgr.Head) + return FALSE; + else if(prev != NOT_A_DS_ID && DV_ARRAY[prev].Link != i) + return FALSE; + else if(post != NOT_A_DS_ID && DV_ARRAY[post].BackLink != i) return FALSE; DVCount++; } + // could check link and backlinks too for (i = VarsCmd.MemMgr.FreeHead; i != NOT_A_DS_ID; i = DV_ARRAY[i].Link) { DVCount++; @@ -2556,7 +2990,7 @@ NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length) else { //Allocate dope vector for message - Status = cCmdAllocDopeVector(&GET_WRITE_MSG(QueueID), 1, NOT_AN_OFFSET); + Status = cCmdAllocDopeVector(&GET_WRITE_MSG(QueueID), 1); if (IS_ERR(Status)) return Status; } @@ -2665,114 +3099,365 @@ NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pBuffer, UWORD Length, UBYTE R return Status; } - // -// Dataspace Support functions +// Datalog Queue function(s) // -UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index) -{ - if (Index < VarsCmd.DataspaceCount) - return TRUE; - else - return FALSE; -} - -TYPE_CODE cCmdDSType(DS_ELEMENT_ID DSElementID) +NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length) { - NXT_ASSERT(cCmdIsDSElementIDSane(DSElementID)); - - return (VarsCmd.pDataspaceTOC[DSElementID].TypeCode); -} + NXT_STATUS Status = NO_ERR; + if (pData == NULL) + return ERR_ARG; -void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode) -{ - UBYTE ModuleID; - UWORD FieldID; - void * ret_val = NULL; + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return (ERR_NO_PROG); - // - //!!! DATA_ARG masking system only for internal c_cmd use! - // All normal bytecode arguments should go through top if() block. - // + //Can't accept oversize messages because we treat them as strings (truncation would remove null termination) + if (Length > MAX_DATALOG_SIZE) + return ERR_INVALID_SIZE; - if (DataArg <= (DATA_ARG)(DATA_ARG_ADDR_MASK) ) + if (IS_DV_INDEX_SANE(GET_WRITE_DTLG())) { - NXT_ASSERT(cCmdIsDSElementIDSane(DataArg)); - ret_val = cCmdDSPtr(DataArg, Offset); - if (TypeCode) - *TypeCode = VarsCmd.pDataspaceTOC[DataArg].TypeCode; + //A message is already there, the queue is full + NXT_ASSERT(VarsCmd.DatalogBuffer.WriteIndex == VarsCmd.DatalogBuffer.ReadIndex); + Status = STAT_MSG_BUFFERWRAP; + //Bump read index, drop existing message to make room for our newly acquired datalog + VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; } - else if (DataArg & ~((DATA_ARG)(DATA_ARG_ADDR_MASK))) + else { - //DataArg refers to a field in the IO map - ModuleID = (UBYTE)((DataArg >> 9) & 0x001F); - FieldID = (UWORD)(DataArg & 0x01FF); - - //!!! Preliminary bounds check -- still could allow invalid combos through - if (ModuleID > MOD_OUTPUT || FieldID >= IO_OUT_FIELD_COUNT) - { - NXT_BREAK; - return NULL; - } + //Allocate dope vector for message + Status = cCmdAllocDopeVector(&GET_WRITE_DTLG(), 1); + if (IS_ERR(Status)) + return Status; + } - ret_val = IO_PTRS[ModuleID][FieldID]; - if (TypeCode) - *TypeCode = IO_TYPES[ModuleID][FieldID]; + //Allocate storage for message + Status |= cCmdDVArrayAlloc(GET_WRITE_DTLG(), Length); + if (IS_ERR(Status)) + { + //Clear the dope vector for the message, since we're unable to put a message there. + cCmdFreeDopeVector(GET_WRITE_DTLG()); + SET_WRITE_DTLG(NOT_A_DS_ID); + return Status; } - //!!! Caller beware! If DataArg isn't sane, ret_val may be out of range or NULL! - return ret_val; + //Copy message + memmove(cCmdDVPtr(GET_WRITE_DTLG()), pData, Length); + + //Advance write index + VarsCmd.DatalogBuffer.WriteIndex = (VarsCmd.DatalogBuffer.WriteIndex + 1) % DATALOG_QUEUE_DEPTH; + + return Status; } -void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal) +NXT_STATUS cCmdDatalogGetSize(UWORD * Size) { + DV_INDEX ReadDVIndex; - if (pVal) + if (Size == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) { - switch (TypeCode) - { - case TC_ULONG: - case TC_SLONG: - { - *(ULONG*)pVal = NewVal; - } - break; + *Size = 0; + return (ERR_NO_PROG); + } - case TC_UWORD: - case TC_SWORD: - { - *(UWORD*)pVal = (UWORD)NewVal; - } - break; + ReadDVIndex = GET_READ_DTLG(); - case TC_UBYTE: - case TC_SBYTE: - { - *(UBYTE*)pVal = (UBYTE)NewVal; - } - break; - } + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + *Size = (DV_ARRAY[ReadDVIndex].Count); + return (NO_ERR); + } + else + { + *Size = 0; + return (STAT_MSG_EMPTY_MAILBOX); } - - return; } - -ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) +NXT_STATUS cCmdDatalogRead(UBYTE * pBuffer, UWORD Length, UBYTE Remove) { - if (pVal) - { - switch (TypeCode) - { - case TC_ULONG: - { - return (ULONG)(*(ULONG*)pVal); - } + NXT_STATUS Status = NO_ERR; + DV_INDEX ReadDVIndex; - case TC_SLONG: - { + if (pBuffer == NULL) + return (ERR_ARG); + + if (VarsCmd.ActiveProgHandle == NOT_A_HANDLE) + return (ERR_NO_PROG); + + ReadDVIndex = GET_READ_DTLG(); + + if (IS_DV_INDEX_SANE(ReadDVIndex)) + { + //If Buffer doesn't have room for the entire message, + //don't risk incomplete string floating around + if (Length < DV_ARRAY[ReadDVIndex].Count) + return (ERR_INVALID_SIZE); + + //Copy message + memmove(pBuffer, cCmdDVPtr(ReadDVIndex), DV_ARRAY[ReadDVIndex].Count); + + if (Remove) + { + //Free memory used by message + Status = cCmdFreeDopeVector(ReadDVIndex); + if (IS_ERR(Status)) + return Status; + + SET_READ_DTLG(NOT_A_DS_ID); + + //Advance read index + VarsCmd.DatalogBuffer.ReadIndex = (VarsCmd.DatalogBuffer.ReadIndex + 1) % DATALOG_QUEUE_DEPTH; + } + } + else + { + //No message to read, datalog Queue is empty + NXT_ASSERT(VarsCmd.DatalogBuffer.ReadIndex == VarsCmd.DatalogBuffer.WriteIndex); + + return (STAT_MSG_EMPTY_MAILBOX); + } + + return Status; +} + + +// +// Color Sensor Functions +// +NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD * SensorValue, UWORD * RawArray, UWORD * NormalizedArray, + SWORD * ScaledArray, UBYTE * InvalidData) +{ + ULONG i; + //Make sure Port is valid for Color Sensor + if (!(pMapInput->Inputs[Port].SensorType == COLORFULL || pMapInput->Inputs[Port].SensorType == COLORRED + || pMapInput->Inputs[Port].SensorType == COLORGREEN || pMapInput->Inputs[Port].SensorType == COLORBLUE + || pMapInput->Inputs[Port].SensorType == COLORNONE)) + { + return (ERR_COMM_CHAN_NOT_READY); //TODO - is this the right error? + } + //Copy Detected Color + *SensorValue = pMapInput->Inputs[Port].SensorValue; + + //Copy all raw, normalized and scaled data from I/O Map + for (i=0; iColors[Port].ADRaw[i]; + NormalizedArray[i] = pMapInput->Colors[Port].SensorRaw[i]; + ScaledArray[i] = pMapInput->Colors[Port].SensorValue[i]; + } + //Copy the Invalid Data Flag + *InvalidData = pMapInput->Inputs[Port].InvalidData; + + return NO_ERR; + +} + + +// +// Dataspace Support functions +// + +UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index) +{ + if (Index < VarsCmd.DataspaceCount) + return TRUE; + else + return FALSE; +} + +void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode) +{ + void * ret_val = NULL; + + //!!! DATA_ARG masking system only for internal c_cmd use! + // All normal bytecode arguments should go through top if() block. + + NXT_ASSERT(cCmdIsDSElementIDSane(DataArg)); + ret_val = cCmdDSPtr(DataArg, Offset); + if (TypeCode) + *TypeCode = VarsCmd.pDataspaceTOC[DataArg].TypeCode; + + //!!! Caller beware! If DataArg isn't sane, ret_val may be out of range or NULL! + return ret_val; +} + +// normal Resolve handles both, but this is specific to I/O args +void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode) + { + void * ret_val = NULL; + + ULONG ModuleID; + ULONG FieldID; + //DataArg refers to a field in the IO map + // ModuleID = ((DataArg >> 9) & 0x1F); + ModuleID = ((DataArg & 0x3FFF) >> 9); + FieldID = (DataArg & 0x01FF); + + //!!! Preliminary bounds check -- still could allow invalid combos through + if (ModuleID > MOD_OUTPUT || FieldID >= IO_OUT_FIELD_COUNT) + { + NXT_BREAK; + return NULL; + } + + ret_val = IO_PTRS[ModuleID][FieldID]; + if (TypeCode) + *TypeCode = IO_TYPES[ModuleID][FieldID]; + return ret_val; +} + +void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal) +{ + + if (pVal) + { + switch (TypeCode) + { + case TC_ULONG: + case TC_SLONG: + { + *(ULONG*)pVal = NewVal; + } + break; + + case TC_UWORD: + case TC_SWORD: + { + *(UWORD*)pVal = (UWORD)NewVal; + } + break; + + case TC_UBYTE: + case TC_SBYTE: + { + *(UBYTE*)pVal = (UBYTE)NewVal; + } + break; + + case TC_FLOAT: + { + *(float*)pVal = (float)NewVal; + } + break; + } + } + + return; +} + +ULONG cCmdGetUByte(void * pVal); +ULONG cCmdGetSByte(void * pVal); +ULONG cCmdGetUWord(void * pVal); +ULONG cCmdGetSWord(void * pVal); +ULONG cCmdGetULong(void * pVal); +ULONG cCmdGetSLong(void * pVal); +ULONG cCmdGetError(void * pVal); +ULONG cCmdGetFloat(void * pVal); + +void cCmdSetByte(void * pVal, ULONG NewVal); +void cCmdSetWord(void * pVal, ULONG NewVal); +void cCmdSetLong(void * pVal, ULONG NewVal); +void cCmdSetError(void * pVal, ULONG NewVal); + + +typedef ULONG (*pGetOperand)(void *); +static pGetOperand GetProcArray[11]= {cCmdGetUByte, cCmdGetUByte, cCmdGetSByte, cCmdGetUWord, cCmdGetSWord, cCmdGetULong, cCmdGetSLong, cCmdGetError, cCmdGetError, cCmdGetError, cCmdGetFloat}; // dup UByte to line up + +typedef void (*pSetOperand)(void *, ULONG); +static pSetOperand SetProcArray[9]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError}; // dup UByte to line up + +void cCmdSetError(void * pVal, ULONG NewVal) { + NXT_BREAK; +} + +void cCmdSetLong(void * pVal, ULONG NewVal) { + *(ULONG*)pVal = NewVal; +} + +void cCmdSetWord(void * pVal, ULONG NewVal) { + *(UWORD*)pVal = (UWORD)NewVal; +} + +void cCmdSetByte(void * pVal, ULONG NewVal) { + *(UBYTE*)pVal = (UBYTE)NewVal; +} + +// only works on simple types, equivalent to resolve and get, but faster +ULONG cCmdGetScalarValFromDataArg(DATA_ARG DataArg, UWORD Offset) +{ + DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; + return GetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset + Offset); +} + + +ULONG cCmdGetError(void * pVal) { + NXT_BREAK; + return 0; +} + +ULONG cCmdGetULong(void * pVal) { + return (ULONG)(*(ULONG*)pVal); +} + +ULONG cCmdGetSLong(void * pVal) { + return (SLONG)(*(SLONG*)pVal); +} + +ULONG cCmdGetUWord(void * pVal) { + return (UWORD)(*(UWORD*)pVal); +} + +ULONG cCmdGetSWord(void * pVal) { + return (SWORD)(*(SWORD*)pVal); +} + +ULONG cCmdGetUByte(void * pVal) { + return (UBYTE)(*(UBYTE*)pVal); +} + +ULONG cCmdGetSByte(void * pVal) { + return (SBYTE)(*(SBYTE*)pVal); +} + +ULONG cCmdGetFloat(void * pVal) { + float tempVal = *(float*)pVal; + if (tempVal >= 0) { + tempVal += 0.5; + } + else { + tempVal -= 0.5; + } + return (ULONG)tempVal; +} + +ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) +{ + if (pVal) + return GetProcArray[TypeCode](pVal); + else + //!!! Default return value places responsibility on caller to use this function wisely + return 0; +} + + +float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode) +{ + if (pVal) + { + switch (TypeCode) + { + case TC_ULONG: + { + return (ULONG)(*(ULONG*)pVal); + } + + case TC_SLONG: + { return (SLONG)(*(SLONG*)pVal); } @@ -2796,6 +3481,11 @@ ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) return (SBYTE)(*(SBYTE*)pVal); } + case TC_FLOAT: + { + return (float)(*(float*)pVal); + } + default: break; } @@ -2806,34 +3496,19 @@ ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode) } -UWORD cCmdSizeOf(TYPE_CODE TypeCode) -{ - //!!! Why not use a lookup table? No particular reason... - switch(TypeCode) - { - case TC_ULONG: - return SIZE_ULONG; - case TC_SLONG: - return SIZE_SLONG; - case TC_UWORD: - return SIZE_UWORD; - case TC_SWORD: - return SIZE_SWORD; - case TC_UBYTE: - return SIZE_UBYTE; - case TC_SBYTE: - return SIZE_SBYTE; - case TC_MUTEX: - return SIZE_MUTEX; - case TC_ARRAY: - //Arrays have a 2-byte structure in the dataspace for the DVIndex - return SIZE_UWORD; - case TC_CLUSTER: - default: - return 0; - } + +// Only for scalar types and no offset +void cCmdSetScalarValFromDataArg(DATA_ARG DataArg, ULONG NewVal) +{ + DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg]; + SetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset, NewVal); } +void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal) +{ + if (pVal) + SetProcArray[TypeCode](pVal, NewVal); +} void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset) { @@ -3179,23 +3854,19 @@ DS_ELEMENT_ID cCmdGetDataspaceCount(void) } -CODE_INDEX cCmdGetCodespaceCount(CLUMP_ID Clump) -{ - if (Clump == NOT_A_CLUMP) - return (VarsCmd.CodespaceCount); - else - { - NXT_ASSERT(cCmdIsClumpIDSane(Clump)); - return (VarsCmd.pAllClumps[Clump].CodeEnd - VarsCmd.pAllClumps[Clump].CodeStart + 1); - } -} - - UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) { SLONG SVal1, SVal2; - - if (IS_SIGNED_TYPE(TypeCode1) && IS_SIGNED_TYPE(TypeCode2)) + if (QUICK_UNSIGNED_TEST(TypeCode1) || QUICK_UNSIGNED_TEST(TypeCode2)) + { + return ((CompCode == OPCC1_LT && Val1 < Val2) + || (CompCode == OPCC1_GT && Val1 > Val2) + || (CompCode == OPCC1_LTEQ && Val1 <= Val2) + || (CompCode == OPCC1_GTEQ && Val1 >= Val2) + || (CompCode == OPCC1_EQ && Val1 == Val2) + || (CompCode == OPCC1_NEQ && Val1 != Val2)); + } + else { SVal1 = (SLONG)Val1; SVal2 = (SLONG)Val2; @@ -3206,16 +3877,17 @@ UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, T || (CompCode == OPCC1_EQ && SVal1 == SVal2) || (CompCode == OPCC1_NEQ && SVal1 != SVal2)); } - else - { - return ((CompCode == OPCC1_LT && Val1 < Val2) - || (CompCode == OPCC1_GT && Val1 > Val2) - || (CompCode == OPCC1_LTEQ && Val1 <= Val2) - || (CompCode == OPCC1_GTEQ && Val1 >= Val2) - || (CompCode == OPCC1_EQ && Val1 == Val2) - || (CompCode == OPCC1_NEQ && Val1 != Val2)); - } +} +UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2) +{ + //!!! add threshold to equality comparisons + return ((CompCode == OPCC1_LT && Val1 < Val2) + || (CompCode == OPCC1_GT && Val1 > Val2) + || (CompCode == OPCC1_LTEQ && Val1 <= Val2) + || (CompCode == OPCC1_GTEQ && Val1 >= Val2) + || (CompCode == OPCC1_EQ && Val1 == Val2) + || (CompCode == OPCC1_NEQ && Val1 != Val2)); } @@ -3253,9 +3925,6 @@ NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBY UWORD Count2, Count3, MinCount; UWORD i; - void *pArg2 = NULL, - *pArg3 = NULL; - TypeCode2 = cCmdDSType(Arg2); TypeCode3 = cCmdDSType(Arg3); @@ -3269,11 +3938,8 @@ NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBY //Simple case, both args are scalars. Solve and return. if (!IS_AGGREGATE_TYPE(TypeCode2)) { - pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); - pArg3 = cCmdResolveDataArg(Arg3, Offset3, &TypeCode3); - - ArgVal2 = cCmdGetVal(pArg2, TypeCode2); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); //Once we find an inequality, we can determine the result of the comparison *Finished = cCmdCompare(OPCC1_NEQ, ArgVal2, ArgVal3, TypeCode2, TypeCode3); @@ -3355,102 +4021,188 @@ NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBY return Status; } +ULONG gClearProfileInfo= 0, bigExecTime= 0; +#if VMProfilingCode +void UpdateProfileInfo(ULONG shortOp, CODE_WORD *pInstr, ULONG execTime, ULONG InstrSize) +{ + ULONG j; + ULONG opCode; + + if(execTime > 500 && shortOp == 8) + bigExecTime= shortOp; + if(gClearProfileInfo) { + ExecutedInstrs= 0; + CmdCtrlTime= 0; + OverheadTime= 0; + CmdCtrlCalls= 0; + LastAvgCount= 0; + for(j= 0; j < 255; j++) + CmdCtrlClumpTime[j]= 0; + for(j= 0; j < OPCODE_COUNT; j++) { + InstrProfile[j].Avg= 0; + InstrProfile[j].Time= 0; + InstrProfile[j].Count= 0; + InstrProfile[j].Max= 0; + } + for(j= 0; j < SYSCALL_COUNT; j++) { + SysCallProfile[j].Avg= 0; + SysCallProfile[j].Time= 0; + SysCallProfile[j].Count= 0; + SysCallProfile[j].Max= 0; + } + for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) { + ShortInstrProfile[j].Avg= 0; + ShortInstrProfile[j].Time= 0; + ShortInstrProfile[j].Count= 0; + ShortInstrProfile[j].Max= 0; + } + for(j= 0; j < NUM_INTERP_FUNCS; j++) { + InterpFuncProfile[j].Avg= 0; + InterpFuncProfile[j].Time= 0; + InterpFuncProfile[j].Count= 0; + InterpFuncProfile[j].Max= 0; + } + gClearProfileInfo= FALSE; + } + ExecutedInstrs ++; + if(shortOp > 7) // shortop bit set + { + ShortInstrProfile[shortOp-8].Time += execTime; + ShortInstrProfile[shortOp-8].Count++; + if(execTime > ShortInstrProfile[shortOp-8].Max) + ShortInstrProfile[shortOp-8].Max= execTime; + } + else + { + opCode = OP_CODE(pInstr); + InstrProfile[opCode].Time += execTime; + InstrProfile[opCode].Count++; + if(execTime > InstrProfile[opCode].Max) + InstrProfile[opCode].Max= execTime; + if(opCode == OP_SYSCALL) + { + SysCallProfile[GetDataArg(pInstr[1])].Time += execTime; + SysCallProfile[GetDataArg(pInstr[1])].Count++; + if(execTime > SysCallProfile[GetDataArg(pInstr[1])].Max) + SysCallProfile[GetDataArg(pInstr[1])].Max= execTime; + } + + InterpFuncProfile[InstrSize].Time += execTime; + InterpFuncProfile[InstrSize].Count++; + if(execTime > InterpFuncProfile[InstrSize].Max) + InterpFuncProfile[InstrSize].Max= execTime; + } + if(ExecutedInstrs - LastAvgCount > 999) // every N instrs, update avgs + { + for(j= 0; j < OPCODE_COUNT; j++) + if(InstrProfile[j].Count) + InstrProfile[j].Avg= InstrProfile[j].Time/InstrProfile[j].Count; + for(j= 0; j < SYSCALL_COUNT; j++) + if(SysCallProfile[j].Count) + SysCallProfile[j].Avg= SysCallProfile[j].Time/SysCallProfile[j].Count; + for(j= 0; j < NUM_SHORT_OPCODE_COUNT; j++) + if(ShortInstrProfile[j].Count) + ShortInstrProfile[j].Avg= ShortInstrProfile[j].Time/ShortInstrProfile[j].Count; + for(j= 0; j < NUM_INTERP_FUNCS; j++) + if(InterpFuncProfile[j].Count) + InterpFuncProfile[j].Avg= InterpFuncProfile[j].Time/InterpFuncProfile[j].Count; + LastAvgCount= ExecutedInstrs; + } +} +#endif + // // Interpreter Functions // -#define VAR_INSTR_SIZE 0xE -NXT_STATUS cCmdInterpFromClump(CLUMP_ID Clump) +NXT_STATUS cCmdInterpFromClump() { + CLUMP_ID Clump= VarsCmd.RunQ.Head; NXT_STATUS Status = NO_ERR; CLUMP_REC * pClumpRec; - CODE_WORD * pInstr; - UBYTE InterpFuncIndex, InstrSize; + CODE_WORD * pInstr, *lastClumpInstr; + UBYTE InstrSize; + ULONG shortOp, nextMSTick; + SLONG i; #if VM_BENCHMARK ULONG InstrTime = dTimerRead(); #endif - if (!cCmdIsClumpIDSane(Clump)) - { - //Caller gave us a bad clump ID -- something is very wrong! Force interpretter to halt. - NXT_BREAK; - return (ERR_ARG); - } + if (!cCmdIsClumpIDSane(Clump)) // this means all clumps are asleep + return TIMES_UP; //Resolve clump record structure and current instruction pointer pClumpRec = &(VarsCmd.pAllClumps[Clump]); - pInstr = (VarsCmd.pCodespace + pClumpRec->CodeStart + pClumpRec->PC); - - //Get instruction size in bytes. - InstrSize = INSTR_SIZE(pInstr); - - //If instruction is odd-sized or if "real" op code is out of range, give up and return ERR_INSTR - if ((InstrSize & 0x01) || OP_CODE(pInstr) >= OPCODE_COUNT) - return (ERR_INSTR); - - InterpFuncIndex = (InstrSize / 2) - 1; + pInstr = pClumpRec->PC; // abs + lastClumpInstr= pClumpRec->CodeEnd; // abs -#ifdef USE_SHORT_OPS - //If instruction has shortened encoding, add 1 for true interpretter - if (IS_SHORT_OP(pInstr)) + i= gInstrsToExecute; + nextMSTick= dTimerGetNextMSTickCnt(); + do { - InterpFuncIndex++; - } +#if VMProfilingCode + ULONG instrStartTime; + instrStartTime= dTimerReadHiRes(); #endif - //Peg InterpFuncIndex to 'Other'. Illegal instructions will be caught in cCmdInterpOther(). - if (InterpFuncIndex > 4) - InterpFuncIndex = 4; - - //If instruction is variably-sized; true size is held in the first argument - //!!! This InstrSize wrangling MUST occur after computing InterpFuncIndex - //because variable sized instructions may confuse the code otherwise - if (InstrSize == VAR_INSTR_SIZE) - InstrSize = (UBYTE)(pInstr[1]); - - //Set ScratchPC to clump's current PC so sub-interpreters can apply relative offsets - VarsCmd.ScratchPC = pClumpRec->PC; - - //Set CallerClump to Clump, for use by instructions such as OP_ACQUIRE - VarsCmd.CallerClump = Clump; - - Status = (*InterpFuncs[InterpFuncIndex])(pInstr); + ULONG instrWord= *(UWORD*)pInstr; + shortOp= (instrWord>>8) & 0x0F; + if(shortOp > 7) // shortop bit set + Status= ShortInterpFuncs[shortOp - 8](pInstr); + else + { // we know this is a long instr, dispatch on num params, which correlates to size + InstrSize = INSTR_SIZE(instrWord); // keep in a local for profiling + Status = (*InterpFuncs[InstrSize])(pInstr); + } - if (Status == ERR_MEM) - { - //Memory is full. Compact dataspace and try the instruction again. - //!!! Could compact DopeVectorArray here - cCmdDSCompact(); - Status = (*InterpFuncs[InterpFuncIndex])(pInstr); - } +#if VMProfilingCode + UpdateProfileInfo(shortOp, pInstr, dTimerReadHiRes() - instrStartTime, InstrSize); +#endif - if (!IS_ERR(Status)) - { - //If clump is finished, reset PC and firecount - if (Status == CLUMP_DONE) +afterCompaction: + if (Status == NO_ERR) + pInstr += gPCDelta; + else if (Status == CLUMP_DONE) // already requeued { - pClumpRec->PC = 0; + pClumpRec->PC = pClumpRec->CodeStart; pClumpRec->CurrFireCount = pClumpRec->InitFireCount; + return Status; } - //Else, if instruction has provided override program counter, use it - else if (Status == PC_OVERRIDE) + else if (Status == CLUMP_SUSPEND || Status == BREAKOUT_REQ || Status == ROTATE_QUEUE) // already requeued { - pClumpRec->PC = VarsCmd.ScratchPC; + pClumpRec->PC = pInstr + gPCDelta; + //Throw error if we ever advance beyond the clump's codespace + if (pInstr > lastClumpInstr) + { + NXT_BREAK; + Status = ERR_INSTR; + } + return Status; } - //Else, auto-advance from encoded instruction size (PC is word-based) - else + else if (Status == ERR_MEM) { - pClumpRec->PC += InstrSize / 2; + //Memory is full. Compact dataspace and try the instruction again. + //!!! Could compact DopeVectorArray here + cCmdDSCompact(); + if(shortOp > 7) // shortop bit set + Status= ShortInterpFuncs[shortOp - 8](pInstr); + else + Status = (*InterpFuncs[InstrSize])(pInstr); + if(Status == ERR_MEM) + return Status; + else + goto afterCompaction; } + else // other errors, breakout, stop + return Status; //Throw error if we ever advance beyond the clump's codespace - if (pClumpRec->PC > cCmdGetCodespaceCount(Clump)) + if (pInstr > lastClumpInstr) { NXT_BREAK; Status = ERR_INSTR; } - } #if VM_BENCHMARK //Increment opcode count @@ -3463,8 +4215,16 @@ NXT_STATUS cCmdInterpFromClump(CLUMP_ID Clump) if (InstrTime > VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2]) VarsCmd.OpcodeBenchmarks[OP_CODE(pInstr)][2] = InstrTime; } + VarsCmd.InstrCount++; #endif + //Count one more instruction for this pass + if ((SLONG)(nextMSTick - dTimerReadTicks()) <= 0) // HWTimer has passed ms tick limit + Status= TIMES_UP; + else if(--i <= 0) + Status= ROTATE_QUEUE; + } while (!Status); + pClumpRec->PC= pInstr; return (Status); } @@ -3474,35 +4234,19 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1; - void *pArg1 = NULL; - TYPE_CODE TypeCode1; NXT_ASSERT(pCode != NULL); -#ifdef USE_SHORT_OPS - if (IS_SHORT_OP(pCode)) - { - //add mapping from quick op to real op - opCode = ShortOpMap[SHORT_OP_CODE(pCode)]; - Arg1 = SHORT_ARG(pCode); - } - else - { + gPCDelta= 2; opCode = OP_CODE(pCode); Arg1 = pCode[1]; - } -#else - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; -#endif //USE_SHORT_OPS - switch (opCode) { case OP_JMP: { - VarsCmd.ScratchPC = VarsCmd.ScratchPC + (SWORD)Arg1; - Status = PC_OVERRIDE; + gPCDelta= (SWORD)Arg1; + Status = NO_ERR; } break; @@ -3511,7 +4255,7 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); - Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSPtr(Arg1, 0), VarsCmd.CallerClump); + Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); } break; @@ -3520,7 +4264,7 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); NXT_ASSERT(VarsCmd.pDataspaceTOC[Arg1].TypeCode == TC_MUTEX); - Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSPtr(Arg1, 0), VarsCmd.CallerClump); + Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); } break; @@ -3530,8 +4274,8 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) //Take Subroutine off RunQ //Add Subroutine's caller to RunQ - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.CallerClump); - cCmdEnQClump(&(VarsCmd.RunQ), *((CLUMP_ID *)cCmdDSPtr(Arg1, 0))); + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); + cCmdEnQClump(&(VarsCmd.RunQ), *((CLUMP_ID *)cCmdDSScalarPtr(Arg1, 0))); Status = CLUMP_DONE; } @@ -3539,8 +4283,9 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) case OP_FINCLUMPIMMED: { - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.CallerClump); //Dequeue finalized clump - cCmdSchedDependent(VarsCmd.CallerClump, (CLUMP_ID)Arg1); // Use immediate form + CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val + cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump + cCmdSchedDependent(Clump, (CLUMP_ID)Arg1); // Use immediate form Status = CLUMP_DONE; } @@ -3548,10 +4293,7 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) case OP_GETTICK: { - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - - - cCmdSetVal(pArg1, TypeCode1, dTimerRead()); + cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); } break; @@ -3559,16 +4301,9 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) { //Unwired Arg1 means always stop if (Arg1 == NOT_A_DS_ID) - { Status = STOP_REQ; - } - else - { - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - - if (cCmdGetVal(pArg1, TypeCode1) > 0) - Status = STOP_REQ; - } + else if (cCmdGetScalarValFromDataArg(Arg1, 0) > 0) + Status = STOP_REQ; } break; @@ -3584,6 +4319,78 @@ NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode) return (Status); } +ULONG scalarNots= 0, scalarBrtst= 0, scalarUn2Other= 0, scalarUn2Dispatch= 0, polyUn2Dispatch= 0; +NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + UBYTE opCode; + + NXT_ASSERT(pCode != NULL); + opCode = OP_CODE(pCode); + DATA_ARG Arg1, Arg2; + + scalarUn2Dispatch ++; + if(opCode == OP_NOT) // t2 && t3 guaranteed scalar + { + gPCDelta= 3; + Arg1 = pCode[1]; + Arg2 = pCode[2]; + ULONG ArgVal1, ArgVal2; + + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + ArgVal1= (!ArgVal2); + cCmdSetScalarValFromDataArg(Arg1, ArgVal1); + Status = NO_ERR; + scalarNots ++; + } + else if(opCode == OP_BRTST) + { + ULONG Branch, compare= COMP_CODE(pCode); + ULONG TypeCode; + + Arg1 = pCode[1]; + Arg2 = pCode[2]; + TypeCode = cCmdDSType(Arg2); + + if(Arg2 == NOT_A_DS_ID) + { + Branch= ((compare == OPCC1_EQ) + || (compare == OPCC1_LTEQ) + || (compare == OPCC1_GTEQ)); + } + else + { + if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops + { + UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); + Branch= *pBRVal == 0; + } + else + { + SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); + Branch= ((compare == OPCC1_EQ && SVal1 == 0) + || (compare == OPCC1_NEQ && SVal1 != 0) + || (compare == OPCC1_GT && SVal1 > 0) + || (compare == OPCC1_LT && SVal1 < 0) + || (compare == OPCC1_LTEQ && SVal1 <= 0) + || (compare == OPCC1_GTEQ && SVal1 >= 0)); + } + } + if (Branch) + gPCDelta = (SWORD)Arg1; + else + gPCDelta= 3; + Status = NO_ERR; + scalarBrtst ++; + } + else { + Status= cCmdInterpUnop2(pCode); + scalarUn2Other ++; + } + return Status; +} NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) { @@ -3598,35 +4405,25 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) UWORD ArgC; static UBYTE * ArgV[MAX_CALL_ARGS + 1]; + polyUn2Dispatch ++; UWORD Count; UWORD Offset; SLONG TmpSLong; ULONG TmpULong; ULONG ArgVal2; + float FltArgVal2; + char Buffer[30]; + char FormatString[5]; + UBYTE CheckTrailingZeros = 0; NXT_ASSERT(pCode != NULL); -#ifdef USE_SHORT_OPS - if (IS_SHORT_OP(pCode)) - { - //add mapping from quick op to real op - opCode = ShortOpMap[SHORT_OP_CODE(pCode)]; - Arg1 = SHORT_ARG(pCode) + pCode[1]; - Arg2 = pCode[1]; - } - else - { - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; - Arg2 = pCode[2]; - } -#else + gPCDelta= 3; opCode = OP_CODE(pCode); Arg1 = pCode[1]; Arg2 = pCode[2]; -#endif //USE_SHORT_OPS - if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST) + if (opCode == OP_NEG || opCode == OP_NOT || opCode == OP_TST || opCode == OP_SQRT || opCode == OP_ABS) { return cCmdInterpPolyUnop2(*pCode, Arg1, 0, Arg2, 0); } @@ -3635,24 +4432,7 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) { case OP_MOV: { - //!!! Optimized move for byte arrays (makes File I/O involving CStrs tolerable). Optimize for other cases? - if ((cCmdDSType(Arg1) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg1)) == TC_UBYTE) && - (cCmdDSType(Arg2) == TC_ARRAY) && (cCmdDSType(INC_ID(Arg2)) == TC_UBYTE)) - { - Count = cCmdArrayCount(Arg2, 0); - Status = cCmdDSArrayAlloc(Arg1, 0, Count); - if (IS_ERR(Status)) - return Status; - - pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); - pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); - - memmove(pArg1, pArg2, Count); - } - else - { - Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0); - } + Status= cCmdMove(Arg1, Arg2); } break; @@ -3660,27 +4440,44 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) { //!!! Should throw error if TypeCode1 is non-scalar // Accepting non-scalar destinations could have unpredictable results! - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - cCmdSetVal(pArg1, TypeCode1, Arg2); + cCmdSetScalarValFromDataArg(Arg1, Arg2); } break; case OP_BRTST: { - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - if (cCmdCompare(COMP_CODE(pCode), (SLONG)cCmdGetVal(pArg2, TypeCode2), 0, TC_SLONG, TC_SLONG)) + //!!!BDUGGAN BRTST w/ Float? + ULONG Branch, compare= COMP_CODE(pCode); + ULONG TypeCode = cCmdDSType(Arg2); + if(compare == OPCC1_EQ && TypeCode == TC_UBYTE) // very common for loops { - VarsCmd.ScratchPC = VarsCmd.ScratchPC + (SWORD)Arg1; - Status = PC_OVERRIDE; + UBYTE *pBRVal = (VarsCmd.pDataspace + VarsCmd.pDataspaceTOC[Arg2].DSOffset); + Branch= *pBRVal == 0; + } + else + { + SLONG SVal1 = (SLONG)cCmdGetScalarValFromDataArg(Arg2, 0); + Branch= ((compare == OPCC1_EQ && SVal1 == 0) + || (compare == OPCC1_NEQ && SVal1 != 0) + || (compare == OPCC1_GT && SVal1 > 0) + || (compare == OPCC1_LT && SVal1 < 0) + || (compare == OPCC1_LTEQ && SVal1 <= 0) + || (compare == OPCC1_GTEQ && SVal1 >= 0)); + } + if (Branch) + + { + gPCDelta = (SWORD)Arg1; + Status = NO_ERR; } } break; case OP_FINCLUMP: { - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.CallerClump); //Dequeue finalized clump - cCmdSchedDependents(VarsCmd.CallerClump, (SWORD)Arg1, (SWORD)Arg2); - + CLUMP_ID Clump= VarsCmd.RunQ.Head; // DeQ changes Head, use local val + cCmdDeQClump(&(VarsCmd.RunQ), Clump); //Dequeue finalized clump + cCmdSchedDependents(Clump, (SWORD)Arg1, (SWORD)Arg2); Status = CLUMP_DONE; } break; @@ -3692,9 +4489,9 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); - *((CLUMP_ID *)(cCmdDSPtr(Arg2, 0))) = VarsCmd.CallerClump; + *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; - cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.CallerClump); //Take caller off RunQ + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ Status = CLUMP_SUSPEND; @@ -3703,8 +4500,7 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) case OP_ARRSIZE: { - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - cCmdSetVal(pArg1, TypeCode1, cCmdArrayCount(Arg2, 0)); + cCmdSetScalarValFromDataArg(Arg1, cCmdArrayCount(Arg2, 0)); } break; @@ -3798,43 +4594,72 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); NXT_ASSERT(cCmdDSType(INC_ID(Arg1)) == TC_UBYTE); - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); //Make sure we're trying to convert a scalar to a string + TypeCode2= cCmdDSType(Arg2); NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode2)); - ArgVal2 = cCmdGetVal(pArg2, TypeCode2); - - //Calculate size of array - if (ArgVal2 == 0) - Count = 1; - else - Count = 0; - - if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) + if (TypeCode2 == TC_FLOAT) { - TmpSLong = (SLONG)ArgVal2; - //Add room for negative sign - if (TmpSLong < 0) - Count++; - - while (TmpSLong) - { - TmpSLong /= 10; - Count++; + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + // is number too big for display? then format differently and don't bother with trailing zeros + if ((FltArgVal2 > 9999999999999.99)||(FltArgVal2 < -999999999999.99)){ // these are the widest %.2f numbers that will fit on display + strcpy (FormatString, "%.6g"); + } + else{ + strcpy (FormatString, "%.2f"); + CheckTrailingZeros = 1; + } + Count = sprintf(Buffer, FormatString, FltArgVal2); + Count++; //add room for null terminator + + if (CheckTrailingZeros){ + // Determine if the trailing digits are zeros. If so, drop them + if (Buffer[Count-2] == 0x30) { // NOTE: 0x30 is ASCII 0 + if (Buffer[Count-3] == 0x30){ + strcpy (FormatString, "%.0f"); // the last two digits = 0, copy as integer + Count = Count - 3; // don't need memory for decimal and 2 ascii characters + } + else { + strcpy (FormatString, "%.1f"); // only the 2nd digit = 0 so drop it, but keep the tenths place + Count = Count - 1; // don't need memory for 2nd ascii character + } + } } } else { - TmpULong = ArgVal2; - while (TmpULong) + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + //Calculate size of array + if (ArgVal2 == 0) + Count = 1; + else { + Count = 0; + SLONG digits= 0; + ULONG Tmp= 1; + if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) { - TmpULong /= 10; - Count++; + TmpSLong = (SLONG)ArgVal2; + //Add room for negative sign + if (TmpSLong < 0) { + Count++; + TmpULong= -TmpSLong; + } + else + TmpULong= ArgVal2; } - } + else + TmpULong= ArgVal2; + while (Tmp <= TmpULong && digits < 10) { // maxint is ten digits, max + Tmp *= 10; + digits++; + } + Count += digits; + } //add room for NULL terminator Count++; + } //Allocate array Status = cCmdDSArrayAlloc(Arg1, 0, Count); @@ -3844,7 +4669,11 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); //Populate array - if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) + if (TypeCode2 == TC_FLOAT) + { + sprintf(pArg1, FormatString, FltArgVal2); + } + else if (TypeCode2 == TC_SLONG || TypeCode2 == TC_SWORD || TypeCode2 == TC_SBYTE) { sprintf(pArg1, "%d", (SLONG)ArgVal2); } @@ -3895,7 +4724,22 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) } break; - default: + case OP_WAIT: + { + ULONG wait= 0; + //Unwired Arg2 defaults to wait 0, which rotates queue + if (Arg2 != NOT_A_DS_ID) + wait= cCmdGetScalarValFromDataArg(Arg2, 0); + if(wait == 0) + Status= ROTATE_QUEUE; + else + Status = cCmdSleepClump(wait + IOMapCmd.Tick); // put to sleep, to wake up wait ms in future + if(Arg1 != NOT_A_DS_ID) + cCmdSetScalarValFromDataArg(Arg1, dTimerReadNoPoll()); + } + break; + + default: { //Fatal error: Unrecognized instruction NXT_BREAK; @@ -3908,13 +4752,14 @@ NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode) } -NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2) +NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1Param, DATA_ARG Arg2, UWORD Offset2Param) { NXT_STATUS Status = NO_ERR; TYPE_CODE TypeCode1, TypeCode2; DV_INDEX DVIndex1, DVIndex2; ULONG ArgVal1, ArgVal2; - UWORD Count1, Count2; + float FltArgVal1, FltArgVal2; + UWORD Count1, Count2, Offset1= Offset1Param, Offset2= Offset2Param; UWORD MinArrayCount; UWORD i; //!!! AdvCluster is intended to catch the case where sources are Cluster and an Array of Clusters. @@ -3933,16 +4778,46 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); pArg1 = cCmdResolveDataArg(Arg1, Offset1, &TypeCode1); - pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); - ArgVal2 = cCmdGetVal(pArg2, TypeCode2); - ArgVal1 = cCmdUnop2(Code, ArgVal2, TypeCode2); - cCmdSetVal(pArg1, TypeCode1, ArgVal1); + if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT) + { + pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + FltArgVal1 = cCmdUnop2Flt(Code, FltArgVal2, TypeCode2); + cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); + } + else + { + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, Offset2); + if(OP_CODE(&Code) == OP_MOV) + ArgVal1= ArgVal2; + else + ArgVal1 = cCmdUnop2(Code, ArgVal2, TypeCode2); + cCmdSetVal(pArg1, TypeCode1, ArgVal1); + } return Status; } //At least one of the args is an aggregate type + if(TypeCode1 == TC_ARRAY && TypeCode2 == TC_ARRAY) { + TYPE_CODE tc1, tc2; + tc1= cCmdDSType(INC_ID(Arg1)); + tc2= cCmdDSType(INC_ID(Arg2)); + if(tc1 <= TC_LAST_INT_SCALAR && tc1 == tc2) { + void *pArg1, *pArg2; + ULONG Count = cCmdArrayCount(Arg2, Offset2); + Status = cCmdDSArrayAlloc(Arg1, Offset1, Count); + if (IS_ERR(Status)) + return Status; + pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); + pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); + memmove(pArg1, pArg2, Count * cCmdSizeOf(tc1)); + return Status; + } + } + + // // Initialize Count and ArrayType local variables for each argument // @@ -3966,6 +4841,11 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset NXT_BREAK; return (ERR_ARG); } + if(Count2 == 0) { // both arrays, input is empty, is output already empty? + Count1= cCmdArrayCount(Arg1, Offset1); + if(Count1 == 0) + return NO_ERR; + } MinArrayCount = Count2; @@ -3974,6 +4854,8 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset if (IS_ERR(Status)) return Status; + if(MinArrayCount == 0) // if we emptied array, nothing else to do. + return NO_ERR; Count1 = MinArrayCount; DVIndex1 = cCmdGetDVIndex(Arg1, Offset1); Offset1 = DV_ARRAY[DVIndex1].Offset; @@ -3995,7 +4877,6 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset // Loop through the sub-elements of aggregate arguments. // Call cCmdInterpPolyUnop2 recursively with simpler type. // - for (i = 0; i < Count1; i++) { Status = cCmdInterpPolyUnop2(Code, Arg1, Offset1, Arg2, Offset2); @@ -4013,7 +4894,6 @@ NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset else if ((TypeCode2 == TC_CLUSTER) && AdvCluster) Arg2 = cCmdNextDSElement(Arg2); } - return Status; } @@ -4023,38 +4903,189 @@ ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode) UBYTE opCode; opCode = OP_CODE((&Code)); + if(opCode == OP_MOV) + return Operand; + else if(opCode == OP_NEG) + return (-((SLONG)Operand)); + else if(opCode == OP_NOT) + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + return (!Operand); + else if(opCode == OP_TST) + return cCmdCompare(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); + else if(opCode == OP_ABS) + return abs(Operand); + else + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } +} - switch (opCode) +float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + if(opCode == OP_MOV) + return Operand; + else if(opCode == OP_NEG) + return (-(Operand)); + else if(opCode == OP_NOT) + //!!! OP_NOT is logical, *not* bit-wise. + //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. + return (!Operand); + else if(opCode == OP_TST) + return cCmdCompareFlt(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); + else if(opCode == OP_ABS) + return fabsf(Operand); + else if(opCode == OP_SQRT) + return sqrt(Operand); +#if 0 + else if(opCode == OP_SIN) + return sin(Operand); + else if(opCode == OP_COS) + return cos(Operand); + else if(opCode == OP_TAN) + return tan(Operand); + else if(opCode == OP_ASIN) + return asin(Operand); + else if(opCode == OP_ACOS) + return acos(Operand); + else if(opCode == OP_ATAN) + return atan(Operand); +#endif + else { - case OP_MOV: + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } +} + +NXT_STATUS cCmdIOGetSet(ULONG opCode, DATA_ARG Arg1, DATA_ARG Arg2, DATA_ARG Arg3) +{ + ULONG ArgVal1, ArgVal2; + TYPE_CODE TypeCode2; + void *pArg2 = NULL; + switch(opCode) + { + case OP_GETOUT: { - return Operand; + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(0x200 | (Arg3 + ArgVal2 * IO_OUT_FPP)); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + cCmdSetScalarValFromDataArg(Arg1, cCmdGetVal(pArg2, TypeCode2)); } - - case OP_NEG: + break; + //!!! All IO map access commands should screen illegal port values! + // Right now, cCmdResolveIODataArg's implementation allows SETIN/GETIN to access arbitrary RAM! + case OP_SETIN: { - return (-((SLONG)Operand)); + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + ArgVal1 = cCmdGetScalarValFromDataArg(Arg1, 0); + cCmdSetVal(pArg2, TypeCode2, ArgVal1); } + break; + case OP_GETIN: + { + TYPE_CODE TypeCode1; + void * pArg1; + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, 0); + Arg2 = (UWORD)(Arg3 + ArgVal2 * IO_IN_FPP); + pArg2 = cCmdResolveIODataArg(Arg2, 0, &TypeCode2); + TypeCode1= cCmdDSType(Arg1); + pArg1= cCmdDSScalarPtr(Arg1, 0); + if(TypeCode1 <= TC_SBYTE && TypeCode1 <= TC_SBYTE) // seems really common + *(UBYTE*)pArg1= *(UBYTE*)pArg2; + else + cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2)); + } + break; + } + return NO_ERR; +} + +ULONG scalarCmp= 0, scalarFloatCmp= 0, recursiveCmp= 0, PolyScalarCmp= 0, polyPolyCmp= 0, scalarOther= 0, scalarBinopDispatch= 0, polyBinopDispatch= 0; +NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + UBYTE opCode; + UBYTE CmpBool; - case OP_NOT: + NXT_ASSERT(pCode != NULL); + opCode = OP_CODE(pCode); + DATA_ARG Arg1, Arg2, Arg3; + + scalarBinopDispatch ++; + if(opCode == OP_CMP) // t2 && t3 guaranteed scalar or string + { + gPCDelta= 4; + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + ULONG ArgVal1, ArgVal2, ArgVal3; + TYPE_CODE TypeCode2, TypeCode3; + DS_TOC_ENTRY *dsTOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; + DS_TOC_ENTRY *dsTOC3Ptr= &VarsCmd.pDataspaceTOC[Arg3]; + + TypeCode2 = dsTOC2Ptr->TypeCode; + TypeCode3 = dsTOC3Ptr->TypeCode; + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ArgVal2= GetProcArray[TypeCode2](VarsCmd.pDataspace + dsTOC2Ptr->DSOffset); + ArgVal3= GetProcArray[TypeCode3](VarsCmd.pDataspace + dsTOC3Ptr->DSOffset); + ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + DS_TOC_ENTRY *dsTOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1]; + SetProcArray[dsTOC1Ptr->TypeCode](VarsCmd.pDataspace + dsTOC1Ptr->DSOffset, ArgVal1); + scalarCmp++; + Status = NO_ERR; + } + else if (TypeCode2 == TC_ARRAY) // two strings { - //!!! OP_NOT is logical, *not* bit-wise. - //This differs from the other logical ops because we don't distinguish booleans from UBYTEs. - return (!Operand); + // memcmp(); here or in compareagg, could use memcmp to speed up string compares ??? + Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); + cCmdSetScalarValFromDataArg(Arg1, CmpBool); + recursiveCmp++; } - - case OP_TST: - { - return cCmdCompare(COMP_CODE((&Code)), Operand, 0, TypeCode, TypeCode); + else { // floats + Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); + scalarFloatCmp++; } + } + else if(opCode == OP_BRCMP) { // t2 and t3 guaranteed scalar + TYPE_CODE TypeCode2, TypeCode3; + ULONG ArgVal2, ArgVal3; - default: - { - //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) - NXT_BREAK; - return 0; + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + TypeCode2= cCmdDSType(Arg2); + TypeCode3= cCmdDSType(Arg3); + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + + if (CmpBool) + gPCDelta = (SWORD)Arg1; + else + gPCDelta= 4; + Status= NO_ERR; + } + else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) { + Arg1 = pCode[1]; + Arg2 = pCode[2]; + Arg3 = pCode[3]; + Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); + gPCDelta= 4; } + else { + scalarOther ++; + Status= cCmdInterpBinop(pCode); } + return Status; } @@ -4063,136 +5094,74 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1, Arg2, Arg3; - TYPE_CODE TypeCode1, TypeCode2, TypeCode3; - ULONG ArgVal2, ArgVal3; + ULONG ArgVal3; UBYTE CmpBool; DV_INDEX DVIndex1, DVIndex2; UWORD i; - void * pArg1 = NULL, - *pArg2 = NULL, - *pArg3 = NULL; + polyBinopDispatch ++; + gPCDelta= 4; NXT_ASSERT(pCode != NULL); -#ifdef USE_SHORT_OPS - if (IS_SHORT_OP(pCode)) - { - //add mapping from quick op to real op - opCode = ShortOpMap[SHORT_OP_CODE(pCode)]; - Arg1 = SHORT_ARG(pCode) + pCode[1]; - Arg2 = pCode[1]; - Arg3 = pCode[2]; - } - else - { opCode = OP_CODE(pCode); Arg1 = pCode[1]; Arg2 = pCode[2]; Arg3 = pCode[3]; - } -#else - opCode = OP_CODE(pCode); - Arg1 = pCode[1]; - Arg2 = pCode[2]; - Arg3 = pCode[3]; -#endif //USE_SHORT_OPS - - if (opCode == OP_ADD || opCode == OP_SUB || opCode == OP_MUL || opCode == OP_DIV || opCode == OP_MOD || - opCode == OP_AND || opCode == OP_OR || opCode == OP_XOR) - { - return cCmdInterpPolyBinop(opCode, Arg1, 0, Arg2, 0, Arg3, 0); - } - - //Resolve data arguments, except for opcodes which the arguments are not DataArgs - if (opCode != OP_BRCMP) - { - pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - } - - if (opCode != OP_INDEX) - { - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - ArgVal2 = cCmdGetVal(pArg2, TypeCode2); - } - - if ((opCode != OP_GETOUT) && (opCode != OP_SETIN) && (opCode != OP_GETIN) && (opCode != OP_INDEX) && (opCode != OP_ARRINIT)) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } + if (opCode <= OP_XOR) // && ! OP_NEG, can't happen since it is unop + Status= cCmdInterpPolyBinop(opCode, Arg1, 0, Arg2, 0, Arg3, 0); + else if(opCode >= OP_SETIN && opCode <= OP_GETOUT) + Status= cCmdIOGetSet(opCode, Arg1, Arg2, Arg3); + else { switch (opCode) { - case OP_CMP: { - if (!IS_AGGREGATE_TYPE(cCmdDSType(Arg1)) && IS_AGGREGATE_TYPE(cCmdDSType(Arg2)) && IS_AGGREGATE_TYPE(cCmdDSType(Arg3))) + TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ULONG ArgVal1, ArgVal2, ArgVal3; + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + ArgVal1= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + cCmdSetScalarValFromDataArg(Arg1, ArgVal1); + PolyScalarCmp++; + } + else if (IS_AGGREGATE_TYPE(TypeCode2) && IS_AGGREGATE_TYPE(TypeCode3) && !IS_AGGREGATE_TYPE(cCmdDSType(Arg1))) { //Compare Aggregates Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); - cCmdSetVal(pArg1, TypeCode1, CmpBool); + cCmdSetScalarValFromDataArg(Arg1, CmpBool); + recursiveCmp++; } else { //Compare Elements Status = cCmdInterpPolyBinop(*pCode, Arg1, 0, Arg2, 0, Arg3, 0); + polyPolyCmp++; } } break; case OP_BRCMP: { - //Compare Aggregates + TYPE_CODE TypeCode2= cCmdDSType(Arg2), TypeCode3= cCmdDSType(Arg3); + if(TypeCode2 <= TC_LAST_INT_SCALAR && TypeCode3 <= TC_LAST_INT_SCALAR) { + ULONG ArgVal2, ArgVal3; + ArgVal2= cCmdGetScalarValFromDataArg(Arg2, 0); + ArgVal3= cCmdGetScalarValFromDataArg(Arg3, 0); + CmpBool= cCmdCompare(COMP_CODE(pCode), ArgVal2, ArgVal3, TypeCode2, TypeCode3); + } + else //Compare Aggregates Status = cCmdCompareAggregates(COMP_CODE(pCode), &CmpBool, Arg2, 0, Arg3, 0); if (CmpBool) - { - VarsCmd.ScratchPC = VarsCmd.ScratchPC + (SWORD)Arg1; - Status = PC_OVERRIDE; - } - } - break; - - case OP_GETOUT: - { - Arg2 = (UWORD)(0xC200 | (Arg3 + ArgVal2 * IO_OUT_FPP)); - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - - cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2)); - } - break; - - //!!! All IO map access commands should screen illegal port values! - // Right now, cCmdResolveDataArg's implementation allows SETIN/GETIN to access arbitrary RAM! - case OP_SETIN: - { - Arg2 = (UWORD)(0xC000 | (Arg3 + ArgVal2 * IO_IN_FPP)); - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - - cCmdSetVal(pArg2, TypeCode2, cCmdGetVal(pArg1, TypeCode1)); - } - break; - - case OP_GETIN: - { - Arg2 = (UWORD)(0xC000 | (Arg3 + ArgVal2 * IO_IN_FPP)); - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); - - cCmdSetVal(pArg1, TypeCode1, cCmdGetVal(pArg2, TypeCode2)); + gPCDelta = (SWORD)Arg1; } break; case OP_INDEX: { - if (Arg3 != NOT_A_DS_ID) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } - else //Index input unwired - { - ArgVal3 = 0; - } + ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; DVIndex2 = cCmdGetDVIndex(Arg2, 0); if (ArgVal3 >= DV_ARRAY[DVIndex2].Count) @@ -4206,26 +5175,26 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) { //Arg1 - Dst, Arg2 - element type/default val, Arg3 - length - NXT_ASSERT(TypeCode1 == TC_ARRAY); + NXT_ASSERT(cCmdDSType(Arg1) == TC_ARRAY); - if (Arg3 != NOT_A_DS_ID) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } - else //Length input unwired - { - ArgVal3 = 0; - } + ArgVal3 = (Arg3 != NOT_A_DS_ID) ? cCmdGetScalarValFromDataArg(Arg3, 0) : 0; Status = cCmdDSArrayAlloc(Arg1, 0, (UWORD)ArgVal3); - if (IS_ERR(Status)) - return Status; - + if (!IS_ERR(Status)) + { DVIndex1 = cCmdGetDVIndex(Arg1, 0); - for (i = 0; i < ArgVal3; i++) + if(cCmdDSType(Arg2) <= TC_LAST_INT_SCALAR) + { + ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); + TYPE_CODE TypeCode= cCmdDSType(INC_ID(Arg1)); + for (i = 0; i < ArgVal3; i++) // could init ptr and incr by offset GM??? { //copy Arg2 into each element of Arg1 + cCmdSetVal(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex1, i), TypeCode, val); + } + } + else + for (i = 0; i < ArgVal3; i++) //copy Arg2 into each element of Arg1 Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg1), ARRAY_ELEM_OFFSET(DVIndex1, i), Arg2, 0); } } @@ -4239,7 +5208,7 @@ NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode) } break; } - + } return (Status); } @@ -4250,6 +5219,7 @@ NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset TYPE_CODE TypeCode1, TypeCode2, TypeCode3; DV_INDEX DVIndex1, DVIndex2, DVIndex3; ULONG ArgVal1, ArgVal2, ArgVal3; + float FltArgVal1, FltArgVal2, FltArgVal3; UWORD Count1, Count2, Count3; UWORD MinArrayCount; UWORD i; @@ -4270,14 +5240,23 @@ NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset { NXT_ASSERT(!IS_AGGREGATE_TYPE(TypeCode1)); - pArg1 = cCmdResolveDataArg(Arg1, Offset1, &TypeCode1); - pArg2 = cCmdResolveDataArg(Arg2, Offset2, &TypeCode2); - pArg3 = cCmdResolveDataArg(Arg3, Offset3, &TypeCode3); + pArg1 = cCmdResolveDataArg(Arg1, Offset1, NULL); - ArgVal2 = cCmdGetVal(pArg2, TypeCode2); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); + if (TypeCode1 == TC_FLOAT || TypeCode2 == TC_FLOAT || TypeCode3 == TC_FLOAT){ + pArg2 = cCmdResolveDataArg(Arg2, Offset2, NULL); + pArg3 = cCmdResolveDataArg(Arg3, Offset3, NULL); + FltArgVal2 = cCmdGetValFlt(pArg2, TypeCode2); + FltArgVal3 = cCmdGetValFlt(pArg3, TypeCode3); + FltArgVal1 = cCmdBinopFlt(Code, FltArgVal2, FltArgVal3, TypeCode2, TypeCode3); + cCmdSetValFlt(pArg1, TypeCode1, FltArgVal1); + } + else + { + ArgVal2 = cCmdGetScalarValFromDataArg(Arg2, Offset2); + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, Offset3); ArgVal1 = cCmdBinop(Code, ArgVal2, ArgVal3, TypeCode2, TypeCode3); cCmdSetVal(pArg1, TypeCode1, ArgVal1); + } return Status; } @@ -4472,6 +5451,78 @@ ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE Lef } } + +float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType) +{ + UBYTE opCode; + + opCode = OP_CODE((&Code)); + + switch (opCode) + { + case OP_ADD: + { + return LeftOp + RightOp; + } + + case OP_SUB: + { + return LeftOp - RightOp; + } + + case OP_MUL: + { + return LeftOp * RightOp; + } + + case OP_DIV: + { + //Catch divide-by-zero for a portable, well-defined result. + //(x / 0) = 0. Thus Spake LOTHAR!! (It's technical.) + if (RightOp == 0) + return 0; + + return LeftOp / RightOp; + } + + case OP_MOD: + { + //As with OP_DIV, make sure (x % 0) = x is well-defined + if (RightOp == 0) + return (LeftOp); + + return (SLONG)LeftOp % (SLONG)RightOp; + } + + case OP_AND: + { + return ((SLONG)LeftOp & (SLONG)RightOp); + } + + case OP_OR: + { + return ((SLONG)LeftOp | (SLONG)RightOp); + } + + case OP_XOR: + { + return (((SLONG)LeftOp | (SLONG)RightOp) & (~((SLONG)LeftOp & (SLONG)RightOp))); + } + + case OP_CMP: + { + return cCmdCompareFlt(COMP_CODE((&Code)), LeftOp, RightOp, LeftType, RightType); + } + + default: + { + //Unrecognized instruction, NXT_BREAK for easy debugging (ERR_INSTR handled in caller) + NXT_BREAK; + return 0; + } + } +} + NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode) { //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) @@ -4479,6 +5530,144 @@ NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode) return (ERR_INSTR); } +NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode) +{ + //Fatal error: Unrecognized instruction (no current opcodes have zero instructions) + NXT_BREAK; + return (ERR_INSTR); +} + +NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1, Arg2; + + gPCDelta= 2; + Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); + Arg2 = GetDataArg(pCode[1]); + NXT_ASSERT(cCmdIsClumpIDSane((CLUMP_ID)Arg1)); + NXT_ASSERT(!cCmdIsClumpOnQ(&(VarsCmd.RunQ), (CLUMP_ID)Arg1)); + + NXT_ASSERT(cCmdIsDSElementIDSane(Arg2)); + + *((CLUMP_ID *)(cCmdDSScalarPtr(Arg2, 0))) = VarsCmd.RunQ.Head; + + cCmdDeQClump(&(VarsCmd.RunQ), VarsCmd.RunQ.Head); //Take caller off RunQ + cCmdEnQClump(&(VarsCmd.RunQ), (CLUMP_ID)Arg1); //Add callee to RunQ + + Status = CLUMP_SUSPEND; + + return Status; +} + +ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveArrInt= 0, moveOther= 0; +NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2) +{ + NXT_STATUS Status; + DS_TOC_ENTRY *TOC1Ptr= &VarsCmd.pDataspaceTOC[Arg1], + *TOC2Ptr= &VarsCmd.pDataspaceTOC[Arg2]; + TYPE_CODE tc1= TOC1Ptr->TypeCode, tc2= TOC2Ptr->TypeCode; + void *pArg1, *pArg2; + + if(tc1 <= TC_LAST_INT_SCALAR && tc2 <= TC_LAST_INT_SCALAR) + { + // if tc1 == tc2, do long, byte, then word assignment + if(tc1 == tc2) + { + moveSameInt++; + pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; + pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; + if(tc1 >= TC_ULONG) + *(ULONG*)pArg1= *(ULONG*)pArg2; + else if(tc1 <= TC_SBYTE) + *(UBYTE*)pArg1= *(UBYTE*)pArg2; + else + *(UWORD*)pArg1= *(UWORD*)pArg2; + Status= NO_ERR; + } + else + { + moveDiffInt++; + ULONG val= cCmdGetScalarValFromDataArg(Arg2, 0); + cCmdSetScalarValFromDataArg(Arg1, val); + Status= NO_ERR; + } + } + else if(tc1 == TC_FLOAT && tc2 == TC_FLOAT) { // may also need to speed up float to int and int to float conversions + moveFloat++; + pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset; + pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset; + *(float*)pArg1= *(float*)pArg2; + Status= NO_ERR; + } + //!!! Optimized move for arrays of ints. + else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY) + && ((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR) + && ((TOC1Ptr+1)->TypeCode == (TOC2Ptr+1)->TypeCode)) + { + ULONG Count; + moveArrInt++; + Count = cCmdArrayCount(Arg2, 0); + Status = cCmdDSArrayAlloc(Arg1, 0, Count); + if (IS_ERR(Status)) + return Status; + + pArg1 = cCmdResolveDataArg(Arg1, 0, NULL); + pArg2 = cCmdResolveDataArg(Arg2, 0, NULL); + + memmove(pArg1, pArg2, Count * cCmdSizeOf((TOC1Ptr+1)->TypeCode)); + } + else { // if ((tc1 == TC_CLUSTER) && (tc2 == TC_CLUSTER)) + moveOther++; + Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0); + } + return Status; +} + + +NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1, Arg2; + + Arg1 = GetDataArg(SHORT_ARG(pCode) + pCode[1]); + Arg2 = GetDataArg(pCode[1]); + Status= cCmdMove(Arg1, Arg2); + + gPCDelta= 2; + return Status; +} + +NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1; + + gPCDelta= 1; + Arg1 = GetDataArg(SHORT_ARG(pCode)); + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); + + Status = cCmdAcquireMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + + return Status; +} + +NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode) +{ + NXT_STATUS Status; + DATA_ARG Arg1; + + gPCDelta= 1; + Arg1 = GetDataArg(SHORT_ARG(pCode)); + NXT_ASSERT(cCmdIsDSElementIDSane(Arg1)); + NXT_ASSERT(cCmdDSType(Arg1) == TC_MUTEX); + + Status = cCmdReleaseMutex((MUTEX_Q *)cCmdDSScalarPtr(Arg1, 0)); + + return Status; +} + //OP_SETOUT gets it's own interpreter function because it is relatively complex // (called from cCmdInterpOther()) @@ -4525,8 +5714,7 @@ NXT_STATUS cCmdExecuteSetOut(CODE_WORD * const pCode) } else { - pPort = (UBYTE*)cCmdResolveDataArg(PortArg, 0, NULL); - Port = cCmdGetVal(pPort, TypeCodePortArg); + Port = cCmdGetScalarValFromDataArg(PortArg, 0); } //If user specified a valid port, process the tuples. Else, this port is a no-op @@ -4560,8 +5748,8 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) NXT_STATUS Status = NO_ERR; UBYTE opCode; DATA_ARG Arg1, Arg2, Arg3, Arg4, Arg5; - TYPE_CODE TypeCode1, TypeCode2, TypeCode3, TypeCode4, TypeCode5; - ULONG ArgVal1, ArgVal2, ArgVal3, ArgVal4, ArgVal5; + TYPE_CODE TypeCode1, TypeCode2, TypeCode3, TypeCode5; + ULONG ArgVal2, ArgVal3, ArgVal4, ArgVal5; UWORD ArrayCount1, ArrayCount2, ArrayCount3, ArrayCount4; UWORD MinCount; UWORD i,j; @@ -4575,11 +5763,15 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) void *pArg1 = NULL; void *pArg2 = NULL; void *pArg3 = NULL; - void *pArg4 = NULL; void *pArg5 = NULL; NXT_ASSERT(pCode != NULL); + ULONG sz= INSTR_SIZE(*(UWORD*)pCode); + if (sz == VAR_INSTR_SIZE) + sz = ((UWORD*)pCode)[1]; + gPCDelta= sz/2; // advance words, sz is in bytes + opCode = OP_CODE(pCode); switch (opCode) @@ -4604,7 +5796,7 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) //!!! Could avoid full data copy if we knew which portion to overwrite if (Arg1 != Arg2) { - Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg2, 0); + Status= cCmdMove(Arg1, Arg2); if (IS_ERR(Status)) return Status; } @@ -4672,24 +5864,14 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) ArrayCount2 = cCmdArrayCount(Arg2, 0); if (Arg3 != NOT_A_DS_ID) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); else //Index input unwired - { ArgVal3 = 0; - } if (Arg4 != NOT_A_DS_ID) - { - pArg4 = cCmdResolveDataArg(Arg4, 0, &TypeCode4); - ArgVal4 = cCmdGetVal(pArg4, TypeCode4); - } + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); else //Length input unwired, set to "rest" - { ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); - } //Bounds check if (ArgVal3 > ArrayCount2) @@ -4747,24 +5929,14 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) ArrayCount2--; if (Arg3 != NOT_A_DS_ID) - { - pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); - ArgVal3 = cCmdGetVal(pArg3, TypeCode3); - } + ArgVal3 = cCmdGetScalarValFromDataArg(Arg3, 0); else //Index input unwired - { ArgVal3 = 0; - } if (Arg4 != NOT_A_DS_ID) - { - pArg4 = cCmdResolveDataArg(Arg4, 0, &TypeCode4); - ArgVal4 = cCmdGetVal(pArg4, TypeCode4); - } + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); else //Length input unwired, set to "rest" - { ArgVal4 = (UWORD)(ArrayCount2 - ArgVal3); - } //Bounds check if (ArgVal3 > ArrayCount2) @@ -4863,6 +6035,13 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) { NXT_ASSERT(cCmdDSType(TmpDSID) == TC_ARRAY); TmpDVIndex = cCmdGetDVIndex(TmpDSID, 0); + // if flat, use memmove, otherwise this stuff + if(cCmdDSType(INC_ID(TmpDSID)) <= TC_LAST_INT_SCALAR) + { + memmove(VarsCmd.pDataspace + ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), VarsCmd.pDataspace + DV_ARRAY[TmpDVIndex].Offset, (UWORD)(DV_ARRAY[TmpDVIndex].ElemSize * DV_ARRAY[TmpDVIndex].Count)); + DstIndex += DV_ARRAY[TmpDVIndex].Count; + } + else for (j = 0; j < DV_ARRAY[TmpDVIndex].Count; j++) { Status = cCmdInterpPolyUnop2(OP_MOV, INC_ID(Arg2), ARRAY_ELEM_OFFSET(DVIndex2, DstIndex), INC_ID(TmpDSID), ARRAY_ELEM_OFFSET(TmpDVIndex, j)); @@ -4983,8 +6162,8 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) Arg4 = pCode[4]; //Move Type template to Dst - //This provides a default value for Dst and makes sure Dst is properly sized - Status = cCmdInterpPolyUnop2(OP_MOV, Arg1, 0, Arg4, 0); + //This provides a default value for Dst and makes sure Dst is properly sized + Status= cCmdMove(Arg1, Arg4); if (IS_ERR(Status)) return Status; @@ -5026,7 +6205,9 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) case OP_STRINGTONUM: { - + float ArgValF; + SLONG decimals= 0; + UBYTE cont= TRUE; // Arg1 - Dst number (output) // Arg2 - Offset past match (output) // Arg3 - Src string @@ -5044,18 +6225,12 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) Arg5 = pCode[5]; pArg1 = cCmdResolveDataArg(Arg1, 0, &TypeCode1); - pArg2 = cCmdResolveDataArg(Arg2, 0, &TypeCode2); pArg3 = cCmdResolveDataArg(Arg3, 0, &TypeCode3); if (Arg4 != NOT_A_DS_ID) - { - pArg4 = cCmdResolveDataArg(Arg4, 0, &TypeCode4); - ArgVal4 = cCmdGetVal(pArg4, TypeCode4); - } + ArgVal4 = cCmdGetScalarValFromDataArg(Arg4, 0); else //Offset input unwired - { ArgVal4 = 0; - } if (Arg5 != NOT_A_DS_ID) { @@ -5068,29 +6243,36 @@ NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode) } //Read number from string - if (sscanf(((PSZ)pArg3 + ArgVal4), "%d", &ArgVal1) == 1) + if (sscanf(((PSZ)pArg3 + ArgVal4), "%f", &ArgValF) == 1) { i = (UWORD)ArgVal4; - //Scan until we see the number + //Scan until we see the number, consumes negative sign too while ((((UBYTE *)pArg3)[i] < '0') || (((UBYTE *)pArg3)[i] > '9')) i++; - //Scan until we get past the number - while ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9')) - i++; - + //Scan until we get past the number and no more than one decimal + while (cont) { + if ((((UBYTE *)pArg3)[i] >= '0') && (((UBYTE *)pArg3)[i] <= '9')) + i++; + else if(((UBYTE *)pArg3)[i] == '.' && !decimals) { + i++; + decimals++; + } + else + cont= FALSE; + } ArgVal2 = i; } else { //Number wasn't found in string, use defaults - ArgVal1 = ArgVal5; + ArgValF = ArgVal5; ArgVal2 = 0; } //Set outputs - cCmdSetVal(pArg1, TypeCode1, ArgVal1); - cCmdSetVal(pArg2, TypeCode2, ArgVal2); + cCmdSetValFlt(pArg1, TypeCode1, ArgValF); + cCmdSetScalarValFromDataArg(Arg2, ArgVal2); } break; @@ -5528,6 +6710,7 @@ NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]) //Resolve array arguments DVIndex = *(DV_INDEX *)(ArgV[1]); + UBYTE sndVol= *(ArgV[3]); ArgV[1] = cCmdDVPtr(DVIndex); //!!! Should check filename and/or existence and return error before proceeding @@ -5538,7 +6721,9 @@ NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]) else pMapSound->Mode = SOUND_ONCE; - pMapSound->Volume = *(ArgV[3]); + if(sndVol > 4) + sndVol= 4; + pMapSound->Volume = sndVol; //SampleRate of '0' means "let file specify SampleRate" pMapSound->SampleRate = 0; pMapSound->Flags |= SOUND_UPDATE; @@ -5558,9 +6743,12 @@ NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]) // NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]) { + UBYTE sndVol= *(ArgV[4]); pMapSound->Freq = *(UWORD*)(ArgV[1]); pMapSound->Duration = *(UWORD*)(ArgV[2]); - pMapSound->Volume = *(ArgV[4]); + if(sndVol > 4) + sndVol= 4; + pMapSound->Volume = sndVol; pMapSound->Flags |= SOUND_UPDATE; if (*(ArgV[3]) == TRUE) @@ -5799,6 +6987,65 @@ NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]) return (NO_ERR); } + + +// +//cCmdWrapColorSensorRead +//ArgV[0]: (return) Error code, SBYTE +//ArgV[1]: Port, UBYTE +//ArgV[2]: SensorValue, SWORD +//ArgV[3]: RawArray, UWORD[NO_OF_COLORS] +//ArgV[4]: NormalizedArray, UWORD[NO_OF_COLORS] +//ArgV[5]: ScaledArray, SWORD[NO_OF_COLORS] +//ArgV[6]: InvalidData, UBYTE +// +NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]) +{ + DV_INDEX DVIndex; + NXT_STATUS Status = NO_ERR; + //Resolve return val arguments + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + //Resolve Port argument + UBYTE Port = *(UBYTE*)(ArgV[1]); + //Resolve SensorValue + SWORD SensorValue = *(SWORD*)(ArgV[2]); + //Resolve RawArray as array + DVIndex = *(DV_INDEX*)(ArgV[3]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[3] = cCmdDVPtr (DVIndex); + //Resolve NormalizedArray as array + DVIndex = *(DV_INDEX*)(ArgV[4]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[4] = cCmdDVPtr (DVIndex); + //Resolve ScaledArray as array + DVIndex = *(DV_INDEX*)(ArgV[5]); + NXT_ASSERT(IS_DV_INDEX_SANE(DestDVIndex)); + Status= cCmdDVArrayAlloc(DVIndex, NO_OF_COLORS); + if (IS_ERR(Status)) + return (Status); + ArgV[5] = cCmdDVPtr (DVIndex); + //Resolve InvalidData + UBYTE InvalidData = *(UBYTE*)(ArgV[6]); + + //call implementation with unwrapped parameters + *pReturnVal = cCmdColorSensorRead (Port, &SensorValue, (UWORD*)ArgV[3], (UWORD*)ArgV[4], (SWORD*)ArgV[5], &InvalidData); + + *(ArgV[2]) = SensorValue; + *(ArgV[6]) = InvalidData; + + if (IS_ERR(*pReturnVal)){ + return (*pReturnVal); + } + return NO_ERR; +} + + #define UNPACK_STATUS(StatusWord) ((SBYTE)(StatusWord)) NXT_STATUS cCmdBTCheckStatus(UBYTE Connection) @@ -6017,6 +7264,8 @@ NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]) return (NO_ERR); } + + #define MAX_IOM_BUFFER_SIZE 64 // //cCmdWrapIOMapRead @@ -6228,6 +7477,452 @@ void cCmdWriteBenchmarkFile() } #endif + +///////////////////////////////////////////////////////////// +// Dymanic syscall implementations +//////////////////////////////////////////////////////////// + +// +//cCmdWrapDatalogWrite +//ArgV[0]: (return) Error Code, SBYTE (NXT_STATUS) +//ArgV[1]: Message, CStr +// +NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]) +{ + NXT_STATUS Status = NO_ERR; + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[1]); + ArgV[1] = cCmdDVPtr(DVIndex); + + Status = cCmdDatalogWrite(ArgV[1], DV_ARRAY[DVIndex].Count); + + *(SBYTE *)(ArgV[0]) = Status; + + if (IS_FATAL(Status)) + return Status; + else + return (NO_ERR); +} + +// +//cCmdWrapDatalogGetTimes +//ArgV[0]: SyncTime, U32 +//ArgV[1]: SyncTick, U32 +// +NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]) +{ + *((ULONG *)ArgV[1]) = IOMapCmd.SyncTime; + *((ULONG *)ArgV[2]) = IOMapCmd.SyncTick; + return (NO_ERR); +} + +// +//cCmdWrapSetSleepTimeout +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: desired timer limit in ms, ULONG +// +NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]) +{ + ULONG value = *(ULONG*)(ArgV[1]); + if(value==0) + { + pMapUi->SleepTimeout=0; + } + else if(value < 60000) + { + pMapUi->SleepTimeout=1; //integer math would've made this zero + } + else + { + pMapUi->SleepTimeout= value / 60000; + } + return (NO_ERR); +} + +// currently copied from LS, not finished. +// +//cCmdWrapCommHSWrite +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer to send, UBYTE array, only SIZE_OF_LSBUF bytes will be used +//ArgV[3]: ResponseLength, UBYTE, specifies expected bytes back from slave device +// +NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UWORD BufLength; + UBYTE ResponseLength = *(ArgV[3]); + DV_INDEX DVIndex; + + //Resolve array arguments + DVIndex = *(DV_INDEX *)(ArgV[2]); + pBuf = cCmdDVPtr(DVIndex); + BufLength = DV_ARRAY[DVIndex].Count; + + *pReturnVal = cCmdLSWrite(Port, (UBYTE)BufLength, pBuf, ResponseLength); + + return (NO_ERR); +} + +// +//cCmdWrapCommHSCheckStatus +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: BytesReady, UBYTE +// +NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]) +{ + UBYTE Port = *(ArgV[1]); + + *((SBYTE*)(ArgV[0])) = cCmdLSCheckStatus(Port); + *((UBYTE*)(ArgV[2])) = cCmdLSCalcBytesReady(Port); + + return (NO_ERR); +} + +// +//cCmdWrapCommHSRead +//ArgV[0]: (return) Status code, SBYTE +//ArgV[1]: Port specifier, UBYTE +//ArgV[2]: Buffer for data, UBYTE array, max SIZE_OF_LSBUF bytes will be written +//ArgV[3]: BufferLength, UBYTE, specifies size of buffer requested +// +NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]) +{ + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE Port = *(ArgV[1]); + UBYTE * pBuf; + UBYTE BufLength = *(ArgV[3]); + UBYTE BytesToRead; + DV_INDEX DVIndex = *(DV_INDEX *)(ArgV[2]); + NXT_STATUS AllocStatus; + + *pReturnVal = cCmdLSCheckStatus(Port); + BytesToRead = cCmdLSCalcBytesReady(Port); + + //If channel is OK and has data ready for us, put the data into outgoing buffer + if (!IS_ERR(*pReturnVal) && BytesToRead > 0) + { + //Limit buffer to available data + if (BufLength > BytesToRead) + BufLength = BytesToRead; + + AllocStatus = cCmdDVArrayAlloc(DVIndex, BufLength); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + + pBuf = cCmdDVPtr(DVIndex); + *pReturnVal = cCmdLSRead(Port, BufLength, pBuf); + } + //Else, the channel has an error and/or there's no data to read; clear the output array + else + { + AllocStatus = cCmdDVArrayAlloc(DVIndex, 0); + if (IS_ERR(AllocStatus)) + return (AllocStatus); + } + + return (NO_ERR); +} + +// +//cCmdWrapCommBTOnOff +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Power State, 0-1 +// +NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]) +{ + UWORD retVal; + NXT_STATUS status; + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + + UBYTE powerState = *(ArgV[1]); + if(powerState) + status= pMapComm->pFunc(BTON, 0, 0, 0, NULL, &retVal); + else + status= pMapComm->pFunc(BTOFF, 0, 0, 0, NULL, &retVal); + + *pReturnVal= (status == SUCCESS) ? retVal : status; + return (NO_ERR); +} + +// +//cCmdWrapCommBTConnection +//ArgV[0]: (return) Status byte, SBYTE +//ArgV[1]: Action, UBYTE +//ArgV[2]: name, UBYTE array CStr +//ArgV[3]: connection slot, UBYTE +// +NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]) +{ + UWORD retVal; + NXT_STATUS status; + SBYTE * pReturnVal = (SBYTE*)(ArgV[0]); + UBYTE *nmPtr; + + UBYTE action = *(ArgV[1]); + UBYTE connection = *(ArgV[3]); + nmPtr = cCmdDVPtr(*(DV_INDEX *)(ArgV[2])); + + if(action) // Init + status= pMapComm->pFunc(CONNECTBYNAME, 0, connection, 0, nmPtr, &retVal); + else // Close + status= pMapComm->pFunc(DISCONNECT, connection, 0, 0, NULL, &retVal); + + *pReturnVal= (status == SUCCESS) ? retVal : status; + return (NO_ERR); +} + + +// +//cCmdWrapReadSemData +//ArgV[0]: return data, U8 +//ArgV[1]: which (0=used, 1=request), U8 +// +NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]) +{ + if(!(*((UBYTE *)ArgV[1]))) + *((UBYTE *)ArgV[0])= gUsageSemData; + else + *((UBYTE *)ArgV[0])= gRequestSemData; + return (NO_ERR); +} + +// +//cCmdWrapWriteSemData +//ArgV[0]: return data, U8 +//ArgV[1]: which (0=used, 1=request), U8 +//ArgV[2]: newValue, U8 +//ArgV[3]: action (0= OR, 1= AND), U8 +// +NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]) +{ + UBYTE curVal, newVal, which= (*((UBYTE *)ArgV[1])); + if(!which) + curVal= gUsageSemData; + else + curVal= gRequestSemData; + + newVal= *((UBYTE *)ArgV[2]); + + if(*((UBYTE *)ArgV[3])) + curVal &= ~newVal; + else + curVal |= newVal; + + if(!which) + gUsageSemData= curVal; + else + gRequestSemData= curVal; + *((UBYTE *)ArgV[0])= curVal; + return (NO_ERR); +} + + +// +//cCmdWrapUpdateCalibCacheInfo +//ArgV[0]: return data, U8 +//ArgV[1]: nm, UBYTE array CStr +//ArgV[2]: min, U16 +//ArgV[3]: max , U16 +// +NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]) +{ + UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + SWORD min= (*((SWORD *)ArgV[2])); + SWORD max= (*((SWORD *)ArgV[3])); + + cCmdUpdateCalibrationCache(nm, min, max); + *((UBYTE *)ArgV[0])= SUCCESS; + return (NO_ERR); +} + +// +//cCmdWrapComputeCalibValue +//ArgV[0]: return data, U8 +//ArgV[1]: nm, UBYTE array CStr +//ArgV[2]: raw, U16 ref in out +NXT_STATUS cCmdWrapComputeCalibValue (UBYTE * ArgV[]) +{ + UBYTE *nm= cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + SWORD raw= (*((SWORD *)ArgV[2])); + + *((UBYTE *)ArgV[0])= cCmdComputeCalibratedValue(nm, &raw); + (*((SWORD *)ArgV[2]))= raw; + return (NO_ERR); +} + +typedef struct { + SWORD min, max; + UBYTE nm[FILENAME_LENGTH + 1]; +} CalibCacheType; + +SBYTE gCalibCacheCnt= 0; +DV_INDEX gCalibCacheArrayDVIdx= NOT_A_DS_ID; +CalibCacheType *gCalibCacheArray= NULL; + +SWORD cCmdGetCalibrationIndex(UBYTE *nm) { + SBYTE i; + for(i= 0; i < gCalibCacheCnt; i++) + if(!strcmp((PSZ)nm, (PSZ)gCalibCacheArray[i].nm)) + break; + return i; +} + +NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *pRaw) { + SBYTE i= cCmdGetCalibrationIndex(nm); + NXT_STATUS status= ERR_RC_ILLEGAL_VAL; + SLONG raw= *pRaw, range; + if(i < gCalibCacheCnt) { + status= SUCCESS; + raw -= gCalibCacheArray[i].min; + range= (gCalibCacheArray[i].max - gCalibCacheArray[i].min); + } + else + range= 1023; + raw *= 100; + raw /= range; + if(raw < 0) raw= 0; + else if(raw > 100) raw= 100; + *pRaw= raw; + return status; +} + + +NXT_STATUS ResizeCalibCache(ULONG elements) { // alloc dv if needed, grow if needed. dv never freed. on boot, set to NOT_A_DS_ID. use cnt for valid elements. + NXT_STATUS Status = NO_ERR; + + if(gCalibCacheArrayDVIdx == NOT_A_DS_ID) + Status = cCmdAllocDopeVector(&gCalibCacheArrayDVIdx, sizeof(CalibCacheType)); + if(!IS_ERR(Status) && DV_ARRAY[gCalibCacheArrayDVIdx].Count < elements) //Allocate storage for cache element + Status = cCmdDVArrayAlloc(gCalibCacheArrayDVIdx, elements); + if(!IS_ERR(Status)) + gCalibCacheArray= cCmdDVPtr(gCalibCacheArrayDVIdx); + // on error, does old DVIdx still point to array, or should we null out array??? + return Status; +} + +// called to update min/max on existing cache element, and to add new named element +void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max) { + SWORD i= cCmdGetCalibrationIndex(nm); + NXT_STATUS Status = NO_ERR; + + if(i == gCalibCacheCnt) { // sensor wasn't found, insert into cache + Status= ResizeCalibCache(gCalibCacheCnt+1); + if(!IS_ERR(Status)) { + gCalibCacheCnt++; + strcpy((PSZ)gCalibCacheArray[i].nm, (PSZ)nm); + } + } + if(!IS_ERR(Status)) { + gCalibCacheArray[i].min= min; + gCalibCacheArray[i].max= max; + } +} + +void cCmdLoadCalibrationFiles(void) { + ULONG cnt, DataSize; + UBYTE nm[FILENAME_LENGTH + 1], nmLen; + SWORD Handle, HandleSearch; + gCalibCacheCnt= 0; + gCalibCacheArrayDVIdx= NOT_A_DS_ID; + // file I/O to load all .cal files into cached globals used by scaling syscall + HandleSearch = pMapLoader->pFunc(FINDFIRST, "*.cal", nm, &cnt); // returns total files and nm of first one + while (LOADER_ERR(HandleSearch) == SUCCESS) { // if we have a file, process it by closing and opening + SWORD min= 0, max= 0, tmp; + ULONG length; + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); + Handle = pMapLoader->pFunc(OPENREAD, nm, NULL, &DataSize); + if (LOADER_ERR(Handle) == SUCCESS && DataSize == 4) { + // access data, two bytes for min and two for max + length= 2; + pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); + if (length == 2) + min= tmp; + length= 2; + pMapLoader->pFunc(READ,LOADER_HANDLE_P(Handle),(UBYTE*)&tmp,&length); + if (length == 2) + max= tmp; + } + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(Handle), NULL, NULL); + // update calibration cache with nm, min, and max + nmLen= strlen((PSZ)nm) - 4; // chop off .cal extension + nm[nmLen]= 0; + cCmdUpdateCalibrationCache(nm, min, max); + + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), nm, &cnt); + } + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); +} + +// +//cCmdWrapListFiles +//ArgV[0]: return data, SBYTE +//ArgV[1]: pattern, UBYTE array CStr +//ArgV[2]: list, UBYTE array CStr array ref in out +NXT_STATUS cCmdWrapListFiles (UBYTE * ArgV[]) +{ + ULONG fileSize, matchCount=0, i=0, oldCount; + SWORD HandleSearch; + NXT_STATUS Status = NO_ERR; + DV_INDEX listIdx, *list; + UBYTE *strTemp, *pattern; + UBYTE name[FILENAME_LENGTH + 1]; + + //Resolve array arguments + pattern = cCmdDVPtr(*(DV_INDEX *)(ArgV[1])); + listIdx = *(DV_INDEX *)(ArgV[2]); + + HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern + + //Count how many files we're going to have + while (LOADER_ERR(HandleSearch) == SUCCESS) + { + matchCount++; + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); + } + + HandleSearch = pMapLoader->pFunc(FINDFIRST, pattern, name, &fileSize); // returns first file matching pattern + + oldCount = DV_ARRAY[listIdx].Count; // Check to see how many dope vectors are already in the array (if they passed us a non-blank array of strings) + + Status = cCmdDVArrayAlloc(listIdx, matchCount); // Size the top-level array + if(IS_ERR(Status)) + return Status; + + list = (DV_INDEX*)(VarsCmd.pDataspace + DV_ARRAY[listIdx].Offset); // Get a pointer into the dataspace for the array of DV_INDEXes + + while (LOADER_ERR(HandleSearch) == SUCCESS && !IS_ERR(Status)) + { + pMapLoader->pFunc(CLOSE, LOADER_HANDLE_P(HandleSearch), NULL, NULL); // Close the handle that we automatically opened above + // Allocate a new dope vector if one doesn't already exist + if(i >= oldCount) + Status = cCmdAllocDopeVector(&(list[i]), sizeof(char)); + + // Allocate the string buffer for output array[i] + if(!IS_ERR(Status)) + Status = cCmdDVArrayAlloc(list[i], strlen((PSZ)name) + 1); + + if(!IS_ERR(Status)) + { + strTemp = VarsCmd.pDataspace + DV_ARRAY[list[i]].Offset; // Get a pointer into the dataspace for this string + strcpy((PSZ)strTemp, (PSZ)name); + } + i++; + + HandleSearch = pMapLoader->pFunc(FINDNEXT, LOADER_HANDLE_P(HandleSearch), name, &fileSize); + } + + *(SBYTE *)(ArgV[0]) = Status; + + return Status; +} + #ifdef SIM_NXT // Accessors for simulator library code SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index) @@ -6240,6 +7935,7 @@ SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index) else { NXT_ASSERT(cCmdIsClumpIDSane(Clump)); +#error // CodeStart is now absolute, but not sure how to fix return (((SWORD)VarsCmd.pCodespace[VarsCmd.pAllClumps[Clump].CodeStart + Index])); } } @@ -6281,12 +7977,6 @@ ULONG cCmdGetPoolSize() //!!! !ENABLE_VM implementations really should provide a placeholder function for this pointer //IOMapCmd.pRCHandler = &cCmdHandleRemoteCommands; -//#include "c_cmd_alternate.c" -//#include "c_cmd_FB_LowSpeed_Test.c" -//#include "c_cmd_FB_LowSpeed_JB_Compass.c" -//#include "c_cmd_FB_LowSpeed_Continius.c" -//#include "c_cmd_FB_LowSpeed_JB_Color.c" -#include "c_cmd_FB_LowSpeed_NorthStar_Demo2.c" -//#include "c_cmd_FB_LowSpeed_LEGO_TEST.c" +#include "c_cmd_alternate.c" #endif //ENABLE_VM diff --git a/AT91SAM7S256/Source/c_cmd.h b/AT91SAM7S256/Source/c_cmd.h index 04f10a3..e9227eb 100644 --- a/AT91SAM7S256/Source/c_cmd.h +++ b/AT91SAM7S256/Source/c_cmd.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 24-07-06 8:52 $ +// Revision date $Date: 10-07-08 13:22 $ // // Filename $Workfile:: c_cmd.h $ // -// Version $Revision:: 43 $ +// Version $Revision: 8 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ // // Platform C // @@ -27,7 +27,7 @@ #endif #include "c_cmd_bytecodes.h" -#define SYSCALL_COUNT 34 +#define SYSCALL_COUNT 48 extern const HEADER cCmd; @@ -54,7 +54,7 @@ void cCmdExit(void); //Define it as 0 to compile alternate implementation for testing (see bottom of c_cmd.c) // #define ENABLE_VM 1 - +#undef ARM_DEBUG // //VM_BENCHMARK enables extra instrumentation code to measure VM performance. //When enabled, a file named "benchmark.txt" is produced every time a program completes. @@ -84,7 +84,7 @@ void cCmdWriteBenchmarkFile(); //Assert definitions behind ARM_DEBUG aren't quite as handy as WIN_DEBUG, // but they do record the code line causing the last assert failure. // -#elif defined ARM_DEBUG +#elif defined(ARM_DEBUG) #define NXT_ASSERT(expr) if (expr) {}\ else\ {\ @@ -108,9 +108,6 @@ void cCmdWriteBenchmarkFile(); // typedef SBYTE NXT_STATUS; -//dTimerRead() constantly returns latest system MS tick, so empty loop is convenient macro -#define BUSY_WAIT_NEXT_MS while (IOMapCmd.Tick == dTimerRead()) - #if ENABLE_VM //Intial values for clump records are packed into 4 bytes in the file format. @@ -134,14 +131,15 @@ enum TC_UWORD, TC_SWORD, TC_ULONG, - TC_SLONG, + TC_SLONG, TC_LAST_INT_SCALAR= TC_SLONG, //Aggregate types containing one or more scalar TC_ARRAY, TC_CLUSTER, //Mutex tracks current holder and any waiting clumps - TC_MUTEX + TC_MUTEX, + TC_FLOAT, TC_LAST_VALID= TC_FLOAT }; //Sizes (in bytes) of each scalar type @@ -151,6 +149,7 @@ enum #define SIZE_SWORD 2 #define SIZE_ULONG 4 #define SIZE_SLONG 4 +#define SIZE_FLOAT 4 //MUTEX record is a struct containing 3 8-bit CLUMP_IDs, packed into 32-bit word //See MUTEX_Q typedef @@ -250,14 +249,13 @@ typedef UBYTE FILE_HANDLE; typedef UWORD DV_INDEX; //Dope Vector Index: Index into the DopeVectorArray //DOPE_VECTOR struct: One instance exists in the DopeVectorArray for every array in the dataspace. -//!!! BackPtr is an unused field. Intended to enable compaction of DopeVectorArray. typedef struct { UWORD Offset; UWORD ElemSize; UWORD Count; - UWORD BackPtr; - DV_INDEX Link; + DV_INDEX BackLink; // points to previous DV + DV_INDEX Link; // points to next DV } DOPE_VECTOR; // @@ -278,7 +276,7 @@ typedef struct //Macro to shorten common DVA access code #define DV_ARRAY VarsCmd.MemMgr.pDopeVectorArray //# of nodes to alloc when the Dope Vector Array is full -#define DV_ARRAY_GROWTH_COUNT 5 +#define DV_ARRAY_GROWTH_COUNT 25 //Flag value for invalid Offset fields in DVs #define NOT_AN_OFFSET 0xFFFF //Check for legal index into DVA @@ -322,6 +320,36 @@ typedef struct #define SET_WRITE_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].WriteIndex] = (DVIndex)) #define SET_READ_MSG(QueueID, DVIndex) (VarsCmd.MessageQueues[(QueueID)].Messages[VarsCmd.MessageQueues[(QueueID)].ReadIndex] = (DVIndex)) +// +// Datalog Queuing +// +// The datalog queue is loosely modeled around the message queue except that there is only one queue, not an array of them. +// + +// A datalog has one less byte of 'header' info so different max size +#define MAX_DATALOG_SIZE 60 + +// The number of datalog messages to buffer +#define DATALOG_QUEUE_DEPTH 30 + +// A DATALOG_MESSAGE is a dynamically sized string, so we use a DV_INDEX to get to its information +typedef DV_INDEX DATALOG_MESSAGE; + +// +// DATALOG_QUEUE keeps track of last messages read and written (acts as a circular buffer) +typedef struct +{ + UWORD ReadIndex; + UWORD WriteIndex; + DATALOG_MESSAGE Datalogs[DATALOG_QUEUE_DEPTH]; +} DATALOG_QUEUE; + +//Handy macros for accessing the DATALOG_QUEUE +#define GET_WRITE_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex]) +#define GET_READ_DTLG() (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex]) +#define SET_WRITE_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.WriteIndex] = (DVIndex)) +#define SET_READ_DTLG(DVIndex) (VarsCmd.DatalogBuffer.Datalogs[VarsCmd.DatalogBuffer.ReadIndex] = (DVIndex)) + // //Definitions related to dataflow scheduling @@ -336,6 +364,7 @@ typedef UBYTE CLUMP_ID; // #define NOT_A_CLUMP 0xFF #define MAX_CLUMPS 255 +#define INSTR_MAX_COUNT 20 //CLUMP_Q struct for tracking head and tail of a queue of clumps typedef struct @@ -359,30 +388,32 @@ typedef struct // // Clump Record, run-time book-keeping for each clump // -// CodeStart: Start of this clump's bytecodes -// CodeEnd: End of this clump's bytecodes +// CodeStart: Start of this clump's bytecodes, absolute address +// CodeEnd: End of this clump's bytecodes, absolute address // PC: "program counter" -- current offset into codespace relative to CodeStart // InitFireCount: Initial count of upstream dependencies // CurrFireCount: Run-time count of unsatisfied dependencies // Link: ID of next clump in the queue. NOT_A_CLUMP denotes end or bad link. // -// Priority: number of instructions to run per pass on this clump +// clumpScalarDispatchHints: this clump only uses scalar data args, can be interpretted with faster dispatch tables // // pDependents: pointer to list of downstream dependents' ClumpIDs +// awakenTime: If a clump is on rest queue for sleep, this is the time at which it will return to runQueue // DependentCount: Count of downstream dependents // typedef struct { - CODE_INDEX CodeStart; - CODE_INDEX CodeEnd; - CODE_INDEX PC; + CODE_WORD* CodeStart; + CODE_WORD* CodeEnd; + CODE_WORD* PC; UBYTE InitFireCount; UBYTE CurrFireCount; //AKA ShortCount CLUMP_ID Link; - UBYTE Priority; + UBYTE clumpScalarDispatchHints; CLUMP_ID* pDependents; + ULONG awakenTime; UBYTE DependentCount; } CLUMP_REC; @@ -430,7 +461,6 @@ typedef enum //AllClumpsCount: Count of CLUMP_RECs in list // //RunQ: Head and tail of run queue (elements in-place in AllClumps list) -//ScratchPC: Temp PC value for control flow instructions // //pDataspaceTOC: Pointer to DSTOC entries (stored in flash) //DataspaceCount: Count of entries in DSTOC @@ -485,8 +515,7 @@ typedef struct MEM_MGR MemMgr; CLUMP_Q RunQ; - CODE_INDEX ScratchPC; - CLUMP_ID CallerClump; + CLUMP_Q RestQ; UBYTE ActiveProgHandle; UBYTE ActiveProgName[FILENAME_LENGTH + 1]; @@ -504,6 +533,8 @@ typedef struct ULONG StartTick; + DATALOG_QUEUE DatalogBuffer; + #if VM_BENCHMARK ULONG InstrCount; ULONG Average; @@ -562,13 +593,17 @@ NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ //Clump queuing void cCmdEnQClump(CLUMP_Q * Queue, CLUMP_ID NewClump); void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump); -void cCmdRotateQ(CLUMP_Q * Queue); +void cCmdRotateQ(); UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump); UBYTE cCmdIsQSane(CLUMP_Q * Queue); +// Rest queue functions +NXT_STATUS cCmdSleepClump(ULONG time); +UBYTE cCmdCheckRestQ(ULONG currTime); + //Mutex queuing -NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex, CLUMP_ID Clump); -NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex, CLUMP_ID Clump); +NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex); +NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex); //Conditionally schedule dependents of given clump (Begin and End specify subset of list) NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End); @@ -585,21 +620,13 @@ UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump); //Instruction masking macros -- get the interesting bits out of an encoded instruction word #define COMP_CODE(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0700) >> 8)) -#define INSTR_SIZE(pInstr) ((UBYTE)((((pInstr)[0]) & 0xF000) >> 12)) +#define INSTR_SIZE(wd) ((wd) >> 12) & 0x0F; -#ifdef USE_SHORT_OPS -//!!! IS_SHORT_OP and SHORT_OP_CODE do not check for insane (out of bounds) data. Accessor function would be safer. #define IS_SHORT_OP(pInstr) ((UBYTE)((((pInstr)[0]) & 0x0800) >> 8) == 8) #define SHORT_OP_CODE(pInstr) COMP_CODE(pInstr) #define SHORT_ARG(pInstr) ((SBYTE) (((pInstr)[0]) & 0x00FF)) //ShortOpMap defined in c_cmd_bytecodes.h -#define OP_CODE(pInstr) (IS_SHORT_OP(pInstr) ? ShortOpMap[SHORT_OP_CODE(pInstr)] : (UBYTE) (((pInstr)[0]) & 0x00FF)) -#else -#define OP_CODE(pInstr) ((UBYTE) (((pInstr)[0]) & 0x00FF)) -#endif - -//Access count of codewords belonging to Clump. If no clump specified, return count of all codewords in program. -CODE_INDEX cCmdGetCodespaceCount(CLUMP_ID Clump); +#define OP_CODE(pInstr) (UBYTE) (((pInstr)[0]) & 0x00FF) // //Memory pool management @@ -615,10 +642,9 @@ NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount); NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset); -NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr); +NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize); NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex); NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewCount); -NXT_STATUS cCmdCompactDopeVectorArray(void); UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID); @@ -638,18 +664,35 @@ NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length); NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pData, UWORD Length, UBYTE Remove); NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size); +// +// Datalog Queue management +// + +NXT_STATUS cCmdDatalogWrite(UBYTE * pData, UWORD Length); +NXT_STATUS cCmdDatalogRead(UBYTE * pData, UWORD Length, UBYTE Remove); +NXT_STATUS cCmdDatalogGetSize(UWORD * Size); + +// +// Color Sensor +// + +NXT_STATUS cCmdColorSensorRead (UBYTE Port, SWORD* SensorValue, UWORD* RawArray, UWORD* NormalizedArray, + SWORD* ScaledArray, UBYTE* InvalidData); + // //Dataspace management // #define IS_AGGREGATE_TYPE(TypeCode) ((TypeCode == TC_ARRAY) || (TypeCode == TC_CLUSTER)) +// use carefully, only where tc will be a scalar int +#define QUICK_UNSIGNED_TEST(TypeCode) ((TypeCode) & 0x1) #define IS_SIGNED_TYPE(TypeCode) (((TypeCode) == TC_SBYTE) || ((TypeCode) == TC_SWORD) || ((TypeCode) == TC_SLONG)) +//!!!BDUGGAN add TC_FLOAT? //Test if DS_ELEMENT_ID is sane at run-time (valid for indexing DS TOC) UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index); DS_ELEMENT_ID cCmdGetDataspaceCount(void); -TYPE_CODE cCmdDSType(DS_ELEMENT_ID DSElementID); //Pointer accessors to resolve actual data locations in RAM void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset); @@ -669,6 +712,7 @@ NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, D //Comparison evaluation. Comparison codes defined in c_cmd_bytecodes.h. //cCmdCompare operates on scalars passed as ULONGs -- type-specific comparisons done inside function. UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); +UBYTE cCmdCompareFlt(UBYTE CompCode, float Val1, float Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2); //cCmdCompareAggregates does polymorphic comparisons (with recursive helper function). NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); @@ -689,36 +733,53 @@ TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID); //General data accessors (DS and IO Map) void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode); +void * cCmdResolveIODataArg(DATA_ARG DataArg, ULONG Offset, TYPE_CODE * TypeCode); ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode); void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal); -UWORD cCmdSizeOf(TYPE_CODE TypeCode); + +// Calibration routines +void cCmdLoadCalibrationFiles(void); +NXT_STATUS cCmdComputeCalibratedValue(UBYTE *nm, SWORD *raw); +void cCmdUpdateCalibrationCache(UBYTE *nm, SWORD min, SWORD max); // //Interpreter functions // //Clump-based "master" interpreter -NXT_STATUS cCmdInterpFromClump(CLUMP_ID Clump); +NXT_STATUS cCmdInterpFromClump(); //Function pointer typedef for sub-interpreters typedef NXT_STATUS (*pInterp)(CODE_WORD * const); +typedef NXT_STATUS (*pInterpShort)(CODE_WORD * const); //Sub-interpreter dispatch functions NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode); NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode); NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpScalarUnop2(CODE_WORD * const pCode); NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpScalarBinop(CODE_WORD * const pCode); NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode); -#define INTERP_COUNT 5 +NXT_STATUS cCmdInterpShortError(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortMove(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortAcquire(CODE_WORD * const pCode); +NXT_STATUS cCmdInterpShortRelease(CODE_WORD * const pCode); + +NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2); //Polymorphic interpreter functions NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2); ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode); +float cCmdUnop2Flt(CODE_WORD const Code, float Operand, TYPE_CODE TypeCode); NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3); ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); - +float cCmdBinopFlt(CODE_WORD const Code, float LeftOp, float RightOp, TYPE_CODE LeftType, TYPE_CODE RightType); +void cCmdSetValFlt(void * pVal, TYPE_CODE TypeCode, float NewVal); +float cCmdGetValFlt(void * pVal, TYPE_CODE TypeCode); // //Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications // @@ -770,12 +831,29 @@ NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]); NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]); NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]); NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDatalogWrite(UBYTE * ArgV[]); NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]); NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]); NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]); NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]); NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]); NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapColorSensorRead (UBYTE * ArgV[]); +NXT_STATUS cCmdWrapDatalogGetTimes(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapSetSleepTimeout(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapListFiles(UBYTE * ArgV[]); + +// Handlers for dynamically added syscalls +NXT_STATUS cCmdWrapCommHSWrite(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommHSRead(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommHSCheckStatus(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTOnOff(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapCommBTConnection(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapReadSemData(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapWriteSemData(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapUpdateCalibCacheInfo(UBYTE * ArgV[]); +NXT_STATUS cCmdWrapComputeCalibValue(UBYTE * ArgV[]); + //Handler for remote control protocol packets -- called from comm module via IO map function pointer UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen); diff --git a/AT91SAM7S256/Source/c_cmd.iom b/AT91SAM7S256/Source/c_cmd.iom index 2b36743..7c5906c 100644 --- a/AT91SAM7S256/Source/c_cmd.iom +++ b/AT91SAM7S256/Source/c_cmd.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date: 14-06-06 8:09 $ +// Revision date $Date: 3-02-09 9:28 $ // // Filename $Workfile:: c_cmd.iom $ // -// Version $Revision: 21 $ +// Version $Revision: 5 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd.iom $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_cmd. $ // // Platform C // @@ -28,12 +28,13 @@ // #define STAT_MSG_EMPTY_MAILBOX 64 //0x40 Specified mailbox contains no new messages - +#define STAT_MSG_BUFFERWRAP 16 //0x10 Datalog buffer not being read fast enough #define STAT_COMM_PENDING 32 //0x20 Pending setup operation in progress -#define STOP_REQ 5 //0x05 Abort current program -#define BREAKOUT_REQ 4 //0x04 Break multi-instruction interpreter loop; give I/O a chance to run -#define PC_OVERRIDE 3 //0x03 Move program counter according to ScratchPC value +#define TIMES_UP 6 //0x06 Return to let drivers run +#define ROTATE_QUEUE 5 //0x05 Give a slice to another queue +#define STOP_REQ 4 //0x04 Abort current program +#define BREAKOUT_REQ 3 //0x03 Break multi-instruction interpreter loop; give I/O a chance to run #define CLUMP_SUSPEND 2 //0x02 Place clump in stasis; execute others until this one returns to RunQ #define CLUMP_DONE 1 //0x01 Finish and reset this clump; execute others until this one is rescheduled @@ -99,9 +100,30 @@ enum RC_GET_CURR_PROGRAM, RC_GET_BUTTON_STATE, RC_MESSAGE_READ, + RC_RESERVED1, + RC_RESERVED2, + RC_RESERVED3, + RC_RESERVED4, + RC_RESERVED5, + RC_DATALOG_READ, + RC_DATALOG_SET_TIMES, + RC_BT_GET_CONTACT_COUNT, + RC_BT_GET_CONTACT_NAME, + RC_BT_GET_CONN_COUNT, + RC_BT_GET_CONN_NAME, + RC_SET_PROPERTY, + RC_GET_PROPERTY, + RC_UPDATE_RESET_COUNT, + NUM_RC_OPCODES }; +// selectors for RC Get and Set properties +enum { +RC_PROP_BTONOFF, +RC_PROP_SOUND_LEVEL, +RC_PROP_SLEEP_TIMEOUT +}; // //Published status of last program to be activated @@ -135,7 +157,6 @@ typedef enum //Current firmware version defined in c_loader.iom as FIRMWAREVERSION //This is the oldest compatible version in the same system #define VM_OLDEST_COMPATIBLE_VERSION 0x0004 - // //IO Map for Command Module // pRCHandler: Function pointer to handler for remote control protocol @@ -173,6 +194,9 @@ typedef struct UBYTE FileName[FILENAME_LENGTH + 1]; ULONG MemoryPool[POOL_MAX_SIZE / 4]; + + ULONG SyncTime; + ULONG SyncTick; } IOMAPCMD; #endif //CCMD_IOM diff --git a/AT91SAM7S256/Source/c_cmd_alternate.c b/AT91SAM7S256/Source/c_cmd_alternate.c deleted file mode 100644 index 9366296..0000000 --- a/AT91SAM7S256/Source/c_cmd_alternate.c +++ /dev/null @@ -1,163 +0,0 @@ -// -// File Description: -// This file contains an alternate implementation of c_cmd for testing purposes. -// It implements the minimal standard interface for the module, and serves as -// an example of output module control via C code. -// - -void cCmdInit(void* pHeader) -{ - pHeaders = pHeader; - - IOMapCmd.Awake = TRUE; - - dTimerInit(); - IOMapCmd.Tick = dTimerRead(); - - return; -} - -//Test: Start at speed 100 when enter is pressed; then progressively ramp down every half second until -100. -void cCmdCtrl(void) -{ - static UBYTE State = 0; - static ULONG MyTick = 0; - - if (pMapButton->State[BTN1] & PRESSED_EV) - { - pMapButton->State[BTN1] &= ~PRESSED_EV; - - //Coast both motors - pMapOutPut->Outputs[0].Mode = MOTORON; - pMapOutPut->Outputs[1].Mode = MOTORON; - - pMapOutPut->Outputs[0].Speed = 0; - pMapOutPut->Outputs[0].TachoLimit = 0; - pMapOutPut->Outputs[0].RunState = MOTOR_RUN_STATE_IDLE; - pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_IDLE; - - pMapOutPut->Outputs[1].Speed = 0; - pMapOutPut->Outputs[1].TachoLimit = 0; - pMapOutPut->Outputs[1].RunState = MOTOR_RUN_STATE_IDLE; - pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_IDLE; - - pMapOutPut->Outputs[0].Flags = UPDATE_MODE | UPDATE_SPEED; - pMapOutPut->Outputs[1].Flags = UPDATE_MODE | UPDATE_SPEED; - - //Drop out of ongoing state machine - State = 255; - } - - switch(State) - { - case 0: - { - //Initialize - pMapOutPut->Outputs[0].Flags = UPDATE_RESET_COUNT; - pMapOutPut->Outputs[1].Flags = UPDATE_RESET_COUNT; - pMapOutPut->Outputs[0].RunState = MOTOR_RUN_STATE_IDLE; - pMapOutPut->Outputs[1].RunState = MOTOR_RUN_STATE_IDLE; - - State++; - } - break; - - case 1: - { - //Kick off further states only if Enter button is pressed - if ((pMapButton->State[BTN4] & PRESSED_EV)) - { - //Clear pressed event so UI doesn't re-use it. - pMapButton->State[BTN4] &= ~PRESSED_EV; - - pMapOutPut->Outputs[0].Mode = MOTORON | BRAKE | REGULATED; - pMapOutPut->Outputs[1].Mode = MOTORON | BRAKE | REGULATED; - - pMapOutPut->Outputs[0].Speed = 50; - pMapOutPut->Outputs[0].TachoLimit = 1152; - pMapOutPut->Outputs[0].RunState = MOTOR_RUN_STATE_RUNNING; - pMapOutPut->Outputs[0].SyncTurnParameter = 25; - //pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_MOTOR_SPEED; - pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_MOTOR_SYNC; - - pMapOutPut->Outputs[1].Speed = 50; - pMapOutPut->Outputs[1].TachoLimit = 1152; - pMapOutPut->Outputs[1].RunState = MOTOR_RUN_STATE_RUNNING; - //pMapOutPut->Outputs[1].SyncTurnParameter = -7; - //pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_MOTOR_SPEED; - pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_MOTOR_SYNC; - - pMapOutPut->Outputs[0].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; - pMapOutPut->Outputs[1].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; - - State++; - } - } - break; - - case 2: - { - if (pMapOutPut->Outputs[0].RunState == MOTOR_RUN_STATE_IDLE) - { - pMapOutPut->Outputs[0].Mode = MOTORON; - pMapOutPut->Outputs[1].Mode = MOTORON; - - pMapOutPut->Outputs[0].Speed = 0; - pMapOutPut->Outputs[0].TachoLimit = 0; - pMapOutPut->Outputs[0].RunState = MOTOR_RUN_STATE_IDLE; - pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_IDLE; - - pMapOutPut->Outputs[1].Speed = 0; - pMapOutPut->Outputs[1].TachoLimit = 0; - pMapOutPut->Outputs[1].RunState = MOTOR_RUN_STATE_IDLE; - pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_IDLE; - - pMapOutPut->Outputs[0].Flags = UPDATE_MODE | UPDATE_SPEED; - pMapOutPut->Outputs[1].Flags = UPDATE_MODE | UPDATE_SPEED; - State++; - } - } - break; - - case 3: - { - pMapOutPut->Outputs[0].Mode = MOTORON | BRAKE | REGULATED; - pMapOutPut->Outputs[1].Mode = MOTORON | BRAKE | REGULATED; - - pMapOutPut->Outputs[0].Speed = 50; - pMapOutPut->Outputs[0].TachoLimit = 1152; - pMapOutPut->Outputs[0].RunState = MOTOR_RUN_STATE_RUNNING; - //pMapOutPut->Outputs[0].SyncTurnParameter = 5; - //pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_MOTOR_SPEED; - pMapOutPut->Outputs[0].RegMode = REGULATION_MODE_MOTOR_SYNC; - - pMapOutPut->Outputs[1].Speed = 50; - pMapOutPut->Outputs[1].TachoLimit = 1152; - pMapOutPut->Outputs[1].RunState = MOTOR_RUN_STATE_RUNNING; - //pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_MOTOR_SPEED; - pMapOutPut->Outputs[1].RegMode = REGULATION_MODE_MOTOR_SYNC; - - pMapOutPut->Outputs[0].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; - pMapOutPut->Outputs[1].Flags = UPDATE_MODE | UPDATE_SPEED | UPDATE_TACHO_LIMIT; - - State = 2; - } - break; - - default: - break; - }; - - //Busy loop to ensure return on 1ms boundary - BUSY_WAIT_NEXT_MS; - - IOMapCmd.Tick = dTimerRead(); - MyTick++; - - return; -} - -void cCmdExit(void) -{ - return; -} diff --git a/AT91SAM7S256/Source/c_cmd_bytecodes.h b/AT91SAM7S256/Source/c_cmd_bytecodes.h index 6051aba..5cd9dfd 100644 --- a/AT91SAM7S256/Source/c_cmd_bytecodes.h +++ b/AT91SAM7S256/Source/c_cmd_bytecodes.h @@ -4,83 +4,87 @@ // opcode definitions // symbol, bits, arg format // -#define OPCODE_COUNT 0x36 +#define OPCODE_COUNT 0x38 //Family: Math -#define OP_ADD 0x00 // dest, src1, src2 -#define OP_SUB 0x01 // dest, src1, src2 -#define OP_NEG 0x02 // dest, src -#define OP_MUL 0x03 // dest, src1, src2 -#define OP_DIV 0x04 // dest, src1, src2 -#define OP_MOD 0x05 // dest, src1, src2 +#define OP_ADD 0x00 // dest, src1, src2 +#define OP_SUB 0x01 // dest, src1, src2 +#define OP_NEG 0x02 // dest, src +#define OP_MUL 0x03 // dest, src1, src2 +#define OP_DIV 0x04 // dest, src1, src2 +#define OP_MOD 0x05 // dest, src1, src2 //Family: Logic -#define OP_AND 0x06 // dest, src1, src2 -#define OP_OR 0x07 // dest, src1, src2 -#define OP_XOR 0x08 // dest, src1, src2 -#define OP_NOT 0x09 // dest, src +#define OP_AND 0x06 // dest, src1, src2 +#define OP_OR 0x07 // dest, src1, src2 +#define OP_XOR 0x08 // dest, src1, src2 +#define OP_NOT 0x09 // dest, src //Family: Bit manipulation -#define OP_CMNT 0x0A // dest, src -#define OP_LSL 0x0B // dest, src -#define OP_LSR 0x0C // dest, src -#define OP_ASL 0x0D // dest, src -#define OP_ASR 0x0E // dest, src -#define OP_ROTL 0x0F // dest, src -#define OP_ROTR 0x10 // dest, src +#define OP_CMNT 0x0A // dest, src +#define OP_LSL 0x0B // dest, src +#define OP_LSR 0x0C // dest, src +#define OP_ASL 0x0D // dest, src +#define OP_ASR 0x0E // dest, src +#define OP_ROTL 0x0F // dest, src +#define OP_ROTR 0x10 // dest, src //Family: Comparison -#define OP_CMP 0x11 // dest, src1, src2 -#define OP_TST 0x12 // dest, src -#define OP_CMPSET 0x13 // dest, src, testsrc, testsrc -#define OP_TSTSET 0x14 // dest, src, testsrc +#define OP_CMP 0x11 // dest, src1, src2 +#define OP_TST 0x12 // dest, src +#define OP_CMPSET 0x13 // dest, src, testsrc, testsrc +#define OP_TSTSET 0x14 // dest, src, testsrc //Family: Array ops -#define OP_INDEX 0x15 // dest, src, index -#define OP_REPLACE 0x16 // dest, src, index, val -#define OP_ARRSIZE 0x17 // dest, src -#define OP_ARRBUILD 0x18 // instrsize, dest, src1, src2, … -#define OP_ARRSUBSET 0x19 // dest, src, index, length -#define OP_ARRINIT 0x1A // dest, elem, length +#define OP_INDEX 0x15 // dest, src, index +#define OP_REPLACE 0x16 // dest, src, index, val +#define OP_ARRSIZE 0x17 // dest, src +#define OP_ARRBUILD 0x18 // instrsize, dest, src1, src2, … +#define OP_ARRSUBSET 0x19 // dest, src, index, length +#define OP_ARRINIT 0x1A // dest, elem, length //Family: Memory ops -#define OP_MOV 0x1B // dest, src -#define OP_SET 0x1C // dest, imm +#define OP_MOV 0x1B // dest, src +#define OP_SET 0x1C // dest, imm //Family: String ops -#define OP_FLATTEN 0x1D // dest, src -#define OP_UNFLATTEN 0x1E // dest, err, src, type -#define OP_NUMTOSTRING 0x1F // dest, src -#define OP_STRINGTONUM 0x20 // dest, offsetpast, src, offset, default -#define OP_STRCAT 0x21 // instrsize, dest, src1, src2, … -#define OP_STRSUBSET 0x22 // dest, src, index, length -#define OP_STRTOBYTEARR 0x23 // dest, src -#define OP_BYTEARRTOSTR 0x24 // dest, src +#define OP_FLATTEN 0x1D // dest, src +#define OP_UNFLATTEN 0x1E // dest, err, src, type +#define OP_NUMTOSTRING 0x1F // dest, src +#define OP_STRINGTONUM 0x20 // dest, offsetpast, src, offset, default +#define OP_STRCAT 0x21 // instrsize, dest, src1, src2, … +#define OP_STRSUBSET 0x22 // dest, src, index, length +#define OP_STRTOBYTEARR 0x23 // dest, src +#define OP_BYTEARRTOSTR 0x24 // dest, src //Family: Control flow -#define OP_JMP 0x25 // offset -#define OP_BRCMP 0x26 // offset, src1, src2 -#define OP_BRTST 0x27 // offset, src -#define OP_SYSCALL 0x28 // func, args -#define OP_STOP 0x29 // stop? +#define OP_JMP 0x25 // offset +#define OP_BRCMP 0x26 // offset, src1, src2 +#define OP_BRTST 0x27 // offset, src +#define OP_SYSCALL 0x28 // func, args +#define OP_STOP 0x29 // stop? //Family: Clump scheduling -#define OP_FINCLUMP 0x2A // start, end -#define OP_FINCLUMPIMMED 0x2B // clumpID -#define OP_ACQUIRE 0x2C // mutexID -#define OP_RELEASE 0x2D // mutexID -#define OP_SUBCALL 0x2E // subroutine, callerID -#define OP_SUBRET 0x2F // callerID +#define OP_FINCLUMP 0x2A // start, end +#define OP_FINCLUMPIMMED 0x2B // clumpID +#define OP_ACQUIRE 0x2C // mutexID +#define OP_RELEASE 0x2D // mutexID +#define OP_SUBCALL 0x2E // subroutine, callerID +#define OP_SUBRET 0x2F // callerID //Family: IO ops -#define OP_SETIN 0x30 // src, port, propid -#define OP_SETOUT 0x31 // instrsize, port/portlist, propid1, src1, ... -#define OP_GETIN 0x32 // dest, port, propid -#define OP_GETOUT 0x33 // dest, port, propid +#define OP_SETIN 0x30 // src, port, propid +#define OP_SETOUT 0x31 // src, port, propid +#define OP_GETIN 0x32 // dest, port, propid +#define OP_GETOUT 0x33 // dest, port, propid //Family: Timing -#define OP_WAIT 0x34 // milliseconds -#define OP_GETTICK 0x35 // dest +#define OP_WAIT 0x34 // dest, src +#define OP_GETTICK 0x35 // dest + +//Family: Math NEW +#define OP_SQRT 0x36 // dest, src +#define OP_ABS 0x37 // dest, src // condition code definitions #define OPCC1_LT 0x00 @@ -96,20 +100,20 @@ // short op definitions // #define USE_SHORT_OPS -#define SHORT_OP_MOV 0 -#define SHORT_OP_ACQUIRE 1 -#define SHORT_OP_RELEASE 2 -#define SHORT_OP_SUBCALL 3 +#define SHORT_OP_MOV 0 +#define SHORT_OP_ACQUIRE 1 +#define SHORT_OP_RELEASE 2 +#define SHORT_OP_SUBCALL 3 // // short op mapping table // -static UBYTE ShortOpMap[4] = +static UBYTE ShortOpMap[4] = { - OP_MOV, - OP_ACQUIRE, - OP_RELEASE, - OP_SUBCALL + OP_MOV, + OP_ACQUIRE, + OP_RELEASE, + OP_SUBCALL }; #endif // C_CMD_BYTECODES diff --git a/AT91SAM7S256/Source/c_comm.c b/AT91SAM7S256/Source/c_comm.c index 291c96b..ee0c6ae 100644 --- a/AT91SAM7S256/Source/c_comm.c +++ b/AT91SAM7S256/Source/c_comm.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:42 $ +// Revision date $Date: 8-09-08 14:11 $ // // Filename $Workfile:: c_comm.c $ // -// Version $Revision:: 172 $ +// Version $Revision: 7 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_comm.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ // // Platform C // @@ -126,6 +126,7 @@ void cCommsDisconnectAll(UBYTE *pNextState); void cCommsBtReset(UBYTE *pNextState); void cCommPinCode(UBYTE *pPinCode); void cCommClrConnTable(void); +SBYTE cCommSearchBTDevTableForName(UBYTE*); void cCommInit(void* pHeader) { @@ -328,6 +329,24 @@ void cCommExit(void) dBtExit(); } + +UBYTE cCommCheckSysFileType(UBYTE *pName) +{ + UBYTE RtnVal; + UBYTE TmpFilename[FILENAME_LENGTH + 1]; + + RtnVal = FALSE; + cCommCpyToUpper(TmpFilename, &pName[1], (UBYTE)(FILENAME_LENGTH + 1)); + if ((0 != strstr((PSZ)(TmpFilename), ".RXE")) || + (0 != strstr((PSZ)(TmpFilename), ".SYS")) || + (0 != strstr((PSZ)(TmpFilename), ".RTM"))) + { + RtnVal = TRUE; + } + return(RtnVal); +} + + UWORD cCommInterprete(UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pLength, UBYTE CmdBit, UWORD MsgLength) { UWORD ReturnStatus; @@ -469,18 +488,12 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL { case OPENWRITE: { - UBYTE TmpFilename[FILENAME_LENGTH + 1]; - FileLength = pInBuf[21]; FileLength += (ULONG)pInBuf[22] << 8; FileLength += (ULONG)pInBuf[23] << 16; FileLength += (ULONG)pInBuf[24] << 24; - cCommCpyToUpper(TmpFilename, &pInBuf[1], (UBYTE)(FILENAME_LENGTH + 1)); - - if ((0 != strstr((PSZ)(TmpFilename), ".RXE")) || - (0 != strstr((PSZ)(TmpFilename), ".SYS")) || - (0 != strstr((PSZ)(TmpFilename), ".RTM"))) + if(TRUE == cCommCheckSysFileType(&pInBuf[1])) { Status = pMapLoader->pFunc(OPENWRITELINEAR, &pInBuf[1], NULL, &FileLength); } @@ -564,8 +577,14 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL FileLength += (ULONG)pInBuf[23] << 16; FileLength += (ULONG)pInBuf[24] << 24; - Status = pMapLoader->pFunc(OPENWRITEDATA, &pInBuf[1], NULL, &FileLength); - + if(TRUE == cCommCheckSysFileType(&pInBuf[1])) + { + Status = ILLEGALFILENAME; + } + else + { + Status = pMapLoader->pFunc(OPENWRITEDATA, &pInBuf[1], NULL, &FileLength); + } pOutBuf[0] = LOADER_ERR_BYTE(Status); pOutBuf[1] = LOADER_HANDLE(Status); *pLength = 2; @@ -604,6 +623,14 @@ UWORD cCommInterpreteCmd(UBYTE Cmd, UBYTE *pInBuf, UBYTE *pOutBuf, UBYTE *pL *pLength = 2; } break; + case CROPDATAFILE: + { + Status = pMapLoader->pFunc(CROPDATAFILE, &(pInBuf[1]), NULL, &FileLength); + pOutBuf[0] = LOADER_ERR_BYTE(Status); + pOutBuf[1] = LOADER_HANDLE(Status); + *pLength = 2; + } + break; case OPENREAD: { Status = pMapLoader->pFunc(OPENREAD, &pInBuf[1], NULL, &FileLength); @@ -1181,7 +1208,7 @@ UWORD cCommReceivedBtData(void) } else { - + /* ActiveUpdate has to be idle because BC4 can send stream data even if CMD */ /* mode has been requested - dont try to interprete the data */ /* VarsComm.CmdSwitchCnt != 0 if a transition to Cmd mode is in process */ @@ -3175,7 +3202,7 @@ void cCommsSetCmdMode(UBYTE *pNextState) /* stream status has been cleared now wait until buffers has been emptied */ if (TRUE == dBtTxEnd()) { - + /* Wait 100 ms after last byte has been sent to BC4 - else BC4 can crash */ if (++(VarsComm.BtCmdModeWaitCnt) > 100) { @@ -3435,6 +3462,7 @@ UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *p { ULONG Length; UWORD ReturnVal; + SBYTE foundIndex= 0; ReturnVal = BTBUSY; *pRetVal = BTBUSY; @@ -3473,11 +3501,14 @@ UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *p } } break; - + case CONNECTBYNAME: // redo Param1, then fall through existing CONNECT code + foundIndex= cCommSearchBTDevTableForName(pName); + if(foundIndex != -1) + Param1= foundIndex; case CONNECT: { - if (BLUETOOTH_HANDLE_UNDEFIEND == IOMapComm.BtConnectTable[Param2].HandleNr) + if (BLUETOOTH_HANDLE_UNDEFIEND == IOMapComm.BtConnectTable[Param2].HandleNr && foundIndex != -1) { /* Connection not occupied */ @@ -3577,7 +3608,7 @@ UWORD cCommReq(UBYTE Cmd, UBYTE Param1, UBYTE Param2, UBYTE Param3, UBYTE *p /* to be sent. pName is the pointer to the data */ if (Param1 <= sizeof(VarsComm.BtModuleOutBuf.Buf)) { - if ('\0' != IOMapComm.BtConnectTable[VarsComm.BtCmdData.ParamTwo].Name[0]) + if ('\0' != IOMapComm.BtConnectTable[Param2].Name[0]) { VarsComm.BtCmdData.ParamOne = Param1; VarsComm.BtCmdData.ParamTwo = Param2; @@ -3656,3 +3687,14 @@ void cCommClrConnTable(void) pMapUi->BluetoothState &= ~BT_STATE_CONNECTED; pMapUi->Flags |= UI_REDRAW_STATUS; } + + /* search the BT table */ +SBYTE cCommSearchBTDevTableForName(UBYTE *name) { + UBYTE Tmp; + for (Tmp = 0; Tmp < SIZE_OF_BT_DEVICE_TABLE; Tmp++) + { + if (0 == strcmp((char*)(IOMapComm.BtDeviceTable[Tmp].Name), (char*)name)) + return Tmp; + } + return -1; +} diff --git a/AT91SAM7S256/Source/c_comm.h b/AT91SAM7S256/Source/c_comm.h index 8487a82..a1e112c 100644 --- a/AT91SAM7S256/Source/c_comm.h +++ b/AT91SAM7S256/Source/c_comm.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:42 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_comm.h $ // -// Version $Revision:: 54 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_comm.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_comm.iom b/AT91SAM7S256/Source/c_comm.iom index 6a43149..2dfe994 100644 --- a/AT91SAM7S256/Source/c_comm.iom +++ b/AT91SAM7S256/Source/c_comm.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:42 $ +// Revision date $Date:: 9-06-08 14:57 $ // // Filename $Workfile:: c_comm.iom $ // -// Version $Revision:: 72 $ +// Version $Revision:: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_comm.iom $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_comm $ // // Platform C // @@ -62,7 +62,7 @@ enum enum { HS_INITIALISE = 1, - HS_INIT_RECEIVER, + HS_INIT_RECEIVER, HS_SEND_DATA, HS_DISABLE }; @@ -97,7 +97,8 @@ enum SETBTNAME, EXTREAD, PINREQ, - CONNECTREQ + CONNECTREQ, + CONNECTBYNAME }; @@ -138,7 +139,7 @@ typedef struct typedef struct { UBYTE Buf[SIZE_OF_BTBUF]; - UBYTE InPtr; + UBYTE InPtr; UBYTE OutPtr; UBYTE Spare1; UBYTE Spare2; diff --git a/AT91SAM7S256/Source/c_display.c b/AT91SAM7S256/Source/c_display.c index 36d66e7..6b15495 100644 --- a/AT91SAM7S256/Source/c_display.c +++ b/AT91SAM7S256/Source/c_display.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author: Dkflebun $ // -// Revision date $Date:: 17-02-06 8:45 $ +// Revision date $Date: 9-06-08 13:35 $ // // Filename $Workfile:: c_display.c $ // -// Version $Revision:: 36 $ +// Version $Revision: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ // // Platform C // @@ -349,23 +349,13 @@ void cDisplayFrame(SCREEN_CORDINATE *pCord) void cDisplayEraseLine(UBYTE Line) { - UBYTE Tmp; - - for (Tmp = 0;Tmp < DISPLAY_WIDTH;Tmp++) - { - IOMapDisplay.Display[Line * DISPLAY_WIDTH + Tmp] = 0x00; - } + memset(&IOMapDisplay.Display[Line * DISPLAY_WIDTH], 0x00, DISPLAY_WIDTH); } void cDisplayErase(void) { - UBYTE Tmp; - - for (Tmp = 0;Tmp < (DISPLAY_HEIGHT / 8);Tmp++) - { - cDisplayEraseLine(Tmp); - } + memset(&IOMapDisplay.Display[0], 0x00, DISPLAY_WIDTH*DISPLAY_HEIGHT/8); } diff --git a/AT91SAM7S256/Source/c_display.h b/AT91SAM7S256/Source/c_display.h index 62a89f8..56b6744 100644 --- a/AT91SAM7S256/Source/c_display.h +++ b/AT91SAM7S256/Source/c_display.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 17-02-06 8:45 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_display.h $ // -// Version $Revision:: 8 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_display.iom b/AT91SAM7S256/Source/c_display.iom index 79fd86b..2e1ab74 100644 --- a/AT91SAM7S256/Source/c_display.iom +++ b/AT91SAM7S256/Source/c_display.iom @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 17-02-06 8:45 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_display.iom $ // -// Version $Revision:: 30 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_disp $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_input.c b/AT91SAM7S256/Source/c_input.c index d17c546..47ca7c0 100644 --- a/AT91SAM7S256/Source/c_input.c +++ b/AT91SAM7S256/Source/c_input.c @@ -1,13 +1,14 @@ + // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 3/21/09 10:31a $ // // Filename $Workfile:: c_input.c $ // -// Version $Revision:: 25 $ +// Version $Revision:: 39 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_input.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ // // Platform C // @@ -17,9 +18,13 @@ #include "c_input.h" #include "d_input.h" #include "c_output.iom" +#include "c_loader.iom" +#include + #define INVALID_RELOAD_NORMAL 20 #define INVALID_RELOAD_SOUND 300 +#define INVALID_RELOAD_COLOR 400 #define ROT_SLOW_SPEED 30 #define ROT_OV_SAMPLING 7 @@ -40,6 +45,14 @@ #define NEWSOUNDSENSORMAX ((AD_MAX * 4980L)/VCC_SENSOR) #define NEWSOUNDSENSORPCTDYN (UBYTE)(((NEWSOUNDSENSORMAX - NEWSOUNDSENSORMIN) * 100L)/AD_MAX) +/* Remember this is ARM AD converter - 3,3 VDC as max voltage */ +/* When in color mode background value is substracted => min = 0!!! */ +#define COLORSENSORBGMIN (214/(3300/AD_MAX)) +#define COLORSENSORMIN (1L/(3300/AD_MAX)) /* 1 inserted else div 0 (1L/(120/AD_MAX)) */ +#define COLORSENSORMAX ((AD_MAX * 3300L)/3300) +#define COLORSENSORPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORMIN) * 100L)/AD_MAX) +#define COLORSENSORBGPCTDYN (UBYTE)(((COLORSENSORMAX - COLORSENSORBGMIN) * 100L)/AD_MAX) + enum { POWER = 0x00, @@ -48,24 +61,66 @@ enum ALWAYS_ACTIVE = 0x04, DIGI_0_HIGH = 0x08, DIGI_1_HIGH = 0x10, - CUSTOM_SETUP = 0x20 + DIGI_0_IN = 0x20, + DIGI_1_IN = 0x40, + CUSTOM_SETUP = 0x80 }; -static const UBYTE ActiveList[NO_OF_SENSOR_TYPES] = -{ - NO_POWER, /* NO_SENSOR */ - NO_POWER, /* SWITCH */ - NO_POWER, /* TEMPERATURE */ - ACTIVE, /* REFLECTION */ - ACTIVE, /* ANGLE */ - DIGI_0_HIGH, /* LIGHT_ACTIVE */ - POWER, /* LIGHT_INACTIVE */ - DIGI_0_HIGH, /* SOUND_DB */ - DIGI_1_HIGH, /* SOUND_DBA */ - CUSTOM_SETUP, /* CUSTOM */ - DIGI_0_HIGH | DIGI_1_HIGH, /* LOWSPEED */ - ALWAYS_ACTIVE | DIGI_0_HIGH | DIGI_1_HIGH /* LOWSPEED_9V on */ +const SWORD TempConvTable[] = +{ + 1500, 1460, 1430, 1400, 1380, 1360, 1330, 1310, 1290, 1270, 1250, 1230, 1220, 1200, 1190, 1170, + 1160, 1150, 1140, 1130, 1110, 1100, 1090, 1080, 1070, 1060, 1050, 1040, 1030, 1020, 1010, 1000, + 994, 988, 982, 974, 968, 960, 954, 946, 940, 932, 926, 918, 912, 906, 900, 894, + 890, 884, 878, 874, 868, 864, 858, 854, 848, 844, 838, 832, 828, 822, 816, 812, + 808, 802, 798, 794, 790, 786, 782, 780, 776, 772, 768, 764, 762, 758, 754, 750, + 748, 744, 740, 736, 732, 730, 726, 722, 718, 716, 712, 708, 704, 700, 696, 694, + 690, 688, 684, 682, 678, 674, 672, 668, 666, 662, 660, 656, 654, 650, 648, 644, + 642, 640, 638, 634, 632, 630, 628, 624, 622, 620, 616, 614, 612, 610, 608, 604, + 602, 600, 598, 596, 592, 590, 588, 586, 584, 582, 580, 578, 576, 574, 572, 570, + 568, 564, 562, 560, 558, 556, 554, 552, 550, 548, 546, 544, 542, 540, 538, 536, + 534, 532, 530, 528, 526, 524, 522, 520, 518, 516, 514, 512, 510, 508, 508, 506, + 504, 502, 500, 498, 496, 494, 494, 492, 490, 488, 486, 486, 484, 482, 480, 478, + 476, 476, 474, 472, 470, 468, 468, 466, 464, 462, 460, 458, 458, 456, 454, 452, + 450, 448, 448, 446, 444, 442, 442, 440, 438, 436, 436, 434, 432, 432, 430, 428, + 426, 426, 424, 422, 420, 420, 418, 416, 416, 414, 412, 410, 408, 408, 406, 404, + 404, 402, 400, 398, 398, 396, 394, 394, 392, 390, 390, 388, 386, 386, 384, 382, + 382, 380, 378, 378, 376, 374, 374, 372, 370, 370, 368, 366, 366, 364, 362, 362, + 360, 358, 358, 356, 354, 354, 352, 350, 350, 348, 348, 346, 344, 344, 342, 340, + 340, 338, 338, 336, 334, 334, 332, 332, 330, 328, 328, 326, 326, 324, 322, 322, + 320, 320, 318, 316, 316, 314, 314, 312, 310, 310, 308, 308, 306, 304, 304, 302, + 300, 300, 298, 298, 296, 296, 294, 292, 292, 290, 290, 288, 286, 286, 284, 284, + 282, 282, 280, 280, 278, 278, 276, 274, 274, 272, 272, 270, 270, 268, 268, 266, + 264, 264, 262, 262, 260, 260, 258, 258, 256, 254, 254, 252, 252, 250, 250, 248, + 248, 246, 244, 244, 242, 240, 240, 240, 238, 238, 236, 236, 234, 234, 232, 230, + 230, 228, 228, 226, 226, 224, 224, 222, 220, 220, 218, 218, 216, 216, 214, 214, + 212, 212, 210, 210, 208, 208, 206, 204, 204, 202, 202, 200, 200, 198, 198, 196, + 196, 194, 194, 192, 190, 190, 188, 188, 186, 186, 184, 184, 182, 182, 180, 180, + 178, 178, 176, 176, 174, 174, 172, 172, 170, 170, 168, 168, 166, 166, 164, 164, + 162, 162, 160, 160, 158, 156, 156, 154, 154, 152, 152, 150, 150, 148, 148, 146, + 146, 144, 144, 142, 142, 140, 140, 138, 136, 136, 136, 134, 134, 132, 130, 130, + 128, 128, 126, 126, 124, 124, 122, 122, 120, 120, 118, 118, 116, 116, 114, 114, + 112, 110, 110, 108, 108, 106, 106, 104, 104, 102, 102, 100, 100, 98, 98, 96, + 94, 94, 92, 92, 90, 90, 88, 88, 86, 86, 84, 82, 82, 80, 80, 78, + 78, 76, 76, 74, 74, 72, 72, 70, 70, 68, 68, 66, 66, 64, 62, 62, + 60, 60, 58, 56, 56, 54, 54, 52, 52, 50, 50, 48, 48, 46, 46, 44, + 44, 42, 40, 40, 38, 38, 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, + 24, 24, 22, 22, 20, 20, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, + 6, 6, 4, 2, 2, 0, 0, -2, -4, -4, -6, -6, -8, -10, -10, -12, + -12, -14, -16, - 16, -18, -20, -20, -22, -22, -24, -26, -26, -28, -30, -30, -32, + -34, -34, -36, -36, -38, -40, -40, -42, -42, -44, -46, -46, -48, -50, -50, -52, + -54, -54, -56, -58, -58, -60, -60, -62, -64, -66, -66, -68, -70, -70, -72, -74, + -76, -76, -78, -80, -80, -82, -84, -86, -86, -88, -90, -90, -92, -94, -94, -96, + -98, -98, -100, -102, -104, -106, -106, -108, -110, -112, -114, -114, -116, -118, -120, -120, + -122, -124, -126, -128, -130, -130, -132, -134, -136, -138, -140, -142, -144, -146, -146, -148, + -150, -152, -154, -156, -158, -160, -162, -164, -166, -166, -168, -170, -172, -174, -176, -178, + -180, -182, -184, -186, -188, -190, -192, -194, -196, -196, -198, -200, -202, -204, -206, -208, + -210, -212, -214, -216, -218, -220, -224, -226, -228, -230, -232, -234, -236, -238, -242, -246, + -248, -250, -254, -256, -260, -262, -264, -268, -270, -274, -276, -278, -282, -284, -286, -290, + -292, -296, -298, -300, -306, -308, -312, -316, -320, -324, -326, -330, -334, -338, -342, -344, + -348, -354, -358, -362, -366, -370, -376, -380, -384, -388, -394, -398, -404, -410, -416, -420, + -428, -432, -440, -446, -450, -460, -468, -476, -484, -492, -500, -510, -524, -534, -546, -560, + -572, -588, -600, -630, -656, -684, -720, -770 }; static IOMAPINPUT IOMapInput; @@ -85,18 +140,24 @@ const HEADER cInput = 0x0000 //Code size - not used so far }; -void cInputCalcSensorRaw(UWORD *pRaw, UBYTE Type, UBYTE No); void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvState); -void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp); -void cInputCalcSensor(UBYTE Tmp); -void cInputSetupType(UBYTE Port); +void cInputCalcSensorValue(UWORD NewSensorRaw, UWORD *pOldSensorRaw, SWORD *pSensorValue, + UBYTE *pBoolean, UBYTE *pDebounce, UBYTE *pSampleCnt, + UBYTE *LastAngle, UBYTE *pEdgeCnt, UBYTE Slope, + UBYTE Mode); +void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType); void cInputSetupCustomSensor(UBYTE Port); - +void cInputCalcSensorValues(UBYTE No); +UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus); +void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals); void cInputInit(void* pHeader) { UBYTE Tmp; + memset(IOMapInput.Colors, 0, sizeof(IOMapInput.Colors)); + memset(VarsInput.VarsColor, 0, sizeof(VarsInput.VarsColor)); + /* Init IO map */ for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) { @@ -121,6 +182,10 @@ void cInputInit(void* pHeader) VarsInput.InvalidTimer[Tmp] = INVALID_RELOAD_NORMAL; VarsInput.OldSensorType[Tmp] = NO_SENSOR; } + + VarsInput.ColorStatus = 0; + VarsInput.ColorCnt = 0; + dInputInit(); } @@ -128,6 +193,37 @@ void cInputCtrl(void) { UBYTE Tmp; + + if (VarsInput.ColorStatus) + { + switch(VarsInput.ColorCnt) + { + case 0: + { + VarsInput.ColorCnt = 1; + dInputSetColorClkInput(); + + } + break; + case 1: + { + VarsInput.ColorCnt = 2; + } + break; + case 2: + { + VarsInput.ColorCnt = 0; + dInputGetAllColors(IOMapInput.Colors, VarsInput.ColorStatus); + } + break; + default: + { + VarsInput.ColorCnt = 0; + } + break; + } + } + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) { @@ -139,38 +235,31 @@ void cInputCtrl(void) VarsInput.InputDebounce[Tmp] = 0; VarsInput.LastAngle[Tmp] = 0; VarsInput.SampleCnt[Tmp] = 0; + VarsInput.ColorStatus &= ~(0x01< 928) + { + InputVal = 928; + } + } + InputVal = TempConvTable[(InputVal) - 197]; + InputVal = InputVal + 200; + InputVal = (UWORD)(((SLONG)InputVal * (SLONG)1023)/(SLONG)900); + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + break; + + case REFLECTION: + { + UWORD InputVal; + + dInputGetRawAd(&InputVal, No); + IOMapInput.Inputs[No].ADRaw = InputVal; + cInputCalcFullScale(&InputVal, REFLECTIONSENSORMIN, REFLECTIONSENSORPCTDYN, TRUE); + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + break; + + case ANGLE: + { + UWORD InputVal; + + dInputGetRawAd(&InputVal, No); + IOMapInput.Inputs[No].ADRaw = InputVal; + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + break; + + /* Dual case intended */ + case LIGHT_ACTIVE: + case LIGHT_INACTIVE: + { + UWORD InputVal; + + dInputGetRawAd(&InputVal, No); + IOMapInput.Inputs[No].ADRaw = InputVal; + cInputCalcFullScale(&InputVal, NEWLIGHTSENSORMIN, NEWLIGHTSENSORPCTDYN, TRUE); + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); - /* Calculate the sensor hardware compensated AD values and put then */ - /* in IOMapInput.Inputs[Tmp].SensorRaw */ - cInputCalcSensorRaw(&InputRaw, IOMapInput.Inputs[Tmp].SensorType, Tmp); + } + break; - /* Calculate the sensor value compensated for sensor mode and put */ - /* them in IOMapInput.Inputs[Tmp].SensorValue */ - cInputCalcSensorValue( &InputRaw, - ((IOMapInput.Inputs[Tmp].SensorMode) & SLOPEMASK), - ((IOMapInput.Inputs[Tmp].SensorMode) & MODEMASK), - Tmp); + /* Dual case intended */ + case SOUND_DB: + case SOUND_DBA: + { + UWORD InputVal; + + dInputGetRawAd(&InputVal, No); + IOMapInput.Inputs[No].ADRaw = InputVal; + cInputCalcFullScale(&InputVal, NEWSOUNDSENSORMIN, NEWSOUNDSENSORPCTDYN, TRUE); + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); -} + } + break; + + case CUSTOM: + { + UWORD InputVal; + + /* Setup and read digital IO */ + cInputSetupCustomSensor(No); + dInputRead0(No, &(IOMapInput.Inputs[No].DigiPinsIn)); + dInputRead1(No, &(IOMapInput.Inputs[No].DigiPinsIn)); + + dInputGetRawAd(&InputVal, No); + IOMapInput.Inputs[No].ADRaw = InputVal; + cInputCalcFullScale(&InputVal, IOMapInput.Inputs[No].CustomZeroOffset, IOMapInput.Inputs[No].CustomPctFullScale, FALSE); + cInputCalcSensorValue( InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + + } + break; + + /* Tripple case intended */ + case LOWSPEED: + case LOWSPEED_9V: + case HIGHSPEED: + { + } + break; + + /* Four cases intended */ + case COLORRED: + case COLORGREEN: + case COLORBLUE: + case COLORNONE: + { + + UWORD InputVal; + switch (IOMapInput.Colors[No].CalibrationState) + { + case SENSOROFF: + { + /* Make sure that sensor data are invalid while unplugged*/ + VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; + IOMapInput.Inputs[No].InvalidData = INVALID_DATA; + /* Check if sensor has been attached */ + if (dInputCheckColorStatus(No)) + { -void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) + /* Sensor has been attached now get cal data */ + VarsInput.VarsColor[No].ColorInitState = 0; + (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; + } + } + break; + case SENSORCAL: + { + + UBYTE Status; + if (FALSE == cInputInitColorSensor(No, &Status)) + { + + /* Color sensor has been removed during calibration */ + (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; + } + + if (TRUE == Status) + { + + /* Use clock to detect errors */ + dInputSetDirInDigi0(No); + (IOMapInput.Colors[No].CalibrationState) = 0; + } + } + break; + default: + { + if (dInputGetColor(No, &(IOMapInput.Inputs[No].ADRaw))) + { + InputVal = IOMapInput.Inputs[No].ADRaw; + cInputCalcFullScale(&InputVal, COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); + cInputCalcSensorValue(InputVal, + &(IOMapInput.Inputs[No].SensorRaw), + &(IOMapInput.Inputs[No].SensorValue), + &(IOMapInput.Inputs[No].SensorBoolean), + &(VarsInput.InputDebounce[No]), + &(VarsInput.SampleCnt[No]), + &(VarsInput.LastAngle[No]), + &(VarsInput.EdgeCnt[No]), + ((IOMapInput.Inputs[No].SensorMode) & SLOPEMASK), + ((IOMapInput.Inputs[No].SensorMode) & MODEMASK)); + } + else + { + IOMapInput.Colors[No].CalibrationState = SENSOROFF; + } + } + break; + } + } + break; + case COLORFULL: + { + switch (IOMapInput.Colors[No].CalibrationState) + { + case SENSOROFF: + { + + /* Make sure that sensor data are invalid while unplugged */ + VarsInput.InvalidTimer[No] = INVALID_RELOAD_COLOR; + IOMapInput.Inputs[No].InvalidData = INVALID_DATA; + + /* Check if sensor has been attached */ + if (dInputCheckColorStatus(No)) + { + + /* Sensor has been attached now get cal data */ + VarsInput.VarsColor[No].ColorInitState = 0; + (IOMapInput.Colors[No].CalibrationState) = SENSORCAL; + } + } + break; + case SENSORCAL: + { + UBYTE Status; + + if (FALSE == cInputInitColorSensor(No, &Status)) + { + + /* Color sensor has been removed during calibration */ + (IOMapInput.Colors[No].CalibrationState) = SENSOROFF; + VarsInput.ColorStatus &= ~(0x01<SensorRaw[RED]) > (pC->SensorRaw[BLUE] )) && + ((pC->SensorRaw[RED]) > (pC->SensorRaw[GREEN]))) + { + + /* If all 3 colors are less than 65 OR (Less that 110 and bg less than 40)*/ + if (((pC->SensorRaw[RED]) < 65) || + (((pC->SensorRaw[BLANK]) < 40) && ((pC->SensorRaw[RED]) < 110))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if (((((pC->SensorRaw[BLUE]) >> 2) + ((pC->SensorRaw[BLUE]) >> 3) + (pC->SensorRaw[BLUE])) < (pC->SensorRaw[GREEN])) && + ((((pC->SensorRaw[GREEN]) << 1)) > (pC->SensorRaw[RED]))) + { + IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; + } + else + { + + if ((((pC->SensorRaw[GREEN]) << 1) - ((pC->SensorRaw[GREEN]) >> 2)) < (pC->SensorRaw[RED])) + { + + IOMapInput.Inputs[No].SensorValue = REDCOLOR; + } + else + { + + if ((((pC->SensorRaw[BLUE]) < 70) || + ((pC->SensorRaw[GREEN]) < 70)) || + (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[RED]) < 140))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + else + { + + /* Red is not the dominant color */ + if ((pC->SensorRaw[GREEN]) > (pC->SensorRaw[BLUE])) + { + + /* Green is the dominant color */ + /* If all 3 colors are less than 40 OR (Less that 70 and bg less than 20)*/ + if (((pC->SensorRaw[GREEN]) < 40) || + (((pC->SensorRaw[BLANK]) < 30) && ((pC->SensorRaw[GREEN]) < 70))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((pC->SensorRaw[BLUE]) << 1)) < (pC->SensorRaw[RED])) + { + IOMapInput.Inputs[No].SensorValue = YELLOWCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED])>>2)) < (pC->SensorRaw[GREEN])) || + (((pC->SensorRaw[BLUE]) + ((pC->SensorRaw[BLUE])>>2)) < (pC->SensorRaw[GREEN]))) + { + IOMapInput.Inputs[No].SensorValue = GREENCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) < 70) || + ((pC->SensorRaw[BLUE]) < 70)) || + (((pC->SensorRaw[BLANK]) < 140) && ((pC->SensorRaw[GREEN]) < 140))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + else + { + + /* Blue is the most dominant color */ + /* Colors can be blue, white or black */ + /* If all 3 colors are less than 48 OR (Less that 85 and bg less than 25)*/ + if (((pC->SensorRaw[BLUE]) < 48) || + (((pC->SensorRaw[BLANK]) < 25) && ((pC->SensorRaw[BLUE]) < 85))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((((pC->SensorRaw[RED]) * 48) >> 5) < (pC->SensorRaw[BLUE])) && + ((((pC->SensorRaw[GREEN]) * 48) >> 5) < (pC->SensorRaw[BLUE]))) + || + (((((pC->SensorRaw[RED]) * 58) >> 5) < (pC->SensorRaw[BLUE])) || + ((((pC->SensorRaw[GREEN]) * 58) >> 5) < (pC->SensorRaw[BLUE])))) + { + IOMapInput.Inputs[No].SensorValue = BLUECOLOR; + } + else + { + + /* Color is white or Black */ + if ((((pC->SensorRaw[RED]) < 60) || + ((pC->SensorRaw[GREEN]) < 60)) || + (((pC->SensorRaw[BLANK]) < 110) && ((pC->SensorRaw[BLUE]) < 120))) + { + IOMapInput.Inputs[No].SensorValue = BLACKCOLOR; + } + else + { + if ((((pC->SensorRaw[RED]) + ((pC->SensorRaw[RED]) >> 3)) < (pC->SensorRaw[BLUE])) || + (((pC->SensorRaw[GREEN]) + ((pC->SensorRaw[GREEN]) >> 3)) < (pC->SensorRaw[BLUE]))) + { + IOMapInput.Inputs[No].SensorValue = BLUECOLOR; + } + else + { + IOMapInput.Inputs[No].SensorValue = WHITECOLOR; + } + } + } + } + } + } + } + else + { + IOMapInput.Colors[No].CalibrationState = SENSOROFF; + VarsInput.ColorStatus &= ~(0x01< THRESHOLD_FALSE) + if (NewSensorRaw > THRESHOLD_FALSE) { PresentBoolean = FALSE; } else { - if (*pRaw < THRESHOLD_TRUE) + if (NewSensorRaw < THRESHOLD_TRUE) { PresentBoolean = TRUE; } @@ -246,19 +831,19 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) { /* This is dynamic measure method */ - if (*pRaw > (ACTUAL_AD_RES - Slope)) + if (NewSensorRaw > (ACTUAL_AD_RES - Slope)) { PresentBoolean = FALSE; } else { - if (*pRaw < Slope) + if (NewSensorRaw < Slope) { PresentBoolean = TRUE; } else { - Delta = IOMapInput.Inputs[Tmp].SensorRaw - *pRaw; + Delta = *pOldSensorRaw - NewSensorRaw; if (Delta < 0) { if (-Delta > Slope) @@ -276,35 +861,35 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) } } } - IOMapInput.Inputs[Tmp].SensorRaw = *pRaw; + *pOldSensorRaw = NewSensorRaw; switch(Mode) { case RAWMODE: { - IOMapInput.Inputs[Tmp].SensorValue = *pRaw; + *pSensorValue = NewSensorRaw; } break; case BOOLEANMODE: { - IOMapInput.Inputs[Tmp].SensorValue = PresentBoolean; + *pSensorValue = PresentBoolean; } break; case TRANSITIONCNTMODE: { - if (VarsInput.InputDebounce[Tmp] > 0) + if ((*pDebounce) > 0) { - VarsInput.InputDebounce[Tmp]--; + (*pDebounce)--; } else { - if (IOMapInput.Inputs[Tmp].SensorBoolean != PresentBoolean) + if (*pBoolean != PresentBoolean) { - VarsInput.InputDebounce[Tmp] = DEBOUNCERELOAD; - (IOMapInput.Inputs[Tmp].SensorValue)++; + (*pDebounce) = DEBOUNCERELOAD; + (*pSensorValue)++; } } } @@ -312,22 +897,22 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) case PERIODCOUNTERMODE: { - if (VarsInput.InputDebounce[Tmp] > 0) + if ((*pDebounce) > 0) { - VarsInput.InputDebounce[Tmp]--; + (*pDebounce)--; } else { - if (IOMapInput.Inputs[Tmp].SensorBoolean != PresentBoolean) + if (*pBoolean != PresentBoolean) { - VarsInput.InputDebounce[Tmp] = DEBOUNCERELOAD; - IOMapInput.Inputs[Tmp].SensorBoolean = PresentBoolean; - if (++VarsInput.EdgeCnt[Tmp] > 1) + (*pDebounce) = DEBOUNCERELOAD; + *pBoolean = PresentBoolean; + if (++(*pEdgeCnt) > 1) { if (PresentBoolean == 0) { - VarsInput.EdgeCnt[Tmp] = 0; - (IOMapInput.Inputs[Tmp].SensorValue)++; + (*pEdgeCnt) = 0; + (*pSensorValue)++; } } } @@ -339,7 +924,7 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) { /* Output is 0-100 pct */ - IOMapInput.Inputs[Tmp].SensorValue = ((*pRaw) * 100)/SENSOR_RESOLUTION; + *pSensorValue = ((NewSensorRaw) * 100)/SENSOR_RESOLUTION; } break; @@ -347,8 +932,8 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) { /* Fahrenheit mode goes from -40 to 158 degrees */ - IOMapInput.Inputs[Tmp].SensorValue = (((ULONG)(*pRaw) * 900L)/SENSOR_RESOLUTION) - 200; - IOMapInput.Inputs[Tmp].SensorValue = ((180L * (ULONG)(IOMapInput.Inputs[Tmp].SensorValue))/100L) + 320; + *pSensorValue = (((ULONG)(NewSensorRaw) * 900L)/SENSOR_RESOLUTION) - 200; + *pSensorValue = ((180L * (ULONG)(*pSensorValue))/100L) + 320; } break; @@ -356,27 +941,27 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) { /* Celsius mode goes from -20 to 70 degrees */ - IOMapInput.Inputs[Tmp].SensorValue = (((ULONG)(*pRaw) * 900L)/SENSOR_RESOLUTION) - 200; + *pSensorValue = (((ULONG)(NewSensorRaw * 900L)/SENSOR_RESOLUTION) - 200); } break; case ANGLESTEPSMODE: { - IOMapInput.Inputs[Tmp].SensorBoolean = PresentBoolean; + *pBoolean = PresentBoolean; - if (*pRaw < ANGLELIMITA) + if (NewSensorRaw < ANGLELIMITA) { Sample = 0; } else { - if (*pRaw < ANGLELIMITB) + if (NewSensorRaw < ANGLELIMITB) { Sample = 1; } else { - if (*pRaw < ANGLELIMITC) + if (NewSensorRaw < ANGLELIMITC) { Sample = 2; } @@ -387,37 +972,37 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) } } - switch (VarsInput.LastAngle[Tmp]) + switch (*LastAngle) { case 0 : { if (Sample == 1) { - if (VarsInput.SampleCnt[Tmp] >= ROT_SLOW_SPEED ) + if ((*pSampleCnt) >= ROT_SLOW_SPEED ) { - if (++(VarsInput.SampleCnt[Tmp]) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) + if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } } else { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } } if (Sample == 2) { - (IOMapInput.Inputs[Tmp].SensorValue)--; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)--; + (*LastAngle) = Sample; } if (Sample == 0) { - if (VarsInput.SampleCnt[Tmp] < ROT_SLOW_SPEED) + if ((*pSampleCnt) < ROT_SLOW_SPEED) { - (VarsInput.SampleCnt[Tmp])++; + (*pSampleCnt)++; } } } @@ -426,61 +1011,61 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) { if (Sample == 3) { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } if (Sample == 0) { - (IOMapInput.Inputs[Tmp].SensorValue)--; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)--; + (*LastAngle) = Sample; } - VarsInput.SampleCnt[Tmp] = 0; + (*pSampleCnt) = 0; } break; case 2 : { if (Sample == 0) { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } if (Sample == 3) { - (IOMapInput.Inputs[Tmp].SensorValue)--; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)--; + (*LastAngle) = Sample; } - VarsInput.SampleCnt[Tmp] = 0; + (*pSampleCnt) = 0; } break; case 3 : { if (Sample == 2) { - if (VarsInput.SampleCnt[Tmp] >= ROT_SLOW_SPEED) + if ((*pSampleCnt) >= ROT_SLOW_SPEED) { - if (++(VarsInput.SampleCnt[Tmp]) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) + if (++(*pSampleCnt) >= (ROT_SLOW_SPEED + ROT_OV_SAMPLING)) { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } } else { - (IOMapInput.Inputs[Tmp].SensorValue)++; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)++; + (*LastAngle) = Sample; } } if (Sample == 1) { - (IOMapInput.Inputs[Tmp].SensorValue)--; - VarsInput.LastAngle[Tmp] = Sample; + (*pSensorValue)--; + (*LastAngle) = Sample; } if (Sample == 3) { - if (VarsInput.SampleCnt[Tmp] < ROT_SLOW_SPEED) + if ((*pSampleCnt) < ROT_SLOW_SPEED) { - (VarsInput.SampleCnt[Tmp])++; + (*pSampleCnt)++; } } } @@ -489,149 +1074,202 @@ void cInputCalcSensorValue(UWORD *pRaw, UBYTE Slope, UBYTE Mode, UBYTE Tmp) } } - IOMapInput.Inputs[Tmp].SensorBoolean = PresentBoolean; + *pBoolean = PresentBoolean; } - -const SWORD TempConvTable[] = +void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvStatus) { - 1500, 1460, 1430, 1400, 1380, 1360, 1330, 1310, 1290, 1270, 1250, 1230, 1220, 1200, 1190, 1170, - 1160, 1150, 1140, 1130, 1110, 1100, 1090, 1080, 1070, 1060, 1050, 1040, 1030, 1020, 1010, 1000, - 994, 988, 982, 974, 968, 960, 954, 946, 940, 932, 926, 918, 912, 906, 900, 894, - 890, 884, 878, 874, 868, 864, 858, 854, 848, 844, 838, 832, 828, 822, 816, 812, - 808, 802, 798, 794, 790, 786, 782, 780, 776, 772, 768, 764, 762, 758, 754, 750, - 748, 744, 740, 736, 732, 730, 726, 722, 718, 716, 712, 708, 704, 700, 696, 694, - 690, 688, 684, 682, 678, 674, 672, 668, 666, 662, 660, 656, 654, 650, 648, 644, - 642, 640, 638, 634, 632, 630, 628, 624, 622, 620, 616, 614, 612, 610, 608, 604, - 602, 600, 598, 596, 592, 590, 588, 586, 584, 582, 580, 578, 576, 574, 572, 570, - 568, 564, 562, 560, 558, 556, 554, 552, 550, 548, 546, 544, 542, 540, 538, 536, - 534, 532, 530, 528, 526, 524, 522, 520, 518, 516, 514, 512, 510, 508, 508, 506, - 504, 502, 500, 498, 496, 494, 494, 492, 490, 488, 486, 486, 484, 482, 480, 478, - 476, 476, 474, 472, 470, 468, 468, 466, 464, 462, 460, 458, 458, 456, 454, 452, - 450, 448, 448, 446, 444, 442, 442, 440, 438, 436, 436, 434, 432, 432, 430, 428, - 426, 426, 424, 422, 420, 420, 418, 416, 416, 414, 412, 410, 408, 408, 406, 404, - 404, 402, 400, 398, 398, 396, 394, 394, 392, 390, 390, 388, 386, 386, 384, 382, - 382, 380, 378, 378, 376, 374, 374, 372, 370, 370, 368, 366, 366, 364, 362, 362, - 360, 358, 358, 356, 354, 354, 352, 350, 350, 348, 348, 346, 344, 344, 342, 340, - 340, 338, 338, 336, 334, 334, 332, 332, 330, 328, 328, 326, 326, 324, 322, 322, - 320, 320, 318, 316, 316, 314, 314, 312, 310, 310, 308, 308, 306, 304, 304, 302, - 300, 300, 298, 298, 296, 296, 294, 292, 292, 290, 290, 288, 286, 286, 284, 284, - 282, 282, 280, 280, 278, 278, 276, 274, 274, 272, 272, 270, 270, 268, 268, 266, - 264, 264, 262, 262, 260, 260, 258, 258, 256, 254, 254, 252, 252, 250, 250, 248, - 248, 246, 244, 244, 242, 240, 240, 240, 238, 238, 236, 236, 234, 234, 232, 230, - 230, 228, 228, 226, 226, 224, 224, 222, 220, 220, 218, 218, 216, 216, 214, 214, - 212, 212, 210, 210, 208, 208, 206, 204, 204, 202, 202, 200, 200, 198, 198, 196, - 196, 194, 194, 192, 190, 190, 188, 188, 186, 186, 184, 184, 182, 182, 180, 180, - 178, 178, 176, 176, 174, 174, 172, 172, 170, 170, 168, 168, 166, 166, 164, 164, - 162, 162, 160, 160, 158, 156, 156, 154, 154, 152, 152, 150, 150, 148, 148, 146, - 146, 144, 144, 142, 142, 140, 140, 138, 136, 136, 136, 134, 134, 132, 130, 130, - 128, 128, 126, 126, 124, 124, 122, 122, 120, 120, 118, 118, 116, 116, 114, 114, - 112, 110, 110, 108, 108, 106, 106, 104, 104, 102, 102, 100, 100, 98, 98, 96, - 94, 94, 92, 92, 90, 90, 88, 88, 86, 86, 84, 82, 82, 80, 80, 78, - 78, 76, 76, 74, 74, 72, 72, 70, 70, 68, 68, 66, 66, 64, 62, 62, - 60, 60, 58, 56, 56, 54, 54, 52, 52, 50, 50, 48, 48, 46, 46, 44, - 44, 42, 40, 40, 38, 38, 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, - 24, 24, 22, 22, 20, 20, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, - 6, 6, 4, 2, 2, 0, 0, -2, -4, -4, -6, -6, -8, -10, -10, -12, - -12, -14, -16, -16, -18, -20, -20, -22, -22, -24, -26, -26, -28, -30, -30, -32, - -34, -34, -36, -36, -38, -40, -40, -42, -42, -44, -46, -46, -48, -50, -50, -52, - -54, -54, -56, -58, -58, -60, -60, -62, -64, -66, -66, -68, -70, -70, -72, -74, - -76, -76, -78, -80, -80, -82, -84, -86, -86, -88, -90, -90, -92, -94, -94, -96, - -98, -98, -100, -102, -104, -106, -106, -108, -110, -112, -114, -114, -116, -118, -120, -120, - -122, -124, -126, -128, -130, -130, -132, -134, -136, -138, -140, -142, -144, -146, -146, -148, - -150, -152, -154, -156, -158, -160, -162, -164, -166, -166, -168, -170, -172, -174, -176, -178, - -180, -182, -184, -186, -188, -190, -192, -194, -196, -196, -198, -200, -202, -204, -206, -208, - -210, -212, -214, -216, -218, -220, -224, -226, -228, -230, -232, -234, -236, -238, -242, -246, - -248, -250, -254, -256, -260, -262, -264, -268, -270, -274, -276, -278, -282, -284, -286, -290, - -292, -296, -298, -300, -306, -308, -312, -316, -320, -324, -326, -330, -334, -338, -342, -344, - -348, -354, -358, -362, -366, -370, -376, -380, -384, -388, -394, -398, -404, -410, -416, -420, - -428, -432, -440, -446, -450, -460, -468, -476, -484, -492, -500, -510, -524, -534, -546, -560, - -572, -588, -600, -630, -656, -684, -720, -770 -}; + if (*pRawVal >= ZeroPointOffset) + { + *pRawVal -= ZeroPointOffset; + } + else + { + *pRawVal = 0; + } + + *pRawVal = (*pRawVal * 100)/PctFullScale; + if (*pRawVal > SENSOR_RESOLUTION) + { + *pRawVal = SENSOR_RESOLUTION; + } + if (TRUE == InvStatus) + { + *pRawVal = SENSOR_RESOLUTION - *pRawVal; + } +} -void cInputCalcSensorRaw(UWORD *pRaw, UBYTE Type, UBYTE No) +void cInputSetupType(UBYTE Port, UBYTE *pType, UBYTE OldType) { - switch (Type) + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_NORMAL; + + /* If old type is color sensor in color lamp mode then turn off leds */ + switch (OldType) { - case SWITCH: + case COLORRED: + case COLORGREEN: + case COLORBLUE: + case COLORFULL: + case COLOREXIT: { + if (NO_SENSOR == *pType) + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + *pType = COLOREXIT; + } } break; + } + switch(*pType) + { + case NO_SENSOR: + case SWITCH: case TEMPERATURE: { - if (*pRaw < 290) - { - *pRaw = 290; - } - else - { - if (*pRaw > 928) - { - *pRaw = 928; - } - } - *pRaw = TempConvTable[(*pRaw) - 197]; - *pRaw = *pRaw + 200; - *pRaw = (UWORD)(((SLONG)*pRaw * (SLONG)1023)/(SLONG)900); + dInputSetInactive(Port); + dInputSetDirInDigi0(Port); + dInputSetDirInDigi1(Port); } break; + case REFLECTION: { - - /* Sensor dynanmic is restricted by a double diode connected to ground, */ - /* and it cannot go to the top either, dynamic is approx. 390 - 900 count*/ - cInputCalcFullScale(pRaw, REFLECTIONSENSORMIN, REFLECTIONSENSORPCTDYN, TRUE); + dInputSetActive(Port); + dInputClearDigi0(Port); + dInputClearDigi1(Port); } break; + case ANGLE: { + dInputSetActive(Port); + dInputClearDigi0(Port); + dInputClearDigi1(Port); } break; + case LIGHT_ACTIVE: { - cInputCalcFullScale(pRaw, NEWLIGHTSENSORMIN, NEWLIGHTSENSORPCTDYN, TRUE); + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputClearDigi1(Port); } break; + case LIGHT_INACTIVE: { - cInputCalcFullScale(pRaw, NEWLIGHTSENSORMIN, NEWLIGHTSENSORPCTDYN, TRUE); + dInputSetInactive(Port); + dInputClearDigi0(Port); + dInputClearDigi1(Port); } break; + case SOUND_DB: { - cInputCalcFullScale(pRaw, NEWSOUNDSENSORMIN, NEWSOUNDSENSORPCTDYN, TRUE); + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputClearDigi1(Port); } break; + case SOUND_DBA: { - cInputCalcFullScale(pRaw, NEWSOUNDSENSORMIN, NEWSOUNDSENSORPCTDYN, TRUE); + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_SOUND; + dInputSetInactive(Port); + dInputClearDigi0(Port); + dInputSetDigi1(Port); } break; + + case CUSTOM: + { + cInputSetupCustomSensor(Port); + } + break; + case LOWSPEED: { - /* Intended empty Low Speed module takes over */ + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDigi1(Port); + } + break; + + case LOWSPEED_9V: + { + dInputSet9v(Port); + dInputSetDigi0(Port); + dInputSetDigi1(Port); } break; + case HIGHSPEED: { + dInputSetInactive(Port); + dInputSetDirInDigi0(Port); + dInputSetDirInDigi1(Port); } break; - case CUSTOM: + + case COLORFULL: { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; - /* Setup and read digital IO */ - cInputSetupCustomSensor(No); - dInputRead0(No, &(IOMapInput.Inputs[No].DigiPinsIn)); - dInputRead1(No, &(IOMapInput.Inputs[No].DigiPinsIn)); - cInputCalcFullScale(pRaw, IOMapInput.Inputs[No].CustomZeroOffset, IOMapInput.Inputs[No].CustomPctFullScale, FALSE); } break; - case NO_SENSOR: + + case COLORRED: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; + + case COLORGREEN: { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; } break; + + case COLORBLUE: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; + + case COLORNONE: + { + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; + dInputSetInactive(Port); + dInputSetDigi0(Port); + dInputSetDirInDigi1(Port); + IOMapInput.Colors[Port].CalibrationState = SENSORCAL; + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; + default: { } @@ -639,139 +1277,247 @@ void cInputCalcSensorRaw(UWORD *pRaw, UBYTE Type, UBYTE No) } } -void cInputCalcFullScale(UWORD *pRawVal, UWORD ZeroPointOffset, UBYTE PctFullScale, UBYTE InvStatus) +void cInputSetupCustomSensor(UBYTE Port) { - if (*pRawVal >= ZeroPointOffset) + if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x01) { - *pRawVal -= ZeroPointOffset; + if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x01) + { + dInputSetDigi0(Port); + } + else + { + dInputClearDigi0(Port); + } + } + if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02) + { + if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02) + { + dInputSetDigi1(Port); + } + else + { + dInputClearDigi1(Port); + } } else { - *pRawVal = 0; + dInputSetDirInDigi1(Port); } - *pRawVal = (*pRawVal * 100)/PctFullScale; - if (*pRawVal > SENSOR_RESOLUTION) + if (CUSTOMACTIVE == (IOMapInput.Inputs[Port].CustomActiveStatus)) { - *pRawVal = SENSOR_RESOLUTION; + dInputSetActive(Port); } - if (TRUE == InvStatus) + else { - *pRawVal = SENSOR_RESOLUTION - *pRawVal; + if (CUSTOM9V == (IOMapInput.Inputs[Port].CustomActiveStatus)) + { + dInputSet9v(Port); + } + else + { + dInputSetInactive(Port); + } } } -void cInputSetupType(UBYTE Port) -{ - UBYTE Setup; - Setup = (ActiveList[IOMapInput.Inputs[Port].SensorType]); +UBYTE cInputInitColorSensor(UBYTE Port, UBYTE *pInitStatus) +{ - if (CUSTOM_SETUP & Setup) + *pInitStatus = FALSE; + switch(VarsInput.VarsColor[Port].ColorInitState) { - cInputSetupCustomSensor(Port); - } - else - { - if (NO_POWER & Setup) + case 0: + { + dInputSetDigi0(Port); + dInputSetDigi1(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 1: + { + dInputClearDigi0(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + + case 2: + { + dInputSetDigi0(Port); + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 3: { - /* Setup is not used - set pins in unconfigured state */ - dInputSetInactive(Port); - dInputSetDirInDigi0(Port); - dInputSetDirInDigi1(Port); + dInputClearDigi0(Port); + + /* Clear clock for 100mS - use pit timer*/ + dInputClearColor100msTimer(Port); + VarsInput.VarsColor[Port].ColorInitState++; } - else + break; + case 4: { - if (ACTIVE & Setup) + + /* Wait 100mS */ + if (dInputChkColor100msTimer(Port)) { - dInputSetActive(Port); + VarsInput.VarsColor[Port].ColorInitState += 1; } - else + } + break; + case 5: + { + UBYTE TmpType; + + if (COLOREXIT == IOMapInput.Inputs[Port].SensorType) { - if(ALWAYS_ACTIVE & Setup) - { - dInputSet9v(Port); - } - else - { - dInputSetInactive(Port); - } + TmpType = COLORNONE; } - if (DIGI_0_HIGH & Setup) + else { - dInputSetDigi0(Port); - dInputSetDirOutDigi0(Port); + TmpType = IOMapInput.Inputs[Port].SensorType; } - else + dInputColorTx(Port, TmpType); + + /* Be ready to receive data from sensor */ + dInputSetDirInDigi1(Port); + VarsInput.VarsColor[Port].ReadCnt = 0; + VarsInput.VarsColor[Port].ColorInitState++; + } + break; + case 6: + { + UBYTE Data; + UBYTE DataCnt; + UBYTE *pData; + + DataCnt = (VarsInput.VarsColor[Port].ReadCnt); + pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); + + /* Read first byte of cal data */ + dInputReadCal(Port, &Data); + + pData[DataCnt] = Data; + + /* If all bytes has been read - then continue to next step */ + if (++(VarsInput.VarsColor[Port].ReadCnt) >= ((sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)))) { - dInputClearDigi0(Port); - dInputSetDirOutDigi0(Port); + VarsInput.VarsColor[Port].ColorInitState++; } + } + break; + case 7: + { + + /* Check CRC then continue or restart if false */ + UWORD Crc, CrcCheck; + UBYTE Cnt; + UBYTE Data; + UBYTE *pData; + + dInputReadCal(Port, &Data); + Crc = (UWORD)(Data) << 8; + dInputReadCal(Port, &Data); + Crc += (UWORD)Data; + CrcCheck = 0x5AA5; + pData = (UBYTE*)(IOMapInput.Colors[Port].Calibration); + for (Cnt = 0; Cnt < (sizeof(IOMapInput.Colors[Port].Calibration) + sizeof(IOMapInput.Colors[Port].CalLimits)); Cnt++) + { + UWORD i,j; + UBYTE c; + c = pData[Cnt]; + for(i = 0; i != 8; c >>= 1, i++) + { + j = (c^CrcCheck) & 1; + CrcCheck >>= 1; + + if(j) + { + CrcCheck ^= 0xA001; + } + } - if (DIGI_1_HIGH & Setup) + } + if ((CrcCheck != Crc)) { - dInputSetDigi1(Port); - dInputSetDirOutDigi1(Port); + + /* incorrect!!! try again */ + VarsInput.VarsColor[Port].ColorInitState = 0; + VarsInput.InvalidTimer[Port] = INVALID_RELOAD_COLOR; } else { - dInputClearDigi1(Port); - dInputSetDirOutDigi1(Port); + + /* Correct crc sum -> calculate the calibration values then exit */ + VarsInput.VarsColor[Port].ColorInitState = 0; + + /* Sensor is almost ready - needs a little time to make first measurements */ + VarsInput.InvalidTimer[Port] = 10; + *pInitStatus = TRUE; } } + break; + default: + { + VarsInput.VarsColor[Port].ColorInitState = 0; + } + break; } + return(dInputCheckColorStatus(Port)); } -void cInputSetupCustomSensor(UBYTE Port) + +void cInputCalibrateColor(COLORSTRUCT *pC, UWORD *pNewVals) { - if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x01) + UBYTE CalRange; + + if ((pC->ADRaw[BLANK]) < pC->CalLimits[1]) { - if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x01) - { - dInputSetDigi0(Port); - } - else - { - dInputClearDigi0(Port); - } - dInputSetDirOutDigi0(Port); + CalRange = 2; } - if ((IOMapInput.Inputs[Port].DigiPinsDir) & 0x02) + else { - if ((IOMapInput.Inputs[Port].DigiPinsOut) & 0x02) + if ((pC->ADRaw[BLANK]) < pC->CalLimits[0]) { - dInputSetDigi1(Port); + CalRange = 1; } else { - dInputClearDigi1(Port); + CalRange = 0; } - dInputSetDirOutDigi1(Port); } - else + + pNewVals[RED] = 0; + if ((pC->ADRaw[RED]) > (pC->ADRaw[BLANK])) { - dInputSetDirInDigi1(Port); + pNewVals[RED] = (UWORD)(((ULONG)((pC->ADRaw[RED]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][RED])) >> 16); } - if (CUSTOMACTIVE == (IOMapInput.Inputs[Port].CustomActiveStatus)) + pNewVals[GREEN] = 0; + if ((pC->ADRaw[GREEN]) > (pC->ADRaw[BLANK])) { - dInputSetActive(Port); + pNewVals[GREEN] = (UWORD)(((ULONG)((pC->ADRaw[GREEN]) - (pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][GREEN])) >> 16); } - else + + pNewVals[BLUE] = 0; + if ((pC->ADRaw[BLUE]) > (pC->ADRaw[BLANK])) { - if (CUSTOM9V == (IOMapInput.Inputs[Port].CustomActiveStatus)) - { - dInputSet9v(Port); - } - else - { - dInputSetInactive(Port); - } + pNewVals[BLUE] = (UWORD)(((ULONG)((pC->ADRaw[BLUE]) -(pC->ADRaw[BLANK])) * (pC->Calibration[CalRange][BLUE])) >> 16); } + + pNewVals[BLANK] = (pC->ADRaw[BLANK]); + cInputCalcFullScale(&(pNewVals[BLANK]), COLORSENSORBGMIN, COLORSENSORBGPCTDYN, FALSE); + (pNewVals[BLANK]) = (UWORD)(((ULONG)(pNewVals[BLANK]) * (pC->Calibration[CalRange][BLANK])) >> 16); } + void cInputExit(void) { dInputExit(); } + diff --git a/AT91SAM7S256/Source/c_input.h b/AT91SAM7S256/Source/c_input.h index dfa981b..4e508f3 100644 --- a/AT91SAM7S256/Source/c_input.h +++ b/AT91SAM7S256/Source/c_input.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 14-01-09 10:33 $ // // Filename $Workfile:: c_input.h $ // -// Version $Revision:: 9 $ +// Version $Revision:: 7 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_input.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ // // Platform C // @@ -37,12 +37,26 @@ extern const HEADER cInput; typedef struct { - UWORD InvalidTimer[NO_OF_INPUTS]; - UBYTE InputDebounce[NO_OF_INPUTS]; - UBYTE EdgeCnt[NO_OF_INPUTS]; - UBYTE LastAngle[NO_OF_INPUTS]; - UBYTE OldSensorType[NO_OF_INPUTS]; - UBYTE SampleCnt[NO_OF_INPUTS]; + UBYTE ColorInputDebounce [NO_OF_COLORS]; + UBYTE ColorEdgeCnt [NO_OF_COLORS]; + UBYTE ColorLastAngle [NO_OF_COLORS]; + UBYTE ColorSampleCnt [NO_OF_COLORS]; + UBYTE ColorInitState; + UBYTE ReadCnt; +} VARSCOLOR; + + +typedef struct +{ + UWORD InvalidTimer [NO_OF_INPUTS]; + UBYTE InputDebounce [NO_OF_INPUTS]; + UBYTE EdgeCnt [NO_OF_INPUTS]; + UBYTE LastAngle [NO_OF_INPUTS]; + UBYTE OldSensorType [NO_OF_INPUTS]; + UBYTE SampleCnt [NO_OF_INPUTS]; + VARSCOLOR VarsColor [NO_OF_INPUTS]; + UBYTE ColorCnt; + UBYTE ColorStatus; }VARSINPUT; void cInputInit(void* pHeader); diff --git a/AT91SAM7S256/Source/c_input.iom b/AT91SAM7S256/Source/c_input.iom index 8d651b8..dee1309 100644 --- a/AT91SAM7S256/Source/c_input.iom +++ b/AT91SAM7S256/Source/c_input.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 24-09-08 15:23 $ // // Filename $Workfile:: c_input.iom $ // -// Version $Revision:: 15 $ +// Version $Revision:: 16 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_input.io $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_inpu $ // // Platform C // @@ -22,20 +22,26 @@ /* Constants related to sensor type */ enum { - NO_SENSOR = 0, - SWITCH = 1, - TEMPERATURE = 2, - REFLECTION = 3, - ANGLE = 4, - LIGHT_ACTIVE = 5, - LIGHT_INACTIVE = 6, - SOUND_DB = 7, - SOUND_DBA = 8, - CUSTOM = 9, + NO_SENSOR = 0, + SWITCH = 1, + TEMPERATURE = 2, + REFLECTION = 3, + ANGLE = 4, + LIGHT_ACTIVE = 5, + LIGHT_INACTIVE = 6, + SOUND_DB = 7, + SOUND_DBA = 8, + CUSTOM = 9, LOWSPEED = 10, LOWSPEED_9V = 11, HIGHSPEED = 12, - NO_OF_SENSOR_TYPES = 13 + COLORFULL = 13, + COLORRED = 14, + COLORGREEN = 15, + COLORBLUE = 16, + COLORNONE = 17, + COLOREXIT = 18, /* For internal use when going from color or Lamp to no_sensor*/ + NO_OF_SENSOR_TYPES = 18 }; /* Constants related to sensor mode */ @@ -69,12 +75,57 @@ enum enum { - INVALID_DATA = 0x01 + INVALID_DATA = 0x01 }; +/* Constants related to Colorstruct */ +enum +{ + RED, + GREEN, + BLUE, + BLANK, + NO_OF_COLORS +}; + + +/* Constants related to color sensor value using */ +/* Color sensor as color detector */ +enum +{ + BLACKCOLOR = 1, + BLUECOLOR = 2, + GREENCOLOR = 3, + YELLOWCOLOR = 4, + REDCOLOR = 5, + WHITECOLOR = 6 +}; + + +/* Constants related to Color CalibrationState */ +/* When STARTCAL is TRUE then calibration is */ +/* in progress */ +enum +{ + SENSORCAL = 0x01, + SENSOROFF = 0x02, + RUNNINGCAL = 0x20, + STARTCAL = 0x40, + RESETCAL = 0x80, +}; + +enum +{ + CAL_POINT_0, + CAL_POINT_1, + CAL_POINT_2, + NO_OF_POINTS +}; + + typedef struct { - UWORD CustomZeroOffset; /* Set the offset of the custom sensor */ + UWORD CustomZeroOffset; /* Set the offset of the custom sensor */ UWORD ADRaw; UWORD SensorRaw; SWORD SensorValue; @@ -90,17 +141,32 @@ typedef struct UBYTE CustomActiveStatus; /* Sets the active or inactive state of the custom sensor */ UBYTE InvalidData; /* Indicates wether data is invalid (1) or valid (0) */ - + UBYTE Spare1; UBYTE Spare2; UBYTE Spare3; -}INPUT; +}INPUTSTRUCT; + +typedef struct +{ + ULONG Calibration[NO_OF_POINTS][NO_OF_COLORS]; + UWORD CalLimits[NO_OF_POINTS - 1]; + UWORD ADRaw[NO_OF_COLORS]; + UWORD SensorRaw[NO_OF_COLORS]; + SWORD SensorValue[NO_OF_COLORS]; + UBYTE Boolean[NO_OF_COLORS]; + UBYTE CalibrationState; + UBYTE Free1; + UBYTE Free2; + UBYTE Free3; +}COLORSTRUCT; typedef struct { - INPUT Inputs[NO_OF_INPUTS]; + INPUTSTRUCT Inputs[NO_OF_INPUTS]; + COLORSTRUCT Colors[NO_OF_INPUTS]; }IOMAPINPUT; #endif diff --git a/AT91SAM7S256/Source/c_ioctrl.c b/AT91SAM7S256/Source/c_ioctrl.c index 2964f33..daab322 100644 --- a/AT91SAM7S256/Source/c_ioctrl.c +++ b/AT91SAM7S256/Source/c_ioctrl.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_ioctrl.c $ // -// Version $Revision:: 13 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ioctrl.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_ioctrl.h b/AT91SAM7S256/Source/c_ioctrl.h index a2bd892..5ad4c8f 100644 --- a/AT91SAM7S256/Source/c_ioctrl.h +++ b/AT91SAM7S256/Source/c_ioctrl.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_ioctrl.h $ // -// Version $Revision:: 4 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ioctrl.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_ioctrl.iom b/AT91SAM7S256/Source/c_ioctrl.iom index 3385caa..9742d04 100644 --- a/AT91SAM7S256/Source/c_ioctrl.iom +++ b/AT91SAM7S256/Source/c_ioctrl.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_ioctrl.iom $ // -// Version $Revision:: 8 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ioctrl.i $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ioct $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_loader.c b/AT91SAM7S256/Source/c_loader.c index 8b43bd8..995c920 100644 --- a/AT91SAM7S256/Source/c_loader.c +++ b/AT91SAM7S256/Source/c_loader.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 8:27 $ +// Revision date $Date:: 12-03-08 15:28 $ // // Filename $Workfile:: c_loader.c $ // -// Version $Revision:: 79 $ +// Version $Revision:: 5 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_loader.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ // // Platform C // @@ -116,7 +116,7 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen case OPENWRITEDATA: { - ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) LINEAR, DATAFILE); + ReturnState = dLoaderCreateFileHeader(*pLength, pFileName, (UBYTE) NONLINEAR, DATAFILE); if (0x8000 <= ReturnState) { dLoaderCloseHandle(ReturnState); @@ -141,6 +141,12 @@ UWORD cLoaderFileRq(UBYTE Cmd, UBYTE *pFileName, UBYTE *pBuffer, ULONG *pLen ReturnState = dLoaderCloseHandle(*pFileName); } break; + case CROPDATAFILE: + { + ReturnState = dLoaderCropDatafile(*pFileName); + IOMapLoader.FreeUserFlash = dLoaderReturnFreeUserFlash(); + } + break; case READ: { ReturnState = dLoaderRead(*pFileName, pBuffer, pLength); diff --git a/AT91SAM7S256/Source/c_loader.h b/AT91SAM7S256/Source/c_loader.h index a720c37..03f8062 100644 --- a/AT91SAM7S256/Source/c_loader.h +++ b/AT91SAM7S256/Source/c_loader.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 8:27 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_loader.h $ // -// Version $Revision:: 8 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_loader.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_loader.iom b/AT91SAM7S256/Source/c_loader.iom index 8a86e2d..dde8b6a 100644 --- a/AT91SAM7S256/Source/c_loader.iom +++ b/AT91SAM7S256/Source/c_loader.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 28-03-07 14:54 $ +// Revision date $Date:: 24-06-09 8:53 $ // // Filename $Workfile:: c_loader.iom $ // -// Version $Revision:: 45 $ +// Version $Revision:: 15 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_loader.i $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_load $ // // Platform C // @@ -21,7 +21,7 @@ //For example, version 1.5 would be 0x0105 //If these switch to little-endian, be sure to update //definition and usages of VM_OLDEST_COMPATIBLE_VERSION, too! -#define FIRMWAREVERSION 0x0105 //1.05 +#define FIRMWAREVERSION 0x011D //1.28 #define PROTOCOLVERSION 0x017C //1.124 enum @@ -39,6 +39,7 @@ enum OPENREADLINEAR = 0x8A, OPENWRITEDATA = 0x8B, OPENAPPENDDATA = 0x8C, + CROPDATAFILE = 0x8D, /* New cmd for datalogging */ FINDFIRSTMODULE = 0x90, FINDNEXTMODULE = 0x91, CLOSEMODHANDLE = 0x92, diff --git a/AT91SAM7S256/Source/c_lowspeed.c b/AT91SAM7S256/Source/c_lowspeed.c index a43ba7d..26851db 100644 --- a/AT91SAM7S256/Source/c_lowspeed.c +++ b/AT91SAM7S256/Source/c_lowspeed.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_lowspeed.c $ // -// Version $Revision:: 23 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_lowspeed.h b/AT91SAM7S256/Source/c_lowspeed.h index 7930acc..1595158 100644 --- a/AT91SAM7S256/Source/c_lowspeed.h +++ b/AT91SAM7S256/Source/c_lowspeed.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_lowspeed.h $ // -// Version $Revision:: 11 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_lowspeed.iom b/AT91SAM7S256/Source/c_lowspeed.iom index a8e42a4..290ed35 100644 --- a/AT91SAM7S256/Source/c_lowspeed.iom +++ b/AT91SAM7S256/Source/c_lowspeed.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_lowspeed.iom $ // -// Version $Revision:: 18 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_lows $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_output.c b/AT91SAM7S256/Source/c_output.c index c91eb07..9566938 100644 --- a/AT91SAM7S256/Source/c_output.c +++ b/AT91SAM7S256/Source/c_output.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_output.c $ // -// Version $Revision:: 45 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_output.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_output.h b/AT91SAM7S256/Source/c_output.h index e3d7c43..14faa2c 100644 --- a/AT91SAM7S256/Source/c_output.h +++ b/AT91SAM7S256/Source/c_output.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_output.h $ // -// Version $Revision:: 6 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_output.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_output.iom b/AT91SAM7S256/Source/c_output.iom index e13f0f8..80e35de 100644 --- a/AT91SAM7S256/Source/c_output.iom +++ b/AT91SAM7S256/Source/c_output.iom @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_output.iom $ // -// Version $Revision:: 25 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_output.i $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_outp $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_sound.c b/AT91SAM7S256/Source/c_sound.c index 8e34d32..9d0a81d 100644 --- a/AT91SAM7S256/Source/c_sound.c +++ b/AT91SAM7S256/Source/c_sound.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_sound.c $ // -// Version $Revision:: 33 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_sound.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_sound.h b/AT91SAM7S256/Source/c_sound.h index 93e3221..ebdbb9a 100644 --- a/AT91SAM7S256/Source/c_sound.h +++ b/AT91SAM7S256/Source/c_sound.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 26-08-05 8:37 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_sound.h $ // -// Version $Revision:: 10 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_sound.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_sound.iom b/AT91SAM7S256/Source/c_sound.iom index 8baeb72..ec12076 100644 --- a/AT91SAM7S256/Source/c_sound.iom +++ b/AT91SAM7S256/Source/c_sound.iom @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 24-01-06 11:47 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: c_sound.iom $ // -// Version $Revision:: 18 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_sound.io $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/c_ui.c b/AT91SAM7S256/Source/c_ui.c index dd7e351..c79dca9 100644 --- a/AT91SAM7S256/Source/c_ui.c +++ b/AT91SAM7S256/Source/c_ui.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 2-03-06 13:03 $ +// Revision date $Date:: 10-06-08 9:26 $ // // Filename $Workfile:: c_ui.c $ // -// Version $Revision:: 135 $ +// Version $Revision:: 7 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ui.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.c $ // // Platform C // @@ -157,14 +157,6 @@ enum STATUS_NO // Index in status icon collection file #include "Devices.txt" // Icon collection used for Blue tooth devices -enum -{ - DEVICETYPE_UNKNOWN, - DEVICETYPE_NXT, - DEVICETYPE_PHONE, - DEVICETYPE_PC -}; - // ****** BT CONNECTIONS GRAPHIC RESOURCES *********************************** #include "Connections.txt" // Icon collection used for Blue tooth connections @@ -209,6 +201,11 @@ enum // String index in text string file TXT_FB_OBP_FILE_EXIST_FAIL, // "File exist" TXT_FB_OBP_OVERWRITE_FAIL, // "overwrite!" + // Datalogging + TXT_FB_DL_FILE_SAVED_INFO, // "File saved" + TXT_FB_DL_FILE_EXIST_FAIL, // "File exist" + TXT_FB_DL_OVERWRITE_FAIL, // "overwrite!" + // File delete TXT_FB_FD_FILE_DELETED_INFO, // "File deleted" @@ -226,6 +223,13 @@ enum // String index in text string file TXT_FILESDELETE_DELETING_ALL, // "Deleting all" TXT_FILESDELETE_S_FILES, // "%s files!" + // Datalogging + TXT_DATALOGGING_PRESS_EXIT_TO, // "Press exit to" + TXT_DATALOGGING_STOP_DATALOGGING, // "stop datalogging" + TXT_DATALOGGING_PORT_OCCUPIED, // "Port occupied!" + TXT_DATALOGGING_RATE, // "H:MM:SS:00 + TXT_DATALOGGING_TIME, // "HH:MM:SS" + // File types TXT_FILETYPE_SOUND, // "Sound" TXT_FILETYPE_LMS, // "Software" @@ -256,12 +260,16 @@ enum // String index in text string file // Bluetooth list errors TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_1, // BT save data error! - TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_2, // + TXT_FB_BT_ERROR_LR_COULD_NOT_SAVE_2, // TXT_FB_BT_ERROR_LR_STORE_IS_FULL_1, // BT store is full error! TXT_FB_BT_ERROR_LR_STORE_IS_FULL_2, // TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_1, // BT unknown addr. error! TXT_FB_BT_ERROR_LR_UNKOWN_ADDR_2, // - + + // Datalog errors + TXT_FB_DL_ERROR_MEMORY_FULL_1, // Memory is full! + TXT_FB_DL_ERROR_MEMORY_FULL_2, // + // Power of time TXT_POWEROFFTIME_NEVER // "Never" @@ -272,7 +280,7 @@ enum // String index in text string file #define ALLFILES 0x1A // Icon collection offset enum // File type id's -{ +{ FILETYPE_ALL, // 0 = All FILETYPE_SOUND, // 1 = Sound FILETYPE_LMS, // 2 = LMS @@ -296,7 +304,7 @@ const UBYTE TXT_FILETYPE[FILETYPES] = { 0, // NA TXT_FILETYPE_SOUND, // 1 = Sound - TXT_FILETYPE_LMS, // 2 = LM + TXT_FILETYPE_LMS, // 2 = LMS TXT_FILETYPE_NXT, // 3 = NXT TXT_FILETYPE_TRY_ME,// 4 = Try me TXT_FILETYPE_DATA // 5 = Datalog @@ -315,7 +323,7 @@ const UBYTE PowerOffTimeSteps[POWER_OFF_TIME_STEPS] = { 0,2,5,10,30,60 }; // #define BATTERYLIMITHYST 100 // [mV] #define RECHARGEABLELIMITHYST 50 // [mV] -const UWORD BatteryLimits[BATTERYLIMITS] = +const UWORD BatteryLimits[BATTERYLIMITS] = { 6100,6500,7000,7500 // [mV] }; @@ -330,70 +338,31 @@ const UWORD RechargeableLimits[BATTERYLIMITS] = #include "Mainmenu.rms" #include "Submenu01.rms" #include "Submenu02.rms" +#include "Submenu03.rms" #include "Submenu04.rms" #include "Submenu05.rms" #include "Submenu06.rms" #include "Submenu07.rms" - -SWORD cUiMenuFile(UBYTE Cmd,UBYTE *pFile,UBYTE *pData,ULONG *pLng) +const UBYTE *MenuPointers[] = { - SWORD Result; - UBYTE *pFilePointer; - - Result = -1; - switch (Cmd) - { - case OPENREADLINEAR : - { - if (strcmp((char*)pFile,"Mainmenu.rms") == 0) - { - pFilePointer = (UBYTE*)MAINMENU; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu01.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU01; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu02.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU02; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu04.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU04; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu05.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU05; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu06.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU06; - Result = 0; - } - if (strcmp((char*)pFile,"Submenu07.rms") == 0) - { - pFilePointer = (UBYTE*)SUBMENU07; - Result = 0; - } - if (Result == 0) - { - *pLng = ((UWORD)pFilePointer[2] << 8) + (UWORD)pFilePointer[3] + FILEHEADER_LENGTH; - *((ULONG*)pData) = (ULONG)pFilePointer; - } - } - break; + (UBYTE*)MAINMENU, + (UBYTE*)SUBMENU01, + (UBYTE*)SUBMENU02, + (UBYTE*)SUBMENU03, + (UBYTE*)SUBMENU04, + (UBYTE*)SUBMENU05, + (UBYTE*)SUBMENU06, + (UBYTE*)SUBMENU07 +}; - } - return (Result); +UBYTE* cUiGetMenuPointer(UBYTE FileNo) +{ + return ((UBYTE*)MenuPointers[FileNo]); } + //****************************************************************************************************** UBYTE* cUiGetString(UBYTE No) // Get string in text string file @@ -484,7 +453,7 @@ UBYTE cUiReadButtons(void) // Read buttons if (Result != BUTTON_NONE) { // If key - play key sound file - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_KEYCLICK_SOUND,(char*)TXT_SOUND_EXT); + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_KEYCLICK_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); pMapSound->Volume = IOMapUi.Volume; pMapSound->Mode = SOUND_ONCE; pMapSound->Flags |= SOUND_UPDATE; @@ -577,37 +546,27 @@ void cUiListCalc(UBYTE Limit,UBYTE *Center,UBYTE *Left,UBYTE *Right) } } break; - + } } -UBYTE* cUiGetMenuPointer(UBYTE FileNo) +UBYTE cUiMenuSearchSensorIcon(UBYTE Sensor) { - ULONG Lng; - UWORD Handle; - UBYTE TmpBuffer[FILENAME_LENGTH + 1]; - UBYTE *pPointer; + UBYTE Result = 0; + MENUITEM *MenuItem; + UBYTE Index; - if (FileNo) - { - sprintf((char*)TmpBuffer,"Submenu%02X.rms",(UWORD)FileNo); - } - else + for (Index = 0;(Index < IOMapUi.pMenu->Items) && (Result == NULL);Index++) { - sprintf((char*)TmpBuffer,"Mainmenu.rms"); - } - Handle = cUiMenuFile(OPENREADLINEAR,TmpBuffer,(UBYTE*)&pPointer,&Lng); - if ((Handle & 0x8000)) - { - pPointer = NULL; - } - else - { - cUiMenuFile(CLOSE,(UBYTE*)&Handle,NULL,NULL); + MenuItem = &IOMapUi.pMenu->Data[Index]; + if (MenuItem->FunctionParameter == Sensor) + { + Result = MenuItem->IconImageNo; + } } - return (pPointer); + return (Result); } @@ -697,7 +656,6 @@ UBYTE cUiMenuIdValid(MENUFILE *pMenuFile,ULONG Id) } else { - Id >>= (Level * 4); if ((Id & 0x0000000F) && (!(Id & 0xFFFFFFF0))) { Result = TRUE; @@ -735,7 +693,7 @@ UBYTE cUiMenuGetNoOfMenus(MENU *pMenu,MENUFILE *pMenuFile) if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) { // Datalog menu must be enabled - if (!(VarsUi.NVData & 0x80)) + if (VarsUi.NVData.DatalogEnabled) { // Yes NoOfMenus++; @@ -783,7 +741,7 @@ UBYTE cUiGetMenuItemIndex(MENU *pMenu,MENUFILE *pMenuFile,UBYTE No) if ((cUiMenuGetSpecialMask(&pMenu->Data[Index]) & MENU_ONLY_DATALOG_ENABLED)) { // Datalog menu must be enabled - if (!(VarsUi.NVData & 0x80)) + if (VarsUi.NVData.DatalogEnabled) { // Yes TmpIndex = Index; @@ -1235,7 +1193,7 @@ void cUiLoadLevel(UBYTE FileLevel,UBYTE MenuLevel,UBYTE MenuIndex) { // if items > 0 -> prepare allways center icon Tmp = cUiGetMenuItemIndex(IOMapUi.pMenu,VarsUi.pMenuFile,VarsUi.pMenuLevel->ItemIndex); - + if (VarsUi.pMenuItem != &IOMapUi.pMenu->Data[Tmp - 1]) { VarsUi.pMenuItem = &IOMapUi.pMenu->Data[Tmp - 1]; @@ -1251,7 +1209,7 @@ void cUiLoadLevel(UBYTE FileLevel,UBYTE MenuLevel,UBYTE MenuIndex) VarsUi.pMenuLevel->Parameter = VarsUi.pMenuItem->FunctionParameter; VarsUi.pMenuLevel->NextFileNo = VarsUi.pMenuItem->FileLoadNo; VarsUi.pMenuLevel->NextMenuNo = VarsUi.pMenuItem->NextMenu; - } + } } #include "Functions.inl" @@ -1336,6 +1294,8 @@ void cUiCtrl(void) { case INIT_DISPLAY : // Load font and icons { +// pMapLoader->pFunc(DELETEUSERFLASH,NULL,NULL,NULL); + VarsUi.Initialized = FALSE; IOMapUi.Flags = UI_BUSY; @@ -1363,18 +1323,18 @@ void cUiCtrl(void) VarsUi.BatteryToggle = 0; VarsUi.GUSState = 0; - + IOMapUi.pMenu = (MENU*)cUiGetMenuPointer(0); IOMapUi.State = INIT_INTRO; pMapDisplay->EraseMask = SCREEN_BIT(SCREEN_BACKGROUND); pMapDisplay->pBitmaps[BITMAP_1] = (BMPMAP*)Intro[VarsUi.Pointer]; pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); - pMapDisplay->Flags |= DISPLAY_ON; + pMapDisplay->Flags |= DISPLAY_ON; - cUiNVReadByte(); - IOMapUi.Volume = cUiNVReadVolumeCount(); - IOMapUi.SleepTimeout = PowerOffTimeSteps[cUiNVReadPowerOnTimeCount()]; + cUiNVRead(); + IOMapUi.Volume = VarsUi.NVData.VolumeStep; + IOMapUi.SleepTimeout = PowerOffTimeSteps[VarsUi.NVData.PowerdownCode]; } break; @@ -1438,7 +1398,7 @@ void cUiCtrl(void) pMapDisplay->UpdateMask = BITMAP_BIT(BITMAP_1); if (VarsUi.Pointer == 11) { - sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_STARTUP_SOUND,(char*)TXT_SOUND_EXT); + sprintf((char*)pMapSound->SoundFilename,"%s.%s",(char*)UI_STARTUP_SOUND,(char*)TXT_FILE_EXT[FILETYPE_SOUND]); pMapSound->Volume = IOMapUi.Volume; pMapSound->Mode = SOUND_ONCE; pMapSound->Flags |= SOUND_UPDATE; @@ -1485,7 +1445,7 @@ void cUiCtrl(void) case INIT_MENU : { // Restart menu system - VarsUi.Function = 0; + VarsUi.Function = 0; VarsUi.MenuFileLevel = 0; cUiLoadLevel(0,0,1); @@ -1516,7 +1476,7 @@ void cUiCtrl(void) // Prepare center icon pMapDisplay->pMenuIcons[MENUICON_CENTER] = cUiMenuGetIconImage(VarsUi.pMenuLevel->IconImageNo); pMapDisplay->pMenuText = VarsUi.pMenuLevel->IconText; - + if (VarsUi.pMenuLevel->Items == 2) { // if 2 menues -> prepare left or right icon diff --git a/AT91SAM7S256/Source/c_ui.h b/AT91SAM7S256/Source/c_ui.h index 07a4237..e74dcbe 100644 --- a/AT91SAM7S256/Source/c_ui.h +++ b/AT91SAM7S256/Source/c_ui.h @@ -5,13 +5,13 @@ // // Reviser $Author:: Dktochpe $ // -// Revision date $Date:: 3-02-06 12:50 $ +// Revision date $Date:: 10/21/08 12:08p $ // // Filename $Workfile:: c_ui.h $ // -// Version $Revision:: 75 $ +// Version $Revision:: 10 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ui.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.h $ // // Platform C // @@ -19,6 +19,8 @@ #ifndef C_UI #define C_UI +#define DATALOGENABLED 1 // 1 == Datalog enable + #define NO_OF_FEEDBACK_CHARS 12 // Chars left when bitmap also showed #define SIZE_OF_CURSOR 16 // Bitmap size of cursor (header + 8x8 pixels) #define SIZE_OF_PORTBITMAP 11 // Bitmap size of port no (header + 3x8 pixels) @@ -32,6 +34,8 @@ #define MAX_VOLUME 4 // Max volume in UI [cnt] +#define CHECKBYTE 0x78 // Used to validate NVData + #define BATTERY_COUNT_TO_MV 13.848 // Battery count to mV factor [mV/cnt] #define LOW_BATT_THRESHOLD 6 // Low batt conunts before warning @@ -43,12 +47,15 @@ #define DISPLAY_SHOW_ERROR_TIME 2500 // Error string show time [mS] #define DISPLAY_SHOW_TIME 1500 // Min. response display time [mS] -#define DISPLAY_VIEW_UPDATE 250 // Display update time [mS] +#define DISPLAY_VIEW_UPDATE 200 // Display update time [mS] #define MIN_DISPLAY_UPDATE_TIME 50 // OBP min graphics update time [mS] -#define MIN_SENSOR_READ_TIME 25 // Time between sensor reads [mS] +#define MIN_SENSOR_READ_TIME 100 // Time between sensor reads [mS] #define ARM_WAIT_FOR_POWER_OFF 250 // Time for off command to execute [mS] +#define DISPLAY_SHOW_FILENAME_TIME 3000 // Datalog show saves as time [mS] +#define DATALOG_DEFAULT_SAMPLE_TIME 100L // Default time between samples [mS] + // Menu special flags #define MENU_SKIP_THIS_MOTHER_ID 0x00000001L // Used to seek next common menu (i0000000) @@ -83,18 +90,17 @@ #define MENU_SENSOR_SOUND_DBA 0x03 // Sound sensor dBA #define MENU_SENSOR_LIGHT 0x04 // Light sensor with flood light #define MENU_SENSOR_LIGHT_AMB 0x05 // Light sensor without flood light -#define MENU_SENSOR_LIGHT_OLD 0x06 // Light sensor old with flood light -#define MENU_SENSOR_TOUCH 0x07 // Touch sensor -#define MENU_SENSOR_MOTOR_DEG 0x08 // Motor sensor degrees -#define MENU_SENSOR_MOTOR_ROT 0x09 // Motor sensor rotations -#define MENU_SENSOR_ROTATION 0x0A // Rotation sensor ticks -#define MENU_SENSOR_ULTRASONIC_IN 0x0B // Ultrasonic sensor inch -#define MENU_SENSOR_ULTRASONIC_CM 0x0C // Ultrasonic sensor cm -#define MENU_SENSOR_TEMP_C 0x0D // Temp sensor celcius -#define MENU_SENSOR_TEMP_F 0x0E // Temp sensor fahrenheit -#define MENU_SENSOR_INVALID 0x0F // Invalid - -#define MENU_PORT_EMPTY 0x11 // NA +#define MENU_SENSOR_TOUCH 0x06 // Touch sensor +#define MENU_SENSOR_MOTOR_DEG 0x07 // Motor sensor degrees +#define MENU_SENSOR_MOTOR_ROT 0x08 // Motor sensor rotations +#define MENU_SENSOR_ULTRASONIC_IN 0x09 // Ultrasonic sensor inch +#define MENU_SENSOR_ULTRASONIC_CM 0x0A // Ultrasonic sensor cm +#define MENU_SENSOR_IIC_TEMP_C 0x0B // IIC temp sensor celcius +#define MENU_SENSOR_IIC_TEMP_F 0x0C // IIC temp sensor fahrenheit +#define MENU_SENSOR_COLOR 0x0D // Color sensor +#define MENU_SENSOR_INVALID 0x0E // Invalid + +#define MENU_PORT_EMPTY 0x11 // Port empty #define MENU_PORT_1 0x12 // Port 1 #define MENU_PORT_2 0x13 // Port 2 #define MENU_PORT_3 0x14 // Port 3 @@ -158,6 +164,10 @@ #define MENU_RIGHT 0xFE // Right #define MENU_EXIT 0xFF // Exit +#define DATALOGPORTS (MENU_PORT_INVALID - MENU_PORT_EMPTY - 1) +#define MAX_DATALOGS 9999 // Highest datalog file number +#define DATALOGBUFFERSIZE 25 // Largest number of characters buffered before flash write + #define MENULEVELS 10 // Max no of levels in one file (8 + 2 virtual) #define MENUFILELEVELS 3 // Max deept in menu file pool @@ -185,6 +195,16 @@ typedef struct } MENUFILE; +typedef struct +{ + UBYTE CheckByte; // Check byte (CHECKBYTE) + UBYTE DatalogEnabled; // Datalog enabled flag (0 = no) + UBYTE VolumeStep; // Volume step (0 - MAX_VOLUME) + UBYTE PowerdownCode; // Power down code + UWORD DatalogNumber; // Datalog file number (0 - MAX_DATALOGS) +} +NVDATA; + typedef struct { UBYTE StatusText[STATUSTEXT_SIZE + 1]; // RCX name @@ -235,6 +255,9 @@ typedef struct UBYTE Cursor; // General cursor UBYTE SelectedSensor; // General used for selected sensor UBYTE SelectedPort; // General used for selected port + UBYTE SensorReset; + UBYTE SensorState; // Sensor state (reset, ask, read) + SWORD SensorTimer; // Timer used to time sensor states UBYTE NextState; UBYTE SelectedFilename[FILENAME_LENGTH + 1]; // Selected file name @@ -314,11 +337,23 @@ typedef struct SLONG ViewSampleValue; // Latch for sensor values UBYTE ViewSampleValid; // Latch for sensor valid + // Datalog + ULONG DatalogOldTick; + ULONG DatalogRTC; // Real time in mS + ULONG DatalogTimer; // Logging main timer + ULONG DatalogSampleTime; // Logging sample time + ULONG DatalogSampleTimer; // Logging sample timer + SLONG DatalogSampleValue[DATALOGPORTS]; // Latch for sensor values + UBYTE DatalogSampleValid[DATALOGPORTS]; // Latch for sensor valid + UWORD DatalogError; // Error code + UBYTE DatalogPort[DATALOGPORTS]; // Logging sensor + UBYTE Update; // Update icons flag + // NV storage ULONG NVTmpLength; // Non volatile filelength SWORD NVTmpHandle; // Non volatile filehandle UBYTE NVFilename[FILENAME_LENGTH + 1]; // Non volatile file name - UBYTE NVData; // Non volatile data + NVDATA NVData; // Non volatile data // Feedback UBYTE *FBText; // Seperate text pointer for feedback diff --git a/AT91SAM7S256/Source/c_ui.iom b/AT91SAM7S256/Source/c_ui.iom index 6159a4f..770b682 100644 --- a/AT91SAM7S256/Source/c_ui.iom +++ b/AT91SAM7S256/Source/c_ui.iom @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 28-02-06 14:07 $ +// Revision date $Date:: 10-06-08 9:26 $ // // Filename $Workfile:: c_ui.iom $ // -// Version $Revision:: 45 $ +// Version $Revision:: 4 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_ui.iom $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/c_ui.i $ // // Platform C // @@ -21,14 +21,25 @@ #define pMapUi ((IOMAPUI*)(pHeaders[ENTRY_UI]->pIOMap)) +enum +{ + DEVICETYPE_UNKNOWN, + DEVICETYPE_NXT, + DEVICETYPE_PHONE, + DEVICETYPE_PC +}; + // Various filenames without extension #define UI_NONVOLATILE "NVConfig" // Ui non volatile config filename #define UI_PROGRAM_DEFAULT "Untitled" // On brick programming default filename #define UI_PROGRAM_TEMP "Program" // On brick programming tmp filename #define UI_PROGRAM_READER "RPGReader" // On brick programming script reader filename +#define UI_DATALOG_FILENAME "OBD_" // On brick datalog filename +#define UI_DATALOG_DEFAULT "Untitled" // On brick datalog default name +#define UI_DATALOG_TEMP "Tmp" // On brick datalog tmp filename #define UI_STARTUP_SOUND "! Startup" // Sound file activated when the menu system starts up #define UI_KEYCLICK_SOUND "! Click" // Sound file activated when key pressed in the menu system -#define UI_ATTENTION_SOUND "! Attention" // Sound file activated when incomming BT requests attention +#define UI_ATTENTION_SOUND "! Attention" // Sound file activated when incomming BT requests attention // Various text strings #define UI_NAME_DEFAULT "NXT" // Default blue tooth name diff --git a/AT91SAM7S256/Source/d_bt.c b/AT91SAM7S256/Source/d_bt.c index 55b81f7..6e3e47d 100644 --- a/AT91SAM7S256/Source/d_bt.c +++ b/AT91SAM7S256/Source/d_bt.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:42 $ +// Revision date $Date:: 24-04-08 14:33 $ // // Filename $Workfile:: d_bt.c $ // -// Version $Revision:: 21 $ +// Version $Revision:: 3 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_bt.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.c $ // // Platform C // @@ -39,7 +39,6 @@ void dBtInit(void) SETTimeout(0); BTInit; BTInitPIOPins; - BTInitADC; } void dBtSetBcResetPinLow(void) diff --git a/AT91SAM7S256/Source/d_bt.h b/AT91SAM7S256/Source/d_bt.h index 2e41ded..baf3ab6 100644 --- a/AT91SAM7S256/Source/d_bt.h +++ b/AT91SAM7S256/Source/d_bt.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:41 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_bt.h $ // -// Version $Revision:: 16 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_bt.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.h $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_bt.r b/AT91SAM7S256/Source/d_bt.r index f5c6a7d..8c9558f 100644 --- a/AT91SAM7S256/Source/d_bt.r +++ b/AT91SAM7S256/Source/d_bt.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:42 $ +// Revision date $Date:: 24-04-08 14:33 $ // // Filename $Workfile:: d_bt.r $ // -// Version $Revision:: 28 $ +// Version $Revision:: 3 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_bt.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_bt.r $ // // Platform C // @@ -121,16 +121,13 @@ static UWORD RemainingLength; *AT91C_PIOA_OER = BT_ARM7_CMD_PIN; /* PA27 set to output */\ } -#define BTInitADC {\ - *AT91C_ADC_MR = 0; /* Reset register plus setting only software trigger */\ - *AT91C_ADC_MR |= 0x00003F00; /* ADC-clock set to approximatly 375 kHz */\ - *AT91C_ADC_MR |= 0x00020000; /* Startup set to approximatly 84uS */\ - *AT91C_ADC_MR |= 0x09000000; /* Sample & Hold set to approximatly 20uS */\ - *AT91C_ADC_CHER = AT91C_ADC_CH6 | AT91C_ADC_CH4; /* Enable channel 6 and 4*/\ +#define BTStartADConverter {\ + *AT91C_ADC_CHER = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ + ADStart; \ + while(!((*AT91C_ADC_SR) & AT91C_ADC_CH6)); \ + *AT91C_ADC_CHDR = AT91C_ADC_CH6 | AT91C_ADC_CH4; \ } -#define BTStartADConverter *AT91C_ADC_CR = AT91C_ADC_START; /* Start the ADC converter */\ - #define BTReadADCValue(ADValue) ADValue = *AT91C_ADC_CDR6; #define BTSetResetHigh {\ diff --git a/AT91SAM7S256/Source/d_button.c b/AT91SAM7S256/Source/d_button.c index a74c166..2691e8c 100644 --- a/AT91SAM7S256/Source/d_button.c +++ b/AT91SAM7S256/Source/d_button.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_button.c $ // -// Version $Revision:: 4 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_button.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_button.h b/AT91SAM7S256/Source/d_button.h index 2826c3f..10dacac 100644 --- a/AT91SAM7S256/Source/d_button.h +++ b/AT91SAM7S256/Source/d_button.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_button.h $ // -// Version $Revision:: 4 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_button.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_button.r b/AT91SAM7S256/Source/d_button.r index 3e5e359..c478394 100644 --- a/AT91SAM7S256/Source/d_button.r +++ b/AT91SAM7S256/Source/d_button.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:58 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_button.r $ // -// Version $Revision:: 14 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_button.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_butt $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_display.c b/AT91SAM7S256/Source/d_display.c index 7181913..99f16c6 100644 --- a/AT91SAM7S256/Source/d_display.c +++ b/AT91SAM7S256/Source/d_display.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 29-08-05 11:26 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_display.c $ // -// Version $Revision:: 4 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_display.h b/AT91SAM7S256/Source/d_display.h index c205619..a894685 100644 --- a/AT91SAM7S256/Source/d_display.h +++ b/AT91SAM7S256/Source/d_display.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 29-08-05 11:26 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_display.h $ // -// Version $Revision:: 5 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_display.r b/AT91SAM7S256/Source/d_display.r index d4328b7..e38bb45 100644 --- a/AT91SAM7S256/Source/d_display.r +++ b/AT91SAM7S256/Source/d_display.r @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dktochpe $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 20-12-05 12:28 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_display.r $ // -// Version $Revision:: 18 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_display. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_disp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_hispeed.c b/AT91SAM7S256/Source/d_hispeed.c index cdb79b7..01f2d07 100644 --- a/AT91SAM7S256/Source/d_hispeed.c +++ b/AT91SAM7S256/Source/d_hispeed.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_hispeed.c $ // -// Version $Revision:: 8 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_hispeed. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_hispeed.h b/AT91SAM7S256/Source/d_hispeed.h index 2ebda66..669a5d1 100644 --- a/AT91SAM7S256/Source/d_hispeed.h +++ b/AT91SAM7S256/Source/d_hispeed.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_hispeed.h $ // -// Version $Revision:: 5 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_hispeed. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_hispeed.r b/AT91SAM7S256/Source/d_hispeed.r index 0f4a455..52d5e14 100644 --- a/AT91SAM7S256/Source/d_hispeed.r +++ b/AT91SAM7S256/Source/d_hispeed.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_hispeed.r $ // -// Version $Revision:: 11 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_hispeed. $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_hisp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_input.c b/AT91SAM7S256/Source/d_input.c index 272f35e..771eb3e 100644 --- a/AT91SAM7S256/Source/d_input.c +++ b/AT91SAM7S256/Source/d_input.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 14-01-09 10:34 $ // // Filename $Workfile:: d_input.c $ // -// Version $Revision:: 14 $ +// Version $Revision:: 12 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_input.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ // // Platform C // @@ -24,13 +24,21 @@ void dInputInit(void) INPUTInit; } +void dInputSetColorClkInput(void) +{ + COLORClkInput; +} + +void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status) +{ + UPDATEAllColors(pRaw, Status); +} void dInputGetRawAd(UWORD *pValues, UBYTE No) { INPUTGetVal(pValues, No); } - void dInputSetDirOutDigi0(UBYTE Port) { INPUTSetOutDigi0(Port); @@ -54,21 +62,25 @@ void dInputSetDirInDigi1(UBYTE Port) void dInputClearDigi0(UBYTE Port) { INPUTClearDigi0(Port); + INPUTSetOutDigi0(Port); } void dInputClearDigi1(UBYTE Port) { INPUTClearDigi1(Port); + INPUTSetOutDigi1(Port); } void dInputSetDigi0(UBYTE Port) { INPUTSetDigi0(Port); + INPUTSetOutDigi0(Port); } void dInputSetDigi1(UBYTE Port) { INPUTSetDigi1(Port); + INPUTSetOutDigi1(Port); } void dInputRead0(UBYTE Port, UBYTE *pData) @@ -96,6 +108,42 @@ void dInputSetInactive(UBYTE Port) INPUTSetInactive(Port); } +UBYTE dInputGetColor(UBYTE No, UWORD *pCol) +{ + UBYTE Status; + UPDATELed(No, pCol, Status); + return(Status); +} + +void dInputColorTx(UBYTE Port, UBYTE Data) +{ + COLORTx(Port, Data); +} + +void dInputReadCal(UBYTE Port, UBYTE *pData) +{ + CALDataRead(Port, pData); +} + +UBYTE dInputCheckColorStatus(UBYTE Port) +{ + UBYTE Status; + + CHECKColorState(Port,Status); + return(Status); +} + +void dInputClearColor100msTimer(UBYTE No) +{ + CLEARColor100msTimer(No); +} + +UBYTE dInputChkColor100msTimer(UBYTE No) +{ + UBYTE State; + COLOR100msStatus(No, State); + return(State); +} void dInputExit(void) { diff --git a/AT91SAM7S256/Source/d_input.h b/AT91SAM7S256/Source/d_input.h index 8a7d4ef..d365dd1 100644 --- a/AT91SAM7S256/Source/d_input.h +++ b/AT91SAM7S256/Source/d_input.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 14-01-09 10:33 $ // // Filename $Workfile:: d_input.h $ // -// Version $Revision:: 6 $ +// Version $Revision:: 12 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_input.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ // // Platform C // @@ -34,4 +34,15 @@ void dInputSetDigi1(UBYTE Port); void dInputRead0(UBYTE Port, UBYTE *pData); void dInputRead1(UBYTE Port, UBYTE *pData); +UBYTE dInputGetColor(UBYTE No, UWORD *pCol); + +void dInputColorTx(UBYTE Port, UBYTE Data); +void dInputReadCal(UBYTE Port, UBYTE *pData); +UBYTE dInputCheckColorStatus(UBYTE Port); +void dInputGetAllColors(COLORSTRUCT *pRaw, UBYTE Status); +void dInputSetColorClkInput(void); +void dInputClearColor100msTimer(UBYTE No); +UBYTE dInputChkColor100msTimer(UBYTE No); + + #endif diff --git a/AT91SAM7S256/Source/d_input.r b/AT91SAM7S256/Source/d_input.r index 6e3d989..3dc567e 100644 --- a/AT91SAM7S256/Source/d_input.r +++ b/AT91SAM7S256/Source/d_input.r @@ -1,60 +1,78 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:06 $ +// Revision date $Date:: 14-01-09 10:33 $ // // Filename $Workfile:: d_input.r $ // -// Version $Revision:: 10 $ +// Version $Revision:: 24 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_input.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_inpu $ // // Platform C // + #ifdef SAM7S256 +void rInputWait2uS(void); +void rInputWait20uS(void); +void rInputWait30uS(void); +void rInputSingleADC(UBYTE Port, UWORD *Val); + +const ULONG Digi0Alloc[] = {AT91C_PIO_PA23, AT91C_PIO_PA28, AT91C_PIO_PA29, AT91C_PIO_PA30}; +const ULONG Digi1Alloc[] = {AT91C_PIO_PA18, AT91C_PIO_PA19, AT91C_PIO_PA20, AT91C_PIO_PA2}; +const ULONG ADPinDef[NO_OF_INPUTS] = {AT91C_ADC_CH1, AT91C_ADC_CH2, AT91C_ADC_CH3, AT91C_ADC_CH7}; +unsigned int volatile* ADValRegs[NO_OF_INPUTS] = {AT91C_ADC_CDR1, AT91C_ADC_CDR2, AT91C_ADC_CDR3, AT91C_ADC_CDR7}; + +static UBYTE ColorReset[NO_OF_INPUTS]; +static ULONG ColorClkDef; +static ULONG ColorTimer[NO_OF_INPUTS]; + +#define TIME2US ((OSC/16)/500000L) +#define TIME20US ((OSC/16)/50000L) +#define TIME30US ((OSC/16)/33333L) +#define TIME100MS ((OSC/16)/10L) + #define MAX_AD_VALUE 0x3FF #define INPUTInit {\ - UBYTE Tmp;\ + UBYTE Tmp; \ for (Tmp = 0; Tmp < NOS_OF_AVR_INPUTS; Tmp++)\ - {\ - IoFromAvr.AdValue[Tmp] = MAX_AD_VALUE;\ - }\ - IoToAvr.InputPower = 0;\ - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++)\ - {\ - *AT91C_PIOA_PPUDR = Digi0Alloc[Tmp];\ - *AT91C_PIOA_PPUDR = Digi1Alloc[Tmp];\ - INPUTSetInDigi0(Tmp);\ - INPUTSetInDigi1(Tmp);\ - }\ + { \ + IoFromAvr.AdValue[Tmp] = MAX_AD_VALUE; \ + } \ + IoToAvr.InputPower = 0; \ + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ + { \ + *AT91C_PIOA_PPUDR = Digi0Alloc[Tmp]; \ + *AT91C_PIOA_PPUDR = Digi1Alloc[Tmp]; \ + INPUTSetInDigi0(Tmp); \ + INPUTSetInDigi1(Tmp); \ + ColorReset[Tmp] = FALSE; \ + } \ + ColorClkDef = 0; \ } -#define INPUTGetVal(pValues, No) *pValues = (UWORD)IoFromAvr.AdValue[No];\ +#define INPUTGetVal(pValues, No) *pValues = (UWORD)IoFromAvr.AdValue[No]; \ *pValues &= 0x03FF -#define INPUTSetActive(Input) IoToAvr.InputPower |= (0x01 << Input);\ +#define INPUTSetActive(Input) IoToAvr.InputPower |= (0x01 << Input); \ IoToAvr.InputPower &= ~(0x10 << Input) -#define INPUTSet9v(Input) IoToAvr.InputPower |= (0x10 << Input);\ +#define INPUTSet9v(Input) IoToAvr.InputPower |= (0x10 << Input); \ IoToAvr.InputPower &= ~(0x01 << Input) #define INPUTSetInactive(Input) IoToAvr.InputPower &= ~(0x11 << Input) -const ULONG Digi0Alloc[] = {AT91C_PIO_PA23, AT91C_PIO_PA28, AT91C_PIO_PA29, AT91C_PIO_PA30}; -const ULONG Digi1Alloc[] = {AT91C_PIO_PA18, AT91C_PIO_PA19, AT91C_PIO_PA20, AT91C_PIO_PA2}; - -#define INPUTSetOutDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input];\ +#define INPUTSetOutDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ *AT91C_PIOA_OER = Digi0Alloc[Input] -#define INPUTSetOutDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input];\ +#define INPUTSetOutDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ *AT91C_PIOA_OER = Digi1Alloc[Input] - -#define INPUTSetInDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input];\ +#define INPUTSetInDigi0(Input) *AT91C_PIOA_PER = Digi0Alloc[Input]; \ *AT91C_PIOA_ODR = Digi0Alloc[Input] -#define INPUTSetInDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input];\ +#define INPUTSetInDigi1(Input) *AT91C_PIOA_PER = Digi1Alloc[Input]; \ *AT91C_PIOA_ODR = Digi1Alloc[Input] #define INPUTSetDigi0(Input) *AT91C_PIOA_SODR = Digi0Alloc[Input] @@ -65,32 +83,227 @@ const ULONG Digi1Alloc[] = {AT91C_PIO_PA18, AT91C_PIO_PA19, AT91C_P #define INPUTClearDigi1(Input) *AT91C_PIOA_CODR = Digi1Alloc[Input] -#define INPUTReadDigi0(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Input])\ - {\ - *Data |= 0x00000001;\ - }\ - else\ - {\ - *Data &= ~0x00000001;\ +#define INPUTReadDigi0(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Input]) \ + { \ + *Data |= 0x00000001; \ + } \ + else \ + { \ + *Data &= ~0x00000001; \ } -#define INPUTReadDigi1(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Input])\ - {\ - *Data |= 0x00000002;\ - }\ - else\ - {\ - *Data &= ~0x00000002;\ +#define INPUTReadDigi1(Input, Data) if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Input]) \ + { \ + *Data |= 0x00000002; \ + } \ + else \ + { \ + *Data &= ~0x00000002; \ + } + +#define INPUTClkHigh(Port) INPUTSetDigi0(Port); \ + INPUTSetOutDigi0(Port); \ + rInputWait2uS() + +#define INPUTClkLow(Port) INPUTClearDigi0(Port); \ + INPUTSetOutDigi0(Port); \ + rInputWait2uS() + +#define COLORClkInput *AT91C_PIOA_ODR = ColorClkDef + +#define UPDATEAllColors(Vals, Status){\ + ULONG ADDef; \ + ADDef = 0; \ + ColorClkDef = 0; \ + if (0x01 & Status) \ + { \ + ADDef |= ADPinDef[0]; \ + ColorClkDef |= Digi0Alloc[0]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[0]) \ + { \ + ColorReset[0] = TRUE; \ + } \ + } \ + if (0x02 & Status) \ + { \ + ADDef |= ADPinDef[1]; \ + ColorClkDef |= Digi0Alloc[1]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[1]) \ + { \ + ColorReset[1] = TRUE; \ + } \ + } \ + if (0x04 & Status) \ + { \ + ADDef |= ADPinDef[2]; \ + ColorClkDef |= Digi0Alloc[2]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[2]) \ + { \ + ColorReset[2] = TRUE; \ + } \ + } \ + if (0x08 & Status) \ + { \ + ADDef |= ADPinDef[3]; \ + ColorClkDef |= Digi0Alloc[3]; \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[3]) \ + { \ + ColorReset[3] = TRUE; \ + } \ + } \ + *AT91C_PIOA_OER = ColorClkDef; \ + *AT91C_ADC_CHER = ADDef; \ + GetAdVals(Vals, BLANK, Status); \ + *AT91C_PIOA_SODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, RED, Status); \ + *AT91C_PIOA_CODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, GREEN, Status); \ + *AT91C_PIOA_SODR = ColorClkDef; \ + rInputWait20uS(); \ + GetAdVals(Vals, BLUE, Status); \ + *AT91C_PIOA_CODR = ColorClkDef; \ + *AT91C_ADC_CHDR = ADDef; \ + } + +#define UPDATELed(Port, Col, Status) { \ + rInputSingleADC(Port, Col); \ + if ((*AT91C_PIOA_PDSR) & Digi0Alloc[Port]) \ + { \ + ColorReset[Port] = TRUE; \ + } \ + CHECKColorState(Port, Status); \ } -#define INPUTExit {\ - UBYTE Tmp;\ - for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++)\ - {\ - INPUTSetInDigi0(Tmp);\ - INPUTSetInDigi1(Tmp);\ - }\ +#define SETClkHi(Port) INPUTClkHigh(Port) \ + +#define COLORTx(Port, Data) { \ + UBYTE BitCnt; \ + BitCnt = 0; \ + while(BitCnt++ < 8) \ + { \ + INPUTClkHigh(Port); \ + if (Data & 0x01) \ + { \ + INPUTSetDigi1(Port); \ + } \ + else \ + { \ + INPUTClearDigi1(Port); \ + } \ + rInputWait30uS(); \ + Data >>= 1; \ + INPUTClkLow(Port); \ + rInputWait30uS(); \ + } \ + } + +#define CALDataRead(Port, pData) {\ + UBYTE BitCnt; \ + UBYTE Data; \ + BitCnt = 0; \ + INPUTClkHigh(Port); \ + rInputWait2uS(); \ + while(BitCnt++ < 8) \ + { \ + INPUTClkHigh(Port); \ + rInputWait2uS(); \ + rInputWait2uS(); \ + INPUTClkLow(Port); \ + Data >>= 1; \ + if ((*AT91C_PIOA_PDSR) & Digi1Alloc[Port])\ + { \ + Data |= 0x80; \ + } \ + rInputWait2uS(); \ + } \ + *pData = Data; \ + } + +#define CHECKColorState(Port, Status) {\ + Status = TRUE; \ + if ((IoFromAvr.AdValue[Port] > 50) || (TRUE == ColorReset[Port])) \ + { \ + Status = FALSE; \ + ColorReset[Port] = FALSE; \ + } \ + } + + +#define INPUTExit { \ + UBYTE Tmp; \ + *AT91C_ADC_CHDR = (AT91C_ADC_CH1 | AT91C_ADC_CH2 | AT91C_ADC_CH3 | AT91C_ADC_CH7);\ + for (Tmp = 0; Tmp < NO_OF_INPUTS; Tmp++) \ + { \ + INPUTSetInDigi0(Tmp); \ + INPUTSetInDigi1(Tmp); \ + } \ } + +#define CLEARColor100msTimer(No) ColorTimer[No] = (*AT91C_PITC_PIIR);\ + +#define COLOR100msStatus(No,V) V = FALSE;\ + if (((*AT91C_PITC_PIIR) - ColorTimer[No]) > TIME100MS)\ + {\ + V = TRUE;\ + } + + + +void rInputSingleADC(UBYTE Port, UWORD *Val) +{ + *Val = *AT91C_ADC_LCDR; + *AT91C_ADC_CHER = ADPinDef[Port]; + ADStart; + while(!((*AT91C_ADC_SR) & AT91C_ADC_DRDY)); + *Val = *AT91C_ADC_LCDR; + *AT91C_ADC_CHDR = ADPinDef[Port]; +} + +void GetAdVals(COLORSTRUCT *pColStruct, UBYTE Color, UBYTE Status) +{ + UBYTE ChCnt; + ADStart; + for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) + { + if (Status & (0x01 << ChCnt)) + { + while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); + pColStruct[ChCnt].ADRaw[Color] = *ADValRegs[ChCnt]; + } + } + ADStart; + for(ChCnt = 0; ChCnt < NO_OF_INPUTS; ChCnt++) + { + if (Status & (0x01 << ChCnt)) + { + while(!((*AT91C_ADC_SR) & ADPinDef[ChCnt])); + pColStruct[ChCnt].ADRaw[Color] += *ADValRegs[ChCnt]; + pColStruct[ChCnt].ADRaw[Color] = (pColStruct[ChCnt].ADRaw[Color])>>1; + } + } +} + +void rInputWait2uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME2US); +} + +void rInputWait20uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME20US); +} +void rInputWait30uS(void) +{ + ULONG PitTmr; + PitTmr = (*AT91C_PITC_PIIR); + while (((*AT91C_PITC_PIIR) - PitTmr) < TIME30US); +} #endif diff --git a/AT91SAM7S256/Source/d_ioctrl.c b/AT91SAM7S256/Source/d_ioctrl.c index 7c414f6..2506172 100644 --- a/AT91SAM7S256/Source/d_ioctrl.c +++ b/AT91SAM7S256/Source/d_ioctrl.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 5-12-07 15:23 $ // // Filename $Workfile:: d_ioctrl.c $ // -// Version $Revision:: 11 $ +// Version $Revision:: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_ioctrl.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ // // Platform C // @@ -19,22 +19,10 @@ #include "d_ioctrl.h" #include "d_ioctrl.r" -/* Enum related to State */ -enum -{ - RX_I2C = 1, - TX_I2C = 2, - UNLOCK_I2C = 3, - WAIT_I2C = 4 -}; - - -static UBYTE volatile State; void dIOCtrlInit(void) { IOCTRLInit; - State = UNLOCK_I2C; } void dIOCtrlSetPower(UBYTE Power) @@ -49,52 +37,9 @@ void dIOCtrlSetPwm(UBYTE Pwm) void dIOCtrlTransfer(void) { - UBYTE B; - - CHECKTime(B); - if (B) - { - switch(State) - { - case TX_I2C: - { - FULLDataTx; - State = RX_I2C; - } - break; - case RX_I2C: - { - FULLDataRx; - State = TX_I2C; - } - break; - case UNLOCK_I2C: - { - UNLOCKTx; - State = WAIT_I2C; - } - break; - case WAIT_I2C: - { - - /* Intermediate state as unlock string is 47 */ - /* characters which is a little more than 1mS */ - State = TX_I2C; - } - break; - default: - { - UNLOCKTx; - State = WAIT_I2C; - } - break; - } - SETTime; - } + I2CTransfer; } - - void dIOCtrlExit(void) { IOCTRLExit; diff --git a/AT91SAM7S256/Source/d_ioctrl.h b/AT91SAM7S256/Source/d_ioctrl.h index 4ebedd3..4b7ae4f 100644 --- a/AT91SAM7S256/Source/d_ioctrl.h +++ b/AT91SAM7S256/Source/d_ioctrl.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_ioctrl.h $ // -// Version $Revision:: 7 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_ioctrl.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_ioctrl.r b/AT91SAM7S256/Source/d_ioctrl.r index 71bf0f4..1071276 100644 --- a/AT91SAM7S256/Source/d_ioctrl.r +++ b/AT91SAM7S256/Source/d_ioctrl.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 9:50 $ +// Revision date $Date:: 7-12-07 14:09 $ // // Filename $Workfile:: d_ioctrl.r $ // -// Version $Revision:: 21 $ +// Version $Revision:: 4 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_ioctrl.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_ioct $ // // Platform C // @@ -15,39 +15,61 @@ #ifdef SAM7S256 +extern void I2cHandler(void); + +enum +{ + I2C_IDLE = 1, + I2C_ERROR = 2, + I2C_TX = 3, + I2C_RX = 4 +}; + #define NO_TO_TX BYTES_TO_TX + 1 #define NO_TO_RX BYTES_TO_RX + 1 -#define TIMEOUT 2100 +#define TIMEOUT (((OSC/16)/1000)*30) /* 100 ms timeout on I2C*/ +#define I2CCLK 400000L +#define TIME400KHZ (((OSC/16L)/(I2CCLK * 2)) + 1) +#define CLDIV (((OSC/I2CCLK)/2)-3) +#define DEVICE_ADR 0x01 +static UBYTE *pIrq; +static UBYTE volatile Cnt; +static UBYTE I2cStatus; +static UBYTE I2cLastStatus; +static UBYTE I2cInBuffer[NO_TO_RX]; +static UBYTE I2cOutBuffer[COPYRIGHTSTRINGLENGTH + 1]; +static UBYTE RxSum; +static ULONG I2CTimerValue; -extern void I2cHandler(void); -static UBYTE *pIrq; -static UBYTE Cnt; -static UBYTE NoToTx; -static UBYTE I2cStatus; -static UBYTE I2cInBuffer[NO_TO_RX]; -static UBYTE I2cOutBuffer[NO_TO_TX]; -static UBYTE RxSum; +#define DISABLEI2cIrqs *AT91C_TWI_IDR = 0x000001C7 +#define ISSUEStopCond *AT91C_TWI_CR = AT91C_TWI_STOP +#define INSERTPower(Power) IoToAvr.Power = Power +#define INSERTPwm(Pwm) IoToAvr.PwmFreq = Pwm +#define SETTime I2CTimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) -#define I2C_IDLE 1 -#define I2C_ERROR 2 -#define I2C_TX 3 -#define I2C_RX 4 -#define I2CClk 400000L -#define TIME400KHz (((OSC/16L)/(I2CClk * 2)) + 1) -#define CLDIV (((OSC/I2CClk)/2)-3) +#define DISABLETwi *AT91C_PIOA_PPUDR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* no pull up */\ + *AT91C_PIOA_MDER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is open drain*/\ + *AT91C_PIOA_SODR = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is high */\ + *AT91C_PIOA_OER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* SCL + SDA is output */\ + *AT91C_PIOA_PER = (AT91C_PA4_TWCK | AT91C_PA3_TWD);/* Disable peripheal */\ -#define DEVICE_ADR 0x01 -#define DISABLEI2cIrqs *AT91C_TWI_IDR = 0x000001C7 -#define ISSUEStopCond *AT91C_TWI_CR = AT91C_TWI_STOP + +#define STARTIrqTx I2cStatus = I2C_TX;\ + I2cLastStatus = I2C_TX;\ + pIrq = I2cOutBuffer;\ + *AT91C_TWI_CR = AT91C_TWI_MSEN;\ + *AT91C_TWI_MMR = (AT91C_TWI_IADRSZ_NO | (DEVICE_ADR << 16)); /* no int. adr, write dir */\ + *AT91C_TWI_IER = 0x00000104; /* Enable TX related irq */\ + *AT91C_TWI_THR = *pIrq #define WAITClk {\ ULONG PitTmr;\ - PitTmr = (*AT91C_PITC_PIIR & AT91C_PITC_CPIV) + TIME400KHz;\ + PitTmr = (*AT91C_PITC_PIIR & AT91C_PITC_CPIV) + TIME400KHZ;\ if (PitTmr >= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV))\ {\ PitTmr -= (*AT91C_PITC_PIMR & AT91C_PITC_CPIV);\ @@ -56,247 +78,152 @@ static UBYTE RxSum; } - #define RESETI2c {\ UBYTE Tmp;\ - *AT91C_PMC_PCER = (1L< #include -#define FILEVERSION (0x00000106L) +#define FILEVERSION (0x0000010DL) -#define MAX_FILES ((SECTORSIZE/4) - 1) /* Last file entry is used for file version*/ +#define MAX_FILES ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ +#define FILEVERSIONINDEX ((FILETABLE_SIZE) - 1) /* Last file entry is used for file version*/ #define MAX_WRITE_BUFFERS 4 #define FLASHOFFSET (0x100000L) @@ -56,7 +57,6 @@ typedef struct static HANDLE HandleTable[MAX_HANDLES]; static WRITEBUF WriteBuffer[MAX_WRITE_BUFFERS]; static ULONG SectorTable[NOOFSECTORS>>5]; -static const ULONG *Files; static FILEHEADER Header; static ULONG FreeUserFlash; static UWORD FreeSectors; @@ -84,8 +84,6 @@ void dLoaderInit(void) LOADERInit; - Files = (const ULONG*)STARTOFFILETABLE; - /* Clear handle table */ for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) { @@ -101,18 +99,16 @@ void dLoaderInit(void) dLoaderCheckVersion(); dLoaderUpdateSectorTable(); - FreeUserFlash = dLoaderReturnFreeFlash(); } + UWORD dLoaderAvailFileNo(void) { UBYTE Tmp, Tmp2; UWORD ReturnVal; - const ULONG* FlashPtr; ReturnVal = NOMOREFILES; Tmp2 = 0; - FlashPtr = Files; for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++) { @@ -123,7 +119,7 @@ UWORD dLoaderAvailFileNo(void) Tmp2++; } } - if ((0xFFFFFFFF == FlashPtr[(MAX_FILES - 1) - Tmp2]) || (0 == FlashPtr[(MAX_FILES - 1) - Tmp2])) + if ((0xFFFFFFFF == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2]) || (0 == FILEPTRTABLE[(MAX_FILES - 1) - Tmp2])) { ReturnVal = SUCCESS; } @@ -131,33 +127,46 @@ UWORD dLoaderAvailFileNo(void) } +void dLoaderWriteFilePtrTable(ULONG *RamFilePtrTable) +{ + UWORD TmpTableSize; + + /* FILETABLE_SIZE is in LONG */ + TmpTableSize = (FILETABLE_SIZE * 4); + while(TmpTableSize) + { + TmpTableSize -= SECTORSIZE; + dLoaderWritePage((ULONG)FILEPTRTABLE + TmpTableSize, SECTORSIZE, RamFilePtrTable + (TmpTableSize/4)); + } +} + + UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle) { UWORD TmpCnt; UWORD Status; - ULONG SectorCopy[(SECTORSIZE/4)]; - const ULONG* FlashPtr; + ULONG PtrTable[FILETABLE_SIZE]; /* It is possible to add the file as checking for number of files */ /* is done when initiating the file download */ - FlashPtr = Files; - memset(SectorCopy, 0, sizeof(SectorCopy)); - + memset(PtrTable, 0, sizeof(PtrTable)); TmpCnt = MAX_FILES - 1; while(TmpCnt) { /* TmpCnt-- first because you want to copy from index 0 */ TmpCnt--; - SectorCopy[TmpCnt + 1] = FlashPtr[TmpCnt]; + PtrTable[TmpCnt + 1] = FILEPTRTABLE[TmpCnt]; } /* Copy the new file in position 0 */ - SectorCopy[0] = (ULONG)pAdr; + PtrTable[0] = (ULONG)pAdr; /* Add the File version to the top of the file list */ - SectorCopy[MAX_FILES] = FlashPtr[MAX_FILES]; - dLoaderWritePage((ULONG)Files, SECTORSIZE, SectorCopy); + PtrTable[FILEVERSIONINDEX] = FILEPTRTABLE[FILEVERSIONINDEX]; + + /* Write the file pointer table to flash */ + dLoaderWriteFilePtrTable(PtrTable); /* FileIndex in HandleTable should be incremented by one - new file index is 0 */ for (TmpCnt = 0; TmpCnt < MAX_HANDLES; TmpCnt++) @@ -168,7 +177,6 @@ UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle) } } HandleTable[Handle].FileIndex = 0; - Status = SUCCESS | Handle; return(Status); @@ -177,47 +185,43 @@ UWORD dLoaderInsertPtrTable(const UBYTE *pAdr, UWORD Handle) UWORD dLoaderDeleteFilePtr(UWORD Handle) { - UWORD ErrorCode; UWORD LongCnt; - ULONG SectorCopy[(SECTORSIZE>>2)]; - const ULONG *pFlash; + ULONG PtrTable[FILETABLE_SIZE]; ErrorCode = SUCCESS; - if (0xFFFFFFFF != Files[HandleTable[Handle].FileIndex]) + if (0xFFFFFFFF != FILEPTRTABLE[HandleTable[Handle].FileIndex]) { ErrorCode = dLoaderCheckFiles(Handle); if (0x8000 > ErrorCode) { - pFlash = Files; - for (LongCnt = 0; LongCnt < (HandleTable[Handle].FileIndex); LongCnt++, pFlash++) + for (LongCnt = 0; LongCnt < (HandleTable[Handle].FileIndex); LongCnt++) { - SectorCopy[LongCnt] = *pFlash; + PtrTable[LongCnt] = FILEPTRTABLE[LongCnt]; } - /* Skip the file that has to be deleted */ - pFlash++; - for ( ; LongCnt < (MAX_FILES - 1); LongCnt++, pFlash++) + /* Skip the file that has to be deleted "LongCnt + 1" */ + for ( ; LongCnt < (MAX_FILES - 1); LongCnt++) { - SectorCopy[LongCnt] = *pFlash; + PtrTable[LongCnt] = FILEPTRTABLE[LongCnt+1]; } /* The top file entry is now free */ - SectorCopy[MAX_FILES - 1] = 0xFFFFFFFF; + PtrTable[MAX_FILES - 1] = 0xFFFFFFFF; /* Insert the file version */ - SectorCopy[MAX_FILES] = *pFlash; + PtrTable[MAX_FILES] = FILEPTRTABLE[MAX_FILES]; - - /* Write the sectortable back into flash */ - dLoaderWritePage((ULONG)Files, SECTORSIZE,(ULONG*) &SectorCopy); + /* Write the file pointer table back into flash */ + dLoaderWriteFilePtrTable(PtrTable); dLoaderUpdateSectorTable(); - FreeUserFlash = dLoaderReturnFreeFlash(); /* Update the HandleTable[].FileIndex */ for (LongCnt = 0; LongCnt < MAX_HANDLES; LongCnt++) { - if ((HandleTable[Handle].FileIndex <= HandleTable[LongCnt].FileIndex) && (FREE != HandleTable[LongCnt].Status)) + + /* FileIndex must not be decremented for to the file to be deleted (when Handle = LongCnt)*/ + if ((HandleTable[Handle].FileIndex < HandleTable[LongCnt].FileIndex) && (FREE != HandleTable[LongCnt].Status)) { (HandleTable[LongCnt].FileIndex)--; } @@ -235,7 +239,7 @@ UWORD dLoaderDeleteFilePtr(UWORD Handle) void dLoaderDeleteAllFiles(void) { ULONG Tmp; - ULONG SectorBuf[SECTORSIZE/4]; + ULONG PtrTable[FILETABLE_SIZE]; /* Close all handles - all files is to be wiped out */ for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) @@ -249,9 +253,11 @@ void dLoaderDeleteAllFiles(void) } /* Insert the file version */ - memset(SectorBuf, 0xFF, SECTORSIZE); - SectorBuf[(SECTORSIZE/4) - 1] = FILEVERSION; - dLoaderWritePage(STARTOFFILETABLE, SECTORSIZE, SectorBuf); + memset(PtrTable, 0xFF, sizeof(PtrTable)); + PtrTable[FILEVERSIONINDEX] = FILEVERSION; + + /* Write an empty file pointer table to flash */ + dLoaderWriteFilePtrTable(PtrTable); /* Update all other parameters */ dLoaderUpdateSectorTable(); @@ -264,7 +270,8 @@ void dLoaderUpdateSectorTable(void) UWORD Tmp; UWORD SectorNo; const FILEHEADER *pFile; - ULONG FileStart; + ULONG FileSize; + const UWORD *pSectorTable; Tmp = 0; @@ -273,42 +280,46 @@ void dLoaderUpdateSectorTable(void) /* All file pointer are occupied as default */ while (Tmp < MAX_FILES) { - SectorNo = dLoaderGetSectorNumber((ULONG)&Files[Tmp]); - SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5))); + SectorNo = dLoaderGetSectorNumber((ULONG)&FILEPTRTABLE[Tmp]); + SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); Tmp += (SECTORSIZE >> 2); } for (Tmp = 0; Tmp < MAX_FILES; Tmp++) { - if ((0xFFFFFFFF != Files[Tmp]) && (0x00000000 != Files[Tmp])) + if ((0xFFFFFFFF != FILEPTRTABLE[Tmp]) && (0x00000000 != FILEPTRTABLE[Tmp])) { - pFile = (const FILEHEADER *) Files[Tmp]; - FileStart = pFile->FileStartAdr; + pFile = (const FILEHEADER *) FILEPTRTABLE[Tmp]; /* This is necessary if the start address is at the first address in an sector */ SectorNo = dLoaderGetSectorNumber((ULONG)pFile->FileStartAdr); - SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5))); + SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); /* This is necessary as the first sector (where the fileheader is) is not */ /* included in the sector table */ - SectorNo = dLoaderGetSectorNumber((ULONG)Files[Tmp]); - SectorTable[SectorNo>>5] |= (0x1 << (SectorNo - ((SectorNo>>5)<<5))); - - SectorNo = 0; - while(FileStart > ((ULONG)(&(pFile->FileSectorTable[SectorNo]))) && (NOOFSECTORS > pFile->FileSectorTable[SectorNo])) + SectorNo = dLoaderGetSectorNumber((ULONG)FILEPTRTABLE[Tmp]); + SectorTable[SectorNo>>5] |= (0x1 << (SectorNo & 0x001F)); + + /* First Sector with data has been allocated add this as the initial */ + /* file size */ + FileSize = SECTORSIZE - ((pFile->FileStartAdr) & (SECTORSIZE-1)) ; + pSectorTable = pFile->FileSectorTable; + while((FileSize < (pFile->FileSize)) && (NOOFSECTORS > (*pSectorTable))) { - SectorTable[(pFile->FileSectorTable[SectorNo])>>5] |= (0x1 << ((pFile->FileSectorTable[SectorNo]) - (((pFile->FileSectorTable[SectorNo])>>5)<<5))); - if (0 == ((ULONG)(&(pFile->FileSectorTable[SectorNo+1])) & (SECTORSIZE-1))) + SectorTable[(*pSectorTable)>>5] |= (0x1 << ((*pSectorTable) & 0x1F)); + if (0 == ((ULONG)(pSectorTable + 1) & (SECTORSIZE-1))) { - SectorNo += (((pFile->FileSectorTable[SectorNo]) << SECTORSIZESHIFT) - ((ULONG)&(pFile->FileSectorTable[SectorNo]) & ~FLASHOFFSET)>>1); + pSectorTable = (UWORD*)(((ULONG)(*pSectorTable) << SECTORSIZESHIFT) | FLASHOFFSET); } else { - SectorNo++; + *pSectorTable++; + FileSize += SECTORSIZE; } } } } + FreeUserFlash = dLoaderReturnFreeFlash(); } @@ -336,6 +347,7 @@ UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearStat } if (FILENOTFOUND == (ErrorCode & 0xFF00)) { + /* Here check for the download buffers for a matching download */ /* in progress */ ErrorCode &= 0x00FF; @@ -404,7 +416,6 @@ UWORD dLoaderCreateFileHeader(ULONG FileSize, UBYTE *pName, UBYTE LinearStat if (FileSize <= FreeUserFlash) { - /* Allocate file header */ Tmp = (((CompleteFileByteSize - 1) >> SECTORSIZESHIFT) + 1); Handle = dLoaderAllocateHeader(Handle, &FileStartAdr, &Header, HeaderByteSize, Tmp); @@ -548,7 +559,6 @@ UWORD dLoaderCloseHandle(UWORD Handle) UWORD RtnStatus; FILEHEADER *TmpFileHeader; - RtnStatus = Handle; /* if it is a normal handle or handle closed due to an error then error must be different */ @@ -602,7 +612,6 @@ UWORD dLoaderCloseHandle(UWORD Handle) /* an error has occured during download - now clean up the mess... */ dLoaderUpdateSectorTable(); - FreeUserFlash = dLoaderReturnFreeFlash(); } } } @@ -631,7 +640,7 @@ UWORD dLoaderOpenRead(UBYTE *pFileName, ULONG *pLength) { if (FileLength) { - TmpHeader = (FILEHEADER const *)(Files[HandleTable[Handle].FileIndex]); + TmpHeader = (FILEHEADER const *)(FILEPTRTABLE[HandleTable[Handle].FileIndex]); HandleTable[Handle].pFlash = (const UBYTE *)TmpHeader->FileStartAdr; HandleTable[Handle].pSectorNo = TmpHeader->FileSectorTable; HandleTable[Handle].DataLength = TmpHeader->DataSize; @@ -733,9 +742,9 @@ UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG for (Tmp = ((HandleTable[Handle].FileIndex) + 1); Tmp < MAX_FILES; Tmp++) { - if (0xFFFFFFFF != Files[Tmp]) + if (0xFFFFFFFF != FILEPTRTABLE[Tmp]) { - if (SUCCESS == dLoaderCheckName((UBYTE*)Files[Tmp], HandleTable[Handle].SearchStr, HandleTable[Handle].SearchType)) + if (SUCCESS == dLoaderCheckName((UBYTE*)FILEPTRTABLE[Tmp], HandleTable[Handle].SearchStr, HandleTable[Handle].SearchType)) { HandleTable[Handle].FileIndex = Tmp; Tmp = MAX_FILES; @@ -745,7 +754,7 @@ UWORD dLoaderFindNext(UWORD Handle, UBYTE *pFound, ULONG *pFileLength, ULONG } if (0x8000 > ReturnVal) { - pHeader = (FILEHEADER *)Files[HandleTable[Handle].FileIndex]; + pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; if (NULL != pFileLength) { *pFileLength = pHeader->FileSize; @@ -836,7 +845,7 @@ UWORD dLoaderGetFilePtr(UBYTE *pFileName, UBYTE *pPtrToFile, ULONG *pFileLen if (0x8000 > RtnVal) { - File = (FILEHEADER*) Files[HandleTable[RtnVal].FileIndex]; + File = (FILEHEADER*) FILEPTRTABLE[HandleTable[RtnVal].FileIndex]; if (LINEAR & File->FileType) { *((ULONG*)pPtrToFile) = File->FileStartAdr; @@ -1083,6 +1092,7 @@ UWORD dLoaderFlashFileHeader(UWORD Handle, ULONG FileStartAdr, FILEHEADER *p return(Handle); } + UWORD dLoaderGetSectorNumber(ULONG Adr) { UWORD SectorNo; @@ -1125,7 +1135,7 @@ UWORD dLoaderCheckFiles(UBYTE Handle) Index = HandleTable[Handle].FileIndex; for (Tmp = 0; Tmp < MAX_HANDLES; Tmp++) { - if ((BUSY == HandleTable[Tmp].Status) && (Index == HandleTable[Tmp].FileIndex) && (Tmp != Handle)) + if (((BUSY == HandleTable[Tmp].Status) || (DOWNLOADING == HandleTable[Tmp].Status)) && (Index == HandleTable[Tmp].FileIndex) && (Tmp != Handle)) { ErrorCode = FILEISBUSY; } @@ -1133,6 +1143,7 @@ UWORD dLoaderCheckFiles(UBYTE Handle) return(Handle | ErrorCode); } + void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc) { UBYTE Tmp; @@ -1151,17 +1162,16 @@ void dLoaderCopyFileName(UBYTE *pDst, UBYTE *pSrc) } } + void dLoaderCheckVersion(void) { - ULONG Version; - - Version = *(const ULONG*)(STARTOFFILETABLE + (MAX_FILES * 4)); - if (Version != FILEVERSION) + if (FILEPTRTABLE[FILEVERSIONINDEX] != FILEVERSION) { dLoaderDeleteAllFiles(); } } + UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize) { UWORD Handle; @@ -1180,7 +1190,7 @@ UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize) { /* File has bee found - check for then correct filetype (Datafile) */ - pHeader = (FILEHEADER *)Files[HandleTable[Handle].FileIndex]; + pHeader = (FILEHEADER *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; if (DATAFILE & pHeader->FileType) { if (FileSize > DataSize) @@ -1192,7 +1202,7 @@ UWORD dLoaderOpenAppend(UBYTE *pFileName, ULONG *pAvailSize) dLoaderSetFilePointer(Handle, DataSize, &(HandleTable[Handle].pFlash)); WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex = (ULONG)(HandleTable[Handle].pFlash) & (SECTORSIZE - 1); memcpy(WriteBuffer[HandleTable[Handle].WriteBufNo].Buf, (const UBYTE *)((ULONG)(HandleTable[Handle].pFlash) & ~(SECTORSIZE - 1)), WriteBuffer[HandleTable[Handle].WriteBufNo].BufIndex ); - HandleTable[Handle].FileDlPtr = Files[HandleTable[Handle].FileIndex]; + HandleTable[Handle].FileDlPtr = FILEPTRTABLE[HandleTable[Handle].FileIndex]; HandleTable[Handle].Status = (UBYTE)DOWNLOADING; *pAvailSize = FileSize - DataSize; HandleTable[Handle].DataLength = *pAvailSize; @@ -1229,7 +1239,7 @@ UWORD dLoaderSetFilePointer(UWORD Handle, ULONG BytePtr, const UBYTE **pData pData = pData; - pHeader = (FILEHEADER*)Files[HandleTable[Handle].FileIndex]; + pHeader = (FILEHEADER*)FILEPTRTABLE[HandleTable[Handle].FileIndex]; HandleTable[Handle].pSectorNo = pHeader->FileSectorTable; /* Get the sector offset */ @@ -1397,7 +1407,7 @@ UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName) UBYTE Tmp; FILEHEADER *pHeader; - pFile = (ULONG *)Files[HandleTable[Handle].FileIndex]; + pFile = (ULONG *)FILEPTRTABLE[HandleTable[Handle].FileIndex]; for (Tmp = 0; Tmp < (SECTORSIZE/4); Tmp++) { SectorBuf[Tmp] = pFile[Tmp]; @@ -1432,6 +1442,39 @@ UWORD dLoaderCheckDownload(UBYTE *pName) } + + +UWORD dLoaderCropDatafile(UBYTE Handle) +{ + UWORD ReturnVal; + ULONG SectorBuffer[SECTORSIZE]; + UBYTE FileIndex; + + /* Save the fileindex for use after the handle has been closed */ + FileIndex = HandleTable[Handle].FileIndex; + + ReturnVal = dLoaderCloseHandle(Handle); + if (0x8000 > ReturnVal) + { + + /* Successful close handle now try to crop the file if filesize and datasize differs */ + /* and File exists */ + if (((FILEPTRTABLE[FileIndex]) != 0x00000000) && ((FILEPTRTABLE[FileIndex]) != 0xFFFFFFFF)) + { + if (((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->FileSize != ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize) + { + memcpy(SectorBuffer, (void const*)(FILEPTRTABLE[FileIndex]), SECTORSIZE); + ((FILEHEADER*)SectorBuffer)->FileSize = ((FILEHEADER const *)(FILEPTRTABLE[FileIndex]))->DataSize; + dLoaderWritePage((ULONG)(FILEPTRTABLE[HandleTable[Handle].FileIndex]), SECTORSIZE, SectorBuffer); + + /* Update sectortable and available flash size */ + dLoaderUpdateSectorTable(); + } + } + } + return(ReturnVal); +} + void dLoaderExit(void) { } diff --git a/AT91SAM7S256/Source/d_loader.h b/AT91SAM7S256/Source/d_loader.h index 0279631..4a12f12 100644 --- a/AT91SAM7S256/Source/d_loader.h +++ b/AT91SAM7S256/Source/d_loader.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 28-03-07 14:54 $ +// Revision date $Date:: 24-06-09 12:15 $ // // Filename $Workfile:: d_loader.h $ // -// Version $Revision:: 40 $ +// Version $Revision:: 18 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_loader.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ // // Platform C // @@ -15,9 +15,11 @@ #ifndef D_LOADER #define D_LOADER -#define STARTOFFILETABLE (0x13FF00L) -#define STARTOFUSERFLASH (0x121400L)//(0x11F000L) -#define SIZEOFUSERFLASH (STARTOFFILETABLE - STARTOFUSERFLASH) +#define FILETABLE_SIZE ((2 * SECTORSIZE)/4) +#define STARTOFFILETABLE (0x140000L - (FILETABLE_SIZE*4)) +#define FILEPTRTABLE ((const ULONG*)(0x140000L - (FILETABLE_SIZE*4))) +#define STARTOFUSERFLASH (0x122100L) +#define SIZEOFUSERFLASH ((ULONG)STARTOFFILETABLE - STARTOFUSERFLASH) #define SIZEOFFLASH 262144L #define SECTORSIZE 256L @@ -65,7 +67,7 @@ typedef struct ULONG DataSize; UWORD CheckSum; UWORD FileType; - UWORD FileSectorTable[SIZEOFUSERFLASH/SECTORSIZE]; + UWORD FileSectorTable[(SIZEOFUSERFLASH/SECTORSIZE)]; }FILEHEADER; void dLoaderInit(void); @@ -91,6 +93,7 @@ ULONG dLoaderReturnFreeUserFlash(void); UWORD dLoaderRenameFile(UBYTE Handle, UBYTE *pNewName); UWORD dLoaderCheckFiles(UBYTE Handle); +UWORD dLoaderCropDatafile(UBYTE Handle); diff --git a/AT91SAM7S256/Source/d_loader.r b/AT91SAM7S256/Source/d_loader.r index bec0c90..3fb2556 100644 --- a/AT91SAM7S256/Source/d_loader.r +++ b/AT91SAM7S256/Source/d_loader.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 8:27 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_loader.r $ // -// Version $Revision:: 8 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_loader.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_load $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_lowspeed.c b/AT91SAM7S256/Source/d_lowspeed.c index e3b5ba8..91c1341 100644 --- a/AT91SAM7S256/Source/d_lowspeed.c +++ b/AT91SAM7S256/Source/d_lowspeed.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_lowspeed.c $ // -// Version $Revision:: 14 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_lowspeed.h b/AT91SAM7S256/Source/d_lowspeed.h index 9a680f0..6ec62fd 100644 --- a/AT91SAM7S256/Source/d_lowspeed.h +++ b/AT91SAM7S256/Source/d_lowspeed.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_lowspeed.h $ // -// Version $Revision:: 7 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_lowspeed.r b/AT91SAM7S256/Source/d_lowspeed.r index f811193..4b3b8ba 100644 --- a/AT91SAM7S256/Source/d_lowspeed.r +++ b/AT91SAM7S256/Source/d_lowspeed.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 19-09-06 15:05 $ +// Revision date $Date:: 19-02-09 18:51 $ // // Filename $Workfile:: d_lowspeed.r $ // -// Version $Revision:: 24 $ +// Version $Revision:: 4 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_lowspeed $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_lows $ // // Platform C // @@ -51,6 +51,7 @@ typedef struct UBYTE ReStartBit; UBYTE ComDeviceAddress; UBYTE RxWaitCnt; + UBYTE ClkStatus; }LOWSPEEDPARAMETERS; static LOWSPEEDPARAMETERS LowSpeedData[4]; @@ -271,9 +272,9 @@ ULONG CLK_PINS[4] = {CHANNEL_ONE_CLK, CHANNEL_TWO_CLK, CHANNEL_THREE_CLK, CHANNE }\ }\ }\ + LowSpeedData[ChannelNr].ClkStatus = 0;\ } - #define SETClkHigh(ChannelNr) {\ if (ChannelNr == 0)\ {\ @@ -300,6 +301,7 @@ ULONG CLK_PINS[4] = {CHANNEL_ONE_CLK, CHANNEL_TWO_CLK, CHANNEL_THREE_CLK, CHANNE }\ }\ }\ + LowSpeedData[ChannelNr].ClkStatus = 1;\ } #define SETDataLow(ChannelNr) {\ @@ -444,35 +446,37 @@ __ramfunc void LowSpeedPwmIrqHandler(void) for (ChannelNr = 0; ChannelNr < NO_OF_LOWSPEED_COM_CHANNEL; ChannelNr++) { - switch(LowSpeedData[ChannelNr].ChannelState) + if (((LowSpeedData[ChannelNr].ClkStatus == 1) && (PinStatus & CLK_PINS[ChannelNr])) || (((LowSpeedData[ChannelNr].ClkStatus == 0) && (!(PinStatus & CLK_PINS[ChannelNr]))))) { - case LOWSPEED_IDLE: + switch(LowSpeedData[ChannelNr].ChannelState) { - } - break; + case LOWSPEED_IDLE: + { + } + break; - case LOWSPEED_TX_STOP_BIT: - { - SETDataHigh(ChannelNr); - LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; //Now we have send a STOP sequence, disable this channel - } - break; + case LOWSPEED_TX_STOP_BIT: + { + SETDataHigh(ChannelNr); + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_IDLE; //Now we have send a STOP sequence, disable this channel + } + break; - case LOWSPEED_TRANSMITTING: - { - switch(LowSpeedData[ChannelNr].TxState) + case LOWSPEED_TRANSMITTING: { - case TX_DATA_MORE_DATA: + switch(LowSpeedData[ChannelNr].TxState) { - PinStatus |= CLK_PINS[ChannelNr]; - LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; - } - break; + case TX_DATA_MORE_DATA: + { + PinStatus |= CLK_PINS[ChannelNr]; + LowSpeedData[ChannelNr].TxState = TX_DATA_CLK_HIGH; + } + break; - case TX_DATA_CLK_HIGH: - { - SETClkLow(ChannelNr); - if (LowSpeedData[ChannelNr].MaskBit == 0) //Is Byte Done, then we need a ack from receiver + case TX_DATA_CLK_HIGH: + { + SETClkLow(ChannelNr); + if (LowSpeedData[ChannelNr].MaskBit == 0) //Is Byte Done, then we need a ack from receiver { SETDataToInput(ChannelNr); //Set datapin to input LowSpeedData[ChannelNr].TxState = TX_DATA_READ_ACK_CLK_LOW; @@ -723,6 +727,18 @@ __ramfunc void LowSpeedPwmIrqHandler(void) default: break; + } + } + else + { + + if (LOWSPEED_IDLE != LowSpeedData[ChannelNr].ChannelState) + { + //Data communication error ! + LowSpeedData[ChannelNr].TxByteCnt = 0; + SETClkHigh(ChannelNr); + LowSpeedData[ChannelNr].ChannelState = LOWSPEED_TX_STOP_BIT; + } } } } @@ -758,20 +774,21 @@ __ramfunc void LowSpeedPwmIrqHandler(void) #define TxData(ChannelNumber, Status, DataOutBuffer, NumberOfByte) {\ if (ChannelNumber == LOWSPEED_CHANNEL1)\ {\ - if (GetDataComOnePinLevel && GetClkComOnePinLevel)\ + if ((GetDataComOnePinLevel && GetClkComOnePinLevel) && (LowSpeedData[LOWSPEED_CHANNEL1].ChannelState == LOWSPEED_IDLE))\ {\ *AT91C_PIOA_PER = CHANNEL_ONE_CLK | CHANNEL_ONE_DATA; /* Enable PIO on PA20 & PA28 */\ *AT91C_PIOA_OER = CHANNEL_ONE_CLK | CHANNEL_ONE_DATA; /* PA20 & PA28 set to Output */\ *AT91C_PIOA_PPUDR = CHANNEL_ONE_CLK | CHANNEL_ONE_DATA; /* Disable Pull-up resistor */\ SETClkComOneHigh;\ - LowSpeedData[LOWSPEED_CHANNEL1].pComOutBuffer = DataOutBuffer;\ + SETDataComOneLow;\ + LowSpeedData[LOWSPEED_CHANNEL1].ClkStatus = 1;\ + LowSpeedData[LOWSPEED_CHANNEL1].pComOutBuffer = DataOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL1].ComDeviceAddress = *LowSpeedData[LOWSPEED_CHANNEL1].pComOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL1].MaskBit = MASK_BIT_8;\ LowSpeedData[LOWSPEED_CHANNEL1].TxByteCnt = NumberOfByte;\ - LowSpeedData[LOWSPEED_CHANNEL1].ChannelState = LOWSPEED_TRANSMITTING;\ LowSpeedData[LOWSPEED_CHANNEL1].TxState = TX_DATA_CLK_HIGH;\ - SETDataComOneLow;\ LowSpeedData[LOWSPEED_CHANNEL1].AckStatus = 0;\ + LowSpeedData[LOWSPEED_CHANNEL1].ChannelState = LOWSPEED_TRANSMITTING;\ Status = 1;\ }\ else\ @@ -781,20 +798,21 @@ __ramfunc void LowSpeedPwmIrqHandler(void) }\ if (ChannelNumber == LOWSPEED_CHANNEL2)\ {\ - if (GetDataComTwoPinLevel && GetClkComTwoPinLevel)\ + if ((GetDataComTwoPinLevel && GetClkComTwoPinLevel) && (LowSpeedData[LOWSPEED_CHANNEL2].ChannelState == LOWSPEED_IDLE))\ {\ *AT91C_PIOA_PER = CHANNEL_TWO_CLK | CHANNEL_TWO_DATA; /* Enable PIO on PA20 & PA28 */\ *AT91C_PIOA_OER = CHANNEL_TWO_CLK | CHANNEL_TWO_DATA; /* PA20 & PA28 set to Output */\ *AT91C_PIOA_PPUDR = CHANNEL_TWO_CLK | CHANNEL_TWO_DATA; /* Disable Pull-up resistor */\ SETClkComTwoHigh;\ + SETDataComTwoLow;\ + LowSpeedData[LOWSPEED_CHANNEL2].ClkStatus = 1;\ LowSpeedData[LOWSPEED_CHANNEL2].pComOutBuffer = DataOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL2].ComDeviceAddress = *LowSpeedData[LOWSPEED_CHANNEL2].pComOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL2].MaskBit = MASK_BIT_8;\ LowSpeedData[LOWSPEED_CHANNEL2].TxByteCnt = NumberOfByte;\ - LowSpeedData[LOWSPEED_CHANNEL2].ChannelState = LOWSPEED_TRANSMITTING;\ LowSpeedData[LOWSPEED_CHANNEL2].TxState = TX_DATA_CLK_HIGH;\ - SETDataComTwoLow;\ LowSpeedData[LOWSPEED_CHANNEL2].AckStatus = 0;\ + LowSpeedData[LOWSPEED_CHANNEL2].ChannelState = LOWSPEED_TRANSMITTING;\ Status = 1;\ }\ else\ @@ -804,20 +822,21 @@ __ramfunc void LowSpeedPwmIrqHandler(void) }\ if (ChannelNumber == LOWSPEED_CHANNEL3)\ {\ - if (GetDataComThreePinLevel && GetClkComThreePinLevel)\ + if ((GetDataComThreePinLevel && GetClkComThreePinLevel) && (LowSpeedData[LOWSPEED_CHANNEL3].ChannelState == LOWSPEED_IDLE))\ {\ *AT91C_PIOA_PER = CHANNEL_THREE_CLK | CHANNEL_THREE_DATA; /* */\ *AT91C_PIOA_OER = CHANNEL_THREE_CLK | CHANNEL_THREE_DATA; /* */\ *AT91C_PIOA_PPUDR = CHANNEL_THREE_CLK | CHANNEL_THREE_DATA; /* */\ SETClkComThreeHigh;\ + SETDataComThreeLow;\ + LowSpeedData[LOWSPEED_CHANNEL3].ClkStatus = 1;\ LowSpeedData[LOWSPEED_CHANNEL3].pComOutBuffer = DataOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL3].ComDeviceAddress = *LowSpeedData[LOWSPEED_CHANNEL3].pComOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL3].MaskBit = MASK_BIT_8;\ LowSpeedData[LOWSPEED_CHANNEL3].TxByteCnt = NumberOfByte;\ - LowSpeedData[LOWSPEED_CHANNEL3].ChannelState = LOWSPEED_TRANSMITTING;\ LowSpeedData[LOWSPEED_CHANNEL3].TxState = TX_DATA_CLK_HIGH;\ - SETDataComThreeLow;\ LowSpeedData[LOWSPEED_CHANNEL3].AckStatus = 0;\ + LowSpeedData[LOWSPEED_CHANNEL3].ChannelState = LOWSPEED_TRANSMITTING;\ Status = 1;\ }\ else\ @@ -827,20 +846,21 @@ __ramfunc void LowSpeedPwmIrqHandler(void) }\ if (ChannelNumber == LOWSPEED_CHANNEL4)\ {\ - if (GetDataComFourPinLevel && GetClkComFourPinLevel)\ + if ((GetDataComFourPinLevel && GetClkComFourPinLevel) && (LowSpeedData[LOWSPEED_CHANNEL4].ChannelState == LOWSPEED_IDLE))\ {\ *AT91C_PIOA_PER = CHANNEL_FOUR_CLK | CHANNEL_FOUR_DATA; /* */\ *AT91C_PIOA_OER = CHANNEL_FOUR_CLK | CHANNEL_FOUR_DATA; /* */\ *AT91C_PIOA_PPUDR = CHANNEL_FOUR_CLK | CHANNEL_FOUR_DATA; /* */\ SETClkComFourHigh;\ + SETDataComFourLow;\ + LowSpeedData[LOWSPEED_CHANNEL4].ClkStatus = 1;\ LowSpeedData[LOWSPEED_CHANNEL4].pComOutBuffer = DataOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL4].ComDeviceAddress = *LowSpeedData[LOWSPEED_CHANNEL4].pComOutBuffer;\ LowSpeedData[LOWSPEED_CHANNEL4].MaskBit = MASK_BIT_8;\ LowSpeedData[LOWSPEED_CHANNEL4].TxByteCnt = NumberOfByte;\ - LowSpeedData[LOWSPEED_CHANNEL4].ChannelState = LOWSPEED_TRANSMITTING;\ LowSpeedData[LOWSPEED_CHANNEL4].TxState = TX_DATA_CLK_HIGH;\ - SETDataComFourLow;\ LowSpeedData[LOWSPEED_CHANNEL4].AckStatus = 0;\ + LowSpeedData[LOWSPEED_CHANNEL4].ChannelState = LOWSPEED_TRANSMITTING;\ Status = 1;\ }\ else\ @@ -863,7 +883,7 @@ __ramfunc void LowSpeedPwmIrqHandler(void) #define STATUSTxCom(ChannelNumber, Status) {\ if (LowSpeedData[ChannelNumber].ChannelState != 0)\ {\ - if (LowSpeedData[ChannelNumber].TxByteCnt == 0)\ + if ((LowSpeedData[ChannelNumber].TxByteCnt == 0) && (LowSpeedData[ChannelNumber].ChannelState != LOWSPEED_RESTART_CONDITION))\ {\ if (LowSpeedData[ChannelNumber].MaskBit == 0)\ {\ @@ -873,7 +893,7 @@ __ramfunc void LowSpeedPwmIrqHandler(void) }\ else\ {\ - Status = 0xFF; /* TX ERROR */\ + Status = 0xFF; /* TX ERROR */\ }\ }\ else\ diff --git a/AT91SAM7S256/Source/d_output.c b/AT91SAM7S256/Source/d_output.c index e542cf6..d953b84 100644 --- a/AT91SAM7S256/Source/d_output.c +++ b/AT91SAM7S256/Source/d_output.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 5-02-07 13:48 $ +// Revision date $Date:: 3-02-09 14:46 $ // // Filename $Workfile:: d_output.c $ // -// Version $Revision:: 118 $ +// Version $Revision:: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_output.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ // // Platform C // @@ -906,6 +906,16 @@ void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo) SyncData.SyncTachoDif += SyncData.SyncTurnParameter; + if (SyncData.SyncTachoDif > 500) + { + SyncData.SyncTachoDif = 500; + } + if (SyncData.SyncTachoDif < -500) + { + SyncData.SyncTachoDif = -500; + } + + /* if ((SWORD)SyncData.SyncTachoDif > 500) { SyncData.SyncTachoDif = 500; @@ -914,6 +924,7 @@ void dOutputSyncMotorPosition(UBYTE MotorOne, UBYTE MotorTwo) { SyncData.SyncTachoDif = -500; } + */ PValue = (SWORD)SyncData.SyncTachoDif * (SWORD)(MotorData[MotorOne].RegPParameter/REG_CONST_DIV); diff --git a/AT91SAM7S256/Source/d_output.h b/AT91SAM7S256/Source/d_output.h index cb0de5e..7369b34 100644 --- a/AT91SAM7S256/Source/d_output.h +++ b/AT91SAM7S256/Source/d_output.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_output.h $ // -// Version $Revision:: 48 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_output.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_output.r b/AT91SAM7S256/Source/d_output.r index 0ed35ff..1a30c5f 100644 --- a/AT91SAM7S256/Source/d_output.r +++ b/AT91SAM7S256/Source/d_output.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 12:13 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_output.r $ // -// Version $Revision:: 36 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_output.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_outp $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_sound.c b/AT91SAM7S256/Source/d_sound.c index 66745d3..72dfb60 100644 --- a/AT91SAM7S256/Source/d_sound.c +++ b/AT91SAM7S256/Source/d_sound.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_sound.c $ // -// Version $Revision:: 11 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_sound.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_sound.h b/AT91SAM7S256/Source/d_sound.h index 8cef028..c580342 100644 --- a/AT91SAM7S256/Source/d_sound.h +++ b/AT91SAM7S256/Source/d_sound.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_sound.h $ // -// Version $Revision:: 10 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_sound.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_sound.r b/AT91SAM7S256/Source/d_sound.r index 00c7511..01a3353 100644 --- a/AT91SAM7S256/Source/d_sound.r +++ b/AT91SAM7S256/Source/d_sound.r @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_sound.r $ // -// Version $Revision:: 34 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_sound.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_soun $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_sound_adpcm.r b/AT91SAM7S256/Source/d_sound_adpcm.r index 03e16b7..2feff3b 100644 --- a/AT91SAM7S256/Source/d_sound_adpcm.r +++ b/AT91SAM7S256/Source/d_sound_adpcm.r @@ -32,15 +32,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_sound_adpcm.r $ // // Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_sound_adpcm.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_sound_adpc $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_timer.c b/AT91SAM7S256/Source/d_timer.c index 7c38aed..cba73d0 100644 --- a/AT91SAM7S256/Source/d_timer.c +++ b/AT91SAM7S256/Source/d_timer.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:18 $ +// Revision date $Date: 23-04-08 11:15 $ // // Filename $Workfile:: d_timer.c $ // -// Version $Revision:: 3 $ +// Version $Revision: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_timer.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ // // Platform C // @@ -27,13 +27,33 @@ void dTimerInit(void) ULONG dTimerRead(void) { - ULONG Tmp; + ULONG V; - TIMERRead(Tmp); + TIMERReadAlt(V) + return (V); +} - return (Tmp); +ULONG dTimerReadNoPoll(void) +{ + return (Timer1mS); } +ULONG dTimerReadHiRes(void) +{ + +// return ((*AT91C_PITC_PIIR)/3); following code is equivalent and about five times faster, see Hacker's Delight or exact division + ULONG tmp= ((*AT91C_PITC_PIIR)*2863311531); + if(tmp > 2863311531) + return tmp - 2863311531; + else if(tmp > 1431655766) + return tmp - 1431655766; + else + return tmp; +} + +ULONG dTimerGetNextMSTickCnt(void) { + return NextTimerValue; +} void dTimerExit(void) { diff --git a/AT91SAM7S256/Source/d_timer.h b/AT91SAM7S256/Source/d_timer.h index bf01b25..9d7eadb 100644 --- a/AT91SAM7S256/Source/d_timer.h +++ b/AT91SAM7S256/Source/d_timer.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:18 $ +// Revision date $Date: 23-04-08 11:15 $ // // Filename $Workfile:: d_timer.h $ // -// Version $Revision:: 2 $ +// Version $Revision: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_timer.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ // // Platform C // @@ -18,6 +18,12 @@ void dTimerInit(void); ULONG dTimerRead(void); +ULONG dTimerReadNoPoll(void); +ULONG dTimerReadHiRes(void); + +ULONG dTimerGetNextMSTickCnt(void); +#define dTimerReadTicks() (*AT91C_PITC_PIIR) + void dTimerExit(void); #endif diff --git a/AT91SAM7S256/Source/d_timer.r b/AT91SAM7S256/Source/d_timer.r index 91e9f7b..93c3a3b 100644 --- a/AT91SAM7S256/Source/d_timer.r +++ b/AT91SAM7S256/Source/d_timer.r @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:18 $ +// Revision date $Date:: 23-04-08 11:15 $ // // Filename $Workfile:: d_timer.r $ // -// Version $Revision:: 11 $ +// Version $Revision:: 2 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_timer.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_time $ // // Platform C // @@ -19,11 +19,13 @@ #define MS_1_TIME ((OSC/16)/1000) static ULONG TimerValue; +static ULONG NextTimerValue; static ULONG Timer1mS; /* PIT timer is used as main timer - timer interval is 1mS */ #define TIMERInit TimerValue = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV);\ + NextTimerValue = (((*AT91C_PITC_PIIR) + MS_1_TIME) & AT91C_PITC_CPIV);\ Timer1mS = 0 #define TIMERRead(V) if (MS_1_TIME < ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) - TimerValue) & AT91C_PITC_CPIV))\ @@ -34,6 +36,24 @@ static ULONG Timer1mS; }\ V = Timer1mS +#define TIMERReadAlt(V) if((SLONG)((*AT91C_PITC_PIIR) - NextTimerValue) >= 0)\ + {\ + Timer1mS ++;\ + NextTimerValue += MS_1_TIME;\ + }\ + V = Timer1mS;\ + +#define TIMERReadSkip(V) diff= (((*AT91C_PITC_PIIR)) - NextTimerValue);\ + if (diff >= 0)\ + {\ + diff /= MS_1_TIME;\ + diff += 1;\ + Timer1mS += diff;\ + diff *= MS_1_TIME;\ + NextTimerValue += diff;\ + }\ + V = Timer1mS;\ + #define TIMERExit diff --git a/AT91SAM7S256/Source/d_usb.c b/AT91SAM7S256/Source/d_usb.c index b4b92f4..0caf317 100644 --- a/AT91SAM7S256/Source/d_usb.c +++ b/AT91SAM7S256/Source/d_usb.c @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkpechri $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 19-07-06 10:02 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_usb.c $ // -// Version $Revision:: 32 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_usb.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_usb.h b/AT91SAM7S256/Source/d_usb.h index 3a176b3..b8e78c4 100644 --- a/AT91SAM7S256/Source/d_usb.h +++ b/AT91SAM7S256/Source/d_usb.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkpechri $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 19-07-06 10:02 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_usb.h $ // -// Version $Revision:: 10 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_usb.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ // // Platform C // diff --git a/AT91SAM7S256/Source/d_usb.r b/AT91SAM7S256/Source/d_usb.r index a3c3284..6c7a0c3 100644 --- a/AT91SAM7S256/Source/d_usb.r +++ b/AT91SAM7S256/Source/d_usb.r @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkpechri $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 19-07-06 10:02 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: d_usb.r $ // -// Version $Revision:: 9 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/d_usb.r $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/d_usb. $ // // Platform C // diff --git a/AT91SAM7S256/Source/m_sched.c b/AT91SAM7S256/Source/m_sched.c index bc394a5..7c69551 100644 --- a/AT91SAM7S256/Source/m_sched.c +++ b/AT91SAM7S256/Source/m_sched.c @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:15 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: m_sched.c $ // -// Version $Revision:: 14 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/m_sched.c $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ // // Platform C // diff --git a/AT91SAM7S256/Source/m_sched.h b/AT91SAM7S256/Source/m_sched.h index 6bf5a07..bd05a26 100644 --- a/AT91SAM7S256/Source/m_sched.h +++ b/AT91SAM7S256/Source/m_sched.h @@ -1,13 +1,13 @@ // // Date init 14.12.2004 // -// Revision date $Date:: 16-05-06 10:15 $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: m_sched.h $ // -// Version $Revision:: 20 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/m_sched.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/m_sche $ // // Platform C // diff --git a/AT91SAM7S256/Source/modules.h b/AT91SAM7S256/Source/modules.h index 6060800..a5f3bb1 100644 --- a/AT91SAM7S256/Source/modules.h +++ b/AT91SAM7S256/Source/modules.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Dkflebun $ +// Reviser $Author:: Dktochpe $ // -// Revision date $Date:: 5-02-07 13:36 $ +// Revision date $Date:: 19-02-08 8:15 $ // // Filename $Workfile:: modules.h $ // -// Version $Revision:: 49 $ +// Version $Revision:: 4 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/modules.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/module $ // // Platform C // @@ -29,8 +29,7 @@ #define TXT_LMS_EXT "rxe" // Mindstorms program filename extension #define TXT_NXT_EXT "rpg" // Program filename extension #define TXT_TRYME_EXT "rtm" // Try me program filename extension -#define TXT_DATA_EXT "rdt" // Datalog filename extension -#define TXT_MENU_EXT "rms" // Menu system filename extension (hidden) +#define TXT_DATA_EXT "log" // Datalog filename extension #define TXT_SYS_EXT "sys" // System filename extension (hidden) #define TXT_TMP_EXT "tmp" // Temporary filename extension (hidden) @@ -295,10 +294,6 @@ typedef struct } DATALOG; -#define DATALOG_FILE_LENGTH 64000L// Max datalog file size -#define DATALOG_HEADER_LENGTH 9 // Datalog sensor header length [Bytes] -#define DATALOG_DATA_LENGTH 5 // Datalog sensor data length [Bytes] - #define ICON_TEXTLNG 15 // 15 characters #define ICON_IMAGESIZE 72 // 24 x 24 pixels #define MAX_MENUITEMS 256 diff --git a/AT91SAM7S256/Source/stdconst.h b/AT91SAM7S256/Source/stdconst.h index 81bf972..fa1c59e 100644 --- a/AT91SAM7S256/Source/stdconst.h +++ b/AT91SAM7S256/Source/stdconst.h @@ -3,15 +3,15 @@ // // Date init 14.12.2004 // -// Reviser $Author:: Us8jamlo $ +// Reviser $Author:: Dkandlun $ // -// Revision date $Date:: 3/04/05 2:59p $ +// Revision date $Date:: 14-11-07 12:40 $ // // Filename $Workfile:: stdconst.h $ // -// Version $Revision:: 3 $ +// Version $Revision:: 1 $ // -// Archive $Archive:: /LMS2006/Sys01/Main/Firmware/Source/stdconst.h $ +// Archive $Archive:: /LMS2006/Sys01/Main_V02/Firmware/Source/stdcon $ // // Platform C // -- cgit v1.2.3