commit f0e8b4985468e8617fabee4a43a57ff7995b74ff Author: Flo Date: Mon Dec 8 19:24:47 2025 +0100 added tone request gateway before actually swithcing the pin diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..49819c0 --- /dev/null +++ b/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..9379397 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..3900500 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,24 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nodemcu-32s] +platform = espressif32 +board = nodemcu-32s +framework = arduino +upload_port = COM9 +upload_speed = 921600 +monitor_speed = 115200 +build_flags = + -I ./src/xcp + -I ./src/Receivers433 + -I ./src/Receivers433/Receivers3ByteKeys +lib_deps = + adafruit/Adafruit GFX Library@^1.12.4 + thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.6.1 diff --git a/src/Base32.cpp b/src/Base32.cpp new file mode 100644 index 0000000..edf5cd4 --- /dev/null +++ b/src/Base32.cpp @@ -0,0 +1,126 @@ +/* + Base32.cpp - Library for encoding to/decoding from Base32. + Compatible with RFC 4648 ( http://tools.ietf.org/html/rfc4648 ) + Created by Vladimir Tarasow, December 18, 2012. + Released into the public domain. +*/ +#include "Arduino.h" +#include "Base32.h" +#include "stdint.h" + +Base32::Base32() +{ +} + + +/* appends 0 to the base32 string */ +int Base32::toBase32(byte* in, long length, char * out, boolean usePadding) +{ + char base32StandardAlphabet[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"}; + char standardPaddingChar = '='; + + int result = 0; + int count = 0; + int bufSize = 8; + int index = 0; + + if (length < 0 || length > 268435456LL) + { + return 0; + } + + if (length > 0) + { + int buffer = in[0]; + int next = 1; + int bitsLeft = 8; + + while (count < bufSize && (bitsLeft > 0 || next < length)) + { + if (bitsLeft < 5) + { + if (next < length) + { + buffer <<= 8; + buffer |= in[next] & 0xFF; + next++; + bitsLeft += 8; + } + else + { + int pad = 5 - bitsLeft; + buffer <<= pad; + bitsLeft += pad; + } + } + index = 0x1F & (buffer >> (bitsLeft -5)); + + bitsLeft -= 5; + out[result] = (byte)base32StandardAlphabet[index]; + result++; + } + } + + if (usePadding) + { + int pads = (result % 8); + if (pads > 0) + { + pads = (8 - pads); + for (int i = 0; i < pads; i++) + { + out[result] = standardPaddingChar; + result++; + } + } + } + + out[result] = '\0'; + + return result; +} + + + +int Base32::fromBase32(byte* in, long length, byte*& out) +{ + int result = 0; // Length of the array of decoded values. + int buffer = 0; + int bitsLeft = 0; + byte* temp = NULL; + + temp = (byte*)malloc(length); // Allocating temporary array. + + for (int i = 0; i < length; i++) + { + byte ch = in[i]; + + // ignoring some characters: ' ', '\t', '\r', '\n', '=' + if (ch == 0xA0 || ch == 0x09 || ch == 0x0A || ch == 0x0D || ch == 0x3D) continue; + + // recovering mistyped: '0' -> 'O', '1' -> 'L', '8' -> 'B' + if (ch == 0x30) { ch = 0x4F; } else if (ch == 0x31) { ch = 0x4C; } else if (ch == 0x38) { ch = 0x42; } + + + // look up one base32 symbols: from 'A' to 'Z' or from 'a' to 'z' or from '2' to '7' + if ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A)) { ch = ((ch & 0x1F) - 1); } + else if (ch >= 0x32 && ch <= 0x37) { ch -= (0x32 - 26); } + else { free(temp); return 0; } + + buffer <<= 5; + buffer |= ch; + bitsLeft += 5; + if (bitsLeft >= 8) + { + temp[result] = (unsigned char)((unsigned int)(buffer >> (bitsLeft - 8)) & 0xFF); + result++; + bitsLeft -= 8; + } + } + + out = (byte*)malloc(result); + memcpy(out, temp, result); + free(temp); + + return result; +} diff --git a/src/Base32.h b/src/Base32.h new file mode 100644 index 0000000..af8e914 --- /dev/null +++ b/src/Base32.h @@ -0,0 +1,22 @@ +/* + Base32.h - Library for encoding to/decoding from Base32. + Compatible with RFC 4648 ( http://tools.ietf.org/html/rfc4648 ) + Created by Vladimir Tarasow, December 18, 2012. + Released into the public domain. +*/ + +#ifndef Base32_h +#define Base32_h + +#include "Arduino.h" +#include "stdint.h" + +class Base32 +{ + public: + Base32(); + int toBase32(byte*, long, char*, boolean); + int fromBase32(byte*, long, byte*&); +}; + +#endif diff --git a/src/DataSender.cpp b/src/DataSender.cpp new file mode 100644 index 0000000..54f771b --- /dev/null +++ b/src/DataSender.cpp @@ -0,0 +1,83 @@ +/* + * DataSender.cpp + * + * Created on: 08.10.2022 + * Author: flori + */ + + +#include "main.h" +#include "MyWifiClient.h" +#include "Seconds.h" + +#include "DataSender.h" + +DataSender dataSender; + +#define SEND_INTERVAL_SECONDS 120 +#define DATA_SIZE_PER_FENSTER 11 + +static uint8_t buf[DATA_SIZE_PER_FENSTER * NUM_FENSTER]; + + +DataSender::DataSender() +{ + bRequestSendWifi = true; + tNextSend = SEND_INTERVAL_SECONDS; +} + +DataSender::~DataSender() +{ + // TODO Auto-generated destructor stub +} + + +/** + * + */ +void DataSender::onSetup(void) +{ + myWifiClient.onSetup(); +} + +/** + * + */ +void DataSender::onLoop(void) +{ + if (Seconds::Get() >= tNextSend ) + { + bRequestSendWifi = true; + } + + if (bRequestSendWifi && myWifiClient.canSend()) + { + bRequestSendWifi = false; + + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + uint8_t offset = DATA_SIZE_PER_FENSTER * i; + memcpy( &buf[offset], alleFenster[i]->name, 8 ); + + uint16_t remainingTime = (uint16_t) alleFenster[i]->GetRemainingTime(); + memcpy( &buf[offset+8], &remainingTime , 2); + + uint8_t state = alleFenster[i]->IsOpen() ? 1 : 0; + state |= alleFenster[i]->ShallPiep() ? 2 : 0; + memcpy( &buf[offset+10], &state , 1); + } + + myWifiClient.send(buf, sizeof(buf)); + tNextSend = Seconds::Get() + SEND_INTERVAL_SECONDS; + } + + myWifiClient.onLoop(); +} + +/** + * + */ +void DataSender::requestSend(void) +{ + bRequestSendWifi = true; +} diff --git a/src/DataSender.h b/src/DataSender.h new file mode 100644 index 0000000..1ba3831 --- /dev/null +++ b/src/DataSender.h @@ -0,0 +1,27 @@ +/* + * DataSender.h + * + * Created on: 08.10.2022 + * Author: flori + */ + +#ifndef DATASENDER_H_ +#define DATASENDER_H_ + +class DataSender +{ +public: + DataSender(); + virtual ~DataSender(); + void onSetup(void); + void onLoop(void); + void requestSend(void); +private: + bool bRequestSendWifi; + uint32_t tNextSend; + +}; + +extern DataSender dataSender; + +#endif /* DATASENDER_H_ */ diff --git a/src/Display.cpp b/src/Display.cpp new file mode 100644 index 0000000..14d2b8d --- /dev/null +++ b/src/Display.cpp @@ -0,0 +1,178 @@ +#include "main.h" + +#if VERSION_BIG_DISPLAY +/* + * Display.cpp + * + * Created on: 15.05.2020 + * Author: flori + */ + +#include "Arduino.h" +#include +#include // needs Adafruit_GFX_Library + Adafruit_BusIO +#include // needs Adafruit_ST7735_and_ST7789_Library + +#include + + +#include "Display.h" + +Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_MOSI, TFT_PIN_CLK, TFT_PIN_RST); // ST7735-Bibliothek Setup + +Display display; + +static int wWindow = 38; +static int hWindow = 18; + + +/** + * + */ +void Display::Init(void) +{ + tft.initR(INITR_BLACKTAB); + tft.setRotation(1); + tft.fillScreen(ST7735_BLACK); +} + + +void drawWindow(int x, int y, Fenster *fenster) +{ + uint16_t col = fenster->ShallPiep() ? ST7735_ORANGE : fenster->IsOpen() ? ST77XX_WHITE : 0x0010; + + if (col != fenster->color) + { + tft.fillRect(x,y,wWindow, hWindow, ST7735_BLACK); + tft.drawRect(x,y,wWindow, hWindow, col); + tft.setCursor( x+2, y + hWindow/2 - 3); + + tft.setTextSize(1); + tft.setTextColor(col); + tft.print(fenster->name); + + fenster->color = col; + } + +} + +DeciSeconds_t calcRemainingTime() +{ + + DeciSeconds_t remainingTime = 99999; + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + if (alleFenster[i]->IsOpen()) remainingTime = min(remainingTime, alleFenster[i]->GetRemainingTime()); + } + + return remainingTime; +} + +/** + * + */ +void Display::Update(void) +{ + // drawRect(pos_links,pos_oben,breite,hoehe,farbe); + + // setTextSize(groesse); + + //tft.fillScreen(ST7735_BLACK); + tft.drawRect(0, 0, 160, 128, ST7735_BLUE); + + tft.setFont(NULL); + int x = 0; + int xs = 1; + int y = 1; +#if 0 + drawWindow(xs + 0 * (wWindow + 2), y, &fensterBadOben); + drawWindow(xs + 1 * (wWindow + 2), y, &fensterFlo); + drawWindow(xs + 2 * (wWindow + 2), y, &fensterHanna); + drawWindow(xs + 3 * (wWindow + 2), y, &fensterFloBuero); + + y += hWindow + 2; +#endif + + drawWindow(xs , y, &fensterBadUnten); + drawWindow(xs + 1 * (wWindow + 2), y, &fensterKueche); + drawWindow(xs + 2 * (wWindow + 2), y, &fensterWz); + drawWindow(xs + 3 * (wWindow + 2), y, &fensterWz2); + //drawWindow(xs+3*(wWindow+2), y, "Bad", true); + + y += hWindow + 2; + drawWindow(xs + 0 * (wWindow + 2), y, &fensterToniNeu); + drawWindow(xs + 1 * (wWindow + 2), y, &fensterGefrier); + + y += hWindow + 2; + drawWindow(xs + 0 * (wWindow + 2), y, &fensterKeller); + drawWindow(xs + 1 * (wWindow + 2), y, &fensterGaeste); + // drawWindow(xs+1*(wWindow+2), y, "Vorrat", getRandBool(), getRandBool()); + //drawWindow(xs+2*(wWindow+2), y, "Wohnz", true); + //drawWindow(xs+3*(wWindow+2), y, "Bad", true); + + //tft.setFont(&FreeSans9pt7b); + tft.setTextSize(2); + tft.setTextColor( ST77XX_CYAN); + x = 90; + y = 70; + tft.setCursor(x, y); + tft.fillRect(x, y-1, 159-90, 20, ST7735_BLACK ); + //thermoData.rh = 50; thermoData.temp =7.3; + if (thermoData.rhPercent > 0) + { + sprintf(strBuf, "% 3d C", (int) thermoData.tempC ); + } + else + { + sprintf(strBuf, " --"); + } + tft.print(strBuf); + + x = 10; + y = 97; + + tft.setTextSize(3); + + int yrect = 90; + int xrect = 1; + uint16_t wrect = 158; + uint16_t hrect = 127-yrect; + + strcpy(strBuf, ""); + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + if (alleFenster[i]->ShallPiep()) + { + strcpy(strBuf, alleFenster[i]->name); + break; + } + } + + if (strlen(strBuf)==0) + { + DeciSeconds_t remainingTime = calcRemainingTime(); + uint8_t mins = (remainingTime / 10) / 60; + uint8_t secs = (remainingTime / 10) % 60; + if (mins < 60) + { + sprintf(strBuf, "%d:%02d", (int) (mins), (int) (secs)); + } + } + if (strlen(strBuf)==0) + { + tft.fillRect(xrect, yrect, wrect, hrect, ST7735_BLACK); + } + else + { + tft.fillRect(xrect, yrect, wrect, hrect, ST7735_WHITE); + tft.setTextColor( ST77XX_BLACK); + uint16_t w, h; + int16_t x1, y1; + tft.getTextBounds(strBuf, x, y, &x1, &y1, &w, &h); + tft.setCursor(xrect + (wrect - w) / 2, yrect + (hrect - h) / 2); + tft.print(strBuf); + } + +} + +#endif diff --git a/src/Display.h b/src/Display.h new file mode 100644 index 0000000..778db69 --- /dev/null +++ b/src/Display.h @@ -0,0 +1,29 @@ +/* + * Display.h + * + * Created on: 15.05.2020 + * Author: flori + */ +#include "main.h" +#if VERSION_BIG_DISPLAY + +#ifndef DISPLAY_H_ +#define DISPLAY_H_ + +class Display +{ +public: + void Init(void); + void Update(void); + +private: + + char strBuf[50]; + +}; + +extern Display display; + +#endif /* DISPLAY_H_ */ + +#endif /* #if VERSION_EG_ONLY */ diff --git a/src/Display_SSD1306.cpp b/src/Display_SSD1306.cpp new file mode 100644 index 0000000..bb49ee5 --- /dev/null +++ b/src/Display_SSD1306.cpp @@ -0,0 +1,153 @@ +#include "main.h" + +#if VERSION_SMALL_DISPLAY +/* + * Display.cpp + * + * Created on: 15.05.2020 + * Author: flori + */ + + +#include "Arduino.h" +#include "Display_SSD1306.h" +#include "SSD1306Wire.h" /* LIBRARY : ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays */ + +// for 128x64 displays: +SSD1306Wire ssd1306(0x3c, SDA, SCL); // ADDRESS, SDA, SCL + +Display display; + + +/** + * + */ +void Display::Init(void) +{ + ssd1306.init(); +} + + + +DeciSeconds_t calcRemainingTime() +{ + + DeciSeconds_t remainingTime = 99999; + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + if (alleFenster[i]->IsOpen()) remainingTime = min(remainingTime, alleFenster[i]->GetRemainingTime()); + } + + return remainingTime; +} + +/** + * + */ +void Display::Update(void) +{ + ssd1306.clear(); + ssd1306.setFont(ArialMT_Plain_16); /* https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/README.md */ + ssd1306.setBrightness(100u); + + int x = 2; + int y = 0; + int yrect = 0; + int xrect = 0; + uint16_t wrect = 64; + uint16_t hrect = 18; + + /* print Windows */ + uint8_t i; + for (i=0; iIsOpen()) + { + ssd1306.setColor(WHITE); + ssd1306.fillRect(xrect, yrect, wrect, hrect); + + ssd1306.setColor(BLACK); + ssd1306.drawString(x, y, alleFenster[i]->name); + ssd1306.drawString(x+1, y, alleFenster[i]->name); + ssd1306.drawString(x+1, y+1, alleFenster[i]->name); + ssd1306.drawString(x, y+1, alleFenster[i]->name); + } + else + { + ssd1306.setColor(WHITE); + ssd1306.drawString(x, y, alleFenster[i]->name); + } + if (i&1) + { + xrect = 0u; + x = 2u; + yrect += 20; + y+= 20; + } + else + { + xrect = 64; + x = 66; + } + } + + + /* print Temperature */ + x=0; + y=64-16; + if (thermoData.rhPercent > 0) + { + sprintf(strBuf, "% 3d C", (int) thermoData.tempC); + } + else + { + sprintf(strBuf, " --"); + } + //tft.print(strBuf); + ssd1306.setColor(WHITE); + ssd1306.drawString(x, y, strBuf); + + /* print Remaining time */ + yrect = 64-16; + xrect = 64; + wrect = 32; + hrect = 16; + strcpy(strBuf, ""); + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + if (alleFenster[i]->ShallPiep()) + { + strcpy(strBuf, alleFenster[i]->name); + break; + } + } + + if (strlen(strBuf)==0) + { + DeciSeconds_t remainingTime = calcRemainingTime(); + uint8_t mins = (remainingTime / 10) / 60; + uint8_t secs = (remainingTime / 10) % 60; + if (mins < 60) + { + sprintf(strBuf, "%d:%02d", (int) (mins), (int) (secs)); + } + } + if (strlen(strBuf)==0) + { + //ssd1306.setColor(BLACK); + //ssd1306.fillRect(xrect, yrect, wrect, hrect); + } + else + { + ssd1306.setColor(WHITE); + //ssd1306.fillRect(xrect, yrect, wrect, hrect); + //ssd1306.setColor(BLACK); + + ssd1306.drawString(xrect,yrect, strBuf); + ssd1306.drawString(xrect+1,yrect, strBuf); + } + + ssd1306.display(); +} + +#endif // #if VERSION_DG_ONLY diff --git a/src/Display_SSD1306.h b/src/Display_SSD1306.h new file mode 100644 index 0000000..951cd79 --- /dev/null +++ b/src/Display_SSD1306.h @@ -0,0 +1,30 @@ +/* + * Display.h + * + * Created on: 15.05.2020 + * Author: flori + */ + +#include "main.h" + +#if VERSION_SMALL_DISPLAY + +#ifndef DISPLAY_SSD1306_H_ +#define DISPLAY_SSD1306_H_ + +class Display +{ +public: + void Init(void); + void Update(void); + +private: + + char strBuf[50]; + +}; + +extern Display display; + +#endif /* DISPLAY_SSD1306_H_ */ +#endif diff --git a/src/Fenster.cpp b/src/Fenster.cpp new file mode 100644 index 0000000..9ceaed2 --- /dev/null +++ b/src/Fenster.cpp @@ -0,0 +1,107 @@ +/* + * Fenster.cpp + * + * Created on: 29.02.2020 + * Author: flori + */ + +#include "main.h" +#include "Fenster.h" +#include "ReceiverFunkThermometer.h" + +#define SERIAL_PRINT(x) //Serial.print(" "); Serial.print(x) + + +/** + * + */ +Fenster::Fenster(const char *_name, uint8_t myKeyNumber) +{ + strcpy(this->name , _name); + this->myKeyNumber = myKeyNumber; + openingTime = 0; + shallPiep = false; + color = 0; +} + +/** + * keyNum : key number with offset + */ +bool Fenster::HandleKey(int8_t keyNum, bool direction) +{ + bool bThisWindowChanged = false; + if (keyNum == myKeyNumber) + { + if (direction == DIRECTION_OPEN) + { + if (openingTime == 0u) + { + bThisWindowChanged = true; + openingTime = tDecis; + SERIAL_PRINT("open "); + SERIAL_PRINT(myKeyNumber); + SERIAL_PRINT(waitTimeDs); + } + } + else + { + if (openingTime != 0u) + { + bThisWindowChanged = true; + shallPiep = false; + openingTime = 0; + SERIAL_PRINT("close "); + SERIAL_PRINT(myKeyNumber); + } + } + } + + return bThisWindowChanged; +} + + + +/** + * + */ +bool Fenster::ShallPiep() +{ + DeciSeconds_t tWaitDs = waitTimeDs; + if (this == &fensterGefrier) + { + tWaitDs = 300u; + } + if ((tDecis > openingTime + tWaitDs) && (openingTime > 0)) + { + shallPiep = true; + } + return shallPiep; +} + + +/** + * + */ +DeciSeconds_t Fenster::GetRemainingTime() +{ + DeciSeconds_t tWaitDs = waitTimeDs; + if (this == &fensterGefrier) + { + tWaitDs = 300u; + } + if (openingTime > 0) + { + DeciSeconds_t remainingTime = openingTime + tWaitDs - tDecis; + return remainingTime; + } + else + { + return 0; + } + +} + +bool Fenster::IsOpen() +{ + return (openingTime > 0); +} diff --git a/src/Fenster.h b/src/Fenster.h new file mode 100644 index 0000000..f1b214f --- /dev/null +++ b/src/Fenster.h @@ -0,0 +1,32 @@ +/* + * Fenster.h + * + * Created on: 29.02.2020 + * Author: flori + */ + +#ifndef FENSTER_H_ +#define FENSTER_H_ + +#include "typedefs.h" + +class Fenster +{ +public: + char name[8]; + uint16_t color; + Fenster(const char *_name, uint8_t myKeyNumber); + + bool HandleKey(int8_t keyNum, bool direction); + + bool ShallPiep(); + DeciSeconds_t GetRemainingTime(); + bool IsOpen(); + +private: + uint8_t myKeyNumber; + DeciSeconds_t openingTime; + bool shallPiep; +}; + +#endif /* FENSTER_H_ */ diff --git a/src/Hamming.cpp b/src/Hamming.cpp new file mode 100644 index 0000000..0cbd093 --- /dev/null +++ b/src/Hamming.cpp @@ -0,0 +1,20 @@ +/* + * Hamming.cpp + * + * Created on: 10.10.2022 + * Author: flori + */ + +#include "Hamming.h" + +Hamming::Hamming() +{ + // TODO Auto-generated constructor stub + +} + +Hamming::~Hamming() +{ + // TODO Auto-generated destructor stub +} + diff --git a/src/Hamming.h b/src/Hamming.h new file mode 100644 index 0000000..301302e --- /dev/null +++ b/src/Hamming.h @@ -0,0 +1,18 @@ +/* + * Hamming.h + * + * Created on: 10.10.2022 + * Author: flori + */ + +#ifndef HAMMING_H_ +#define HAMMING_H_ + +class Hamming +{ +public: + Hamming(); + virtual ~Hamming(); +}; + +#endif /* HAMMING_H_ */ diff --git a/src/InterruptHandler.cpp b/src/InterruptHandler.cpp new file mode 100644 index 0000000..687b2c2 --- /dev/null +++ b/src/InterruptHandler.cpp @@ -0,0 +1,149 @@ + +#include "main.h" +#include "PiepPattern.h" +#include "ReceiverSmartWares.h" +#include "ReceiverAiggend.h" +#include "ReceiverOval.h" +#include "ReceiverKerui.h" +#include "ReceiverFunkThermometer.h" + +#include "InterruptHandler.h" + + + +#define LOOP_COUNTS_FOR_PAUSE (2u) +/*****************************************************/ + +IRAM_ATTR void timerIsr(); +IRAM_ATTR void pinLevelChangeIsr(void); + +/*****************************************************/ + + + +/** + * + */ +void InterruptHandler_Init(void) +{ + /* setup interrupt */ + attachInterrupt(digitalPinToInterrupt(DIN_FUNK), pinLevelChangeIsr, CHANGE); + +#if 1 + hw_timer_t * timer = timerBegin(0, 80, true); /* 80 -> 1 Mhz */ + timerAttachInterrupt(timer, &timerIsr, true); + timerAlarmWrite(timer, ISR_TIME_US, true); + timerAlarmEnable(timer); +#endif + +} + + +/** + * called every 10 ms + * + * used to update tDecis, and for beeping + */ +IRAM_ATTR void timerIsr() +{ + static uint32_t tshortPiepStartedMs = 0; + static uint8_t count = 0; + static boolean toneOn = false; + uint32_t tMillis = millis(); + +#if 0 + static bool on = true; + if (on) digitalWrite(DOUT_TEST_TIMER, HIGH); + else digitalWrite(DOUT_TEST_TIMER, LOW); + on = !on; +#endif + + if (++count == MS_TO_ISR_COUNT(100uL) ) + { + /* increment tDecis every 100ms */ + count = 0; + tDecis++; + } + + if (bRequestShortBeep) + { + bRequestShortBeep = false; + tshortPiepStartedMs = tMillis; + } + + if (tshortPiepStartedMs > 0u) + { + if (tMillis < (tshortPiepStartedMs + 30uL)) + { + if (false == toneOn) + { + TONE_REQUEST_ON(TONE_REQUEST_SOURCE_SHORTPIEP); + toneOn = true; + } + } + else + { + TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_SHORTPIEP); + tshortPiepStartedMs = 0; + toneOn = false; + } + } + else + { + piepPattern->TaskCyclic(); + } + + if (toneRequest != 0u) + { + digitalWrite(DOUT_PIEP_VCC, HIGH); + } + else + { + digitalWrite(DOUT_PIEP_VCC, LOW); + } +} + + +IRAM_ATTR void InterruptHandler_PauseReceive() +{ + loopCountSincePause = 0u; +} + +/** + * + */ +IRAM_ATTR void pinLevelChangeIsr(void) +{ + static bool lastVal = LOW; + static uint32_t lastMics = 0; + static uint32_t MINIMAL_DT_MICROS_FOR_RECEIVERS = 100u; + + uint32_t dtMicros = micros() - lastMics; + bool pinFunkVal = digitalRead(DIN_FUNK); + + if (lastVal == pinFunkVal) + { + return; + } + else + { + lastMics = micros(); + + lastVal = pinFunkVal; + if (loopCountSincePause < LOOP_COUNTS_FOR_PAUSE) + { + /* after receiving a key, wait for the main loop to run x times before activating receiving again */ + return; + } + else if (dtMicros > MINIMAL_DT_MICROS_FOR_RECEIVERS) + { + receiverSw.Isr(dtMicros, pinFunkVal); + receiverAiggend.Isr(dtMicros, pinFunkVal); + receiverOval.Isr(dtMicros, pinFunkVal); + receiverKerui.Isr(dtMicros, pinFunkVal); + receiverThermo.Isr(dtMicros, pinFunkVal); + + //digitalWrite(LED_BUILTIN, pinFunkVal); + } + } +} diff --git a/src/InterruptHandler.h b/src/InterruptHandler.h new file mode 100644 index 0000000..6bb18fc --- /dev/null +++ b/src/InterruptHandler.h @@ -0,0 +1,25 @@ +/* + * interruptHandler.h + * + * Created on: 11.10.2022 + * Author: flori + */ + +#ifndef INTERRUPTHANDLER_H_ +#define INTERRUPTHANDLER_H_ + +#include "Arduino.h" + + +#define ISR_TIME_US (10000uL) + +#define MS_TO_ISR_COUNT(ms) ( ((ms)*1000uL) / ISR_TIME_US ) + + +void InterruptHandler_Init(void); +void InterruptHandler_PauseReceive(); + + + + +#endif /* INTERRUPTHANDLER_H_ */ diff --git a/src/LedBlinker.cpp b/src/LedBlinker.cpp new file mode 100644 index 0000000..2e5ada1 --- /dev/null +++ b/src/LedBlinker.cpp @@ -0,0 +1,54 @@ +/* + * LedBlinker.cpp + * + * Created on: 29.02.2020 + * Author: flori + */ + +#include "main.h" +#include "LedBlinker.h" +#include "ReceiverFunkThermometer.h" + +#define BLINK_TIME ((DeciSeconds_t)2) + +LedBlinker ledBlinker; + +/** + * + */ +void LedBlinker::OnLoop() +{ + + static DeciSeconds_t tOn; + static DeciSeconds_t tOff; + static uint32_t numBlinkFast = 0; + + if (numberWindowsOpen > 0) + { + if (tDecis > tOn) + { + digitalWrite(LED_BUILTIN, HIGH); + tOff = tDecis + BLINK_TIME; + tOn = tOff + BLINK_TIME; + } + if (tDecis > tOff) + { + digitalWrite(LED_BUILTIN, LOW); + tOn = tDecis + BLINK_TIME; + tOff = tOn + BLINK_TIME; + if (numBlinkFast>0) + { + numBlinkFast--; + } + else + { + numBlinkFast = numberWindowsOpen-1; + tOn += BLINK_TIME*3; + tOff += BLINK_TIME*3; + } + + } + } + +} + diff --git a/src/LedBlinker.h b/src/LedBlinker.h new file mode 100644 index 0000000..4f20552 --- /dev/null +++ b/src/LedBlinker.h @@ -0,0 +1,19 @@ +/* + * LedBlinker.h + * + * Created on: 29.02.2020 + * Author: flori + */ + +#ifndef LEDBLINKER_H_ +#define LEDBLINKER_H_ + +class LedBlinker +{ +public: + void OnLoop(); +}; + +extern LedBlinker ledBlinker; + +#endif /* LEDBLINKER_H_ */ diff --git a/src/MyWifiClient.cpp b/src/MyWifiClient.cpp new file mode 100644 index 0000000..024cf91 --- /dev/null +++ b/src/MyWifiClient.cpp @@ -0,0 +1,194 @@ +/* + * MyWifiClient.cpp + * + * Created on: 24.09.2020 + * Author: flori + */ + +#include "main.h" +#include "Base32.h" +#include "Seconds.h" +#include "Version.h" + +#include "MyWifiClient.h" + +Base32 base32; + + +#if 1 +#define MonitorPrint(...) Serial.print(__VA_ARGS__) +#define MonitorPrintln(...) Serial.println(__VA_ARGS__) +#else +#define MonitorPrint(...) +#define MonitorPrintln(...) +#endif + + +MyWifiClient myWifiClient; + + +/** + * + */ +MyWifiClient::MyWifiClient() +{ + state = IDLE; + bSend = false; +} + +/** + * + */ +MyWifiClient::~MyWifiClient() +{ + +} + +/** + * + */ +bool MyWifiClient::canSend(void) +{ + return state == IDLE && bSend == false; +} + + +/* converts dat to base32 and triggers GET request */ +void MyWifiClient::send(uint8_t *dat, uint16_t len) +{ + strcpy( wifibufMsg , "GET /genericData.php?project=fensterpiepser&dataname=fenster&data="); + size_t pos = strlen(wifibufMsg); + (void) base32.toBase32(dat, len, &wifibufMsg[pos], true); + strcat( wifibufMsg, " HTTP/1.1\r\nHost: fly-with-cats.com\r\nAccept: */*\r\n\r\n"); + + bSend = true; +} + +/** + * + */ +void MyWifiClient::onSetup(void) +{ + +} + + +/** + * + */ +void MyWifiClient::onLoop(void) +{ + static substate_t substate = ENTRY; + static state_t prevState = IDLE; + + if (prevState != state) + { + substate = ENTRY; + prevState = state; + switch(state) + { + case IDLE: + MonitorPrintln("IDLE"); + break; + case WAIT_CONNECT: + MonitorPrintln("WAIT_CONNECT"); + break; + case WAIT_RECEIVE: + MonitorPrintln("WAIT_RECEIVE"); + break; + } + } + + + switch (state) + { + case IDLE: + switch (substate) + { + static uint32_t tConnectWifiEndSeconds; + case ENTRY: + tConnectWifiEndSeconds = Seconds::Get() + 60; + substate = CYCLIC; + break; + + case CYCLIC: + if (WiFi.isConnected()) + { + tConnectWifiEndSeconds = Seconds::Get() + 60; + if (bSend) + { + bSend = false; + state = WAIT_CONNECT; + } + } + else + { + if (Seconds::Get() > tConnectWifiEndSeconds) + { + Serial.println("RESET (Wifi)"); + ESP.restart(); + } + } + break; + } + + break; + + case WAIT_CONNECT: + switch (substate) + { + static uint32_t tConnectEndSeconds; + case ENTRY: + /* Connect to Server */ + this->connect("fly-with-cats.com", 8887, 100); + tConnectEndSeconds = Seconds::Get() + 5; + substate = CYCLIC; + break; + + case CYCLIC: + if (this->connected()) + { + /* send HTTP request */ + this->print(wifibufMsg); + MonitorPrint(wifibufMsg); + state = WAIT_RECEIVE; + } + else if (Seconds::Get() > tConnectEndSeconds) + { + state = IDLE; + } + break; + + } + break; + + case WAIT_RECEIVE: + switch (substate) + { + static uint32_t tReceiveEndSeconds; + + case ENTRY: + tReceiveEndSeconds = Seconds::Get() + 5; + substate = CYCLIC; + break; + + case CYCLIC: + if (this->available()) + { + int sizeRec = this->read(wifibufRx, WIFI_BUF_SIZE_RX); + wifibufRx[sizeRec] = 0; + //MonitorPrintln((char*)wifibufRx); + state = IDLE; + } + else if (Seconds::Get() >= tReceiveEndSeconds) + { + this->stop(); + state = IDLE; + } + break; + } + } + + + +} diff --git a/src/MyWifiClient.h b/src/MyWifiClient.h new file mode 100644 index 0000000..77e4db3 --- /dev/null +++ b/src/MyWifiClient.h @@ -0,0 +1,41 @@ +/* + * MyWifiClient.h + * + * Created on: 24.09.2020 + * Author: flori + */ + +#ifndef MYWIFICLIENT_H_ +#define MYWIFICLIENT_H_ + +#include +#include "Base32.h" +#include + +#define WIFI_BUF_SIZE_RX 1024 + + +typedef enum { IDLE, WAIT_CONNECT, WAIT_RECEIVE } state_t; +typedef enum { ENTRY, CYCLIC } substate_t; +class MyWifiClient: public WiFiClient +{ +public: + MyWifiClient(); + virtual ~MyWifiClient(); + void send(uint8_t *dat, uint16_t len); + void onSetup(void); + void onLoop(void); + bool canSend(void); + +private: + bool bSend; + state_t state; + char wifibufMsg[WIFI_BUF_SIZE_RX]; + + uint8_t wifibufRx[WIFI_BUF_SIZE_RX]; +}; + +extern MyWifiClient myWifiClient; +extern Base32 base32; + +#endif /* MYWIFICLIENT_H_ */ diff --git a/src/PiepMode.cpp b/src/PiepMode.cpp new file mode 100644 index 0000000..94a0efd --- /dev/null +++ b/src/PiepMode.cpp @@ -0,0 +1,146 @@ +/* + * PiepMode.cpp + * + * Created on: 25.02.2020 + * Author: flori + */ + +#include "main.h" +#include "PiepMode.h" + +#define SERIAL_PRINT(x) //Serial.print(" "); Serial.print(x) + + +#define STANDBY 0 +#define ON 1 +#define OFF 2 + + + + +/** + * + */ +PiepMode::PiepMode() +{ + // TODO Auto-generated constructor stub + state = STANDBY; + startRequest = false; + stopRequest = false; + requestCount = 255; + timer = 0; + onTime = 100; + offTime = 100; + counter = 0; + outPin = 13; + + +} + + +/** + * + */ +IRAM_ATTR void PiepMode::Start(uint8_t outPin) +{ + startRequest = true; + this->outPin = outPin; + //pinMode(outPin, OUTPUT); + state = STANDBY; +} + + +/** + * + */ +IRAM_ATTR void PiepMode::Stop() +{ + stopRequest = true; + TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_MODE); +} + + +/** + * + */ +IRAM_ATTR bool PiepMode::HasCompleted(void) +{ + return (state == STANDBY); +} + + +/** + * + */ +IRAM_ATTR void PiepMode::TaskCyclic() +{ + switch (state) + { + case STANDBY: + SERIAL_PRINT("S"); + stopRequest = false; + if (startRequest) + { + startRequest = false; + state = ON; + counter = 0; + timer = onTime; + } + break; + + case ON: + SERIAL_PRINT(timer); + SERIAL_PRINT(onTime); + /* switch on */ + startRequest = false; + if (stopRequest) + { + state = STANDBY; + } + else if (timer > 0) + { + TONE_REQUEST_ON(TONE_REQUEST_SOURCE_MODE); + timer--; + } + else + { + timer = offTime; + state = OFF; + } + break; + + case OFF: + SERIAL_PRINT("F"); + /* switch off */ + startRequest = false; + if (stopRequest) + { + state = STANDBY; + } + else if (timer > 0) + { + TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_MODE); + timer--; + } + else if (requestCount == 0) + { + timer = onTime; + state = ON; + } + else if (++counter < requestCount) + { + timer = onTime; + state = ON; + } + else + { + state = STANDBY; + } + + break; + + default: + Serial.print(state); + break; + } +} diff --git a/src/PiepMode.h b/src/PiepMode.h new file mode 100644 index 0000000..650c2b5 --- /dev/null +++ b/src/PiepMode.h @@ -0,0 +1,30 @@ +/* + * PiepMode.h + * + * Created on: 25.02.2020 + * Author: flori + */ + +#ifndef PIEPMODE_H_ +#define PIEPMODE_H_ + +class PiepMode +{ +public: + PiepMode(); + + void TaskCyclic(); + void Start(uint8_t outPin); + void Stop(); + bool HasCompleted(void); + + uint32_t onTime, offTime; + uint32_t requestCount; + +private : + uint32_t counter, timer, outPin; + uint8_t state; + uint8_t startRequest, stopRequest; +}; + +#endif /* PIEPMODE_H_ */ diff --git a/src/PiepPattern.cpp b/src/PiepPattern.cpp new file mode 100644 index 0000000..129c5ca --- /dev/null +++ b/src/PiepPattern.cpp @@ -0,0 +1,115 @@ +/* + * PiepPattern.cpp + * + * Created on: 25.02.2020 + * Author: flori + */ +#include "main.h" +#include "PiepPattern.h" +#include "PiepMode.h" + +#define SERIAL_PRINT(x) // Serial.print(" "); Serial.print(x) + +#define STANDBY 0 +#define ON 1 + +/** + * + */ +PiepPattern::PiepPattern() +{ + requestCount = 0; + numberModes = 0; + counter = 0; + modeIndex = 0; + startRequest = false; + stopRequest = false; + state = STANDBY; + outPin = 13; + piepModes = NULL; +} + + +/** + * + */ +IRAM_ATTR void PiepPattern::Start(uint8_t outPin) +{ + startRequest = true; + this->outPin = outPin; + state = STANDBY; +} + + +/** + * + */ +IRAM_ATTR void PiepPattern::Stop() +{ + stopRequest = true; +} + + +/** + * + */ +IRAM_ATTR void PiepPattern::TaskCyclic() +{ + switch (state) + { + case STANDBY: + SERIAL_PRINT("STDBY"); + stopRequest = false; + if (startRequest) + { + startRequest = false; + counter = 0; + modeIndex = 0; + if (numberModes > 0) + { + state = ON; + piepModes[modeIndex]->Start(outPin); + piepModes[modeIndex]->TaskCyclic(); + } + } + break; + + case ON: + SERIAL_PRINT(modeIndex); + SERIAL_PRINT(piepModes[modeIndex]->onTime); + startRequest = false; + piepModes[modeIndex]->TaskCyclic(); + + if (stopRequest) + { + piepModes[modeIndex]->Stop(); + state = STANDBY; + } + else + { + if (piepModes[modeIndex]->HasCompleted()) + { + if (++modeIndex < numberModes) + { + piepModes[modeIndex]->Start(outPin); + } + else if ( requestCount == 0) + { + modeIndex = 0; + piepModes[modeIndex]->Start(outPin); + } + else if ( ++counter < requestCount ) + { + modeIndex = 0; + piepModes[modeIndex]->Start(outPin); + } + } + } + break; + + default: + Serial.print(state); + break; + } + +} diff --git a/src/PiepPattern.h b/src/PiepPattern.h new file mode 100644 index 0000000..28d456e --- /dev/null +++ b/src/PiepPattern.h @@ -0,0 +1,36 @@ +/* + * PiepPattern.h + * + * Created on: 25.02.2020 + * Author: flori + */ + +#ifndef PIEPPATTERN_H_ +#define PIEPPATTERN_H_ + +#include "PiepMode.h" + +class PiepPattern +{ +public: + PiepPattern(); + void TaskCyclic(); + void Start(uint8_t outPin); + void Stop(void); + + + uint8_t requestCount; + uint8_t numberModes; + class PiepMode **piepModes; + + +private : + uint8_t counter; + uint8_t modeIndex; + uint8_t outPin; + uint8_t startRequest, stopRequest; + uint8_t state; + +}; + +#endif /* PIEPPATTERN_H_ */ diff --git a/src/Receivers433/ReceiverFunkThermometer.cpp b/src/Receivers433/ReceiverFunkThermometer.cpp new file mode 100644 index 0000000..b584aaa --- /dev/null +++ b/src/Receivers433/ReceiverFunkThermometer.cpp @@ -0,0 +1,326 @@ +/* + * ReceiverFunkThermometer.cpp + * + * Created on: 10.05.2020 + * Author: flori + */ +#include "main.h" +#include "DataSender.h" +#include "ReceiverFunkThermometer.h" + +#define DEBUG_LEVEL 0 + +#define MonitorPrint(x) // Serial.print(x) + +ReceiverFunkThermometer receiverThermo; + +/* ca. alle 50s wird temp + rh gesendet */ + +/** + * + */ +ReceiverFunkThermometer::ReceiverFunkThermometer() +{ + ResetBuffer(); + data.tempC = 10; + data.rhPercent = 50; + bNewData = false; + dataLast.tempC = 99; + dataLast.rhPercent = 0u; + rBitNumber = 0u; +} + + +/** + * + */ +bool ReceiverFunkThermometer::HasNewData(void) +{ + return bNewData; +} + +/** + * + */ +ReceiverFunkThermometerData_t ReceiverFunkThermometer::GetData(void) +{ + ReceiverFunkThermometerData_t datTemp = data; + return datTemp; +} + +/** + * + */ +IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue) +{ + static SignalDurationThermometer_t lastDuration = FUNK_THERMO_INVALID; + SignalDurationThermometer_t thisDuration = FUNK_THERMO_INVALID; + + + if (dtMicros > 350 && dtMicros < 600) + { + thisDuration = MS_0_5; + } + else if (dtMicros > 800 && dtMicros < 1200) + { + thisDuration = MS_1_0; + } + else if (dtMicros > 1800 && dtMicros < 2200) + { + thisDuration = MS_2_0; + } + else + { + thisDuration = FUNK_THERMO_INVALID; + } + + + if (thisDuration == FUNK_THERMO_INVALID ) + { + + ResetBuffer(); + } + else + { + + if (lastDuration == FUNK_THERMO_INVALID) + { + + } + else if (pinValue == HIGH ) + { +#if DEBUG_LEVEL > 1 + bool bprint = (rByteIndex > 0 || rBitIndex<7); +#else + bool bprint = false; +#endif + + if (bprint) + { + sprintf(textBuf, "\n%d %d : ", rByteIndex, rBitIndex ); + MonitorPrint(textBuf); + } + if (thisDuration==MS_2_0 && lastDuration == MS_0_5) + { + if (bprint) + { + MonitorPrint(F("1")); + } + /* bit 1 received */ + rBytes[rByteIndex] |= (1 << rBitIndex); + if (rBitIndex == 0) + { + NextByte(); + } + else + { + rBitIndex--; + } + rBitNumber++; + if (THERMO_NUM_BITS_IGNORED == rBitNumber) + { + rByteIndex = 0; + rBitIndex = 7; + rBytes[0] = 0; + } + } + else if (thisDuration==MS_1_0 &&lastDuration == MS_0_5) + { + if (bprint) + { + MonitorPrint(F("0")); + } + /* bit 0 received */ + if (rBitIndex == 0) + { + NextByte(); + } + else + { + rBitIndex--; + } + rBitNumber++; + if (THERMO_NUM_BITS_IGNORED == rBitNumber) + { + rByteIndex = 0; + rBitIndex = 7; + rBytes[0] = 0; + } + } + + + } + + } + lastDuration = thisDuration; + + +} + +/** + * + */ +IRAM_ATTR void ReceiverFunkThermometer::ResetBuffer(void) +{ + + rByteIndex = 0; + rBitIndex = 7; + rBytes[0] = 0; + rBitNumber = 0u; +} + +/** + * + */ +IRAM_ATTR void ReceiverFunkThermometer::NextByte(void) +{ + rByteIndex++; + rBitIndex = 7; + + if (rByteIndex == THERMO_KEY_NUMBYTES_PER_KEY) + { + OnTempReceived(); + ResetBuffer(); + } + else + { + /* init the next byte */ + rBytes[rByteIndex] = 0; + } +} + +/* + * +bytes received from woolworth temp + -0,9C 89% +112 +255 +127 +89 +------------ +-0,8 89 +112 +255 +143 +89 +------------ +-0,7 89 +112 +255 +159 +89 +------------ +-0,6 89 +112 +255 +175 +89 +------------ +-0,5 89 +112 +255 +191 +89 +------------ +0,0 90 +112 +0 +15 +90 rh +------------ +0.1 90 +112 +0 +31 +90 + + +112 +0 +95 +90 + +6.4 +112 +4 +15 +69 + + + * + */ +IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void) +{ + + /* first 4 bits of 36 bits are thrown away.. Rest : + bytes 0 1 2 3 + nibbles : 0 1 2 3 4 5 6 7 + value : id id t t t 0xf h h + */ +#define PRINT_ON_TEMP_RECEIVED 0 +#if 0 + /* testdaten */ + rBytes[0] = 112u; + rBytes[1] = 255u; + rBytes[2] = 191u; + rBytes[3] = 89u; +#endif +#if PRINT_ON_TEMP_RECEIVED + Serial.println(rBytes[0]); + Serial.println(rBytes[1]); + Serial.println(rBytes[2]); + Serial.println(rBytes[3]); +#endif + + if ((rBytes[2]&0xF) == 0xF) /* these 4 bits must be 1 */ + { + + + int16_t tempInt = 0; + int16_t tempNow = 0; + uint8_t rhNow = rBytes[3]; + bool isNegative; + + tempInt = rBytes[1] << 4; + tempInt |= (int16_t)(rBytes[2] >> 4); + isNegative = (rBytes[1]&0x80) != 0u; + + if ( isNegative) // the first bit of nibble 1 shows if the value is negative + { + /* 2's complement */ + tempInt = (~tempInt) & 0xFFFu; + tempInt += 1; + } + #if PRINT_ON_TEMP_RECEIVED + Serial.println(tempInt); + #endif + /* do the rounding with positive number */ + tempNow = (tempInt + 5) / 10; + + if (isNegative) + { + /* set to negative */ + tempNow = -tempNow; + } + #if PRINT_ON_TEMP_RECEIVED + Serial.println(tempNow); + #endif + + int16_t dTempAbs = (tempNow >= dataLast.tempC) ? (tempNow - dataLast.tempC) : (dataLast.tempC - tempNow); + uint8_t dRHAbs = (rhNow >= dataLast.rhPercent) ? (rhNow - dataLast.rhPercent) : (dataLast.rhPercent - rhNow); + + dataLast.tempC = tempNow; + dataLast.rhPercent = rhNow; + #if 1 + /* plausibility check: Temp and RH cannot have changed more than 2 units , if a similar value was received two times, it should be ok*/ + if ( (dTempAbs <= 2) && + (dRHAbs <= 2u) ) + #endif + { + bNewData = true; + data = dataLast; + } + } + + +} diff --git a/src/Receivers433/ReceiverFunkThermometer.h b/src/Receivers433/ReceiverFunkThermometer.h new file mode 100644 index 0000000..d327206 --- /dev/null +++ b/src/Receivers433/ReceiverFunkThermometer.h @@ -0,0 +1,63 @@ +/* + * ReceiverFunkThermometer.h + * + * Created on: 10.05.2020 + * Author: flori + */ + +#ifndef RECEIVERFUNKTHERMOMETER_H_ +#define RECEIVERFUNKTHERMOMETER_H_ + +#define THERMO_NUM_BITS_IGNORED 4 +#define THERMO_NUM_BITS_PER_KEY 36 +#define THERMO_KEY_NUMBYTES_PER_KEY 4/* 36 bits, but first 4 bits are ignored -> 32 bits */ + +typedef enum +{ + FUNK_THERMO_INVALID, + MS_0_5, + MS_1_0, + MS_2_0 +} SignalDurationThermometer_t; + + +typedef struct +{ + int16_t tempC; + uint8_t rhPercent; +} ReceiverFunkThermometerData_t; + + + +class ReceiverFunkThermometer +{ +public: + ReceiverFunkThermometer(); + + void Isr(uint32_t dtMicros, bool pinValue); + bool HasNewData(void); + ReceiverFunkThermometerData_t GetData(void); + void ResetNewData(void){ bNewData = false; } + + + +private: + void OnTempReceived(void); + void ResetBuffer(void); + void NextByte(void); + + + uint8_t rBytes[THERMO_KEY_NUMBYTES_PER_KEY]; + uint8_t rByteIndex = 0; + uint8_t rBitIndex = 7; + uint8_t rBitNumber = 0; + ReceiverFunkThermometerData_t data; + ReceiverFunkThermometerData_t dataLast; + bool bNewData = false; +}; + + +extern ReceiverFunkThermometer receiverThermo; + + +#endif /* RECEIVERFUNKTHERMOMETER_H_ */ diff --git a/src/Receivers433/ReceiverSmartWares.cpp b/src/Receivers433/ReceiverSmartWares.cpp new file mode 100644 index 0000000..8ef6837 --- /dev/null +++ b/src/Receivers433/ReceiverSmartWares.cpp @@ -0,0 +1,219 @@ +/* + * ReceiverSmartWares.cpp + * + * Created on: 22.02.2020 + * Author: flori + */ + +#include "main.h" +#include "ReceiverSmartWares.h" + +#define MonitorPrint(x) //Serial.print(x) +#define MonitorPrintln(x) //Serial.println(x) + +#define KEY_BYTE_OPEN 0x56 +#define KEY_BYTE_CLOSE 0x55 + +ReceiverSmartWares receiverSw; + +#if 0 +static const char* keyNames[] = { + "DAEMM","FB1","FB2","FB3","FB4", + "HAUSTUERE","KLO EG","BAD","WIN 4","KELLERTREPPE", + "GEFRIER","ABSTELL","WIN TONI","Doppel_L","DOPPEL_R", + "LICHT S","LICHT W","LICHT O","LICHT GARAGE","BEW GARAGE", + "STECK 1","STECK 2"}; +#endif + +/* bytes 4 + 5 sind immer 0x55, byte 6 sagt ON oder oFF, daher hier nur als 0 aufgefuehrt */ +const uint8_t ReceiverSmartWares::keys[SMW_KEY_NUMKEYS][SMW_KEY_NUMBYTES_PER_KEY] = +{ + /* ausgelesene Keys */ + { 0b01010101, 0b01100101, 0b10010110, 0b10011001, 0, 0, 0, 0b01010110 }, //0 DAEMMERUNG + { 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01010110 }, //1 FB1 + { 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01011001 }, //2 FB2 + { 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01011010 }, //3 FB3 + { 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01100101 }, //4 FB4 + { 0b01010110, 0b01010101, 0b10101001, 0b01100110, 0, 0, 0, 0b01010110 }, //5 BEW HAUSTUERE + { 0b01010101, 0b01101001, 0b10010110, 0b10010101, 0, 0, 0, 0b01010110 }, //6 WINDOW KLO unten + { 0b01010101, 0b10011010, 0b10010110, 0b10100110, 0, 0, 0, 0b01010110 }, //7 WINDOW BAD oben + { 0b01010101, 0b10100110, 0b01011010, 0b01011010, 0, 0, 0, 0b01010110 }, //8 WINDOW FLO + { 0b01010101, 0b01011001, 0b01010101, 0b01100110, 0, 0, 0, 0b01010110 }, //9 BEW KELLERTREPPE + { 0b01010101, 0b10011010, 0b01101001, 0b01100110, 0, 0, 0, 0b01010110 }, //10 GEFRIER + { 0b01010101, 0b10100110, 0b01011010, 0b01011010, 0, 0, 0, 0b01010110 }, //11 ABSTELLRAUM + { 0b01010101, 0b10101001, 0b01100110, 0b01011010, 0, 0, 0, 0b01010110 }, //12 WINDOW TONI + { 0b01011001, 0b01101001, 0b01100101, 0b01011001, 0, 0, 0, 0b01010110 }, //13 DOPPELSCHALTER_L + { 0b01011001, 0b01101001, 0b01100101, 0b01011001, 0, 0, 0, 0b01011001 }, //14 DOPPELSCHALTER_R + + /* selbst erfundene Keys */ + /* nur 5,6,9,a : immer genausoviele 1en wie 0en -> immer gleich lange sendedauer */ + { 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x55}, //15 LICHT TERASSE_SUED + { 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x56}, //16 LICHT TERASSE_WEST + { 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x59}, //17 LICHT HAUSTÜRE_OST + { 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x5a}, //18 LICHT GARAGE + { 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x65}, //19 BEW GARAGE (weitergeleitet von ReceiverBew) + { 0x6A, 0x95, 0x55, 0x99, 0, 0, 0, 0x56} , // Smartwares Ferbedienung Steckdose Au�en A + { 0x6A, 0x95, 0x55, 0x99, 0, 0, 0, 0x59} , // Smartwares Ferbedienung Steckdose Au�en B +}; + +#define NUM_SW_WINDOW_KEYS 5u +const uint8_t smWindowKeys[NUM_SW_WINDOW_KEYS] = {6u, 7u, 8u, 10u, 12u }; + +/* NUR FENSTER KEYS WERDEN WEITERGELEITET , SIEHE UNTEN*/ + +/** + * + */ +ReceiverSmartWares::ReceiverSmartWares() +{ + lastReceivedKeyNum = -1; + lastKeyOpenDirection = 0; + ResetBuffer(); + +} + +/** + * + */ +IRAM_ATTR void ReceiverSmartWares::Isr(uint32_t dtMicros, bool pinValue) +{ + static SignalDuration_t lastDuration = INVALID; + SignalDuration_t thisDuration = INVALID; + + if (dtMicros > 150 && dtMicros < 350) + { + thisDuration = SHORT; + } + else if (dtMicros > 1000 && dtMicros < 1350) + { + thisDuration = LONG; + } + else + { + thisDuration = INVALID; + } + + if (thisDuration == INVALID) + { + if (numBits == 64) + { + compareKeys(); + } + ResetBuffer(); + } + else + { + if (lastDuration == INVALID) + { + + } + else if (pinValue == HIGH) + { + numBits++; + + if (thisDuration == LONG && lastDuration == SHORT) + { + rBytes[rByteIndex] |= (1 << rBitIndex); /* set a 1 */ + + if (rBitIndex == 0) + { + NextByte(); + } + else + { + rBitIndex--; + } + } + else if (thisDuration == SHORT && lastDuration == SHORT) + { + /* leave the 0 that was the init value of every bit */ + if (rBitIndex == 0) + { + NextByte(); + } + else + { + rBitIndex--; + } + } + } + + } + lastDuration = thisDuration; +} + + +/** + * + */ +IRAM_ATTR void ReceiverSmartWares::ResetBuffer() +{ + rByteIndex = 0; + rBitIndex = 7; + numBits = 0; + rBytes[0] = 0; +} + +/** + * + */ +IRAM_ATTR void ReceiverSmartWares::NextByte() +{ + rByteIndex++; + rBitIndex = 7; + if (rByteIndex == SMW_KEY_NUMBYTES_PER_KEY) + { + compareKeys(); + ResetBuffer(); + } + else + { + rBytes[rByteIndex] = 0; + } +} + + +/** + * + */ +IRAM_ATTR void ReceiverSmartWares::compareKeys() +{ + int8_t keyFound = -1; + uint8_t i,j; + for (i=0; i=6 && keyFound<=8) || keyFound==12 || keyFound==10) /* NUR FENSTER KEYS WERDEN WEITERGELEITET */ + { + if ((keyFound != lastReceivedKeyNum) || (direction != lastKeyOpenDirection)) + { + newKeyReceived = true; + lastReceivedKeyNum = keyFound; + lastKeyOpenDirection = direction; + } + } + else + { + sprintf(textBuf, "SM %x %x %x %X %x %x %x %x", rBytes[0], rBytes[1], + rBytes[2], rBytes[3], rBytes[4], rBytes[5], rBytes[6], + rBytes[7]); + MonitorPrintln(textBuf); + } +} diff --git a/src/Receivers433/ReceiverSmartWares.h b/src/Receivers433/ReceiverSmartWares.h new file mode 100644 index 0000000..7061a50 --- /dev/null +++ b/src/Receivers433/ReceiverSmartWares.h @@ -0,0 +1,46 @@ +/* + * ReceiverSmartWares.h + * + * Created on: 22.02.2020 + * Author: flori + */ + +#ifndef RECEIVERSMARTWARES_H_ +#define RECEIVERSMARTWARES_H_ + +#include "ReceiverWinSensor433.h" + +#define SMW_KEY_NUMKEYS 22 +#define SMW_KEY_NUMBYTES_PER_KEY 8 + + +class ReceiverSmartWares : public Receiver433 +{ +public: + ReceiverSmartWares(); + + virtual void Isr(uint32_t dtMicros, bool pinValue); + + +private: + static const uint8_t keys[SMW_KEY_NUMKEYS][SMW_KEY_NUMBYTES_PER_KEY]; + uint8_t rBytes[SMW_KEY_NUMBYTES_PER_KEY]; + uint8_t rByteIndex = 0; + uint8_t rBitIndex = 7; + uint8_t numBits = 0; + char textBuf[32]; + + //void printByteBits(byte by); + //void printBuffer(); + void compareKeys(); + //uint8_t correlationFunction(uint8_t buf1[], uint8_t buf2[], uint8_t sizeBufs, int8_t shift); + void ResetBuffer(); + void NextByte(); + + +}; + +extern ReceiverSmartWares receiverSw; + + +#endif /* RECEIVERSMARTWARES_H_ */ diff --git a/src/Receivers433/ReceiverWinSensor433.cpp b/src/Receivers433/ReceiverWinSensor433.cpp new file mode 100644 index 0000000..e3db29d --- /dev/null +++ b/src/Receivers433/ReceiverWinSensor433.cpp @@ -0,0 +1,37 @@ +/* + * Receiver433.cpp + * + * Created on: 17.10.2021 + * Author: flori + */ + +#include "ReceiverWinSensor433.h" + +Receiver433::Receiver433() +{ + doBuffer = true; + newKeyReceived = false; + lastReceivedKeyNum = -1; + lastKeyOpenDirection = false; +} + +Receiver433::~Receiver433() +{ + // TODO Auto-generated destructor stub +} + + +int8_t Receiver433::GetLastReceivedKeyNum() +{ + if (newKeyReceived) return lastReceivedKeyNum; + else return -1; +} +void Receiver433::ResetReceivedKeyNum() +{ + newKeyReceived = false; +} + +bool Receiver433::GetLastReceivedDirection() +{ + return lastKeyOpenDirection; +} diff --git a/src/Receivers433/ReceiverWinSensor433.h b/src/Receivers433/ReceiverWinSensor433.h new file mode 100644 index 0000000..1d3215b --- /dev/null +++ b/src/Receivers433/ReceiverWinSensor433.h @@ -0,0 +1,47 @@ +/* + * Receiver433.h + * + * Created on: 17.10.2021 + * Author: flori + */ + +#ifndef RECEIVERWINSENSOR433_H_ +#define RECEIVERWINSENSOR433_H_ + +#include "Arduino.h" + + + +typedef enum +{ + INVALID, + SHORT, + LONG +} SignalDuration_t; + + +/* VIRTUAL BASE CLASS FOR RECEIVERS */ + + + +class Receiver433 +{ +public: + Receiver433(); + virtual ~Receiver433(); + + virtual void Isr(uint32_t dtMicros, bool pinValue) = 0; + + virtual int8_t GetLastReceivedKeyNum(); + virtual void ResetReceivedKeyNum(); + virtual bool GetLastReceivedDirection(); + +protected: + + bool lastKeyOpenDirection; // TRUE -> OPEN, FALSE -> CLOSE + bool doBuffer; + bool newKeyReceived; + int8_t lastReceivedKeyNum; +}; + +#endif /* RECEIVERWINSENSOR433_H_ */ diff --git a/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.cpp b/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.cpp new file mode 100644 index 0000000..19f6eb2 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.cpp @@ -0,0 +1,194 @@ +/* + * Receiver3ByteKey.cpp + * + * Created on: 12.10.2022 + * Author: flori + */ + +#include "Receiver3ByteKey.h" +#include "InterruptHandler.h" + +/*******************************************************************/ +#define DEBUG_LEVEL_NO_PRINT 0 +#define DEBUG_LEVEL_PRINT_NEW_KEYS_ONLY 1 +#define DEBUG_LEVEL_PRINT_ALL_RECEIVED_KEYS 2 + + +#define DEBUG_LEVEL DEBUG_LEVEL_NO_PRINT +#define SERIAL_PRINT(x) Serial.print(x) + +/*******************************************************************/ + +/** + * + */ +Receiver3ByteKey::Receiver3ByteKey() +{ + lastDuration = INVALID; + lastReceivedKeyNum = -1; + lastKeyOpenDirection = 0; + ResetBuffer(); +} + + +/** + * + */ +IRAM_ATTR void Receiver3ByteKey::Isr(uint32_t dtMicros, bool pinValue) +{ + + SignalDuration_t thisDuration = INVALID; + + if (dtMicros > config.tShortMin && dtMicros < config.tShortMax) + { + thisDuration = SHORT; + //if (doBuffer) buft[ibuf++] = dtMicros; + } + else if (dtMicros > config.tLongMin && dtMicros < config.tLongMax) + { + thisDuration = LONG; + //if (doBuffer) buft[ibuf++] = dtMicros; + } + else + { + thisDuration = INVALID; + } + + if (thisDuration == INVALID) + { + ResetBuffer(); + } + else + { + if (lastDuration == INVALID) + { + /* ResetBuffer was already called last time */ + } + else if (pinValue == HIGH) + { + // a valid bit is always terminated with a rising edge (the last bit is always 0 so this is the termination for the last bit to read ) + + if (thisDuration == LONG && lastDuration == SHORT) // short high, long low -> bit 0 + { + /* bytes are initialized as 0, so for bit 0, nothing to change */ + NextBit(); + } + else if (thisDuration == SHORT && lastDuration == LONG) // long high, short low -> bit 1 + { + rBytes[rByteIndex] |= (1 << rBitIndex); // bit 1 + + NextBit(); + } + else + { + // long -> long or short->short is invalid + ResetBuffer(); + } + } + else + { + /* falling edge -> wait for next rising edge */ + } + + } + lastDuration = thisDuration; + +} + +/** + * + */ +IRAM_ATTR void Receiver3ByteKey::ResetBuffer() +{ + rByteIndex = 0; + rBitIndex = 7; + rBytes[0] = 0; /* all other bytes are set to 0 in NextByte() */ + ibuf = 0; +} + +/** + * + */ +IRAM_ATTR void Receiver3ByteKey::NextBit() +{ + if (rBitIndex == 0) + { + NextByte(); + } + else + { + rBitIndex--; + } +} + +/** + * + */ +IRAM_ATTR void Receiver3ByteKey::NextByte() +{ + rByteIndex++; + rBitIndex = 7; + if (rByteIndex == NUM_BYTES_PER_KEY) + { + compareKeys(); + ResetBuffer(); + } + else + { + rBytes[rByteIndex] = 0; + } +} + + +/** + * + */ +IRAM_ATTR void Receiver3ByteKey::compareKeys() +{ + int8_t keyFound = -1; + bool direction = false; + uint8_t i; + + for (i=0; i=0) + { + uint8_t iBase = keyFound*(NUM_BYTES_PER_KEY+1u); + direction = rBytes[2] == config.keys[ iBase + 2 ]; + + + if ( (keyFound != lastReceivedKeyNum ) || (lastKeyOpenDirection != direction) ) + { + doBuffer = false; + newKeyReceived = true; + lastReceivedKeyNum = keyFound; + lastKeyOpenDirection = direction; + + InterruptHandler_PauseReceive(); + + #if DEBUG_LEVEL>=DEBUG_LEVEL_PRINT_ALL_RECEIVED_KEYS + sprintf(textBuf, "\n%s %d %d", config.name, keyFound, lastKeyOpenDirection); + SERIAL_PRINT(textBuf); + #endif + } + } + else + { + #if DEBUG_LEVEL>=DEBUG_LEVEL_PRINT_NEW_KEYS_ONLY + sprintf(textBuf, "\nnew %s %x %x %x", config.name, rBytes[0], rBytes[1], rBytes[2]); + SERIAL_PRINT(textBuf); + #endif + } +} diff --git a/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.h b/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.h new file mode 100644 index 0000000..be0fe05 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/Receiver3ByteKey.h @@ -0,0 +1,60 @@ +/* + * Receiver3ByteKey.h + * + * Created on: 12.10.2022 + * Author: flori + */ + +#ifndef RECEIVER3BYTEKEY_H_ +#define RECEIVER3BYTEKEY_H_ + +#include "ReceiverWinSensor433.h" + + +#define NUM_BYTES_PER_KEY 3u + +class Receiver3ByteKey : public Receiver433 +{ +public: + Receiver3ByteKey(); + + void Isr(uint32_t dtMicros, bool pinValue); + void startBuffering(){ doBuffer = true; } + + uint32_t buft[10*8]; + +protected: + class Config + { + public: + const char *name; + uint16_t tShortMin; + uint16_t tShortMax; + uint16_t tLongMin; + uint16_t tLongMax; + uint8_t numberKeys; + const uint8_t *keys; + }; + class Config config; + +private: + SignalDuration_t lastDuration; + uint8_t rBytes[NUM_BYTES_PER_KEY]; + uint8_t rByteIndex = 0; + uint8_t rBitIndex = 7; + uint32_t ibuf; + + //void printByteBits(byte by); + //void printBuffer(); + void compareKeys(); + //uint8_t correlationFunction(uint8_t buf1[], uint8_t buf2[], uint8_t sizeBufs, int8_t shift); + void ResetBuffer(); + void NextBit(); + void NextByte(); + + char textBuf[32]; +}; + + + +#endif /* RECEIVER3BYTEKEY_H_ */ diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.cpp b/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.cpp new file mode 100644 index 0000000..7ba16a1 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.cpp @@ -0,0 +1,49 @@ +/* + * ReceiverAiggend.cpp + * + * Created on: 21.10.2020 + * Author: flori + */ +#include "main.h" +#include "Receiver3ByteKey.h" +#include "ReceiverAiggend.h" + +/*******************************************************************/ +#define KEY_NIBBLE_OPEN 0x0A +#define KEY_NIBBLE_CLOSE 0x0E + +#define NUM_KEYS_AIGGEND 4u + +/*******************************************************************/ + +static const char* nameAiggend = "Aiggend"; + +static const uint8_t keysAiggend[NUM_KEYS_AIGGEND * (NUM_BYTES_PER_KEY+1u) ] = +{ + //0b10101110, 0b10110010, 0b00001010 , // 10101110 10110010 0000 1010 0 AUF, 10101110 10110010 0000 1110 0 ZU + 0xae, 0xb2, 0x0a , 0x0e, + 0xa4, 0x30, 0x0a , 0x0e, // 0xa auf, zu: 0xe + 0xa1, 0x4a, 0x0a , 0x0e, // 0xa auf, zu: 0xe + 0xe6, 0x80, 0x46 , 0x49 // 0x49 auf, zu 0x46 +}; + +/*******************************************************************/ + +ReceiverAiggend receiverAiggend; + +/*******************************************************************/ + + +ReceiverAiggend::ReceiverAiggend() : Receiver3ByteKey() +{ + config.name = nameAiggend; + config.tShortMin = 370u; + config.tShortMax = 680u; + config.tLongMin = 1100u; + config.tLongMax = 1540u; + config.numberKeys = NUM_KEYS_AIGGEND; + config.keys = keysAiggend; +} + + + diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.h b/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.h new file mode 100644 index 0000000..ac12f72 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverAiggend.h @@ -0,0 +1,23 @@ +/* + * ReceiverAiggend.h + * + * Created on: 21.10.2020 + * Author: flori + */ + +#ifndef RECEIVERAIGGEND_H_ +#define RECEIVERAIGGEND_H_ + +#include "Receiver3ByteKey.h" + + +class ReceiverAiggend : public Receiver3ByteKey +{ +public: + ReceiverAiggend(); +}; + + +extern ReceiverAiggend receiverAiggend; + +#endif /* RECEIVERAIGGEND_H_ */ diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.cpp b/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.cpp new file mode 100644 index 0000000..8b51c87 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.cpp @@ -0,0 +1,46 @@ +/* + * ReceiverKerui.cpp + * + * Created on: 12.10.2022 + * Author: flori + */ +#include "main.h" +#include "ReceiverKerui.h" + +/*******************************************************************/ + +#define KEY_NIBBLE_OPEN 0x0E +#define KEY_NIBBLE_CLOSE 0x07 +#define NUM_KEYS_KERUI 3u + +/*******************************************************************/ + +static const char* nameKerui = "Kerui"; + +static const uint8_t keysKerui[NUM_KEYS_KERUI* (NUM_BYTES_PER_KEY+1u) ] = +{ + + 0x3c, 0xf3, 0x0E, 0x07 , /* key, key, open, close */ + 0xea, 0x3a, 0x0E, 0x07 , + 0xbd, 0x14, 0x0E, 0x07 +}; + +/*******************************************************************/ + +ReceiverKerui receiverKerui = ReceiverKerui(); + +/*******************************************************************/ + +ReceiverKerui::ReceiverKerui() : Receiver3ByteKey() +{ + config.name = nameKerui; + config.tShortMin = 250u; + config.tShortMax = 450u; + config.tLongMin = 850u; + config.tLongMax = 1150u; + config.numberKeys = NUM_KEYS_KERUI; + config.keys = keysKerui; +} + + + diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.h b/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.h new file mode 100644 index 0000000..13adc27 --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverKerui.h @@ -0,0 +1,22 @@ +/* + * ReceiverKerui.h + * + * Created on: 12.10.2022 + * Author: flori + */ + +#ifndef RECEIVERKERUI_H_ +#define RECEIVERKERUI_H_ + +#include "Receiver3ByteKey.h" + +class ReceiverKerui : public Receiver3ByteKey +{ +public: + ReceiverKerui(); +}; + + +extern ReceiverKerui receiverKerui; + +#endif /* RECEIVERKERUI_H_ */ diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverOval.cpp b/src/Receivers433/Receivers3ByteKeys/ReceiverOval.cpp new file mode 100644 index 0000000..d9a054d --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverOval.cpp @@ -0,0 +1,52 @@ +/* + * ReceiverOval.cpp + * + * Created on: 12.10.2022 + * Author: flori + */ +#include "main.h" +#include "ReceiverOval.h" + + +/*******************************************************************/ +#define KEY_NIBBLE_OPEN 0x03 +#define KEY_NIBBLE_CLOSE 0x09 + +#define NUM_KEYS_OVAL 6u + +/*******************************************************************/ + +static const char* nameOval = "Oval"; + +static const uint8_t keysOval[NUM_KEYS_OVAL * (NUM_BYTES_PER_KEY+1u)] = +{ + 0xdc, 0x86, 0x03 , 0x09, // 0x3 auf 0x9 zu, + 0x30, 0xa5, 0x03 , 0x09, // 0x3 auf 0x9 zu, + 0x4c, 0xe6, 0x03 , 0x09, // 0x3 auf 0x9 zu, + 0x74, 0xa5, 0x03 , 0x09, // 0x3 auf 0x9 zu, + 0x29, 0x66, 0x03 , 0x09, // 0x3 auf 0x9 zu, + 0xe4, 0x0f, 0x76 , 0x79 // 0x3 auf 0x9 zu, +}; + +/*******************************************************************/ + +ReceiverOval receiverOval; + +/*******************************************************************/ + + +ReceiverOval::ReceiverOval() : Receiver3ByteKey() +{ + config.name = nameOval; + config.tShortMin = 320u; + config.tShortMax = 510u; + config.tLongMin = 1100u; + config.tLongMax = 1330u; + config.numberKeys = NUM_KEYS_OVAL; + config.keys = keysOval; +} + + + + + diff --git a/src/Receivers433/Receivers3ByteKeys/ReceiverOval.h b/src/Receivers433/Receivers3ByteKeys/ReceiverOval.h new file mode 100644 index 0000000..f7800ff --- /dev/null +++ b/src/Receivers433/Receivers3ByteKeys/ReceiverOval.h @@ -0,0 +1,23 @@ +/* + * ReceiverOval.h + * + * Created on: 12.10.2022 + * Author: flori + */ + +#ifndef RECEIVEROVAL_H_ +#define RECEIVEROVAL_H_ + +#include "Receiver3ByteKey.h" + + +class ReceiverOval : public Receiver3ByteKey +{ +public: + ReceiverOval(); +}; + + +extern ReceiverOval receiverOval; + +#endif /* RECEIVEROVAL_H_ */ diff --git a/src/Seconds.cpp b/src/Seconds.cpp new file mode 100644 index 0000000..41ae1be --- /dev/null +++ b/src/Seconds.cpp @@ -0,0 +1,30 @@ +/* + * Seconds.cpp + * + * Created on: 10.09.2020 + * Author: flori + */ +#include "Seconds.h" + +uint32_t Seconds::lastMillisShifted = 0; +uint32_t Seconds::seconds = 0; +uint32_t Seconds::secondsOverflow = 0; +boolean volatile Seconds::semaphore = false; + + + +uint32_t Seconds::Get(void) +{ + uint32_t secRet; + uint32_t secNow = millis() / 1000; + + if (secNow < seconds) + { + secondsOverflow += seconds + 1; + } + seconds = secNow; + + secRet = seconds + secondsOverflow; + + return secRet; +} diff --git a/src/Seconds.h b/src/Seconds.h new file mode 100644 index 0000000..c48412f --- /dev/null +++ b/src/Seconds.h @@ -0,0 +1,25 @@ +/* + * Seconds.h + * + * Created on: 10.09.2020 + * Author: flori + */ + +#ifndef SECONDS_H_ +#define SECONDS_H_ + +#include "Arduino.h" + +class Seconds +{ +public: + static uint32_t Get(); + +private: + static uint32_t lastMillisShifted; + static uint32_t seconds; + static uint32_t secondsOverflow; + static volatile boolean semaphore; +}; + +#endif /* SECONDS_H_ */ diff --git a/src/UpdateHandler.cpp b/src/UpdateHandler.cpp new file mode 100644 index 0000000..4f622cd --- /dev/null +++ b/src/UpdateHandler.cpp @@ -0,0 +1,119 @@ +/* + * UpdateHandler.c + * + * Created on: 04.08.2023 + * Author: flori + */ + +#include "WebServer.h" +#include +#include "Version.h" + +WebServer webServer; + +const char* serverIndex = +"" +"
" PROJECT_NAME " " VERSION_STR "

" +"
" + "" + "" + "
" + "
progress: 0%
" + ""; + + +void UpdateHandler() +{ + static bool initDone = false; + if (false == WiFi.isConnected()) + { + initDone = false; + } + else + { + if (initDone == false) + { + initDone = true; + webServer.on("/", HTTP_GET, []() + { + Serial.printf("HTTP_GET"); + webServer.sendHeader("Connection", "close"); + webServer.send(200, "text/html", serverIndex); + }); + + /*handling uploading firmware file */ + webServer.on("/update", HTTP_POST, []() + { + webServer.sendHeader("Connection", "close"); + webServer.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); + ESP.restart(); + }, []() + { + HTTPUpload& upload = webServer.upload(); + if (upload.status == UPLOAD_FILE_START) + { + Serial.printf("Update: %s\n", upload.filename.c_str()); + if (!Update.begin(UPDATE_SIZE_UNKNOWN)) + { //start with max available size + Update.printError(Serial); + } + } + else if (upload.status == UPLOAD_FILE_WRITE) + { + /* flashing firmware to ESP*/ + if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) + { + Update.printError(Serial); + } + } + else if (upload.status == UPLOAD_FILE_END) + { + if (Update.end(true)) + { //true to set the size to the current progress + Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); + } + else + { + Update.printError(Serial); + } + } + }); + webServer.begin(80u); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + Serial.printf("webServer init done"); + } + webServer.handleClient(); + } + +} + + diff --git a/src/UpdateHandler.h b/src/UpdateHandler.h new file mode 100644 index 0000000..898c51d --- /dev/null +++ b/src/UpdateHandler.h @@ -0,0 +1,15 @@ +/* + * UpdateHandler.h + * + * Created on: 04.08.2023 + * Author: flori + */ + +#ifndef UPDATEHANDLER_H_ +#define UPDATEHANDLER_H_ + + +void UpdateHandler(void); + + +#endif /* UPDATEHANDLER_H_ */ diff --git a/src/Version.h b/src/Version.h new file mode 100644 index 0000000..119cc08 --- /dev/null +++ b/src/Version.h @@ -0,0 +1,21 @@ +/* + * Version.h + * + * Created on: 04.08.2023 + * Author: flori + */ + +#ifndef VERSION_H_ +#define VERSION_H_ + +#include "main.h" + +#if VERSION_DG_ONLY +#define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_DG" +#else +#define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_EG" +#endif +#define VERSION_STR "v1.3.2" + + +#endif /* VERSION_H_ */ diff --git a/src/fensterPIEP.cpp b/src/fensterPIEP.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/fensterPIEP.h b/src/fensterPIEP.h new file mode 100644 index 0000000..c6edc43 --- /dev/null +++ b/src/fensterPIEP.h @@ -0,0 +1,22 @@ +// Only modify this file to include +// - function definitions (prototypes) +// - include files +// - extern variable definitions +// In the appropriate section + +#ifndef _fensterPIEP_H_ +#define _fensterPIEP_H_ +#include "Arduino.h" +//add your includes for the project fensterPIEP here + + +//end of add your includes here + + +//add your function definitions for the project fensterPIEP here + + + + +//Do not add code below this line +#endif /* _fensterPIEP_H_ */ diff --git a/src/fensterPiepser_NodeMCU_32S.cpp b/src/fensterPiepser_NodeMCU_32S.cpp new file mode 100644 index 0000000..865d74b --- /dev/null +++ b/src/fensterPiepser_NodeMCU_32S.cpp @@ -0,0 +1,635 @@ + +#include "ReceiverSmartWares.h" +#include "ReceiverAiggend.h" +#include "ReceiverOval.h" +#include "ReceiverKerui.h" +#include "ReceiverFunkThermometer.h" +#include "PiepMode.h" +#include "PiepPattern.h" +#include "LedBlinker.h" +#include "Fenster.h" +#include "Display.h" +#include "Display_SSD1306.h" +#include "Seconds.h" +#include "DataSender.h" +#include "InterruptHandler.h" +#include "xcp/XcpPort.h" +#include "UpdateHandler.h" +#include "main.h" +#include "Version.h" +#include "WiFi.h" +#include "time.h" + + +/* + * platform esp32/1.0.6 + * NodeMCU-32S + * FlashFreq 80MHz + * Upload Speed 921600 + * + * + * LIBRARIES : + * ----------- + * Adafruit_BusIO + * Adafruit_GFX_Library + * Adafruit_ST7735_and_ST7789_Library + * ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays + * FS + * SPI + * Update + * WebServer + * WiFi + * Wire + * + */ + +/* COM PORT : Silicon Labs CP210x USB to UART Bridge */ + +/*---------------- DEFINES ------------- */ + +#define TEST_PIEPEN_BEI_START 0 +#define SECONDS_TO_DECIS(x) ((DeciSeconds_t)10UL*x) +#define MINUTES_TO_DECIS(x) ((DeciSeconds_t)600UL*x) +#define MINUTES_TO_SECONDS(x) (60*x) +#define DAYS_TO_MILLIS(x) ((x)*24UL*3600UL*1000UL) +#define SERIAL_PRINT(x) Serial.print(x) + +#define AIGGEND_KEY_INDEX_OFFSET 30u +#define OVAL_KEY_INDEX_OFFSET 40u +#define KERUI_KEY_INDEX_OFFSET 50u + +#define TONE_FREQUENCY_HZ 2000 + +#define USE_XCP (1u) +#define USE_WIFI (1u) /* WARNING, no OTA update without wifi ! */ +#define USE_DATASENDER (0u) +/*---------------- GLOBAL VARIABLES ------------- */ + +uint32_t gtMillis; +char textBuf[100]; +DeciSeconds_t waitTimeDs = 0; /* in deciSeconds */ +DeciSeconds_t tDecis = 0; +uint8_t numberWindowsOpen = 0; +ReceiverFunkThermometerData_t thermoData = {0, 0}; +bool bRequestShortBeep = false; +bool bIsNightTime = false; + +PiepPattern *piepPattern; + +/* + * every sensor type has a list of keys, index starting at 0. + * the handleKeyReceived adds a offset for each sensor type. + * in the config here, the key must be configured with resulting sum. + */ +/* SMART WARES */ +Fenster fensterGefrier("Gefrier" ,10); +/* Aiggend keys */ +Fenster fensterWz("Wohnz", 2 + KERUI_KEY_INDEX_OFFSET); /* NICHT GENUTZT AKTUELL */ +Fenster fensterFlo("Flo", 2 + AIGGEND_KEY_INDEX_OFFSET); +Fenster fensterBadUnten("Bad u", 3 + AIGGEND_KEY_INDEX_OFFSET); + +/* OVAL keys */ +Fenster fensterKeller("Keller", 0 + OVAL_KEY_INDEX_OFFSET); +Fenster fensterToniNeu("Toni", 1 + OVAL_KEY_INDEX_OFFSET); +Fenster fensterKueche("Kueche", 2 + OVAL_KEY_INDEX_OFFSET); +Fenster fensterWz2("Wohnz", 3 + OVAL_KEY_INDEX_OFFSET); +Fenster fensterFloBuero("Buero", 4 + OVAL_KEY_INDEX_OFFSET); +Fenster fensterHanna("Hanna", 5 + OVAL_KEY_INDEX_OFFSET); +/** */ +Fenster fensterGaeste("Gaeste" , 1 + KERUI_KEY_INDEX_OFFSET); +Fenster fensterBadOben("Bad o", 1 + AIGGEND_KEY_INDEX_OFFSET); + +#if VERSION_SMALL_DISPLAY + +#if VERSION_DG_ONLY /* DACHGESCHOSS */ +Fenster* alleFenster[NUM_FENSTER] = + { + &fensterBadOben, &fensterFlo, &fensterHanna, &fensterFloBuero , //OG + }; +#else +Fenster* alleFenster[NUM_FENSTER] = + { + &fensterWz, &fensterBadUnten, &fensterKueche, &fensterToniNeu , //EG + }; +#endif + + +#else +#ifdef VERSION_BIG_DISPLAY +Fenster* alleFenster[NUM_FENSTER] = + { + &fensterBadUnten, &fensterKueche, &fensterWz, &fensterWz2, &fensterToniNeu, &fensterGefrier,//EG + &fensterKeller, &fensterGaeste //KG + }; +#else +Fenster* alleFenster[NUM_FENSTER] = + { + &fensterBadOben, &fensterFlo, &fensterHanna, &fensterFloBuero , //OG + &fensterBadUnten, &fensterKueche, &fensterWz, &fensterWz2, &fensterToniNeu, &fensterGefrier,//EG + &fensterKeller, &fensterGaeste //KG + }; +#endif +#endif + +uint32_t loopCountSincePause = 0u; +uint8_t toneRequest = 0u; + +/*---------------- LOCAL VARIABLES ------------- */ +static PiepMode *piepFast, *piepSlow, *piepPauseLong, *piepPauseShort; +static PiepMode *piepModes[3]; +static int8_t manualKeyNo = -1; +static bool manualKeyDirection = false; +static bool bUpdateDisp = false; +static uint32_t tBeepingStartWithoutWindowClose = 0u; + +/*---------------- LOCAL FUNCTIONS ------------- */ + +static void handleManualInputRequest(); +static void updateWaittime(void); +static void xcpLoop(void); +#ifdef TEST_WAITTIME +static void testWaitTime(void); +#endif +static void handleDispUpdate(void); +static void handleKeyReceived(void); +static void updateIsNighttime(); +static void updatePiepPattern(void); + + +/** + * + */ +void setup() +{ +#if USE_XCP + XcpInit(); +#endif + +#if USE_WIFI + static const char* ssidElektro = "Elektrosmog"; + static const char* password = "r4g8f-xz5av"; + WiFi.setHostname(PROJECT_NAME); + WiFi.mode(WIFI_STA); + WiFi.begin(ssidElektro, password); + + dataSender.onSetup(); + + const char* ntpServer = "ptbtime3.ptb.de"; + const long gmtOffset_sec = 3600; + const int daylightOffset_sec = 3600; + configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); +#endif + + /* setup pins receiver */ + pinMode(DOUT_TEST_TIMER, OUTPUT); digitalWrite(DOUT_TEST_TIMER, HIGH); + pinMode(DOUT_FUNK_VCC, OUTPUT); digitalWrite(DOUT_FUNK_VCC, HIGH); + pinMode(DOUT_FUNK_GND, OUTPUT); digitalWrite(DOUT_FUNK_GND, LOW); + pinMode(DOUT_PIEP_VCC, OUTPUT); + pinMode(DIN_FUNK, INPUT_PULLUP); + + /* TONE SETUP */ + ledcSetup(TONE_PWM_CHANNEL, TONE_FREQUENCY_HZ, 8); + ledcAttachPin(DOUT_PIEP_PWM, TONE_PWM_CHANNEL); + ledcWrite(TONE_PWM_CHANNEL, 127); + + /* setup Serial */ + Serial.begin(115200uL); + Serial.println(F("\n---\nOK\n")); + + /* Piep times based on 33.3ms */ + /* setup Piep mode fast*/ + piepFast = new PiepMode(); + piepFast->onTime = MS_TO_ISR_COUNT(20uL); + piepFast->offTime = MS_TO_ISR_COUNT(80uL); + piepFast->requestCount = 2u; + /* setup Piep mode slow*/ + piepSlow = new PiepMode(); + piepSlow->onTime = MS_TO_ISR_COUNT(500uL); + piepSlow->offTime = MS_TO_ISR_COUNT(100uL); + piepSlow->requestCount = 1u; + /* setup Piep mode pause*/ + piepPauseLong = new PiepMode(); + piepPauseLong->onTime = 0u; + piepPauseLong->offTime = MS_TO_ISR_COUNT(1000uL); /* 1s */ + piepPauseLong->requestCount = 120u; /* 60s pause */ + piepPauseShort = new PiepMode(); + piepPauseShort->onTime = 0u; + piepPauseShort->offTime = MS_TO_ISR_COUNT(1000uL); /* 1s */ + piepPauseShort->requestCount = 20u; /* 10s pause */ + /* setup Piep pattern*/ + piepPattern = new PiepPattern(); + piepPattern->numberModes = 3u; + piepPattern->requestCount = 0u; + piepPattern->piepModes = piepModes; + piepPattern->piepModes[0] = piepFast; + piepPattern->piepModes[1] = piepSlow; + piepPattern->piepModes[2] = piepPauseLong; + +#if TEST_PIEPEN_BEI_START + /* start piep pattern (just for debugging, uncomment stopping in loop for debugging)*/ + piepPattern->Start(DOUT_PIEP_PWM); +#endif + + InterruptHandler_Init(); + + display.Init(); + + updateWaittime(); +#ifdef TEST_WAITTIME + testWaitTime(); +#endif + +} + +/** + * + */ +void loop() +{ + handleKeyReceived(); + + handleDispUpdate(); + +#if USE_WIFI + //updateIsNighttime(); + +#if USE_DATASENDER + dataSender.onLoop(); +#endif + + UpdateHandler(); +#endif + + updatePiepPattern(); + +#if USE_XCP + xcpLoop(); +#endif + + /* reset ECU every day */ + if (millis() > DAYS_TO_MILLIS(1uL) && numberWindowsOpen == 0) + { + Serial.print("RESET"); + ESP.restart(); + } + + loopCountSincePause++; +} + +static void handleDispUpdate(void) +{ + /* cyclically request display update */ + + static DeciSeconds_t nextDispUpdateDecis = 0; + if (tDecis > nextDispUpdateDecis || bUpdateDisp) + { + bUpdateDisp = true; + if (numberWindowsOpen > 0) + { + nextDispUpdateDecis = tDecis + SECONDS_TO_DECIS(1u); + } + else + { + nextDispUpdateDecis = tDecis + SECONDS_TO_DECIS(10u); + } + } + + + /* update display if requested*/ + if (bUpdateDisp) + { + //noInterrupts(); + bUpdateDisp = false; + display.Update(); + //interrupts(); + } +} + + +static void updateIsNighttime() +{ + static DeciSeconds_t nextUpdateDecis = SECONDS_TO_DECIS(120u); + + if (tDecis > nextUpdateDecis ) + { + struct tm timeinfo; + if (!getLocalTime(&timeinfo, 100u)) + { + Serial.println("Failed to obtain time"); + nextUpdateDecis = tDecis + SECONDS_TO_DECIS(120u); + return; + } + else + { + nextUpdateDecis = tDecis + SECONDS_TO_DECIS(120u); + bIsNightTime = (timeinfo.tm_hour >= 22 || timeinfo.tm_hour < 6); + if (bIsNightTime) + { + Serial.print("\nNIGHT"); + } + else + { + Serial.print("\nDAY"); + } + } + } +} + + +/** + * reduce paus time after x minutes, when beep is active + * + */ +static void updatePiepPattern(void) +{ + +#if TEST_PIEPEN_BEI_START + piepPattern->piepModes[2] = piepPauseShort; +#else + if (tBeepingStartWithoutWindowClose == 0u) + { + piepPattern->piepModes[2] = piepPauseLong; + } + else if ((Seconds::Get() - tBeepingStartWithoutWindowClose) < MINUTES_TO_SECONDS(6u) ) /* reduce pause time after x mintues */ + { + piepPattern->piepModes[2] = piepPauseLong; + } + else + { + piepPattern->piepModes[2] = piepPauseShort; + } +#endif +} + + +/**/ +static void handleKeyReceived(void) +{ + int8_t lastKey = - 1; /* lastKey gets an offset for each receiver type */ + bool lastKeyDirection = DIRECTION_CLOSE; + + //delay(10); + + //handleManualInputRequest(); + if (manualKeyNo >= 0) + { + lastKey = manualKeyNo; + lastKeyDirection = manualKeyDirection; + } + if (lastKey < 0) + { + /* first check if a SW key was received */ + lastKey = receiverSw.GetLastReceivedKeyNum(); + if (lastKey >= 0) + { + receiverSw.ResetReceivedKeyNum(); + lastKeyDirection = receiverSw.GetLastReceivedDirection(); + } + } + if (lastKey < 0) /* if no SW key was received, check if a aiggend key was received */ + { + lastKey = receiverAiggend.GetLastReceivedKeyNum(); + if (lastKey >= 0) + { + receiverAiggend.ResetReceivedKeyNum(); + lastKey += AIGGEND_KEY_INDEX_OFFSET; + lastKeyDirection = receiverAiggend.GetLastReceivedDirection(); + #if 0 + Serial.println("--"); + for (uint32_t i=0; i<24; i++) + { + Serial.println(receiverAiggend.buft[i]); + } + receiverAiggend.startBuffering(); + #endif + } + } + if (lastKey < 0) + { + lastKey = receiverOval.GetLastReceivedKeyNum(); + if (lastKey >= 0) + { + receiverOval.ResetReceivedKeyNum(); + lastKey += OVAL_KEY_INDEX_OFFSET; + lastKeyDirection = receiverOval.GetLastReceivedDirection(); + } + } + if (lastKey < 0) + { + lastKey = receiverKerui.GetLastReceivedKeyNum(); + if (lastKey >= 0) + { + receiverKerui.ResetReceivedKeyNum(); + lastKey += KERUI_KEY_INDEX_OFFSET; + lastKeyDirection = receiverKerui.GetLastReceivedDirection(); + } + } + + /* read the thermo data and update wait time */ + if (receiverThermo.HasNewData()) + { + thermoData = receiverThermo.GetData(); + receiverThermo.ResetNewData(); + bUpdateDisp = true; + /* + char buf[16]; + sprintf(buf, "\n%d.%dC %d%%", (int)floor(thermoData.temp), (int) floor(thermoData.temp*10) -(int) floor(thermoData.temp)*10, (int)floor(thermoData.rh)); + Serial.print(buf); + */ + + /* update wait time according to temperature */ + updateWaittime(); + } + + + /* handle windows and possibly start/stop beep pattern */ + { + static bool shallPiepPrevious = false; + bool shallPiepNew = false; + uint8_t numberWindowsOpenNew = 0; + for (uint8_t i = 0; i < NUM_FENSTER; i++) + { + bool bWindowChanged = alleFenster[i]->HandleKey(lastKey, lastKeyDirection); + numberWindowsOpenNew += alleFenster[i]->IsOpen() ? 1 : 0; + shallPiepNew |= alleFenster[i]->ShallPiep(); + + if (bWindowChanged) + { + bUpdateDisp = true; + dataSender.requestSend(); + bRequestShortBeep = true; + if (lastKeyDirection == DIRECTION_CLOSE) + { + tBeepingStartWithoutWindowClose = 0u; + } + } + } + + /* possibly stop or start beeping */ + if (bIsNightTime) + { +#if (TEST_PIEPEN_BEI_START == 0) + piepPattern->Stop(); +#endif + } + else if (false == shallPiepNew) + { +#if (TEST_PIEPEN_BEI_START == 0) + piepPattern->Stop(); +#endif + } + else if ((true == shallPiepNew) && (false == shallPiepPrevious)) + { + tBeepingStartWithoutWindowClose = Seconds::Get(); + piepPattern->Start(DOUT_PIEP_PWM); + bUpdateDisp = true; + } + shallPiepPrevious = shallPiepNew; + numberWindowsOpen = numberWindowsOpenNew; + } + + if (numberWindowsOpen == 0u) + { + tBeepingStartWithoutWindowClose = 0u; + } +} + +#ifdef TEST_WAITTIME +static void testWaitTime() +{ + thermoData.rhPercent = 5; + float tempC; + for (tempC = -10; tempC < 30; tempC += 0.5f) + { + thermoData.tempC = tempC; + updateWaittime(); + Serial.print(tempC); + Serial.print(" "); + Serial.print(waitTimeDs); + Serial.print("\n"); + } +} +#endif + +/** + * + */ +static void updateWaittime(void) +{ + /** < -5 : 5min + * -5 .. 19 : 5..30 min min = 5 + t- (-5) * (30-5) / (19- (-5) ) ; + * >19 : inf + * >25 : 30 min + */ + if (thermoData.rhPercent > 0.0f) + { + /* VALUE RECEIVED */ + if (thermoData.tempC > 25.0f) + { + waitTimeDs = MINUTES_TO_DECIS(30); + } + else if (thermoData.tempC > 19.5f) + { + waitTimeDs = MINUTES_TO_DECIS(60*24*14); //zwei Wochen = unendlich + } + else if (thermoData.tempC < -5.0f) + { + waitTimeDs = MINUTES_TO_DECIS(5); + piepPauseLong->requestCount = 20; + } + else + { + const float dy = 30.0f-5.0f; + const float dx = 19.5f-(-5.0f); + float minutes = 5.0f + (thermoData.tempC-(-5.0f)) * dy / dx ; + waitTimeDs = (DeciSeconds_t)(600.0f * minutes); + } + } + else + { + /* DEFAULT IF NO VALUE WAS RECEIVED YET*/ +#if 0 + /* calculate the wait Time from the poti value */ + waitTimeDs = ((DeciSeconds_t) analogRead(AIN_POTI) + * MINUTES_TO_DECIS(19UL)) / 1023UL; /* max 19 minutes */ + waitTimeDs += MINUTES_TO_DECIS(1UL); /* minimum 1 Minute */ +#endif + waitTimeDs = MINUTES_TO_DECIS(10); + } +} + + +/** + * im serial monitor zwei zahlen mit leerzeichen eingeben, um einen key zu senden : + * 1 1 sendet key 1 an, + * 2 0 sendet key 2 aus,.. + */ +static void handleManualInputRequest() +{ + if (Serial.available()) + { + char buf[10]; + size_t numBytesRead = Serial.readBytesUntil(' ', buf, 10); + if (numBytesRead > 0) + { + buf[numBytesRead] = '\0'; + int n1; + sscanf(buf, "%d", &n1); + Serial.print(n1); + Serial.print(" n1 \n"); + + numBytesRead = Serial.readBytesUntil(' ', buf, 10); + if (numBytesRead > 0) /* send key */ + { + buf[numBytesRead] = '\0'; + int n2; + sscanf(buf, "%d", &n2); + Serial.print(n2); + Serial.print(" n2 \n"); + + if (n1 > 0 && n2 >= 0 && n2 <= 1) + { + manualKeyNo = n1; + manualKeyDirection = n2; + } + } + } + } +} + +#if USE_XCP +static void xcpLoop(void) +{ + static uint32_t tNext10ms = 0; + static uint32_t tNext100ms = 0; + static uint32_t tNext500ms = 0; + static uint32_t tNext1000ms = 0; + + /* trigger events */ + if (millis() >= tNext10ms) + { + tNext10ms += 10; + XcpEvent(0); + } + if (millis() >= tNext100ms) + { + tNext100ms += 100; + XcpEvent(1); + } + if (millis() >= tNext500ms) + { + tNext500ms += 500; + XcpEvent(2); + + + } + if (millis() >= tNext1000ms) + { + tNext1000ms += 1000; + XcpEvent(3); + } + + XcpPoll(); + XcpSendLoop(); +} +#endif diff --git a/src/fensterPiepser_NodeMCU_32S.h b/src/fensterPiepser_NodeMCU_32S.h new file mode 100644 index 0000000..f35def7 --- /dev/null +++ b/src/fensterPiepser_NodeMCU_32S.h @@ -0,0 +1,12 @@ +// Only modify this file to include +// - function definitions (prototypes) +// - include files +// - extern variable definitions +// In the appropriate section + +#ifndef _fenster_PIEPSER_NodeMCU32S_H_ +#define _fenster_PIEPSER_NodeMCU32S_H_ + +/* USE main.h */ + +#endif /* _fenster_PIEPSER_NodeMCU32S_H_ */ diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..a68e232 --- /dev/null +++ b/src/main.h @@ -0,0 +1,100 @@ +/* + * main.h + * + * Created on: 22.02.2020 + * Author: flori + */ + +#ifndef MAIN_H_ +#define MAIN_H_ + +/* -------------- INCLUDES --------------*/ + +#include "Arduino.h" +#include "typedefs.h" +#include "PiepPattern.h" +#include "ReceiverFunkThermometer.h" +#include "Fenster.h" + + +/* --------------- TYPEDEFS -------------*/ + + +/* --------- SYMBOLIC CONSTANTS ---------*/ + +#define VERSION_DG_ONLY 0 + +#define VERSION_SMALL_DISPLAY 1 + +#define VERSION_BIG_DISPLAY (! VERSION_SMALL_DISPLAY) + +/* singal pins */ + + +#define TFT_PIN_CLK 14 /* SCK */ +#define TFT_PIN_MOSI 13 /* SDA */ +#define TFT_PIN_RST 22 // RES +#define TFT_PIN_DC 21 // RS (Data/Command = Register select) +#define TFT_PIN_CS 15 /* CS Chip select */ + +#define DOUT_TEST_TIMER 16 +#define DOUT_FUNK_VCC 12 +#define DOUT_FUNK_GND 32 +#define DIN_FUNK 26 + +#define DOUT_PIEP_PWM 33 +#define DOUT_PIEP_VCC 18 + +#define TONE_PWM_CHANNEL 12 +#define TONE_REQUEST_ON(source) toneRequest |= (1u< check if the buffer has space left + * 2. getWritePointer returns the pointer to the element + * that can be written on (or NULL if writing is forbidden) + * 3. write moves the write index to the next position and thereby + * signals that the just written element can be read now + * + * reading is done by + * 1. canRead -> check if there are elements that have been written + * but not yet read + * 2. getReadPointer : returns pointer to the next available element + * and increments the read index. Reading from the pointer + * is safe (data will not be overwritten) until the next call of + * getReadPointer + * + */ + +template class RingBuffer +{ + public: + /** + * The RingBuffer does not create the underlying array itself, it must be + * created outside. + * \param : array : pointer to first element of the array + * arraySize : number of elements in the array + */ + RingBuffer(T * array, uint32_t arraySize) + { + this->array = array; //constant + this->arraySize = arraySize; //constant + + iBufEnd = arraySize-1; + iWrite = 0; + iRead = 0; + } + + /** + * return if the buffer has at least one element left to write on + * without overwriting unread elements + */ + bool canWrite(void) + { + return iWrite != iBufEnd; + } + + /** + * returns NULL if write is not permitted! + * (Check can be done with canWrite()) + * When the writing to the pointer is finished call write()! + */ + T* getWritePointer(void) + { + T* pWrite = NULL; + if (canWrite()) + { + pWrite = &array[iWrite]; + } + return pWrite; + } + + /** + * to be called as soon as the data has been written. + * Don't put this into getWritePointer to allow reading + * the element immediately + */ + void write(void) + { + if ( canWrite() ) + { + /* should always be true, otherwise there was an error before */ + if (++iWrite==arraySize){ + iWrite = 0; //wrap + } + } + } + + /** + * return true if there are elements that can be read + */ + bool canRead(void) + { + return iRead != iWrite; + } + + /** + * return the number of received elements that haven't been read yet + */ + uint32_t getNumberUnread(void) + { + uint32_t numUnread; + if ( iRead == iWrite ) + { + numUnread = 0; + } + else if ( iWrite > iRead ) + { + numUnread = iWrite-iRead; + } + else + { + numUnread = arraySize + iWrite - iRead; + } + return numUnread; + } + + /** + * get Pointer to next received frame that hasn't been read yet. + * the data will be safe to read until the next call of the function + * (because array[iBufEnd] will not be overwritten) + * The function increments the read index, so it may only be called once per element + */ + T* getReadPointer(void) + { + T* pEntry = &array[iRead]; + iBufEnd = iRead; + if (++iRead==arraySize){ + iRead = 0; //wrap + } + return pEntry; + } + + private: + T* array; + uint32_t arraySize; + uint32_t iWrite; + uint32_t iRead; + uint32_t iBufEnd; +}; + + +#endif diff --git a/src/xcp/XcpAppInterface.h b/src/xcp/XcpAppInterface.h new file mode 100644 index 0000000..7388a9e --- /dev/null +++ b/src/xcp/XcpAppInterface.h @@ -0,0 +1,19 @@ +/* + * XcpApplInterface.h + * + * Created on: 30.07.2022 + * Author: flori + */ + +#ifndef XCP_XCPAPPINTERFACE_H_ +#define XCP_XCPAPPINTERFACE_H_ + +#include "xcp_cfg.h" + +extern const vuint8 kXcpEventDirection[kXcpMaxEvent]; //DAQ +extern const vuint8 kXcpEventCycle[kXcpMaxEvent]; +extern const vuint8 kXcpEventUnit[kXcpMaxEvent]; +extern const char kXcpEventName[kXcpMaxEvent][7]; +extern const vuint8 kXcpEventNameLength[kXcpMaxEvent]; + +#endif /* XCP_XCPAPPINTERFACE_H_ */ diff --git a/src/xcp/XcpApplnterface.cpp b/src/xcp/XcpApplnterface.cpp new file mode 100644 index 0000000..2c2aaf4 --- /dev/null +++ b/src/xcp/XcpApplnterface.cpp @@ -0,0 +1,139 @@ +/* + * XcpApplnterface.c + * + * Created on: 30.07.2022 + * Author: flori + */ + +/****************************************************************************/ +#include "XcpBasic.h" +#include "XcpFrameReceiver.h" +#include "XcpDriverCom.h" + +#include "XcpAppInterface.h" + + +/****************************************************************************/ +#define XCPFRAME_BUFFERSIZE 5 /* x frames are sufficient */ + +/****************************************************************************/ +const vuint8 kXcpEventDirection[kXcpMaxEvent] = { 4, 4, 4, 4 }; //DAQ +const vuint8 kXcpEventCycle[kXcpMaxEvent] = { 1, 1, 5, 1 }; +const vuint8 kXcpEventUnit[kXcpMaxEvent] = { 7, 8, 8, 9 }; +const char kXcpEventName[kXcpMaxEvent][7] = { {"10ms "}, {"100ms "}, {"500ms "}, {"1000ms"}}; +const vuint8 kXcpEventNameLength[kXcpMaxEvent] = { 4, 5, 5, 6 }; + +/****************************************************************************/ +static XcpFrame tlComXcpRxPackets[XCPFRAME_BUFFERSIZE]; +static XcpFrameReceiver xcpFrameReceiver( tlComXcpRxPackets, XCPFRAME_BUFFERSIZE, false ); +#define XCP_SEND_BUFFER_SIZE 10u +static XcpFrame sendBuffer[XCP_SEND_BUFFER_SIZE]; +static vuint16 xcpSendBufWritePos = 0; +static vuint16 xcpSendBufReadPos = 0; + +/****************************************************************************/ + +/** + * + */ +void XcpPoll() +{ + /* receive message */ + if (XCP_COM_AVAILABLE()) + { + while (XCP_COM_AVAILABLE()) + { + uint8_t serData = XCP_COM_READ(); + if (xcpFrameReceiver.hasSpace()) + { + xcpFrameReceiver.putData(1, &serData); + } + if (xcpFrameReceiver.hasFrames()) + { + XcpFrame *pFrame = xcpFrameReceiver.getFrame(); + XcpCommand(pFrame->data.u32); + break; + } + } + } +} + +/** + * + */ +void ApplXcpSend( uint8_t len, MEMORY_ROM BYTEPTR msg ) +{ + uint8_t iBuf = 0; + sendBuffer[xcpSendBufWritePos].data.u8[iBuf++] = XcpFrameReceiver::ESCBYTE; + sendBuffer[xcpSendBufWritePos].data.u8[iBuf++] = len; + for (uint8_t iMsg = 0; iMsg= XCP_SEND_BUFFER_SIZE) + { + xcpSendBufWritePos = 0u; + } + + XcpSendCallBack(); +} + + +/** + * send max one frame from buffer + */ +void XcpSendLoop() +{ +#define SEND_MAX_FRAMES_PER_CALL 3u + for (uint8_t i=0; i= XCP_SEND_BUFFER_SIZE) + { + xcpSendBufReadPos = 0u; + } + } + } + +} + + + +/** + * + */ +MTABYTEPTR ApplXcpGetPointer( uint8_t addr_ext, uint32_t addr ) +{ + //return (MTABYTEPTR)&kXcpEventName; + return (MTABYTEPTR)(addr + 0*addr_ext); +} + + +/** + * + */ +void ApplXcpInterruptEnable() +{ + //interrupts(); +} + + +/** + * + */ +void ApplXcpInterruptDisable() +{ + //noInterrupts(); +} + + +/** + * + */ +uint16_t ApplXcpGetTimestamp(void) +{ + return (uint16_t) millis(); +} diff --git a/src/xcp/XcpBasic.cpp b/src/xcp/XcpBasic.cpp new file mode 100644 index 0000000..8c2b2b1 --- /dev/null +++ b/src/xcp/XcpBasic.cpp @@ -0,0 +1,3742 @@ + + +/***************************************************************************** +| Project Name: XCP Protocol Layer +| File Name: XcpBasic.c +| +| Description: Implementation of the XCP Protocol Layer +| XCP V1.0 slave device driver +| Basic Version (see feature list below) +| +| +| Limitations of the XCP basic version: +| +| - Stimulation (Bypassing) is not available +| XCP_ENABLE_STIM +| - Bit stimulation is not available +| XCP_ENABLE_STIM_BIT +| - SHORT_DOWNLOAD is not available +| XCP_ENABLE_SHORT_DOWNLOAD +| - MODIFY_BITS is not available +| XCP_ENABLE_MODIFY_BITS +| - FLASH and EEPROM Programming is not available +| XCP_ENABLE_PROGRAM, XCP_ENABLE_BOOTLOADER_DOWNLOAD, XCP_ENABLE_READ_EEPROM, XCP_ENABLE_WRITE_EEPROM +| - Block mode for UPLOAD, DOWNLOAD and PROGRAM is not available +| XCP_ENABLE_BLOCK_UPLOAD, XCP_ENABLE_BLOCK_DOWNLOAD +| - Resume mode is not available +| XCP_ENABLE_DAQ_RESUME +| - Memory write and read protection is not supported +| XCP_ENABLE_WRITE_PROTECTION +| XCP_ENABLE_READ_PROTECTION +| - Checksum calculation with AUTOSAR CRC module is not supported +| XCP_ENABLE_AUTOSAR_CRC_MODULE +| - No support from Vector Generation Tool +| +| All these feature are available in the full version. +| Please contact Vector Informatik GmbH for more information +| +| General limitations: +| +| - Daq and Event numbers are BYTE +| - Only dynamic DAQ list allocation supported +| - Max. checksum block size is 0xFFFF +| - CECKSUM_TYPE CRC16, CRC32 and 'user defined' are not supported +| - MAX_DTO is limited to max. 255 +| - The resume bits in daq lists are not set +| - STORE_DAQ, CLEAR_DAQ and STORE_CAL will not send a event message +| - Entering resume mode will not send a event message +| - Overload indication by event is not supported +| - Page Info and Segment Info is not supported +| - DAQ does not support address extensions +| - DAQ-list and event channel prioritization is not supported +| - Event channels contain one DAQ-list +| - ODT optimization not supported +| - Interleaved communication mode is not supported +| - The seed size is equal or less MAX_CTO-2 +| - The key size is equal or less MAX_CTO-2 +| - Only default programming data format is supported +| - GET_SECTOR_INFO does not return sequence numbers +| - PROGRAM_VERIFY and PROGRAM_FORMAT are not supported +| +|----------------------------------------------------------------------------- +| D E M O +|----------------------------------------------------------------------------- +| +| Please note, that the demo and example programs +| only show special aspects of the software. +| With regard to the fact that these programs are meant +| for demonstration purposes only, +| Vector Informatik's liability shall be expressly excluded in cases +| of ordinary negligence, to the extent admissible by law or statute. +| +|----------------------------------------------------------------------------- +| C O P Y R I G H T +|----------------------------------------------------------------------------- +| Copyright (c) 2008 by Vector Informatik GmbH. All rights reserved. +| +| This software is copyright protected and +| proporietary to Vector Informatik GmbH. +| Vector Informatik GmbH grants to you only +| those rights as set out in the license conditions. +| All other rights remain with Vector Informatik GmbH. +| +| Diese Software ist urheberrechtlich geschuetzt. +| Vector Informatik GmbH raeumt Ihnen an dieser Software nur +| die in den Lizenzbedingungen ausdruecklich genannten Rechte ein. +| Alle anderen Rechte verbleiben bei Vector Informatik GmbH. +| +|----------------------------------------------------------------------------- +| A U T H O R I D E N T I T Y +|----------------------------------------------------------------------------- +| Initials Name Company +| -------- --------------------- ------------------------------------- +| Ds Sven Deckardt Vector Informatik GmbH +| Eta Edgar Tongoona Vector Informatik GmbH +| Hr Andreas Herkommer Vector Informatik GmbH +| Svh Sven Hesselmann Vector Informatik GmbH +| Tri Frank Triem Vector Informatik GmbH +| Za Rainer Zaiser Vector Informatik GmbH +| Bwr Brandon Root Vector CANtech +|----------------------------------------------------------------------------- +| R E V I S I O N H I S T O R Y +|----------------------------------------------------------------------------- +| Date Version Author Description +| ---------- ------- ------ ----------------------------------------------- +| 2003-03-01 0.9.00 Ds Created +| 2003-05-01 0.9.10 Za Still a lot of changes, no detailled history yet +| 2003-06-31 1.0.00 Za Released +| 2003-09-19 1.0.00 Za XCP_DAQ_TIMESTAMP_FIXED +| 2003-10-22 1.0.01 Ds Change #if def instruction +| 2003-10-30 1.0.02 Ds Bugfix in the loop of the ODT Entry +| 2003-10-30 1.0.03 Ds Rename xcp20.c to xcpProf.c +| 2003-11-20 1.01.00 Tri Updated to PSC standard +| MISRA rules applied. +| Minor changes. +| 2004-02-11 1.01.01 Ds,Tri Updated and adaption for CANape +| ESCAN00007511: Warning when compiling XCP.H +| ESCAN00007517: Compiler error when using a packet length of 253 bytes or greater +| ESCAN00007518: Seed & Key: reading of the unlock key not performed correctly +| ESCAN00007532: Division by zero in calculation of the queue size +| ESCAN00007533: Memory overflow check during memory allocation might not be detected. +| 2004-06-16 1.02.00 Tri ESCAN00008482: Add user defined function to service GET_ID +| 2005-01-03 1.03.00 Tri,Za ESCAN00008009: Rename module versions according to PD_PSC_Development +| ESCAN00009121: Add copyright note +| ESCAN00009125: Remove defines for revision 18 +| ESCAN00009127: Remove XCP_ENABLE_SEND_BUFFER +| ESCAN00009130: Add support for data stimulation (STIM) +| ESCAN00007824: Warning due to unreferenced label 'negative_response1' +| ESCAN00008012: Remove include definitions of the standard libraries within XCP Professional +| ESCAN00008015: Avoid usage of the test mode within XCP Professional +| ESCAN00008018: XCP module version in response of CC_GET_COMM_MODE_INFO corrected +| ESCAN00008004: Compiler error when block upload is enabled and block download is disabled +| ESCAN00008005: Resource bit for CAL/PAG always set in response upon CC_CONNECT +| ESCAN00009141: Compiler warnings while compilation with Tasking Compiler +| ESCAN00007823: Warning about unreferenced variable 'prescaler' +| ESCAN00008003: Compiler error when block download is disabled and Programming enabled +| ESCAN00008060: Issue in negative response of command BUILD_CHECKSUM +| ESCAN00008013: Checksum calculation wrong +| ESCAN00008072: Compiler warning in range check of defines +| ESCAN00007971: Implement and support 'session configuration id' +| ESCAN00008006: Page switching always enabled when programming is enabled. +| ESCAN00008010: Remove extern declaration for xcp struct +| ESCAN00009154: Update Seed & Key +| ESCAN00010703: PROGRAM size = 0 is valid +| ESCAN00008017: Rework of Flash Programming by Flash Kernel +| ESCAN00009200: Positive Response upon command PROGRAM_START not correct +| ESCAN00010705: Rework command PROGRAM_RESET +| ESCAN00010706: Return the status of event channels +| ESCAN00010707: Consistency check in case of no DAQ released +| ESCAN00008008: Apply PSC naming convention for types and structures +| ESCAN00009173: Consistency check for generator DLL and component +| ESCAN00008007: Rename the post-organified filenames to xcpProf.h and xcpProf.c +| ESCAN00009172: Atmega only: Compiler error due to pointer conversion from RAM to Flash +| ESCAN00007209: Apply naming convention to callback functions +| ESCAN00009144: Minor changes +| 2005-02-01 1.04.00 Tri ESCAN00010989: Update comment for version scan +| ESCAN00010848: Move timestamp unit of response to GET_DAQ_EVENT_INFO in low nibble +| 2005-02-17 1.05.00 Tri ESCAN00011210: Support GENy Fwk 1.3 DLL Versions +| 2005-02-28 1.06.00 Tri ESCAN00010961: Include XCP Transport Layer on CAN +| 2005-05-10 1.07.00 Tri ESCAN00011446: Tasking Compiler only: Compiler Warnings +| ESCAN00012314: Compatibility with CANape 5.5.x regarding timestamp unit +| ESCAN00012356: Support data paging on Star12X / Metrowerks +| ESCAN00012617: Add service to retrieve XCP state +| 2006-01-03 1.08.00 Tri ESCAN00013899: Data acquisition not possible during cold start +| ESCAN00009196: PROGRAM_FORMAT is not implemented as specified +| ESCAN00009199: Negative Response to command PROGRAM_PREPARE is not correct +| ESCAN00009202: Programming Info not implemented correctly +| ESCAN00014313: Warning because of undefined 'kXcpStimOdtCount' +| ESCAN00013634: Remove kXcpPacketHeaderSize +| ESCAN00014710: Rework Calibration Data Page Freeze +| ESCAN00014712: Rework Segment Info and Page Info +| ESCAN00014775: Delayed EEPROM read access not possible +| 2006-03-09 1.09.00 Tri ESCAN00013637: Support command TRANSPORT_LAYER_CMD +| ESCAN00015283: Start of a single DAQ list is not possible +| ESCAN00015607: Support XCP on FlexRay Transport Layer +| 2006-05-05 1.10.00 Tri ESCAN00016158: Add demo disclaimer to XCP Basic +| ESCAN00016098: Calculation of CRC16 CCITT is not correct +| 2006-05-30 1.11.00 Tri ESCAN00016225: Support Cp_XcpOnLin +| 2006-07-18 1.12.00 Tri ESCAN00016955: Support AUTOSAR CRC module +| ESCAN00016958: Delayed EEPROM read access not possible +| 2006-10-26 1.13.00 Tri ESCAN00017516: Support Cp_XcpOnCanAsr +| ESCAN00017504: Replace P_MEM_ROM by MEMORY_FAR resp. V_MEMRAM2_FAR +| ESCAN00017804: Multiple definitions of XCP_DISABLE_TESTMODE +| ESCAN00017878: Overwriting of memory during data acquisition allocation +| 2007-01-30 1.14.00 Tri ESCAN00018808: Support data paging on Star12X / Cosmic +| 2007-04-03 1.15.00 Eta ESCAN00018153: Overwriting of memory during data stimulation +| Svh ESCAN00020126: Commands SHORT_DOWNLOAD and MODIFY_BITS must be supported +| ESCAN00012618: Support command MODIFY_BITS +| ESCAN00020127: It has to be possible to en-/disable XCP globally +| ESCAN00019094: Extend implementation for runtime deactivation of XCP (professional) +| ESCAN00020128: Add AUTOSAR based API +| ESCAN00018154: Support overwriting of XcpSendDto() in header +| ESCAN00015859: Support memory read protection +| 2007-05-25 1.16.00 Svh ESCAN00020906: Compiler error due to incorrect pointer assignment +| 2007-07-09 1.16.01 Hr Support AUTOSAR Memory Mapping +| 2007-12-07 1.16.02 Hr ISS046 - Only CTOs are flushed by the Protocol Layer +| 2007-09-14 1.17.00 Svh ESCAN00022293: Support for SET_SEGMENT_MODE and GET_SEGMENT_MODE added +| 2007-12-17 1.18.00 Svh ESCAN00023759: Compile error for MCS12x +| 2008-03-17 1.19.00 Svh ESCAN00021035: XcpSendCallBack() always returns 1 +| ESCAN00024265: STIM with time stamp is not supported +| ESCAN00024863: Missing error code in CC_TRANSPORT_LAYER_CMD +| ESCAN00025020: Possible stack issues with big MAX_DTO values in case Send Queue is not used +| ESCAN00023570: Do not set default answer is last CRM is still pending +| 2008-04-10 1.20.00 Svh ESCAN00025979: tXcpDto wrong structure ordering causing erroneous one-time Stim trigger +| 2008-04-30 1.21.00 Eta ESCAN00026424: compiler error when using Cosmic with option -pck +| Svh ESCAN00026491: Data inconsistency of ODTs in case of Overrun + FlexRay +| 2008-04-30 1.21.01 Svh ESCAN00026541: compiler error due to unknown symbol +| 2008-06-04 1.21.02 Svh ESCAN00027343: Redefinition of ApplXcpSendFlush +| 2008-07-21 1.22.00 Hr ESCAN00022545: Memory Read Protection always returns Ok to CANape +| ESCAN00020637: Support different Info Time Unit for DTO handling +| ESCAN00017954: Support MIN_ST_PGM +| ESCAN00017951: Add open interface for command processing +| ESCAN00028579: CC_PROGRAM_START should support an application callback +| Svh ESCAN00028720: Support ADDRESS_GRANULARITY WORD +| 2008-09-10 1.23.00 Svh ESCAN00029890: Incorrect checksum calculation +| ESCAN00029896: Command pending for several call backs added +| ESCAN00029897: XcpStimEventStatus() returns 1 also if no STIM data is available +| ESCAN00029905: Configuration of parameter MIN_ST in response of GET_COMM_MODE_INFO command added +| 2008-10-01 1.23.01 Hr ESCAN00030382: Compiler error due to missing ; +| 2008-10-10 1.23.02 Bwr ESCAN00030037: Support for more than 255 ODT entries +| 2008-12-01 1.24.00 Hr ESCAN00031342: Version information of implementation inconsistent to release version information +| ESCAN00031726: Add support for XcpOnTcpIpAsr +| ESCAN00031948: Event gets lost, if a Response is still pending +| ESCAN00031949: Add error check for ODT_SIZE_WORD with no DAQ_HDR_ODT_DAQ +| Bwr ESCAN00030566: SET_REQUEST with incorrect mode is ignored +| ESCAN00030601: Support for more than 255 ODTs +| 2009-02-05 1.24.01 Hr ESCAN00032861: CC_SET_DAQ_PTR fails due to Diab Data Compiler bug +| 2009-02-27 1.24.02 Hr ESCAN00031794: Compiler warning: large type was implicitly cast to small type +| ESCAN00033655: Canbedded compile error due to uint8 +| 2009-05-13 1.25.00 Hr ESCAN00033909: New features implemented: Prog Write Protection, Timestamps, Calibration activation +| 2009-10-08 1.25.01 Hr ESCAN00038283: After second measurement start with INCA no timestamps are generated anymore. +| ESCAN00039240: Compile error by uint8 +| ESCAN00039241: Variables not in NOINIT sections +| 2009-11-26 Hr ESCAN00039350: TMS320 Compile error: struct has no field "EightByteField" +|***************************************************************************/ + + + +/***************************************************************************/ +/* Include files */ +/***************************************************************************/ + +#include "XcpBasic.h" +#include "XcpAppInterface.h" + +/* Include AUTOSAR CRC module header file. */ + +/* XCP DPRAM Client Mode */ + +#if defined ( XCP_ENABLE_SERV_TEXT_PRINTF ) && defined ( XCP_ENABLE_TESTMODE ) + #include + #include +#endif + + +/***************************************************************************/ +/* Version check */ +/***************************************************************************/ +#if ( CP_XCP_VERSION != 0x0125u ) + #error "Source and Header file are inconsistent!" +#endif +#if ( CP_XCP_RELEASE_VERSION != 0x01u ) + #error "Source and Header file are inconsistent!" +#endif + +#if defined ( VGEN_GENY ) + #if defined ( CP_XCPDLL_VERSION ) + #if ( CP_XCPDLL_VERSION >= 0x0211u ) + #else + #error "XCP component version and generator version are not consistent!" + #endif + #else + #if defined ( VGEN_VERSION_CP_XCP_MAIN ) + #if ( ( VGEN_VERSION_CP_XCP_MAIN > 1 ) || ( VGEN_VERSION_CP_XCP_SUB > 5 ) ) + #else + #error "XCP component version and generator version are not consistent!" + #endif + #else + #error "XCP component version and generator version are not consistent!" + #endif + #endif +#endif + +/* Check specifcation version of AUTOSAR CRC module. */ + + +/***************************************************************************/ +/* Check of Transport Layer availability */ +/***************************************************************************/ + + + + +/****************************************************************************/ +/* Definitions */ +/****************************************************************************/ + +/* Definition of endianess. */ +#if defined ( XCP_CPUTYPE_BIGENDIAN ) || defined ( XCP_CPUTYPE_LITTLEENDIAN ) +#else + #if defined ( C_CPUTYPE_BIGENDIAN ) + #define XCP_CPUTYPE_BIGENDIAN + #endif + #if defined ( C_CPUTYPE_LITTLEENDIAN ) + #define XCP_CPUTYPE_LITTLEENDIAN + #endif + #if defined ( CPU_BYTE_ORDER ) + #if ( CPU_BYTE_ORDER == HIGH_BYTE_FIRST ) + #define XCP_CPUTYPE_BIGENDIAN + #endif + #if ( CPU_BYTE_ORDER == LOW_BYTE_FIRST ) + #define XCP_CPUTYPE_LITTLEENDIAN + #endif + #endif +#endif + + +#if defined ( C_COMP_TASKING_ST10_CCAN ) || defined ( C_COMP_TASKING_C16X ) || defined ( C_COMP_TASKING_XC16X ) + #if defined ( XCP_ENABLE_NO_P2INT_CAST ) || defined ( XCP_DISABLE_NO_P2INT_CAST ) + #else + /* Some uCs use DPPs in the small memory model and encode the information in the most significant bits of pointers. + The DPP register information gets lost if these pointers are converted to integers. + The following options disables casts from pointers to integer. */ + #define XCP_ENABLE_NO_P2INT_CAST + #endif +#endif + + +/****************************************************************************/ +/* Macros */ +/****************************************************************************/ + +/* Definition of macros that have to be used within the context of XcpCommand. */ +/* They have to be declared global Due to MISRA rule 91. */ + +#define error(e) { err=(e); goto negative_response; } +#define check_error(e) { err=(e); if (err!=0) { goto negative_response; } } +#define error1(e,b1) { err=(e); CRM_BYTE(2)=(b1); xcp.CrmLen=3; goto negative_response1; } +#define error2(e,b1,b2) { err=(e); CRM_BYTE(2)=(b1); CRM_BYTE(3)=(b2); xcp.CrmLen=4; goto negative_response1; } + +#if defined ( XCP_ENABLE_SEED_KEY ) + /* Return CRC_ACCESS_LOCKED if the resource is locked. */ + #define CheckResourceProtection(resource) if ( (xcp.ProtectionStatus & (resource)) != 0 ) { error(CRC_ACCESS_LOCKED) } +#else + /* The resource protection is unavailable. */ + #define CheckResourceProtection(resource) +#endif + + + +#if defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) + #define XCP_WRITE_BYTE_2_ADDR(addr, data) ApplXcpWrite( (vuint32)(addr), (vuint8)(data) ) + #define XCP_READ_BYTE_FROM_ADDR(addr) ApplXcpRead ( (vuint32)(addr) ) + #if defined ( XCP_ENABLE_CHECKSUM ) + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) + #define XCP_READ_CHECKSUMVALUE_FROM_ADDR(addr) ApplXcpReadChecksumValue ( (vuint32)(addr) ) + #else + #define XCP_READ_CHECKSUMVALUE_FROM_ADDR(addr) XCP_READ_BYTE_FROM_ADDR(addr) + #endif + #endif +#else + #define XCP_WRITE_BYTE_2_ADDR(addr, data) *(addr) = (data) + #define XCP_READ_BYTE_FROM_ADDR(addr) *(addr) + #if defined ( XCP_ENABLE_CHECKSUM ) + #if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) + #define XCP_READ_CHECKSUMVALUE_FROM_ADDR(addr) ApplXcpReadChecksumValue ( (vuint32)(addr) ) + #else + #define XCP_READ_CHECKSUMVALUE_FROM_ADDR(addr) *((tXcpChecksumAddType*)addr) + #endif + #endif +#endif + + #define XcpPlCheckControlState( ) + #define XcpPlCheckControlStateRet( ret_value ) + +/****************************************************************************/ +/* Constants */ +/****************************************************************************/ + +/****************************************************************************/ +/* 8 Bit Constants for export */ +/****************************************************************************/ + +/* Global constants with XCP Protocol Layer main and subversion */ +V_MEMROM0 MEMORY_ROM vuint8 kXcpMainVersion = (vuint8)(CP_XCP_VERSION >> 8); +V_MEMROM0 MEMORY_ROM vuint8 kXcpSubVersion = (vuint8)(CP_XCP_VERSION & 0x00ff); +V_MEMROM0 MEMORY_ROM vuint8 kXcpReleaseVersion = (vuint8)(CP_XCP_RELEASE_VERSION); + + + +/****************************************************************************/ +/* Local data */ +/****************************************************************************/ + +/* This section containes all RAM locations needed by the XCP driver */ + +/******************************************************************************/ +/* Local Data definitions with unspecified size */ +/******************************************************************************/ + +static RAM tXcpData xcp; + + +#if defined ( XCP_ENABLE_TESTMODE ) +vuint8 gDebugLevel; +#endif + +/******************************************************************************/ +/* Local Data definitions with 8Bit size */ +/******************************************************************************/ + + + + +/***************************************************************************/ +/* Prototypes for local functions */ +/***************************************************************************/ + +static vuint8 XcpWriteMta( vuint8 size, MEMORY_ROM BYTEPTR data ); +static vuint8 XcpReadMta( vuint8 size, BYTEPTR data ); + +#if defined ( XcpMemClr ) +#else +static void XcpMemClr( BYTEPTR p, vuint16 n ); +#endif + +#if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) +static void XcpSendEv( void ); +#endif + +#if defined ( XCP_ENABLE_SEND_QUEUE ) +static vuint8 XcpSendDtoFromQueue( void ); +static void XcpQueueInit( void ); +#endif + +#if defined ( XCP_ENABLE_DAQ ) +static void XcpFreeDaq( void ); +static vuint8 XcpAllocMemory( void ); +static vuint8 XcpAllocDaq( vuint8 daqCount ); +static vuint8 XcpAllocOdt( vuint8 daq, vuint8 odtCount ); +static vuint8 XcpAllocOdtEntry( vuint8 daq, vuint8 odt, vuint8 odtEntryCount ); +static void XcpStartDaq( vuint8 daq ); +static void XcpStartAllSelectedDaq( void ); +static void XcpStopDaq( vuint8 daq ); +static void XcpStopAllSelectedDaq( void ); +static void XcpStopAllDaq( void ); + + +#endif + + + +/****************************************************************************** +* +* +* Code Part for Cp_Xcp +* +* +*******************************************************************************/ + + +/***************************************************************************** +| NAME: XcpMemSet +| CALLED BY: XcpFreeDaq +| PRECONDITIONS: none +| INPUT PARAMETERS: p : pointer to start address. +| n : number of data bytes. +| d : data byte to initialize with. +| RETURN VALUES: none +| DESCRIPTION: Initialize n bytes starting from address p with b. +******************************************************************************/ + +#if defined ( XcpMemSet ) + /* XcpMemSet is overwritten */ +#else +void XcpMemSet( BYTEPTR p, vuint16 n, vuint8 b ) +{ + for ( ; n > 0; n-- ) + { + *p = b; + p++; + } +} +#endif + +/***************************************************************************** +| NAME: XcpMemClr +| CALLED BY: XcpFreeDaq, XcpInit +| PRECONDITIONS: none +| INPUT PARAMETERS: p : pointer to start address. +| n : number of data bytes. +| RETURN VALUES: none +| DESCRIPTION: Initialize n bytes starting from address p 0. +******************************************************************************/ + +#if defined ( XcpMemClr ) + /* XcpMemClr is overwritten */ +#else +/* A macro would be more efficient. Due to MISRA rule 96 violations a function is implemented. */ +static void XcpMemClr( BYTEPTR p, vuint16 n ) +{ + XcpMemSet( p, n, (vuint8)0u); +} +#endif + +/***************************************************************************** +| NAME: XcpMemCpy +| CALLED BY: XcpEvent +| PRECONDITIONS: none +| INPUT PARAMETERS: dest : pointer to destination address. +| src : pointer to source address. +| n : number of data bytes to copy. +| RETURN VALUES: none +| DESCRIPTION: Copy n bytes from src to dest. +| A maximum of 255 Bytes can be copied at once. +******************************************************************************/ + +/* Optimize this function + It is used in the inner loop of XcpEvent for data acquisition sampling +*/ + +#if defined ( XcpMemCpy ) || defined ( C_COMP_COSMIC_MCS12X_MSCAN12 ) + /* XcpMemCpy is overwritten */ +#else +void XcpMemCpy( DAQBYTEPTR dest, MEMORY_ROM DAQBYTEPTR src, vuint8 n ) +{ + for ( ; n > 0; n-- ) + { + XCP_WRITE_BYTE_2_ADDR( dest, *src ); + dest++; + src++; + } +} +#endif + + +/****************************************************************************/ +/* Transmit */ +/****************************************************************************/ + + +/***************************************************************************** +| NAME: XcpSendCrm +| CALLED BY: XcpBackground, XcpCommand, XcpSendCallBack, application +| PRECONDITIONS: XCP is initialized and in connected state and +| a command packet (CMD) has been received. +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Transmission of a command response packet (RES), +| or error packet (ERR) if no other packet is pending. +******************************************************************************/ +void XcpSendCrm( void ) +{ + /* Activation control */ + XcpPlCheckControlState() + +#if defined ( XCP_ENABLE_SEND_QUEUE ) + + ApplXcpInterruptDisable(); + + if ( (xcp.SendStatus & (vuint8)XCP_SEND_PENDING) != 0 ) + { + if ( (xcp.SendStatus & (vuint8)XCP_CRM_REQUEST) != 0 ) + { + XCP_ASSERT(0); + xcp.SessionStatus |= (vuint8)SS_ERROR; + } + xcp.SendStatus |= (vuint8)XCP_CRM_REQUEST; + } + else + { + xcp.SendStatus |= (vuint8)XCP_CRM_PENDING; + ApplXcpSend(xcp.CrmLen,&xcp.Crm.b[0]); + } + + ApplXcpInterruptEnable(); + +#else + + ApplXcpSend(xcp.CrmLen,&xcp.Crm.b[0]); + +#endif + + ApplXcpSendFlush(); + +} + +#if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) +/***************************************************************************** +| NAME: XcpSendEv +| CALLED BY: XcpSendEvent, XcpSendCallBack, XcpPutchar +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Send a EV or SERV message, if no other message is pending. +******************************************************************************/ +static void XcpSendEv( void ) +{ + #if defined ( XCP_ENABLE_SEND_QUEUE ) + + ApplXcpInterruptDisable(); + + if ( (xcp.SendStatus & (vuint8)XCP_SEND_PENDING) != 0 ) + { + if ( (xcp.SendStatus & (vuint8)XCP_EVT_REQUEST) != 0 ) + { + XCP_ASSERT(0); + xcp.SessionStatus |= (vuint8)SS_ERROR; + } + xcp.SendStatus |= (vuint8)XCP_EVT_REQUEST; + } + else + { + xcp.SendStatus |= (vuint8)XCP_EVT_PENDING; + ApplXcpSend(xcp.EvLen,xcp.Ev.b); + xcp.EvLen = 0; + } + + ApplXcpInterruptEnable(); + + #else + + ApplXcpSend(xcp.EvLen,xcp.Ev.b); + xcp.EvLen = 0; + + #endif + + ApplXcpSendFlush(); + +} +#endif /* XCP_ENABLE_SEND_EVENT || XCP_ENABLE_SERV_TEXT */ + + +#if defined ( XCP_ENABLE_DAQ ) +/***************************************************************************** +| NAME: XcpSendDto +| CALLED BY: XcpSendDtoFromQueue, XcpEvent, XcpSendCallBack +| PRECONDITIONS: none +| INPUT PARAMETERS: dto : pointer to XCP packet type definition +| RETURN VALUES: none +| DESCRIPTION: Send a DTO. +******************************************************************************/ + #if defined ( XcpSendDto ) + /* XcpSendDto is redefined */ + #else +void XcpSendDto( MEMORY_ROM tXcpDto *dto ) +{ +#if defined ( XCP_ALLIGN_WORD ) + ApplXcpSend( dto->l, &dto->XcpDtoByteField.b[0] ); +#else + ApplXcpSend( dto->l, &dto->b[0] ); +#endif +} + #endif +#endif /* XCP_ENABLE_DAQ */ + + +#if defined ( XCP_ENABLE_SEND_QUEUE ) +/***************************************************************************** +| NAME: XcpSendDtoFromQueue +| CALLED BY: XcpEvent, XcpSendCallBack +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: 0 : DTO has NOT been transmitted from queue. +| 1 : DTO has been transmitted from queue. +| DESCRIPTION: Send a DTO from the queue. +******************************************************************************/ +static vuint8 XcpSendDtoFromQueue( void ) +{ + ApplXcpInterruptDisable(); + if ( ( (xcp.SendStatus & (vuint8)XCP_SEND_PENDING) == 0 ) && ( xcp.QueueLen != 0 )) + { + xcp.SendStatus |= (vuint8)XCP_DTO_PENDING; + XcpSendDto(&xcp.pQueue[xcp.QueueRp]); + xcp.QueueRp++; + if ( (vuint8)(xcp.QueueRp>=xcp.QueueSize) != (vuint8)0u ) + { + xcp.QueueRp = 0; + } + xcp.QueueLen--; + ApplXcpInterruptEnable(); + return (vuint8)1u; + } + ApplXcpInterruptEnable(); + return (vuint8)0u; +} /* Deviation of MISRA rule 82 (more than one return path). */ +#endif /* XCP_ENABLE_SEND_QUEUE */ + + +/****************************************************************************/ +/* Transmit Queue */ +/****************************************************************************/ + +#if defined ( XCP_ENABLE_SEND_QUEUE ) + +/***************************************************************************** +| NAME: XcpQueueInit +| CALLED BY: XcpFreeDaq, XcpStopDaq, XcpStopAllDaq +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Initialize the transmit queue. +******************************************************************************/ +static void XcpQueueInit(void) +{ + + xcp.QueueLen = (vuint8)0u; + xcp.QueueRp = (vuint8)0u; +} + +#endif /* XCP_ENABLE_SEND_QUEUE */ + + +/****************************************************************************/ +/* Handle Mta (Memory-Transfer-Address) */ +/****************************************************************************/ + +/* Assign a pointer to a Mta */ +#if defined ( XcpSetMta ) +#else + #define XcpSetMta(p,e) (xcp.Mta = (p)) +#endif + +/***************************************************************************** +| NAME: XcpWriteMta +| CALLED BY: XcpCommand +| PRECONDITIONS: none +| INPUT PARAMETERS: size : number of data bytes. +| data : address of data. +| RETURN VALUES: XCP_CMD_OK, XCP_CMD_DENIED +| DESCRIPTION: Write n bytes. +| Copying of size bytes from data to xcp.Mta +******************************************************************************/ +static vuint8 XcpWriteMta( vuint8 size, MEMORY_ROM BYTEPTR data ) +{ +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) + vuint8 r; +#endif + + /* DPRAM Client */ + + /* Checked ram memory write access */ + + /* EEPROM write access */ + + /* Standard RAM memory write access */ +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) && !defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) + r = ApplXcpCalibrationWrite(xcp.Mta, size, data); + xcp.Mta += size; + return r; +#else + while ( size > (vuint8)0u ) + { + XCP_WRITE_BYTE_2_ADDR( xcp.Mta, *data ); + xcp.Mta++; + data++; + size--; + } + return (vuint8)XCP_CMD_OK; +#endif +} + +/***************************************************************************** +| NAME: XcpReadMta +| CALLED BY: XcpCommand +| PRECONDITIONS: none +| INPUT PARAMETERS: size : +| data : address of data +| RETURN VALUES: XCP_CMD_OK +| DESCRIPTION: Read n bytes. +| Copying of size bytes from data to xcp.Mta +******************************************************************************/ +static vuint8 XcpReadMta( vuint8 size, BYTEPTR data ) +{ +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) + vuint8 r; +#endif + + /* DPRAM Client */ + + /* Checked ram memory read access */ + + /* EEPROM read access */ + +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) && !defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) + r = ApplXcpCalibrationRead(xcp.Mta, size, data); + xcp.Mta += size; + return r; +#else + /* Standard RAM memory read access */ + while (size > 0) + { + /* + Compiler bug Tasking + *(data++) = *(xcp.Mta++); + */ + *(data) = XCP_READ_BYTE_FROM_ADDR( xcp.Mta ); + data++; + xcp.Mta++; + size--; + } + return (vuint8)XCP_CMD_OK; +#endif +} + + +/****************************************************************************/ +/* Data Aquisition Setup */ +/****************************************************************************/ + + +#if defined ( XCP_ENABLE_DAQ ) + +/***************************************************************************** +| NAME: XcpFreeDaq +| CALLED BY: XcpCommand +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Free all dynamic DAQ lists +******************************************************************************/ +static void XcpFreeDaq( void ) +{ + xcp.SessionStatus &= (vuint8)((~SS_DAQ) & 0xFFu); + + xcp.Daq.DaqCount = 0; + xcp.Daq.OdtCount = 0; + xcp.Daq.OdtEntryCount = 0; + + xcp.pOdt = (tXcpOdt*)0; + xcp.pOdtEntryAddr = 0; + xcp.pOdtEntrySize = 0; + + XcpMemClr((BYTEPTR)&xcp.Daq.u.b[0], (vuint16)kXcpDaqMemSize); /* Deviation of MISRA rule 44. */ + #if defined ( kXcpMaxEvent ) + XcpMemSet( (BYTEPTR)&xcp.Daq.EventDaq[0], (vuint16)sizeof(xcp.Daq.EventDaq), (vuint8)0xFFu); /* Deviation of MISRA rule 44. */ + #endif + + #if defined ( XCP_ENABLE_SEND_QUEUE ) + XcpQueueInit(); + #endif +} + +/***************************************************************************** +| NAME: XcpAllocMemory +| CALLED BY: XcpAllocDaq, XcpAllocOdt, XcpAllocOdtEntry, XcpInit +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: 0, CRC_MEMORY_OVERFLOW +| DESCRIPTION: Allocate Memory for daq,odt,odtEntries and Queue +| according to DaqCount, OdtCount and OdtEntryCount +******************************************************************************/ +static vuint8 XcpAllocMemory( void ) +{ + vuint16 s; + #if defined ( XCP_ENABLE_NO_P2INT_CAST ) + vuint8* p; + vuint8 i; + #endif + + /* Check memory overflow */ + s = (vuint16)( ( xcp.Daq.DaqCount * (vuint8)sizeof(tXcpDaqList) ) + + ( xcp.Daq.OdtCount * (vuint16)sizeof(tXcpOdt) ) + + ( xcp.Daq.OdtEntryCount * ( (vuint8)sizeof(DAQBYTEPTR) + (vuint8)sizeof(vuint8) ) ) + ); + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + s += 3; /* Worst case 3 bytes needed for alignment */ + #endif + if (s>=(vuint16)kXcpDaqMemSize) + { + return (vuint8)CRC_MEMORY_OVERFLOW; + } + + /* Force WORD alignment for ODTs */ + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + #if defined ( XCP_ENABLE_NO_P2INT_CAST ) + p = (vuint8*)&xcp.Daq.u.DaqList[xcp.Daq.DaqCount]; + i = ((vuint8)p) & (vuint8)0x01u; + p += i; + xcp.pOdt = (tXcpOdt*)p; + #else + #if defined ( C_CPUTYPE_8BIT ) || defined ( C_CPUTYPE_16BIT ) + /* Allign to words */ + xcp.pOdt = (tXcpOdt*)((((vuint32)(&xcp.Daq.u.DaqList[xcp.Daq.DaqCount])) + (vuint32)1u) & (vuint32)0xFFFFFFFEu ); + #else + /* Allign to dwords */ + xcp.pOdt = (tXcpOdt*)((((vuint32)(&xcp.Daq.u.DaqList[xcp.Daq.DaqCount])) + (vuint32)3u) & (vuint32)0xFFFFFFFCu ); + #endif + #endif + #else + xcp.pOdt = (tXcpOdt*)&xcp.Daq.u.DaqList[xcp.Daq.DaqCount]; + #endif + + /* Force DWORD alignment for ODT entries */ + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + #if defined ( XCP_ENABLE_NO_P2INT_CAST ) + p = (vuint8*)&xcp.pOdt[xcp.Daq.OdtCount]; + i = ((vuint8)p) & (vuint8)0x03u; + i = (vuint8)4u - i; + i &= 0x03; + p += i; + xcp.pOdtEntryAddr = (DAQBYTEPTR*)p; + #else + xcp.pOdtEntryAddr = (DAQBYTEPTR*) ((((vuint32)&xcp.pOdt[xcp.Daq.OdtCount]) + (vuint32)3u) & (vuint32)0xFFFFFFFCu ); + #endif + #else + xcp.pOdtEntryAddr = (DAQBYTEPTR*)&xcp.pOdt[xcp.Daq.OdtCount]; + #endif + xcp.pOdtEntrySize = (vuint8*)&xcp.pOdtEntryAddr[xcp.Daq.OdtEntryCount]; + + #if defined ( XCP_ENABLE_SEND_QUEUE ) + /* Force WORD alignment for the queue */ + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + #if defined ( XCP_ENABLE_NO_P2INT_CAST ) + p = (vuint8*)&xcp.pOdtEntrySize[xcp.Daq.OdtEntryCount]; + i = ((vuint8)p) & (vuint8)0x01u; + p += i; + xcp.pQueue = (tXcpDto*)p; + #else + #if defined ( C_CPUTYPE_8BIT ) || defined ( C_CPUTYPE_16BIT ) + /* Allign to words */ + xcp.pQueue = (tXcpDto*)((((vuint32)(&xcp.pOdtEntrySize[xcp.Daq.OdtEntryCount])) + (vuint32)1u) & (vuint32)0xFFFFFFFEu ); + #else + /* Allign to dwords */ + xcp.pQueue = (tXcpDto*)((((vuint32)(&xcp.pOdtEntrySize[xcp.Daq.OdtEntryCount])) + (vuint32)3u) & (vuint32)0xFFFFFFFCu ); + #endif + #endif + #else + xcp.pQueue = (tXcpDto*)&xcp.pOdtEntrySize[xcp.Daq.OdtEntryCount]; + #endif + + qs = ((vuint16)kXcpDaqMemSize - s) / sizeof(tXcpDto); + if (qs>=128) + { + xcp.QueueSize = 127; /* Maximum possible size because of the modulo operation in XcpQueueWrite */ + } + else + { + xcp.QueueSize = (vuint8)qs; + } + + #if defined ( kXcpSendQueueMinSize ) + if (xcp.QueueSize<(vuint8)kXcpSendQueueMinSize) + { + return (vuint8)CRC_MEMORY_OVERFLOW; + } + #else + /* At least one queue entry per odt */ + if (xcp.QueueSize (vuint16)0xFBu) + { + return (vuint8)CRC_MEMORY_OVERFLOW; + } + #endif + + xcp.Daq.u.DaqList[daq].firstOdt = xcp.Daq.OdtCount; + xcp.Daq.OdtCount += odtCount; + #if defined ( XCP_ALLIGN_WORD ) + xcp.Daq.OdtCount &= 0x00FFu; + #endif + xcp.Daq.u.DaqList[daq].lastOdt = (tXcpOdtIdx)(xcp.Daq.OdtCount-1); + + return XcpAllocMemory(); +} /* Deviation of MISRA rule 82 (more than one return path). */ + +/***************************************************************************** +| NAME: XcpAllocOdtEntry +| CALLED BY: XcpCommand +| PRECONDITIONS: none +| INPUT PARAMETERS: daq : +| odt : +| odtEntryCount : +| RETURN VALUES: return value of XcpAllocMemory +| DESCRIPTION: Allocate all ODT entries +| Parameter odt is relative odt number +******************************************************************************/ +static vuint8 XcpAllocOdtEntry( vuint8 daq, vuint8 odt, vuint8 odtEntryCount ) +{ + tXcpOdtIdx xcpFirstOdt; + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if ( (xcp.Daq.DaqCount==0) || (xcp.Daq.OdtCount==0) ) + { + return (vuint8)CRC_SEQUENCE; + } + #endif + + /* Absolute ODT entry count count must fit in a WORD */ + if (xcp.Daq.OdtEntryCount > (0xFFFFu - odtEntryCount)) + { + return (vuint8)CRC_MEMORY_OVERFLOW; + } + xcpFirstOdt = xcp.Daq.u.DaqList[daq].firstOdt; + xcp.pOdt[xcpFirstOdt+odt].firstOdtEntry = xcp.Daq.OdtEntryCount; + xcp.Daq.OdtEntryCount += (vuint16)odtEntryCount; + xcp.pOdt[xcpFirstOdt+odt].lastOdtEntry = (vuint16)(xcp.Daq.OdtEntryCount-1); + + return XcpAllocMemory(); +} /* Deviation of MISRA rule 82 (more than one return path). */ + +/***************************************************************************** +| NAME: XcpStartDaq +| CALLED BY: XcpCommand, XcpStartAllSelectedDaq +| PRECONDITIONS: none +| INPUT PARAMETERS: daq : +| RETURN VALUES: none +| DESCRIPTION: Start DAQ +******************************************************************************/ +static void XcpStartDaq( vuint8 daq ) +{ + /* Initialize the DAQ list */ + DaqListFlags(daq) |= (vuint8)DAQ_FLAG_RUNNING; + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + DaqListCycle(daq) = 1; + #endif + + xcp.SessionStatus |= (vuint8)SS_DAQ; +} + +/***************************************************************************** +| NAME: XcpStartAllSelectedDaq +| CALLED BY: XcpCommand, XcpInit +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Start all selected DAQs +******************************************************************************/ +static void XcpStartAllSelectedDaq(void) +{ + vuint8 daq; + + /* Start all selected DAQs */ + for (daq=0;daq= (vuint8)kXcpMaxEvent) + { + return (vuint8)XCP_EVENT_NOP; + } + #endif + + BEGIN_PROFILE(4); /* Timingtest */ + daq = xcp.Daq.EventDaq[event]; + if ( ((daq=xcp.QueueSize) + { + status |= (vuint8)XCP_EVENT_DAQ_OVERRUN; /* Queue overflow */ + DaqListFlags(daq) |= (vuint8)DAQ_FLAG_OVERRUN; + goto next_odt; + } + dtop = &xcp.pQueue[(xcp.QueueRp+xcp.QueueLen)%xcp.QueueSize]; + #if defined ( XCP_SEND_QUEUE_SAMPLE_ODT ) + xcp.QueueLen++; + #endif + #else + dtop = &dto; + #endif /* XCP_ENABLE_SEND_QUEUE */ + + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) + + /* ODT,DAQ */ + #if defined ( XCP_ALLIGN_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_0 = odt-DaqListFirstOdt(daq); /* Relative odt number */ + dtop->XcpDtoByteField.EightByteField.byte_1 = daq; + #else + dtop->b[0] = odt-DaqListFirstOdt(daq); /* Relative odt number */ + dtop->b[1] = daq; + #endif + i = 2; + + #else + + /* PID */ + #if defined ( XCP_ALLIGN_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_0 = odt; + #else + dtop->b[0] = odt; + #endif + i = 1; + + #endif + + /* Use BIT7 of PID or ODT to indicate overruns */ + #if defined ( XCP_ENABLE_SEND_QUEUE ) + #if defined ( XCP_ENABLE_DAQ_OVERRUN_INDICATION ) + if ( (DaqListFlags(daq) & (vuint8)DAQ_FLAG_OVERRUN) != 0 ) + { + #if defined ( XCP_ALLIGN_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_0 |= (vuint8)0x80; + #else + dtop->b[0] |= (vuint8)0x80; + #endif + DaqListFlags(daq) &= (vuint8)(~DAQ_FLAG_OVERRUN & 0xFFu); + } + #endif + #endif + + /* Timestamps */ + #if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + + #if !defined ( XCP_ENABLE_DAQ_TIMESTAMP_FIXED ) + if ( (DaqListFlags(daq) & (vuint8)DAQ_FLAG_TIMESTAMP) != 0 ) + { + #endif + + if (odt==DaqListFirstOdt(daq)) + { + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + t = ApplXcpGetTimestamp(); + #endif + + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) + + #if defined ( XCP_ALLIGN_WORD ) + *(XcpDaqTimestampType*)&dtop->XcpDtoByteField.b[1] = ApplXcpGetTimestamp(); + #else + //*(XcpDaqTimestampType*)&dtop->b[2] = ApplXcpGetTimestamp(); //hier krachts, wenn Timestamp 4byte hat + XcpMemCpy(&dtop->b[2],ApplXcpGetTimestamp_Address(),sizeof(XcpDaqTimestampType)); + #endif + i = 2 + sizeof(XcpDaqTimestampType); + + #else /* XCP_ENABLE_DAQ_HDR_ODT_DAQ */ + + #if defined ( XCP_DISABLE_UNALIGNED_MEM_ACCESS ) + #if defined ( XCP_CPUTYPE_BIGENDIAN ) /* Avoid WORD access */ + #if defined ( XCP_ALLIGN_WORD ) + #if( kXcpDaqTimestampSize == DAQ_TIMESTAMP_BYTE ) + dtop->XcpDtoByteField.EightByteField.byte_1 = (vbittype)(t&0xFFu); + #elif( kXcpDaqTimestampSize == DAQ_TIMESTAMP_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_2 = (vbittype)(t&0xFFu); + dtop->XcpDtoByteField.EightByteField.byte_1 = (vbittype)((t>>8)&0xFFu); + #elif( kXcpDaqTimestampSize == DAQ_TIMESTAMP_DWORD ) + dtop->XcpDtoByteField.EightByteField.byte_4 = (vbittype)(t&0xFFu); + dtop->XcpDtoByteField.EightByteField.byte_3 = (vbittype)((t>>8)&0xFFu); + dtop->XcpDtoByteField.EightByteField.byte_2 = (vbittype)((t>>16)&0xFFu); + dtop->XcpDtoByteField.EightByteField.byte_1 = (vbittype)((t>>24)&0xFFu); + #endif + #else + #if( kXcpDaqTimestampSize == DAQ_TIMESTAMP_BYTE ) + dtop->b[i+0u] = (vuint8)t; + #elif( kXcpDaqTimestampSize == DAQ_TIMESTAMP_WORD ) + dtop->b[i+1u] = (vuint8)t; + dtop->b[i+0u] = (vuint8)(t>>8); + #elif( kXcpDaqTimestampSize == DAQ_TIMESTAMP_DWORD ) + dtop->b[i+3u] = (vuint8)t; + dtop->b[i+2u] = (vuint8)(t>>8); + dtop->b[i+1u] = (vuint8)(t>>16); + dtop->b[i+0u] = (vuint8)(t>>24); + #endif + #endif + #else + #if defined ( XCP_ALLIGN_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_1 = (vbittype)(t&0xFFu); + #if( kXcpDaqTimestampSize > DAQ_TIMESTAMP_BYTE ) + dtop->XcpDtoByteField.EightByteField.byte_2 = (vbittype)((t>>8)&0xFFu); + #endif + #if( kXcpDaqTimestampSize > DAQ_TIMESTAMP_WORD ) + dtop->XcpDtoByteField.EightByteField.byte_3 = (vbittype)((t>>16)&0xFFu); + dtop->XcpDtoByteField.EightByteField.byte_4 = (vbittype)((t>>24)&0xFFu); + #endif + #else + dtop->b[i+0u] = (vuint8)t; + #if( kXcpDaqTimestampSize > DAQ_TIMESTAMP_BYTE ) + dtop->b[i+1u] = (vuint8)(t>>8); + #endif + #if( kXcpDaqTimestampSize > DAQ_TIMESTAMP_WORD ) + dtop->b[i+2u] = (vuint8)(t>>16); + dtop->b[i+3u] = (vuint8)(t>>24); + #endif + #endif + #endif + #else + *(XcpDaqTimestampType*)&dtop->b[i] = ApplXcpGetTimestamp(); + #endif /* XCP_DISABLE_UNALIGNED_MEM_ACCESS */ + i += sizeof(XcpDaqTimestampType); + + #endif /* XCP_ENABLE_DAQ_HDR_ODT_DAQ */ + } + + #if !defined ( XCP_ENABLE_DAQ_TIMESTAMP_FIXED ) + } + #endif + + #endif /* XCP_ENABLE_DAQ_TIMESTAMP */ + + /* Sample data */ + /* This is the inner loop, optimize here */ + e = DaqListOdtFirstEntry(odt); + if (OdtEntrySize(e)==0) + { + goto next_odt; + } + el = DaqListOdtLastEntry(odt); + #if defined ( XCP_ALLIGN_WORD ) + i = (i+1)>>1; + d = (vuint8*)&dtop->XcpDtoByteField.b[i]; + #else + d = (vuint8*)&dtop->b[i]; + #endif + if (el!=0xFFFF) //wenn ODT0 kein ODTE hat, gibts sonst mit dem Zeitstempel ein Problem.. + while (e<=el) + { + n = OdtEntrySize(e); + if (n == 0) + { + break; + } + #if defined ( C_COMP_COSMIC_MCS12X_MSCAN12 ) + src = (vuint32)OdtEntryAddr(e); + for ( ; n > 0; n-- ) + { + *d = XCP_READ_BYTE_FROM_ADDR( src ); + d++; + src++; + } + #else + XcpMemCpy((DAQBYTEPTR)d, OdtEntryAddr(e), n); + d = &d[n]; /* d += n; Suppress warning for MISRA rule 101 (pointer arithmetic) */ + #endif + e++; + } + #if defined ( XCP_ALLIGN_WORD ) + dtop->l = (vuint8)(d-(&dtop->XcpDtoByteField.b[0]) ); + #else + dtop->l = (vuint8)(d-(&dtop->b[0]) ); + #endif + #if defined ( XCP_ALLIGN_WORD ) + /* There are 2 bytes within one adress */ + dtop->l = dtop->l << 1; + #endif + XCP_ASSERT(dtop->l<=kXcpMaxDTO); + + /* Queue or transmit the DTO */ + #if defined ( XCP_ENABLE_SEND_QUEUE ) + #if defined ( XCP_SEND_QUEUE_SAMPLE_ODT ) + /* No action yet */ + #else + if ( (xcp.SendStatus & (vuint8)XCP_SEND_PENDING) != 0 ) + { + xcp.QueueLen++; + } + else + { + xcp.SendStatus |= (vuint8)XCP_DTO_PENDING; + XcpSendDto(dtop); + } + #endif + #else + XcpSendDto(&dto); + #endif /* XCP_ENABLE_SEND_QUEUE */ + next_odt: + + ApplXcpInterruptEnable(); + + } /* odt */ + + #if defined ( XCP_ENABLE_SEND_QUEUE ) && defined ( XCP_SEND_QUEUE_SAMPLE_ODT ) + (void)XcpSendDtoFromQueue(); + #endif + + + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + } + #endif + + } /* daq */ + + END_PROFILE(4); /* Timingtest */ + return status; +} + +#endif /* XCP_ENABLE_DAQ */ + + +/****************************************************************************/ +/* Background Processing */ +/* Used for Checksum Calculation */ +/****************************************************************************/ + +#if defined ( XCP_ENABLE_CHECKSUM ) +/* Table for CCITT checksum calculation */ + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) + + + + V_MEMROM0 MEMORY_ROM vuint16 CRC16CCITTtab[256] = { + #if defined ( XCP_ENABLE_CRC16CCITT_REFLECTED ) + 0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF, + 0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C,0xDBE5,0xE97E,0xF8F7, + 0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E, + 0x9CC9,0x8D40,0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876, + 0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434,0x55BD, + 0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5, + 0x3183,0x200A,0x1291,0x0318,0x77A7,0x662E,0x54B5,0x453C, + 0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974, + 0x4204,0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB, + 0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1,0xAB7A,0xBAF3, + 0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A, + 0xDECD,0xCF44,0xFDDF,0xEC56,0x98E9,0x8960,0xBBFB,0xAA72, + 0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9, + 0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1, + 0x7387,0x620E,0x5095,0x411C,0x35A3,0x242A,0x16B1,0x0738, + 0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70, + 0x8408,0x9581,0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7, + 0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76,0x7CFF, + 0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036, + 0x18C1,0x0948,0x3BD3,0x2A5A,0x5EE5,0x4F6C,0x7DF7,0x6C7E, + 0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5, + 0x2942,0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD, + 0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226,0xD0BD,0xC134, + 0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C, + 0xC60C,0xD785,0xE51E,0xF497,0x8028,0x91A1,0xA33A,0xB2B3, + 0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB, + 0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232, + 0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1,0x0D68,0x3FF3,0x2E7A, + 0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1, + 0x6B46,0x7ACF,0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9, + 0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9,0x8330, + 0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78 + #else + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7u, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1efu, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6u, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3deu, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485u, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58du, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4u, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bcu, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823u, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92bu, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12u, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1au, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41u, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49u, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70u, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78u, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16fu, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067u, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35eu, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256u, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50du, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405u, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73cu, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634u, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9abu, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3u, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9au, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92u, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9u, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1u, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8u, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0u + #endif /* defined ( XCP_ENABLE_CRC16CCITT_REFLECTED ) */ + }; + + + + #endif /* ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) */ + + + #if !defined ( kXcpChecksumBlockSize ) + #define kXcpChecksumBlockSize 256 + #endif + +#endif /* defined ( XCP_ENABLE_CHECKSUM ) */ + + +/***************************************************************************** +| NAME: XcpBackground +| CALLED BY: application +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: 0 : background calculation finished +| 1 : background calculation still pending +| DESCRIPTION: perform background calculation of checksum +******************************************************************************/ +vuint8 XcpBackground( void ) +{ + + BEGIN_PROFILE(3); /* Timingtest */ + + /* Activation control */ + XcpPlCheckControlStateRet((vuint8)0u) + + /* STORE_DAQ_REQ or CLEAR_DAQ_REQ pending */ +#if defined ( XCP_ENABLE_DAQ ) +#endif /* XCP_ENABLE_DAQ */ + + /* XCP checksum calculation */ +#if defined ( XCP_ENABLE_CHECKSUM ) + + /* + Checksum algorithm is not defined by the standard + Type is defined by tXcpChecksumSumType, the maximum blocksize is 64K + */ + + /* Checksum calculation in progress */ + if ( (xcp.CheckSumSize) != (tXcpChecksumSumType)0u ) + { + + vuint16 n; + + if (xcp.CheckSumSize<=(kXcpChecksumBlockSize-1)) + { + n = xcp.CheckSumSize; + xcp.CheckSumSize = 0; + } + else + { + n = (vuint16)kXcpChecksumBlockSize; + xcp.CheckSumSize -= kXcpChecksumBlockSize; + } + + + do + { + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) + + #if defined ( XCP_ENABLE_CRC16CCITT_REFLECTED ) + /* CRC16 CCITT Reflected: Refin = true and refout = true. */ + xcp.CheckSum = CRC16CCITTtab[((vuint8)(xcp.CheckSum&0xFF)) ^ XCP_READ_CHECKSUMVALUE_FROM_ADDR( xcp.Mta )] ^ ((vuint8)((xcp.CheckSum>>8)&0xFF)); + #else + /* CRC16 CCITT */ + xcp.CheckSum = CRC16CCITTtab[((vuint8)((xcp.CheckSum >> 8)&0xFF)) ^ XCP_READ_CHECKSUMVALUE_FROM_ADDR( xcp.Mta )] ^ (xcp.CheckSum << 8); + #endif + + xcp.Mta++; + n--; + + #else + + /* Checksum calculation method: XCP_ADD_xx */ + xcp.CheckSum += (tXcpChecksumSumType)(XCP_READ_CHECKSUMVALUE_FROM_ADDR( xcp.Mta )); + xcp.Mta += (vuint8)sizeof(tXcpChecksumAddType); + n -= (vuint8)sizeof(tXcpChecksumAddType); + + #endif + } + while (n!=0); + + + /* Checksum calculation finished ? */ + if ( (xcp.CheckSumSize) != 0 ) + { + END_PROFILE(3); /* Timingtest */ + return (vuint8)1u; /* Still pending */ + } + + CRM_BUILD_CHECKSUM_TYPE = kXcpChecksumMethod; + CRM_BUILD_CHECKSUM_RESULT = xcp.CheckSum; + xcp.CrmLen = CRM_BUILD_CHECKSUM_LEN; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF checksum=%08Xh, type=%02Xh\n",CRM_BUILD_CHECKSUM_RESULT,CRM_BUILD_CHECKSUM_TYPE); + } + #endif + + XcpSendCrm(); + + } /* xcp.CheckSumSize */ +#endif /* XCP_ENABLE_CHECKSUM */ + + /* Application specific background ground loop. */ + ApplXcpBackground(); + + END_PROFILE(3); /* Timingtest */ + + return (vuint8)0u; +} + + +/****************************************************************************/ +/* Command Processor */ +/****************************************************************************/ + + +/***************************************************************************** +| NAME: XcpDisconnect +| CALLED BY: XcpCommand +| PRECONDITIONS: XCP is initialized and in connected state. +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: If the XCP slave is connected to a XCP master a call of this +| function discontinues the connection (transition to disconnected state). +| If the XCP slave is not connected this function performs no action. +******************************************************************************/ +void XcpDisconnect( void ) +{ + /* Activation control */ + XcpPlCheckControlState() + + xcp.SessionStatus &= (vuint8)(~SS_CONNECTED & 0xFFu); + +#if defined ( XCP_ENABLE_DAQ ) + XcpStopAllDaq(); +#endif +#if defined ( XCP_ENABLE_SEED_KEY ) + /* Lock all resources */ + xcp.ProtectionStatus = (vuint8)RM_CAL_PAG|RM_DAQ|RM_PGM|RM_STIM; +#endif + +} + + +/***************************************************************************** +| NAME: XcpCommand +| CALLED BY: XcpSendCallBack, XCP Transport Layer +| PRECONDITIONS: none +| INPUT PARAMETERS: pCmd : data of received CTO message. +| RETURN VALUES: none +| DESCRIPTION: +******************************************************************************/ +void XcpCommand( MEMORY_ROM vuint32* pCommand ) +{ + MEMORY_ROM tXcpCto* pCmd = (MEMORY_ROM tXcpCto*) pCommand; + vuint8 err; + + /* Activation control */ + XcpPlCheckControlState() + + /* XCP Data Stimulation Handler */ + + + + /* XCP Command Handler */ + + BEGIN_PROFILE(1); /* Timingtest */ + + /* CONNECT */ + if (CRO_CMD==CC_CONNECT) + { + + /* Prepare the default response */ + /* ESCAN00023570 */ + CRM_CMD = 0xFF; /* No Error */ + xcp.CrmLen = 1; /* Length = 1 */ + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("\n-> CONNECT mode=%u\n",CRO_CONNECT_MODE); + } +#endif + + /* DPRAM */ + /* DPRAM Client */ + + /* Reset DAQ */ + /* Do not reset DAQ if in resume mode */ +#if defined ( XCP_ENABLE_DAQ ) + if ( (xcp.SessionStatus & (vuint8)SS_RESUME) == 0 ) + { + XcpFreeDaq(); + #if defined ( XCP_ENABLE_SEND_QUEUE ) + xcp.SendStatus = 0; /* Clear all transmission flags */ + #endif + } +#endif /* XCP_ENABLE_DAQ */ + +#if defined ( XCP_ENABLE_SEED_KEY ) + /* Lock all resources. */ + xcp.ProtectionStatus = (vuint8)RM_CAL_PAG|RM_DAQ|RM_PGM|RM_STIM; +#endif + + /* Reset Session Status */ + xcp.SessionStatus = SS_CONNECTED; + + xcp.CrmLen = CRM_CONNECT_LEN; + + /* Versions of the XCP Protocol Layer and Transport Layer Specifications. */ + CRM_CONNECT_TRANSPORT_VERSION = (vuint8)( (vuint16)XCP_TRANSPORT_LAYER_VERSION >> 8 ); + CRM_CONNECT_PROTOCOL_VERSION = (vuint8)( (vuint16)XCP_VERSION >> 8 ); + + CRM_CONNECT_MAX_CTO_SIZE = kXcpMaxCTO; + CRM_CONNECT_MAX_DTO_SIZE = kXcpMaxDTO; + +#if defined ( XCP_ENABLE_CALIBRATION_PAGE ) + CRM_CONNECT_RESOURCE = RM_CAL_PAG; /* Calibration */ +#else + CRM_CONNECT_RESOURCE = 0x00; /* Reset resource mask */ +#endif +#if defined ( XCP_ENABLE_DAQ ) + CRM_CONNECT_RESOURCE |= (vuint8)RM_DAQ; /* Data Acquisition */ +#endif + + CRM_CONNECT_COMM_BASIC = 0; +#if defined ( XCP_ENABLE_COMM_MODE_INFO ) + CRM_CONNECT_COMM_BASIC |= (vuint8)CMB_OPTIONAL; +#endif +#if defined ( XCP_ALLIGN_WORD ) + CRM_CONNECT_COMM_BASIC |= (vuint8)CMB_ADDRESS_GRANULARITY_WORD; +#endif +#if defined ( XCP_CPUTYPE_BIGENDIAN ) + CRM_CONNECT_COMM_BASIC |= (vuint8)PI_MOTOROLA; +#endif + + XCP_PRINT(("<- 0xFF version=%02Xh/%02Xh, maxcro=%02Xh, maxdto=%02Xh, resource=%02X, mode=%02X\n", + CRM_CONNECT_PROTOCOL_VERSION, + CRM_CONNECT_TRANSPORT_VERSION, + CRM_CONNECT_MAX_CTO_SIZE, + CRM_CONNECT_MAX_DTO_SIZE, + CRM_CONNECT_RESOURCE, + CRM_CONNECT_COMM_BASIC)); + + goto positive_response; + + } + + /* Handle other commands only if connected */ + else /* CC_CONNECT */ + { + if ( (xcp.SessionStatus & (vuint8)SS_CONNECTED) != 0 ) + { + /* Ignore commands if the previous command sequence has not been completed */ +#if defined ( XCP_ENABLE_SEND_QUEUE ) + if ( (xcp.SendStatus & (vuint8)(XCP_CRM_PENDING|XCP_CRM_REQUEST)) != 0 ) + { + xcp.SessionStatus |= (vuint8)SS_ERROR; + END_PROFILE(1); /* Timingtest */ + + /* No response */ + return; + } +#endif + + /* Prepare the default response */ + /* ESCAN00023570 */ + CRM_CMD = 0xFF; /* No Error */ + xcp.CrmLen = 1; /* Length = 1 */ + + switch (CRO_CMD) + { + + case CC_SYNC: + { + /* Always return a negative response with the error code ERR_CMD_SYNCH. */ + xcp.CrmLen = CRM_SYNCH_LEN; + CRM_CMD = PID_ERR_XCP; + CRM_ERR = CRC_CMD_SYNCH; + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> SYNC\n"); + ApplXcpPrint("<- 0xFE 0x00\n"); + } +#endif + } + break; + + +#if defined ( XCP_ENABLE_COMM_MODE_INFO ) + case CC_GET_COMM_MODE_INFO: + { + xcp.CrmLen = CRM_GET_COMM_MODE_INFO_LEN; + /* Transmit the version of the XCP Protocol Layer implementation. */ + /* The higher nibble is the main version, the lower the sub version. */ + /* The lower nibble overflows, if the sub version is greater than 15.*/ + CRM_GET_COMM_MODE_INFO_DRIVER_VERSION = (vuint8)( ((CP_XCP_VERSION & 0x0F00) >> 4) | + (CP_XCP_VERSION & 0x000F) ); + CRM_GET_COMM_MODE_INFO_COMM_OPTIONAL = 0; + CRM_GET_COMM_MODE_INFO_QUEUE_SIZE = 0; + CRM_GET_COMM_MODE_INFO_MAX_BS = 0; + CRM_GET_COMM_MODE_INFO_MIN_ST = 0; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_COMM_MODE_INFO\n"); + ApplXcpPrint("<- 0xFF \n"); + } + #endif + + } + break; +#endif /* XCP_ENABLE_COMM_MODE_INFO */ + + + case CC_DISCONNECT: + { + xcp.CrmLen = CRM_DISCONNECT_LEN; + XcpDisconnect(); + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> DISCONNECT\n"); + ApplXcpPrint("<- 0xFF\n"); + } +#endif + } + break; + + +#if defined ( kXcpStationIdLength ) || defined ( XCP_ENABLE_VECTOR_MAPNAMES ) + case CC_GET_ID: + { + xcp.CrmLen = CRM_GET_ID_LEN; + CRM_GET_ID_MODE = 0; + CRM_GET_ID_LENGTH = 0; + + #if defined ( kXcpStationIdLength ) + if ( CRO_GET_ID_TYPE == IDT_ASAM_NAME ) /* Type = ASAM MC2 */ + { + CRM_GET_ID_LENGTH = (vuint32)kXcpStationIdLength; + XcpSetMta( ApplXcpGetPointer(0xFF, (vuint32)(&kXcpStationId[0])), 0xFF); + } + #endif + #if defined ( XCP_ENABLE_VECTOR_MAPNAMES ) + if ( CRO_GET_ID_TYPE == IDT_VECTOR_MAPNAMES ) /* Type = Vector Type */ + { + MTABYTEPTR pData; + + CRM_GET_ID_LENGTH = ApplXcpGetIdData(&pData); + XcpSetMta(pData,0xFF); + } + #endif + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_ID type=%u\n",CRO_GET_ID_TYPE); + ApplXcpPrint("<- 0xFF mode=%u,len=%u\n",CRM_GET_ID_MODE,CRM_GET_ID_LENGTH); + } + #endif + } + break; +#endif + + + case CC_GET_STATUS: + { + xcp.CrmLen = CRM_GET_STATUS_LEN; + CRM_GET_STATUS_STATUS = xcp.SessionStatus; +#if defined ( XCP_ENABLE_SEED_KEY ) + /* Return current resource protection status. If a bit is one, the associated resource is locked. */ + CRM_GET_STATUS_PROTECTION = xcp.ProtectionStatus; +#else + CRM_GET_STATUS_PROTECTION = 0; +#endif + + /* Session configuration ID not available. */ + CRM_GET_STATUS_CONFIG_ID = 0x00; + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_STATUS\n"); + ApplXcpPrint("<- 0xFF sessionstatus=%02Xh, protectionstatus=%02X\n",CRM_GET_STATUS_STATUS,CRM_GET_STATUS_PROTECTION); + } +#endif + } + break; + + +#if defined ( XCP_ENABLE_SEED_KEY ) + + case CC_GET_SEED: + { + /* Only seeds with a maximum length of MAX_CTO-2 are supported so far. */ + + /* Check whether the first part or a remaining part of the seed is requested. */ + if (CRO_GET_SEED_MODE == 0x01) + { + /* Remaining parts of seeds are not supported so far. */ + error(CRC_OUT_OF_RANGE) + } + else + { + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + /* Only one resource may be requested at one time. */ + switch (CRO_GET_SEED_RESOURCE) + { + case RM_CAL_PAG: + break; + case RM_PGM: + break; + case RM_DAQ: + break; + case RM_STIM: + break; + default: + error(CRC_OUT_OF_RANGE) + } + + #endif + if ((xcp.ProtectionStatus & CRO_GET_SEED_RESOURCE) != 0) /* locked */ + { + vuint8 seedLength; + seedLength = ApplXcpGetSeed(CRO_GET_SEED_RESOURCE, CRM_GET_SEED_DATA); + if (seedLength > (vuint8)(kXcpMaxCTO-2)) + { + /* A maximum seed length of MAX_CTO-2 is supported. */ + error(CRC_OUT_OF_RANGE) + } + CRM_GET_SEED_LENGTH = seedLength; + } + else /* Unlocked */ + { + /* return 0 if the resource is unprotected. */ + CRM_GET_SEED_LENGTH = 0; + } + xcp.CrmLen = (vuint8)CRM_GET_SEED_LEN; + } + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_SEED resource=%02Xh\n",CRO_GET_SEED_RESOURCE); + ApplXcpPrint("<- 0xFF length=%02Xh, seed=%02X%02X%02X%02X%02X%02X\n",CRM_GET_SEED_LENGTH,CRM_GET_SEED_DATA[0],CRM_GET_SEED_DATA[1],CRM_GET_SEED_DATA[2],CRM_GET_SEED_DATA[3],CRM_GET_SEED_DATA[4],CRM_GET_SEED_DATA[5]); + } + #endif + } + break; + + case CC_UNLOCK: + { + vuint8 resource; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> UNLOCK key=%02X%02X%02X%02X%02X%02X\n",CRO_UNLOCK_KEY[0],CRO_UNLOCK_KEY[1],CRO_UNLOCK_KEY[2],CRO_UNLOCK_KEY[3],CRO_UNLOCK_KEY[4],CRO_UNLOCK_KEY[5]); + } + #endif + + /* Only keys with a maximum length of MAX_CTO-2 are supported so far. */ + if (CRO_UNLOCK_LENGTH > (vuint8)(kXcpMaxCTO-2)) + { + error(CRC_SEQUENCE) + } + else + { + resource = ApplXcpUnlock(CRO_UNLOCK_KEY, CRO_UNLOCK_LENGTH); + if ( resource == (vuint8)0x00u ) + { + /* Key wrong ! */ + /* Send ERR_ACCESS_LOCKED and go to disconnected state. */ + XcpDisconnect(); + error(CRC_ACCESS_LOCKED) + } + else + { + /* unlock (reset) the appropriate resource protection mask bit.. */ + xcp.ProtectionStatus &= (vuint8)~resource; + + /* ..and return the current resource protection status. */ + CRM_UNLOCK_PROTECTION = xcp.ProtectionStatus; + xcp.CrmLen = CRM_UNLOCK_LEN; + } + } + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + +#endif /* XCP_ENABLE_SEED_KEY */ + + +#if defined ( XCP_ENABLE_CALIBRATION_PAGE ) + + case CC_SET_CAL_PAGE: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> SET_CAL_PAGE segment=%u,page =%u,mode=%02Xh\n",CRO_SET_CAL_PAGE_SEGMENT,CRO_SET_CAL_PAGE_PAGE,CRO_SET_CAL_PAGE_MODE); + } + #endif + + check_error( ApplXcpSetCalPage(CRO_SET_CAL_PAGE_SEGMENT,CRO_SET_CAL_PAGE_PAGE,CRO_SET_CAL_PAGE_MODE) ) + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_GET_CAL_PAGE: + { + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_CAL_PAGE Segment=%u, Mode=%u\n",CRO_GET_CAL_PAGE_SEGMENT,CRO_GET_CAL_PAGE_MODE); + } + #endif + + xcp.CrmLen = CRM_GET_CAL_PAGE_LEN; + CRM_GET_CAL_PAGE_PAGE = ApplXcpGetCalPage(CRO_GET_CAL_PAGE_SEGMENT,CRO_GET_CAL_PAGE_MODE); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF page=%u\n",CRM_GET_CAL_PAGE_PAGE); + } + #endif + } + break; + +#endif /* XCP_ENABLE_CALIBRATION_PAGE */ + + +#if defined ( XCP_ENABLE_PAGE_INFO ) + /* Paging Information optional */ + case CC_GET_PAG_PROCESSOR_INFO: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_GET_PAG_PROCESSOR_INFO"); + } + #endif + + xcp.CrmLen = CRM_GET_PAG_PROCESSOR_INFO_LEN; + + CRM_GET_PAG_PROCESSOR_INFO_MAX_SEGMENT = (vuint8)kXcpMaxSegment; + #if defined ( XCP_ENABLE_PAGE_FREEZE ) + CRM_GET_PAG_PROCESSOR_INFO_PROPERTIES = 1; /* FREEZE_SUPPORTED = 1 */ + #else + CRM_GET_PAG_PROCESSOR_INFO_PROPERTIES = 0; /* FREEZE_SUPPORTED = 0 */ + #endif + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF maxsegment=%u\n",(vuint8)kXcpMaxSegment); + } + #endif + + } + break; + + + case CC_GET_SEGMENT_INFO: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_GET_SEGMENT_INFO"); + } + #endif + + if (CRO_GET_SEGMENT_INFO_NUMBER >= (vuint8)kXcpMaxSegment) + { + error(CRC_OUT_OF_RANGE) + } + + xcp.CrmLen = CRM_GET_SEGMENT_INFO_LEN; + /* Get standard info for a segment. + SEGMENT_INFO and MAPPING_INDEX are don't care + */ + if (CRO_GET_SEGMENT_INFO_MODE == 1) + { + CRM_GET_SEGMENT_INFO_MAX_PAGES = 2; + CRM_GET_SEGMENT_INFO_ADDRESS_EXTENSION = 0; + CRM_GET_SEGMENT_INFO_MAX_MAPPING = 0; + CRM_GET_SEGMENT_INFO_COMPRESSION = 0; + CRM_GET_SEGMENT_INFO_ENCRYPTION = 0; + + } + /* Get basic address info for a segment: + SEGMENT_INFO contains address range information and + MAPPING_INDEX is don't care + Get address mapping for a segment: + SEGMENT_INFO contains address range information and + MAPPING_INDEX indicates the range MAPPING_INFO belongs to + */ + if ( (CRO_GET_SEGMENT_INFO_MODE == 0) || (CRO_GET_SEGMENT_INFO_MODE == 2) ) + { + CRM_GET_SEGMENT_INFO_MAPPING_INFO = 0; + } + + #if defined ( XCP_ENABLE_TESTMODE ) + if (gDebugLevel && CRO_GET_SEGMENT_INFO_MODE == 1) + { + ApplXcpPrint("<- 0xFF Mode=%u, Maxpages=%u, AddrExt=%u, Mappingmax=%u, Compression=%u, Encryption=%u\n",CRO_GET_SEGMENT_INFO_MODE,CRM_GET_SEGMENT_INFO_MAX_PAGES,CRM_GET_SEGMENT_INFO_ADDRESS_EXTENSION,CRM_GET_SEGMENT_INFO_MAX_MAPPING,CRM_GET_SEGMENT_INFO_COMPRESSION,CRM_GET_SEGMENT_INFO_ENCRYPTION); + } + if (gDebugLevel && CRO_GET_SEGMENT_INFO_MODE == 0 || CRO_GET_SEGMENT_INFO_MODE == 2) + { + ApplXcpPrint("<- 0xFF Mode=%u, MappingInfo=%u\n",CRO_GET_SEGMENT_INFO_MODE,CRM_GET_SEGMENT_INFO_MAPPING_INFO); + } + #endif + } + break; + + case CC_GET_PAGE_INFO: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_GET_PAGE_INFO"); + } + #endif + + if ( ( CRO_GET_PAGE_INFO_SEGMENT_NUMBER > ((vuint8)(kXcpMaxSegment-1)&0xFFu) ) || + ( CRO_GET_PAGE_INFO_PAGE_NUMBER >((vuint8)(kXcpMaxPages-1)&0xFFu) ) ) + { + error(CRC_OUT_OF_RANGE) + } + + xcp.CrmLen = CRM_GET_PAGE_INFO_LEN; + CRM_GET_PAGE_INFO_PROPERTIES = 0; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF properties=%u\n",CRM_GET_PAGE_INFO_PROPERTIES); + } + #endif + } + break; +#endif /* defined ( XCP_BASIC_VERSION_COMMENT ) */ + + /* Paging freeze mode support */ +#if defined ( XCP_ENABLE_PAGE_FREEZE ) + case CC_SET_SEGMENT_MODE: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_SET_SEGMENT_MODE segment=%u, mode=%u\n",CRO_SET_SEGMENT_MODE_SEGMENT,CRO_SET_SEGMENT_MODE_MODE); + } + #endif + + if (CRO_SET_SEGMENT_MODE_SEGMENT > ((vuint8)(kXcpMaxSegment-1)&0xFFu)) + { + error(CRC_OUT_OF_RANGE) + } + + /* inform application about Set Segment Mode command */ + ApplXcpSetFreezeMode(CRO_SET_SEGMENT_MODE_SEGMENT, CRO_SET_SEGMENT_MODE_MODE); + /* CRO_SET_SEGMENT_MODE_MODE;*/ + xcp.CrmLen = CRM_SET_SEGMENT_MODE_LEN; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_GET_SEGMENT_MODE: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_GET_SEGMENT_MODE"); + } + #endif + + if (CRO_GET_SEGMENT_MODE_SEGMENT > ((vuint8)(kXcpMaxSegment-1)&0xFFu)) + { + error(CRC_OUT_OF_RANGE) + } + + /* request current freeze mode information from application */ + CRM_GET_SEGMENT_MODE_MODE = ApplXcpGetFreezeMode(CRO_GET_SEGMENT_MODE_SEGMENT); + + xcp.CrmLen = CRM_GET_SEGMENT_MODE_LEN; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF mode=%u\n",CRM_GET_SEGMENT_MODE_MODE); + } + #endif + } + break; +#endif /* XCP_ENABLE_PAGE_FREEZE */ + + /* Copy cal page support */ +#if defined ( XCP_ENABLE_PAGE_COPY ) + case CC_COPY_CAL_PAGE: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_COPY_CAL_PAGE"); + } + #endif + + xcp.CrmLen = CRM_COPY_CAL_PAGE_LEN; + + err = ApplXcpCopyCalPage(CRO_COPY_CAL_PAGE_SRC_SEGMENT,CRO_COPY_CAL_PAGE_SRC_PAGE,CRO_COPY_CAL_PAGE_DEST_SEGMENT,CRO_COPY_CAL_PAGE_DEST_PAGE); + + if (err==(vuint8)XCP_CMD_PENDING) + { + goto no_response; + } + + check_error( err ) + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; +#endif /* XCP_ENABLE_PAGE_COPY */ + + + case CC_SET_MTA: + { +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> SET_MTA addr=%08Xh, addrext=%02Xh\n",CRO_SET_MTA_ADDR,CRO_SET_MTA_EXT); + } +#endif + XcpSetMta(ApplXcpGetPointer(CRO_SET_MTA_EXT,CRO_SET_MTA_ADDR),CRO_SET_MTA_EXT); + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } +#endif + } + break; + + + case CC_DOWNLOAD: + { +#if defined ( XCP_ENABLE_CALIBRATION ) + vuint8 size; + +#if defined ( XCP_ENABLE_TESTMODE ) + if (gDebugLevel && (CRO_CMD != CC_DOWNLOAD_NEXT)) + { + vuint16 i; + ApplXcpPrint("-> DOWNLOAD size=%u, data=",CRO_DOWNLOAD_SIZE); + for (i=0;(iCRO_DOWNLOAD_MAX_SIZE) + { + error(CRC_OUT_OF_RANGE) + } + + err = XcpWriteMta(size,CRO_DOWNLOAD_DATA); + if (err==(vuint8)XCP_CMD_PENDING) + { + goto no_response; + } + if (err==(vuint8)XCP_CMD_DENIED) + { + error(CRC_WRITE_PROTECTED) + } + if (err==(vuint8)XCP_CMD_SYNTAX) + { + error(CRC_CMD_SYNTAX) + } + + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } +#endif +#else + error(CRC_CMD_UNKNOWN) +#endif /* !defined ( XCP_ENABLE_CALIBRATION ) */ + + } + break; + + case CC_DOWNLOAD_MAX: + { +#if defined ( XCP_ENABLE_CALIBRATION ) + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + vuint16 i; + ApplXcpPrint("DOWNLOAD_MAX data="); + for (i=0;i UPLOAD size=%u\n",size); + } +#endif + + if ( size > (vuint8)CRM_UPLOAD_MAX_SIZE ) + { + error(CRC_OUT_OF_RANGE) + } + err = XcpReadMta(size,CRM_UPLOAD_DATA); + xcp.CrmLen = (vuint8)((CRM_UPLOAD_LEN+size)&0xFFu); + if (err==(vuint8)XCP_CMD_PENDING) + { + goto no_response; + } + if (err==(vuint8)XCP_CMD_DENIED) + { + error(CRC_ACCESS_DENIED) + } + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + vuint16 i; + ApplXcpPrint("<- 0xFF data="); + for (i=0;i SHORT_UPLOAD addr=%08Xh, addrext=%02Xh, size=%u\n",CRO_SHORT_UPLOAD_ADDR,CRO_SHORT_UPLOAD_EXT,CRO_SHORT_UPLOAD_SIZE); + } +#endif + +#if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (CRO_SHORT_UPLOAD_SIZE > (vuint8)CRM_SHORT_UPLOAD_MAX_SIZE) + { + error(CRC_OUT_OF_RANGE) + } +#endif + XcpSetMta(ApplXcpGetPointer(CRO_SHORT_UPLOAD_EXT,CRO_SHORT_UPLOAD_ADDR),CRO_SHORT_UPLOAD_EXT); + err = XcpReadMta(CRO_SHORT_UPLOAD_SIZE,CRM_SHORT_UPLOAD_DATA); + xcp.CrmLen = (vuint8)((CRM_SHORT_UPLOAD_LEN+CRO_SHORT_UPLOAD_SIZE)&0xFFu); + if (err==(vuint8)XCP_CMD_PENDING) + { + goto no_response; /* ESCAN00014775 */ + } + if (err==(vuint8)XCP_CMD_DENIED) + { + error(CRC_ACCESS_DENIED) + } + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + vuint16 i; + ApplXcpPrint("<- 0xFF data="); + for (i=0; i < (vuint16)CRO_SHORT_UPLOAD_SIZE; i++) + { + ApplXcpPrint("%02X ",CRM_SHORT_UPLOAD_DATA[i]); + } + ApplXcpPrint("\n"); + } +#endif + } + break; + + +#if defined ( XCP_ENABLE_CHECKSUM ) + + case CC_BUILD_CHECKSUM: /* Build Checksum */ + { + vuint32 s; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> BUILD_CHECKSUM size=%u\n",CRO_BUILD_CHECKSUM_SIZE); + } + #endif + + /* Initialization of checksum calculation. */ + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC32 ) + xcp.CheckSum = (tXcpChecksumSumType)0xFFFFFFFFu; + #else + xcp.CheckSum = (tXcpChecksumSumType)0u; + #endif + s = CRO_BUILD_CHECKSUM_SIZE; + /* The blocksize is limited to WORD length. */ + /* If the blocksize exceeds the allowed maximum transmit negative response. */ + if ( (s & (vuint32)0xffff0000u) != (vuint32)0u ) + { + CRM_BUILD_CHECKSUM_RESULT = 0xFFFFu; /* Range, max. 64K-1 */ + err = CRC_OUT_OF_RANGE; + xcp.CrmLen = CRM_BUILD_CHECKSUM_LEN; + /* Response length is arbitrary */ + goto negative_response1; + } + else + { + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + /* Parameter check whether the block size is modulo 2 for ADD_22, ADD_24 */ + /* and ADD_44 (modulo 4). */ + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) + if ( (s % (vuint32)sizeof(tXcpChecksumAddType)) != (vuint32)0u ) + { + error(CRC_OUT_OF_RANGE) + } + else + #endif + #endif + { + xcp.CheckSumSize = (vuint16)s; + goto no_response; /* Checksum calculation will be performed by XcpBackground() */ + } + } + } + /* break; never reached */ + +#endif /* XCP_ENABLE_CHECKSUM */ + + +#if defined ( XCP_ENABLE_DAQ ) + + #if defined ( XCP_ENABLE_DAQ_PROCESSOR_INFO ) + + case CC_GET_DAQ_PROCESSOR_INFO: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_DAQ_PROCESSOR_INFO\n"); + } + #endif + + xcp.CrmLen = CRM_GET_DAQ_PROCESSOR_INFO_LEN; + CRM_GET_DAQ_PROCESSOR_INFO_MIN_DAQ = 0; + CRM_GET_DAQ_PROCESSOR_INFO_MAX_DAQ = xcp.Daq.DaqCount; /* dynamic or static */ + #if defined ( kXcpMaxEvent ) + CRM_GET_DAQ_PROCESSOR_INFO_MAX_EVENT = kXcpMaxEvent; + #else + CRM_GET_DAQ_PROCESSOR_INFO_MAX_EVENT = 0; /* Unknown */ + #endif + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) +#if defined (XCP_ALLIGN_WORD) + CRM_GET_DAQ_PROCESSOR_INFO_DAQ_KEY_BYTE = (vuint8)DAQ_HDR_ODT_DAQW; +#else + /* DTO identification field type: Relative ODT number, absolute list number (BYTE) */ + CRM_GET_DAQ_PROCESSOR_INFO_DAQ_KEY_BYTE = (vuint8)DAQ_HDR_ODT_DAQB; +#endif + #else + /* DTO identification field type: Absolute ODT number */ + CRM_GET_DAQ_PROCESSOR_INFO_DAQ_KEY_BYTE = (vuint8)DAQ_HDR_PID; + #endif + CRM_GET_DAQ_PROCESSOR_INFO_PROPERTIES = (vuint8)( DAQ_PROPERTY_CONFIG_TYPE + #if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + | DAQ_PROPERTY_TIMESTAMP + #endif + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + | DAQ_PROPERTY_PRESCALER + #endif + #if defined ( XCP_ENABLE_DAQ_OVERRUN_INDICATION ) /* DAQ_PROPERTY_OVERLOAD_INDICATION */ + | DAQ_OVERLOAD_INDICATION_PID + #endif + ); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + #endif /* XCP_ENABLE_DAQ_PROCESSOR_INFO */ + + #if defined ( XCP_ENABLE_DAQ_RESOLUTION_INFO ) + + case CC_GET_DAQ_RESOLUTION_INFO: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_DAQ_RESOLUTION_INFO\n"); + } + #endif + + xcp.CrmLen = CRM_GET_DAQ_RESOLUTION_INFO_LEN; + CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_DAQ = GRANULARITY_ODT_ENTRY_SIZE_ODT; + CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_STIM = 1; + CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_DAQ = (vuint8)XCP_MAX_ODT_ENTRY_SIZE; + CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_STIM = (vuint8)XCP_MAX_ODT_ENTRY_SIZE; + #if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_MODE = kXcpDaqTimestampUnit | (vuint8)sizeof(XcpDaqTimestampType) + #if defined ( XCP_ENABLE_DAQ_TIMESTAMP_FIXED ) + | DAQ_TIMESTAMP_FIXED + #endif + ; + CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS = kXcpDaqTimestampTicksPerUnit; /* BCD coded */ + #else + CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_MODE = 0; + CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS = 0; + #endif /* XCP_ENABLE_DAQ_TIMESTAMP */ + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF , mode=%02Xh, , ticks=%02Xh\n",CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_MODE,CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS); + } + #endif + } + break; + #endif /* XCP_ENABLE_DAQ_RESOLUTION_INFO */ + + #if defined ( XCP_ENABLE_DAQ_EVENT_INFO ) && defined ( kXcpMaxEvent ) + case CC_GET_DAQ_EVENT_INFO: + { + vuint8 event = (vuint8)CRO_GET_DAQ_EVENT_INFO_EVENT; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_DAQ_EVENT_INFO event=%u\n",event); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (event >= (vuint8)kXcpMaxEvent ) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + xcp.CrmLen = CRM_GET_DAQ_EVENT_INFO_LEN; + CRM_GET_DAQ_EVENT_INFO_PROPERTIES = kXcpEventDirection[event]; + CRM_GET_DAQ_EVENT_INFO_MAX_DAQ_LIST = 1; /* Only one DAQ-List available per event channel */ + CRM_GET_DAQ_EVENT_INFO_NAME_LENGTH = kXcpEventNameLength[event]; + CRM_GET_DAQ_EVENT_INFO_TIME_CYCLE = kXcpEventCycle[event]; + #if defined ( XCP_ENABLE_CANAPE_5_5_X_SUPPORT ) + CRM_GET_DAQ_EVENT_INFO_TIME_UNIT = kXcpEventUnit[event]; + #else + CRM_GET_DAQ_EVENT_INFO_TIME_UNIT = kXcpEventUnit[event]>>4; + #endif + CRM_GET_DAQ_EVENT_INFO_PRIORITY = 0; /* Event channel prioritization is not supported. */ + XcpSetMta( ApplXcpGetPointer( 0xFF, (vuint32)kXcpEventName[event]), 0xFF ); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF name=%s, unit=%u, cycle=%u\n",kXcpEventName[event],CRM_GET_DAQ_EVENT_INFO_TIME_UNIT,CRM_GET_DAQ_EVENT_INFO_TIME_CYCLE); + } + #endif + } + break; + #endif /* XCP_ENABLE_DAQ_EVENT_INFO && kXcpMaxEvent */ + + + case CC_FREE_DAQ: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> FREE_DAQ\n"); + } + #endif + + CheckResourceProtection( RM_DAQ ) + + XcpFreeDaq(); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_ALLOC_DAQ: + { + vuint8 count = (vuint8)CRO_ALLOC_DAQ_COUNT; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> ALLOC_DAQ count=%u\n",count); + } + #endif + + check_error( XcpAllocDaq(count) ) + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_ALLOC_ODT: + { + vuint8 daq = (vuint8)CRO_ALLOC_ODT_DAQ; + vuint8 count = CRO_ALLOC_ODT_COUNT; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> ALLOC_ODT daq=%u, count=%u\n",daq,count); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (daq>=xcp.Daq.DaqCount) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + check_error( XcpAllocOdt(daq, count) ) + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_ALLOC_ODT_ENTRY: + { + vuint8 daq = (vuint8)CRO_ALLOC_ODT_ENTRY_DAQ; + vuint8 odt = CRO_ALLOC_ODT_ENTRY_ODT; + vuint8 count = CRO_ALLOC_ODT_ENTRY_COUNT; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> ALLOC_ODT_ENTRY daq=%u, odt=%u, count=%u\n",daq,odt,count); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if ( (daq>=xcp.Daq.DaqCount) || (odt>=(vuint8)DaqListOdtCount(daq)) ) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + check_error( XcpAllocOdtEntry(daq, odt, count) ) + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_GET_DAQ_LIST_MODE: + { + vuint8 daq = (vuint8)CRO_GET_DAQ_LIST_MODE_DAQ; + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_DAQ_LIST_MODE daq=%u\n",daq); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (daq>=xcp.Daq.DaqCount) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + xcp.CrmLen = CRM_GET_DAQ_LIST_MODE_LEN; + CRM_GET_DAQ_LIST_MODE_MODE = DaqListFlags(daq); + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + CRM_GET_DAQ_LIST_MODE_PRESCALER = DaqListPrescaler(daq); + #else + CRM_GET_DAQ_LIST_MODE_PRESCALER = 1; + #endif + #if defined ( kXcpMaxEvent ) + CRM_GET_DAQ_LIST_MODE_EVENTCHANNEL = 0; /* #### Lookup in EventDaq[]*/ + #else + CRM_GET_DAQ_LIST_MODE_EVENTCHANNEL = DaqListEventChannel(daq); + #endif + CRM_GET_DAQ_LIST_MODE_PRIORITY = 0; /* DAQ-list prioritization is not supported. */ + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF mode=%02X, prescaler=%u, eventChannel=%u, priority=%u, /*maxOdtEntrySize=%u*/ \n", + CRM_GET_DAQ_LIST_MODE_MODE,CRM_GET_DAQ_LIST_MODE_PRESCALER,CRM_GET_DAQ_LIST_MODE_EVENTCHANNEL,CRM_GET_DAQ_LIST_MODE_PRIORITY); + } + #endif + } + break; + + case CC_SET_DAQ_LIST_MODE: + { + vuint8 daq = (vuint8)CRO_SET_DAQ_LIST_MODE_DAQ; + #if defined ( XCP_ENABLE_TESTMODE ) || defined ( XCP_ENABLE_DAQ_PRESCALER ) || ( !defined ( XCP_ENABLE_DAQ_PRESCALER ) && defined ( XCP_ENABLE_PARAMETER_CHECK ) ) + vuint8 xcpPrescaler = CRO_SET_DAQ_LIST_MODE_PRESCALER; + #endif + vuint8 event = (vuint8)(CRO_SET_DAQ_LIST_MODE_EVENTCHANNEL&0xFFu); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> SET_DAQ_LIST_MODE daq=%u, mode=%02Xh, prescaler=%u, eventchannel=%u\n", + daq,CRO_SET_DAQ_LIST_MODE_MODE,prescaler,event); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (daq>=xcp.Daq.DaqCount) + { + error(CRC_OUT_OF_RANGE) + } + #if defined ( kXcpMaxEvent ) + if (event >= (vuint8)kXcpMaxEvent) + { + error(CRC_OUT_OF_RANGE) + } + #endif + #if !defined ( XCP_ENABLE_DAQ_PRESCALER ) + if (xcpPrescaler!=1) + { + error(CRC_OUT_OF_RANGE) + } + #endif + if (CRO_SET_DAQ_LIST_MODE_PRIORITY!=0) /* Priorization is not supported */ + { + error(CRC_OUT_OF_RANGE) + } + #endif + + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + if (xcpPrescaler==0) + { + xcpPrescaler = 1; + } + DaqListPrescaler(daq) = xcpPrescaler; + #endif + #if defined ( kXcpMaxEvent ) + xcp.Daq.EventDaq[event] = daq; + #else + DaqListEventChannel(daq) = event; + #endif + DaqListFlags(daq) = CRO_SET_DAQ_LIST_MODE_MODE; + + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + + break; + } + + + case CC_SET_DAQ_PTR: + { + vuint8 daq = (vuint8) (CRO_SET_DAQ_PTR_DAQ&0xFFu); + vuint8 odt = CRO_SET_DAQ_PTR_ODT; + vuint8 idx = CRO_SET_DAQ_PTR_IDX; + tXcpOdtIdx odt0 = (tXcpOdtIdx)(DaqListFirstOdt(daq)+odt); /* Absolute odt number */ + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> SET_DAQ_PTR daq=%u,odt=%u,idx=%u\n",daq,odt,idx); + } + #endif + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if ( (daq>=xcp.Daq.DaqCount) || (odt>=(vuint8)DaqListOdtCount(daq)) || (idx>=(vuint8)DaqListOdtEntryCount(odt0)) ) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + xcp.CrmLen = CRM_SET_DAQ_PTR_LEN; + xcp.DaqListPtr = DaqListOdtFirstEntry(odt0)+idx; + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF \n"); + } + #endif + } + break; + + case CC_WRITE_DAQ: /* Write DAQ entry */ + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> WRITE_DAQ size=%u,addr=%08Xh,%02Xh\n",CRO_WRITE_DAQ_SIZE,CRO_WRITE_DAQ_ADDR,CRO_WRITE_DAQ_EXT); + } + #endif + + CheckResourceProtection( RM_DAQ ) + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if ( ((vuint8)CRO_WRITE_DAQ_SIZE==(vuint8)0u ) || (CRO_WRITE_DAQ_SIZE > (vuint8)XCP_MAX_ODT_ENTRY_SIZE) ) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + xcp.CrmLen = CRM_WRITE_DAQ_LEN; + OdtEntrySize(xcp.DaqListPtr) = CRO_WRITE_DAQ_SIZE * GRANULARITY_ODT_ENTRY_SIZE_ODT; //in Bytes + OdtEntryAddr(xcp.DaqListPtr) = (DAQBYTEPTR)ApplXcpGetPointer(CRO_WRITE_DAQ_EXT,CRO_WRITE_DAQ_ADDR); + + xcp.DaqListPtr++; /* Autoincrement */ + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_START_STOP_DAQ_LIST: + { + vuint8 daq = (vuint8)(CRO_START_STOP_DAQ&0xFFu); + + CheckResourceProtection( RM_DAQ ) + + #if defined ( XCP_ENABLE_PARAMETER_CHECK ) + if (daq>=xcp.Daq.DaqCount) + { + error(CRC_OUT_OF_RANGE) + } + #endif + + if ( (CRO_START_STOP_MODE==1 ) || (CRO_START_STOP_MODE==2) ) + { + DaqListFlags(daq) |= (vuint8)DAQ_FLAG_SELECTED; + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + XcpPrintDaqList((vuint8)(CRO_START_STOP_DAQ)&0xFFu); + ApplXcpPrint("-> START_STOP mode=%02Xh, daq=%u\n",CRO_START_STOP_MODE,CRO_START_STOP_DAQ); + } + #endif + if ( CRO_START_STOP_MODE == (vuint8)1u ) + { + XcpStartDaq(daq); + } + xcp.CrmLen = CRM_START_STOP_LEN; + CRM_START_STOP_FIRST_PID = DaqListFirstPid(daq); + } + else + { + XcpStopDaq(daq); + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> START_STOP mode=%02Xh\n",CRO_START_STOP_MODE); + } + #endif + } + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + case CC_START_STOP_SYNCH: + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_START_STOP_SYNCH mode=%02Xh\n",CRO_START_STOP_MODE); + } + #endif + + CheckResourceProtection( RM_DAQ ) + + if (CRO_START_STOP_MODE==2) /* stop selected */ + { + XcpStopAllSelectedDaq(); + + } + else + { + if (CRO_START_STOP_MODE==1) /* start selected */ + { + XcpStartAllSelectedDaq(); + // LED_2_ON(); + } + else + { + /* CRO_START_STOP_MODE==0 : stop all */ + XcpStopAllDaq(); + // LED_2_OFF(); + } + } + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + } + break; + + #if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + case CC_GET_DAQ_CLOCK: + { + xcp.CrmLen = CRM_GET_DAQ_CLOCK_LEN; + CRM_GET_DAQ_CLOCK_TIME = (vuint32)ApplXcpGetTimestamp(); + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> GET_DAQ_CLOCK\n"); + ApplXcpPrint("<- 0xFF time=%04Xh\n",CRM_GET_DAQ_CLOCK_TIME); + } + #endif + } + break; + #endif + +#endif /* XCP_ENABLE_DAQ */ + + + /* Flash Programming Kernel Download */ + + + /* Flash Programming direct and Kernel */ + + /* Flash Programming */ + + +#if defined ( XCP_ENABLE_USER_COMMAND ) + case CC_USER_CMD: + { + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> CC_USER_CMD cmd=%u\n",pCmd[1]); + } + #endif + + { + + #if defined ( XCP_ENABLE_USER_COMMAND ) + err = ApplXcpUserService( (MEMORY_ROM BYTEPTR) &CRO_WORD(0) ); + + if (err==(vuint8)XCP_CMD_PENDING) + { + goto no_response; + } + if (err==(vuint8)XCP_CMD_SYNTAX) + { + error(CRC_CMD_SYNTAX) + } + #endif + } + + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFF\n"); + } + #endif + + } + break; +#endif + + + + + default: /* unknown */ + { + #if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("-> UNKNOWN COMMAND %02X\n",pCmd[0]); + } + #endif + error(CRC_CMD_UNKNOWN) + } + + } /* switch */ + + goto positive_response; + } + + /* Not connected */ + else + { + goto no_response; + } + } /* CC_CONNECT */ + +negative_response: + xcp.CrmLen = 2; + +#if defined ( XCP_ENABLE_CHECKSUM ) +negative_response1: +#endif + CRM_CMD = (vuint8)PID_ERR_XCP; + CRM_ERR = (vuint8)err; +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("<- 0xFE error=%02Xh\n",err); + } +#endif + +positive_response: + XcpSendCrm(); + +no_response: + END_PROFILE(1); /* Timingtest */ + return; +} + + +/****************************************************************************/ +/* Send notification callback */ +/****************************************************************************/ + + +/***************************************************************************** +| NAME: XcpSendCallBack +| CALLED BY: XCP Transport Layer +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: 0 : if the XCP Protocol Layer is idle (no transmit messages are pending) +| DESCRIPTION: Notifies the XCP Protocol Layer about the successful +| transmission of a XCP packet. +******************************************************************************/ +vuint8 XcpSendCallBack( void ) +{ + BEGIN_PROFILE(2); /* Timingtest */ + + /* Activation control */ + XcpPlCheckControlStateRet((vuint8)1u) + +#if defined ( XCP_ENABLE_DAQ ) && defined ( XCP_ENABLE_SEND_QUEUE ) + + /* Clear all pending flags */ + /* A pending flag indicates that ApplXcpSend() is in progress */ + xcp.SendStatus &= (vuint8)(~XCP_SEND_PENDING & 0xFFu); + + /* Now check if there is another transmit request */ + + /* Send a RES or ERR (CRM) message */ + if ( (xcp.SendStatus & (vuint8)XCP_CRM_REQUEST) != 0 ) + { + xcp.SendStatus &= (vuint8)(~XCP_CRM_REQUEST & 0xFFu); + XcpSendCrm(); + END_PROFILE(2); /* Timingtest */ + return (vuint8)0x01u; + } + + /* Send a EV or SERV message */ + #if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) + if ( (xcp.SendStatus & (vuint8)XCP_EVT_REQUEST) != 0 ) + { + xcp.SendStatus &= (vuint8)(~XCP_EVT_REQUEST & 0xFFu); + XcpSendEv(); + END_PROFILE(2); /* Timingtest */ + return (vuint8)0x01u; + } + #endif + + /* Send a DAQ message from the queue or from the buffer */ + if ( (xcp.SessionStatus & (vuint8)SS_DAQ) != 0 ) + { + if ( XcpSendDtoFromQueue() != 0 ) + { + END_PROFILE(2); /* Timingtest */ + return (vuint8)0x01u; + } + } +#endif /* XCP_ENABLE_DAQ && XCP_ENABLE_SEND_QUEUE */ + + /* Continue a pending block upload command */ + + END_PROFILE(2); /* Timingtest */ + return (vuint8)0x00u; +} + + +/****************************************************************************/ +/* Initialization / de-initialization */ +/****************************************************************************/ + + +/***************************************************************************** +| NAME: XcpInit +| CALLED BY: application +| PRECONDITIONS: the data link layer has to be initialized. +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: Initialization of the XCP Protocol Layer +| Application specific initialization +| ( e.g. Vector XCP on CAN Transport Layer ) +******************************************************************************/ +void XcpInit( void ) +{ +#if defined ( XCP_ENABLE_TESTMODE ) + gDebugLevel = 1; +#endif + + /* Application specific initialization function. */ + ApplXcpInit(); + + /* Initialize all XCP variables to zero */ + XcpMemClr((BYTEPTR)&xcp,(vuint16)sizeof(xcp)); + + /* Initialize the RAM interface */ + + /* Initialize the session status (ESCAN00013899) */ + xcp.SessionStatus = (vuint8)0u; + + #if defined ( XCP_ENABLE_SEND_QUEUE) + /* Initialize the transmit queue (ESCAN00013899) */ + xcp.SendStatus = (vuint8)0u; + #endif + + /* Resume DAQ */ +#if defined ( XCP_ENABLE_DAQ ) +#endif /* XCP_ENABLE_DAQ */ +} + +/***************************************************************************** +| NAME: XcpExit +| CALLED BY: application +| PRECONDITIONS: The XCP Protocol Layer has to be initialized. +| INPUT PARAMETERS: none +| RETURN VALUES: none +| DESCRIPTION: De-initialization of the XCP Protocol Layer. +******************************************************************************/ +void XcpExit( void ) +{ + /* Activation control */ + XcpPlCheckControlState() + + /* Deinitialize the RAM interface */ +} + + +/****************************************************************************/ +/* Print via SERV/SERV_TEXT */ +/****************************************************************************/ + + +#if defined ( XCP_ENABLE_SERV_TEXT ) + #if defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) + +/***************************************************************************** +| NAME: XcpPutChar +| CALLED BY: application, XcpPrint +| PRECONDITIONS: XCP is initialized and in connected state. +| INPUT PARAMETERS: c : character +| RETURN VALUES: none +| DESCRIPTION: Put a char into a service request packet (SERV). +******************************************************************************/ +void XcpPutchar( MEMORY_ROM vuint8 c ) +{ + /* Activation control */ + XcpPlCheckControlState() + + /* Check for stall condition */ + #if defined ( XCP_ENABLE_SEND_QUEUE ) + + while ( (xcp.SendStatus & (vuint8)XCP_EVT_REQUEST) != 0 ) + { + if ( ApplXcpSendStall() == 0 ) + { + return; /* Abort */ + } + } + + #endif + + /* If xcp.EvLen!=0 there is a pending text message*/ + if (xcp.EvLen<2) + { + xcp.EvLen = 2; + } + +#if defined ( XCP_ALLIGN_WORD ) + xcp.Ev.b[(xcp.EvLen)>>1] = c; + xcp.EvLen += 2; +#else + xcp.Ev.b[xcp.EvLen] = c; + xcp.EvLen++; +#endif + + if ( (xcp.EvLen>=(vuint8)kXcpMaxCTO) || (c==(vuint8)0x00u) ) /* Flush */ + { + EV_BYTE(0) = 0xFC; /* SERV */ + EV_BYTE(1) = 0x01; /* SERV_TEXT*/ + XcpSendEv(); + } + +} + + #if defined ( XCP_ENABLE_SERV_TEXT_PRINT ) + +/***************************************************************************** +| NAME: XcpPrint +| CALLED BY: application +| PRECONDITIONS: XCP is initialized and in connected state. +| INPUT PARAMETERS: *str : pointer to a string +| RETURN VALUES: none +| DESCRIPTION: Transmission of a service request packet (SERV). +******************************************************************************/ +void XcpPrint( MEMORY_ROM vuint8 *str ) +{ + /* Activation control */ + XcpPlCheckControlState() + + /* Transmit the text message. */ + while ( *str != 0x00 ) + { + XcpPutchar(*str); + str++; + } + /* Transmit the terminating 0x00. */ + XcpPutchar( (vuint8)0x00u ); +} + + #endif + #if defined ( XCP_ENABLE_SERV_TEXT_PRINTF ) + +/***************************************************************************** +| NAME: XcpPrintf +| CALLED BY: application +| PRECONDITIONS: none +| INPUT PARAMETERS: *str : pointer to a string +| ... : varaibale number of parameters (see printf) +| RETURN VALUES: none +| DESCRIPTION: Printf into a SERV_TEXT message +******************************************************************************/ +void XcpPrintf( MEMORY_ROM vuint8 *str, ... ) +{ + va_list argptr; + vuint8 buf[128]; + + /* Activation control */ + XcpPlCheckControlState() + + va_start(argptr,str); + vsprintf((vsint8*)buf,( MEMORY_ROM vsint8*)str,argptr ); + va_end(argptr); + + /* Transmit the text message*/ + { + vuint8 *p = buf; + while (*p != 0) + { + XcpPutchar(*p); + p++; + } + } + /* Transmit the terminating 0x00. */ + XcpPutchar( 0x00 ); +} + + #endif /* XCP_ENABLE_SERV_TEXT_PRINTF */ + #endif /* XCP_ENABLE_SERV_TEXT_PUTCHAR */ +#endif /* XCP_ENABLE_SERV_TEXT */ + + +#if defined ( XCP_ENABLE_SEND_EVENT ) + +/***************************************************************************** +| NAME: XcpSendEvent +| CALLED BY: application +| PRECONDITIONS: none +| INPUT PARAMETERS: evc : event code +| c : pointer to event data +| len : event data length +| RETURN VALUES: none +| DESCRIPTION: Transmission of an event packet (EV). +******************************************************************************/ +void XcpSendEvent( vuint8 evc, MEMORY_ROM BYTEPTR c, vuint8 len) +{ + vuint8 i; + + /* Activation control */ + XcpPlCheckControlState() + + /* Check for stall condition */ +#if defined ( XCP_ENABLE_SEND_QUEUE ) + while ( (xcp.SendStatus & (vuint8)XCP_EVT_REQUEST) != (vuint8)0u ) + { + if (!ApplXcpSendStall()) + { + return; /* Abort */ + } + } +#endif + + EV_BYTE(0) = PID_EV; /* Event*/ + EV_BYTE(1) = evc; /* Event Code*/ + xcp.EvLen = 2; + + if (len <= (vuint8)(kXcpMaxCTO-2) ) + { + if (c != 0x00u) + { + for (i = 0; i < len; i++) + { +#if defined ( XCP_ALLIGN_WORD ) + xcp.Ev.b[(xcp.EvLen)>>1] = c[i]; + xcp.EvLen += 2; + i++; +#else + xcp.Ev.b[xcp.EvLen] = c[i]; + xcp.EvLen++; +#endif + } + } + else + { + xcp.EvLen += len; + } + } + +#if defined ( XCP_ENABLE_TESTMODE ) + if ( gDebugLevel != 0) + { + ApplXcpPrint("[XcpSendEvent]"); + for (i = 0; i < xcp.EvLen; i++) + { + ApplXcpPrint(" %02x",xcp.Ev.b[i]); + } + ApplXcpPrint("\n"); + } +#endif + + XcpSendEv(); +} + +#endif /* XCP_ENABLE_SEND_EVENT */ + +#if defined ( XCP_ENABLE_GET_CONNECTION_STATE ) +/***************************************************************************** +| NAME: XcpGetState +| CALLED BY: XcpPreCopy +| PRECONDITIONS: none +| INPUT PARAMETERS: none +| RETURN VALUES: XCP_CONNECTED : XCP is connected +| XCP_DISCONNECTED : XCP is disconnected +| DESCRIPTION: Get the connection state of the XCP Protocol Layer +******************************************************************************/ +vuint8 XcpGetState( void ) +{ + return ((xcp.SessionStatus & (vuint8)SS_CONNECTED) > (vuint8)0u) ? XCP_CONNECTED : XCP_DISCONNECTED; +} +#endif + +#if defined ( XCP_ENABLE_GET_XCP_DATA_POINTER ) +/***************************************************************************** +| NAME: XcpGetXcpDataPointer +| CALLED BY: Application +| PRECONDITIONS: none +| INPUT PARAMETERS: tXcpData ** pXcpData: Pointer to Pointer that is set to xcp +| RETURN VALUES: none +| DESCRIPTION: Get the pointer to the internal xcp structure +******************************************************************************/ +void XcpGetXcpDataPointer( RAM tXcpData ** pXcpData ) +{ + *pXcpData = &xcp; +} +#endif + + +#if defined ( XCP_ENABLE_VERSION_INFO_API ) +/************************************************************************************************** + Function name : XcpGetVersionInfo + ------------------------------------------------------------------------------------------------ + Description : Returns version information of module + ------------------------------------------------------------------------------------------------ + Called by : - + ------------------------------------------------------------------------------------------------ + Parameter : Pointer to location at which version information shall be stored at + ------------------------------------------------------------------------------------------------ + Returncode : void + ------------------------------------------------------------------------------------------------ + Misc : - +**************************************************************************************************/ +void XcpGetVersionInfo(Std_VersionInfoType *XcpVerInfoPtr) +{ + /* Since this service only access non-volatile data and no channel parameter is passed, + checking of the channel handle and initialization is omitted. */ + XcpVerInfoPtr->vendorID = XCP_VENDOR_ID; + XcpVerInfoPtr->moduleID = XCP_MODULE_ID; + XcpVerInfoPtr->sw_major_version = (CP_XCP_VERSION >> 8u); + XcpVerInfoPtr->sw_minor_version = (CP_XCP_VERSION & 0xff); + XcpVerInfoPtr->sw_patch_version = CP_XCP_RELEASE_VERSION; +} +#endif /* XCP_ENABLE_VERSION_INFO_API */ + + +/****************************************************************************/ +/* Test */ +/* Some screen output functions for test and diagnostics */ +/****************************************************************************/ + + +#if defined ( XCP_ENABLE_TESTMODE ) + #if defined ( XCP_ENABLE_DAQ ) + +/***************************************************************************** +| NAME: XcpPrintDaqList +| CALLED BY: +| PRECONDITIONS: none +| INPUT PARAMETERS: +| RETURN VALUES: none +| DESCRIPTION: Print all DAQ lists to screen +******************************************************************************/ +void XcpPrintDaqList( vuint8 daq ) +{ + vuint8 i; + vuint16 e; +#if 0 + + /* Activation control */ + XcpPlCheckControlState() + + if (daq>=xcp.Daq.DaqCount) + { + return; + } + + ApplXcpPrint("DAQ %u:\n",daq); + #if defined ( kXcpMaxEvent ) + for (i=0;i Master */ +#define PID_RES 0xFF /* response packet */ +#define PID_ERR_XCP 0xFE /* error packet */ +#define PID_EV 0xFD /* event packet */ +#define PID_SERV 0xFC /* service request packet */ + + +/*-------------------------------------------------------------------------*/ +/* Command Return Codes */ + +#define CRC_CMD_SYNCH 0x00 + +#define CRC_CMD_BUSY 0x10 +#define CRC_DAQ_ACTIVE 0x11 +#define CRC_PRM_ACTIVE 0x12 + +#define CRC_CMD_UNKNOWN 0x20 +#define CRC_CMD_SYNTAX 0x21 +#define CRC_OUT_OF_RANGE 0x22 +#define CRC_WRITE_PROTECTED 0x23 +#define CRC_ACCESS_DENIED 0x24 +#define CRC_ACCESS_LOCKED 0x25 +#define CRC_PAGE_NOT_VALID 0x26 +#define CRC_PAGE_MODE_NOT_VALID 0x27 +#define CRC_SEGMENT_NOT_VALID 0x28 +#define CRC_SEQUENCE 0x29 +#define CRC_DAQ_CONDIF 0x2A + +#define CRC_MEMORY_OVERFLOW 0x30 +#define CRC_GENERIC 0x31 +#define CRC_VERIFY 0x32 + + +/*-------------------------------------------------------------------------*/ +/* Event Codes */ + +#define EVC_RESUME_MODE 0x00 +#define EVC_CLEAR_DAQ 0x01 +#define EVC_STORE_DAQ 0x02 +#define EVC_STORE_CAL 0x03 +#define EVC_CMD_PENDING 0x05 +#define EVC_DAQ_OVERLOAD 0x06 +#define EVC_SESSION_TERMINATED 0x07 +#define EVC_USER 0xFE +#define EVC_TRANSPORT 0xFF + + +/*-------------------------------------------------------------------------*/ +/* Service Request Codes */ + +#define SERV_RESET 0x00 /* Slave requesting to be reset */ +#define SERV_TEXT 0x01 /* Plain ASCII text null terminated */ + + + +/***************************************************************************/ +/* Definitions */ +/***************************************************************************/ + +/*-------------------------------------------------------------------------*/ +/* ResourceMask (CONNECT) */ + +#define RM_CAL_PAG 0x01 +#define RM_DAQ 0x04 +#define RM_STIM 0x08 +#define RM_PGM 0x10 + + +/*-------------------------------------------------------------------------*/ +/* CommModeBasic (CONNECT) */ + +#define PI_MOTOROLA 0x01 + +#define CMB_BYTE_ORDER (0x01u<<0) +#define CMB_ADDRESS_GRANULARITY (0x03u<<1) +#define CMB_SLAVE_BLOCK_MODE (0x01u<<6) +#define CMB_OPTIONAL (0x01u<<7) + +#define CMB_ADDRESS_GRANULARITY_BYTE (0<<1) +#define CMB_ADDRESS_GRANULARITY_WORD (1<<1) +#define CMB_ADDRESS_GRANULARITY_DWORD (2<<1) +#define CMB_ADDRESS_GRANULARITY_QWORD (3<<1) + + +/*-------------------------------------------------------------------------*/ +/* Protocol Info (GET_COMM_MODE_INFO - COMM_OPTIONAL) */ + +#define CMO_MASTER_BLOCK_MODE 0x01 +#define CMO_INTERLEAVED_MODE 0x02 + + +/*-------------------------------------------------------------------------*/ +/* Session Status (GET_STATUS and SET_REQUEST) */ + +#define SS_STORE_CAL_REQ 0x01u +#define SS_BLOCK_UPLOAD 0x02u /* Internal */ +#define SS_STORE_DAQ_REQ 0x04u +#define SS_CLEAR_DAQ_REQ 0x08u +#define SS_ERROR 0x10u /* Internal */ +#define SS_CONNECTED 0x20u /* Internal */ +#define SS_DAQ 0x40u +#define SS_RESUME 0x80u + + +/*-------------------------------------------------------------------------*/ +/* Identifier Type (GET_ID) */ + +#define IDT_ASCII 0 +#define IDT_ASAM_NAME 1 +#define IDT_ASAM_PATH 2 +#define IDT_ASAM_URL 3 +#define IDT_ASAM_UPLOAD 4 +#define IDT_VECTOR_MAPNAMES 0xDB + +/*-------------------------------------------------------------------------*/ +/* Checksum Types (BUILD_CHECKSUM) */ + +#define XCP_CHECKSUM_TYPE_ADD11 0x01 /* Add BYTE into a BYTE checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD12 0x02 /* Add BYTE into a WORD checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD14 0x03 /* Add BYTE into a DWORD checksum, ignore overflows */ +#define XCP_CHECKSUM_TYPE_ADD22 0x04 /* Add WORD into a WORD checksum, ignore overflows, blocksize must be modulo 2 */ +#define XCP_CHECKSUM_TYPE_ADD24 0x05 /* Add WORD into a DWORD checksum, ignore overflows, blocksize must be modulo 2 */ +#define XCP_CHECKSUM_TYPE_ADD44 0x06 /* Add DWORD into DWORD, ignore overflows, blocksize must be modulo 4 */ +#define XCP_CHECKSUM_TYPE_CRC16 0x07 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_CRC16CCITT 0x08 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_CRC32 0x09 /* See CRC error detection algorithms */ +#define XCP_CHECKSUM_TYPE_DLL 0xFF /* User defined, ASAM MCD 2MC DLL Interface */ + + +/*-------------------------------------------------------------------------*/ +/* Page Mode (SET_CAL_PAGE) */ + +#define CAL_ECU 0x01 +#define CAL_XCP 0x02 +#define CAL_ALL 0x80 /* not supported */ + + +/*-------------------------------------------------------------------------*/ +/* PAG_PROPERTIES (GET_PAG_PROCESSOR_INFO) */ + +#define PAG_PROPERTY_FREEZE 0x01 + + +/*-------------------------------------------------------------------------*/ +/* PAGE_PROPERTIES (GET_PAGE_INFO)*/ + +#define ECU_ACCESS_TYPE 0x03 +#define XCP_READ_ACCESS_TYPE 0x0C +#define XCP_WRITE_ACCESS_TYPE 0x30 + +/* ECU_ACCESS_TYPE */ +#define ECU_ACCESS_NONE (0<<0) +#define ECU_ACCESS_WITHOUT (1<<0) +#define ECU_ACCESS_WITH (2<<0) +#define ECU_ACCESS_DONT_CARE (3<<0) + +/* XCP_READ_ACCESS_TYPE */ +#define XCP_READ_ACCESS_NONE (0<<2) +#define XCP_READ_ACCESS_WITHOUT (1<<2) +#define XCP_READ_ACCESS_WITH (2<<2) +#define XCP_READ_ACCESS_DONT_CARE (3<<2) + +/* XCP_WRITE_ACCESS_TYPE */ +#define XCP_WRITE_ACCESS_NONE (0<<4) +#define XCP_WRITE_ACCESS_WITHOUT (1<<4) +#define XCP_WRITE_ACCESS_WITH (2<<4) +#define XCP_WRITE_ACCESS_DONT_CARE (3<<4) + + +/*-------------------------------------------------------------------------*/ +/* SEGMENT_MODE (GET_SEGMENT_MODE, SET_SEGMENT_MODE) */ + +#define SEGMENT_FLAG_FREEZE 0x01 /* */ + + +/*-------------------------------------------------------------------------*/ +/* DAQ_LIST_MODE (GET_DAQ_LIST_MODE, SET_DAQ_LIST_MODE) */ + +#define DAQ_FLAG_SELECTED 0x01u /* */ +#define DAQ_FLAG_DIRECTION 0x02u /* Data Stimulation Mode */ + +#define DAQ_FLAG_TIMESTAMP 0x10u /* Timestamps */ +#define DAQ_FLAG_NO_PID 0x20u /* No PID */ +#define DAQ_FLAG_RUNNING 0x40u /* Is started */ +#define DAQ_FLAG_RESUME 0x80u /* Resume Mode */ + +#define DAQ_FLAG_RESERVED 0x08u +#define DAQ_FLAG_OVERRUN 0x08u /* Overun (Internal Use) */ + + +/*-------------------------------------------------------------------------*/ +/* GET_DAQ_PROCESSOR_INFO */ + +/* DAQ_PROPERTIES */ +#define DAQ_PROPERTY_CONFIG_TYPE 0x01 +#define DAQ_PROPERTY_PRESCALER 0x02 +#define DAQ_PROPERTY_RESUME 0x04 +#define DAQ_PROPERTY_BIT_STIM 0x08 +#define DAQ_PROPERTY_TIMESTAMP 0x10 +#define DAQ_PROPERTY_NO_PID 0x20 +#define DAQ_PROPERTY_OVERLOAD_INDICATION 0xC0 + +/* DAQ Overload Indication Type */ +#define DAQ_OVERLOAD_INDICATION_NONE (0<<6) +#define DAQ_OVERLOAD_INDICATION_PID (1<<6) +#define DAQ_OVERLOAD_INDICATION_EVENT (2<<6) + +/* DAQ_KEY_BYTE */ +#define DAQ_OPT_TYPE 0x0F +#define DAQ_EXT_TYPE 0x30 +#define DAQ_HDR_TYPE 0xC0 + +/* DAQ Optimisation Type */ +#define DAQ_OPT_DEFAULT (0<<0) +#define DAQ_OPT_ODT_16 (1<<0) +#define DAQ_OPT_ODT_32 (2<<0) +#define DAQ_OPT_ODT_64 (3<<0) +#define DAQ_OPT_ALIGNMENT (4<<0) +#define DAQ_OPT_MAX_ENTRY_SIZE (5<<0) + +/* DAQ Address Extension Scope */ +#define DAQ_EXT_FREE (0<<4) +#define DAQ_EXT_ODT (1<<4) +#define DAQ_EXT_DAQ (3<<4) + +/* DAQ Identification Field Type */ +#define DAQ_HDR_PID (0<<6) +#define DAQ_HDR_ODT_DAQB (1<<6) +#define DAQ_HDR_ODT_DAQW (2<<6) +#define DAQ_HDR_ODT_FIL_DAQW (3<<6) + + +/*-------------------------------------------------------------------------*/ +/* GET_DAQ_RESOLUTION_INFO */ + +/* TIMESTAMP_MODE */ +#define DAQ_TIMESTAMP_SIZE 0x07 +#define DAQ_TIMESTAMP_FIXED 0x08 +#define DAQ_TIMESTAMP_UNIT 0xF0 + +/* DAQ Timestamp Size */ +#define DAQ_TIMESTAMP_OFF (0<<0) +#define DAQ_TIMESTAMP_BYTE (1<<0) +#define DAQ_TIMESTAMP_WORD (2<<0) +#define DAQ_TIMESTAMP_DWORD (4<<0) + +/* DAQ Timestamp Unit */ +#define DAQ_TIMESTAMP_UNIT_1NS (0<<4) +#define DAQ_TIMESTAMP_UNIT_10NS (1<<4) +#define DAQ_TIMESTAMP_UNIT_100NS (2<<4) +#define DAQ_TIMESTAMP_UNIT_1US (3<<4) +#define DAQ_TIMESTAMP_UNIT_10US (4<<4) +#define DAQ_TIMESTAMP_UNIT_100US (5<<4) +#define DAQ_TIMESTAMP_UNIT_1MS (6<<4) +#define DAQ_TIMESTAMP_UNIT_10MS (7<<4) +#define DAQ_TIMESTAMP_UNIT_100MS (8<<4) +#define DAQ_TIMESTAMP_UNIT_1S (9<<4) + + +/*-------------------------------------------------------------------------*/ +/* DAQ_LIST_PROPERTIES (GET_DAQ_LIST_INFO) */ + +#define DAQ_LIST_PREDEFINED 0x01 +#define DAQ_LIST_FIXED_EVENT 0x02 +#define DAQ_LIST_DIR_DAQ 0x04 +#define DAQ_LIST_DIR_STIM 0x08 + + +/*-------------------------------------------------------------------------*/ +/* EVENT_PROPERTY (GET_DAQ_EVENT_INFO) */ + +#define DAQ_EVENT_DIRECTION_DAQ 0x04 +#define DAQ_EVENT_DIRECTION_STIM 0x08 +#define DAQ_EVENT_DIRECTION_DAQ_STIM 0x0C + + +/*-------------------------------------------------------------------------*/ +/* Comm mode programming parameter (PROGRAM_START) */ + +#define PI_PGM_BLOCK_DOWNLOAD 0x01 +#define PI_PGM_BLOCK_UPLOAD 0x40 + + +/*-------------------------------------------------------------------------*/ +/* PGM_PROPERTIES (GET_PGM_PROCESSOR_INFO) */ + +#define PGM_ACCESS_TYPE 0x03 +#define PGM_COMPRESSION_TYPE 0x0C +#define PGM_ENCRYPTION_TYPE 0x30 +#define PGM_NON_SEQ_TYPE 0xC0 + +/* PGM Access Mode */ +#define PGM_ACCESS_ABSOLUTE (1<<0) +#define PGM_ACCESS_FUNCTIONAL (2<<0) +#define PGM_ACCESS_FREE (3<<0) + +/* PGM Compression type */ +#define PGM_COMPRESSION_NONE (0<<2) +#define PGM_COMPRESSION_SUPPORTED (1<<2) +#define PGM_COMPRESSION_REQUIRED (3<<2) + +/* PGM Encryption type */ +#define PGM_ENCRYPTION_NONE (0<<4) +#define PGM_ENCRYPTION_SUPPORTED (1<<4) +#define PGM_ENCRYPTION_REQUIRED (3<<4) + +/* PGM non sequential programming type */ +#define PGM_NON_SEQ_NONE (0<<6) +#define PGM_NON_SEQ_SUPPORTED (1<<6) +#define PGM_NON_SEQ_REQUIRED (3<<6) + +/* Compatibility defines */ +/* if values kXcpMaxXXX_AG are not exsiting, set them to the kXcpMaxXXX value */ +#if ! defined ( kXcpMaxCTO_AG ) + #define kXcpMaxCTO_AG kXcpMaxCTO +#endif +#if ! defined ( kXcpMaxDTO_AG ) + #define kXcpMaxDTO_AG kXcpMaxDTO +#endif +#if ! defined ( kXcpAG ) + #define kXcpAG 1 +#endif + + +/***************************************************************************/ +/* XCP Commands and Responces, Type Definition */ +/***************************************************************************/ + +/* Protocol command structure definition */ +#define CRO_CMD CRO_BYTE(0) +#define CRM_CMD CRM_BYTE(0) +#define CRM_ERR CRM_BYTE(1) +/* CONNECT */ + +#define CRO_CONNECT_LEN 2 +#define CRO_CONNECT_MODE CRO_BYTE(1) +#define CRM_CONNECT_LEN 8 +#define CRM_CONNECT_RESOURCE CRM_BYTE(1) +#define CRM_CONNECT_COMM_BASIC CRM_BYTE(2) +#define CRM_CONNECT_MAX_CTO_SIZE CRM_BYTE(3) +#define CRM_CONNECT_MAX_DTO_SIZE CRM_WORD(2) +#define CRM_CONNECT_PROTOCOL_VERSION CRM_BYTE(6) +#define CRM_CONNECT_TRANSPORT_VERSION CRM_BYTE(7) + + +/* DISCONNECT */ + +#define CRO_DISCONNECT_LEN 1 +#define CRM_DISCONNECT_LEN 1 + + +/* GET_STATUS */ + +#define CRO_GET_STATUS_LEN 1 + +#define CRM_GET_STATUS_LEN 6 +#define CRM_GET_STATUS_STATUS CRM_BYTE(1) +#define CRM_GET_STATUS_PROTECTION CRM_BYTE(2) +#define CRM_GET_STATUS_CONFIG_ID CRM_WORD(2) + + +/* SYNCH */ + +#define CRO_SYNCH_LEN 1 + +#define CRM_SYNCH_LEN 2 +#define CRM_SYNCH_RESULT CRM_BYTE(1) + + +/* GET_COMM_MODE_INFO */ + +#define CRO_GET_COMM_MODE_INFO_LEN 1 + +#define CRM_GET_COMM_MODE_INFO_LEN 8 +#define CRM_GET_COMM_MODE_INFO_COMM_OPTIONAL CRM_BYTE(2) +#define CRM_GET_COMM_MODE_INFO_MAX_BS CRM_BYTE(4) +#define CRM_GET_COMM_MODE_INFO_MIN_ST CRM_BYTE(5) +#define CRM_GET_COMM_MODE_INFO_QUEUE_SIZE CRM_BYTE(6) +#define CRM_GET_COMM_MODE_INFO_DRIVER_VERSION CRM_BYTE(7) + + +/* GET_ID */ + +#define CRO_GET_ID_LEN 2 +#define CRO_GET_ID_TYPE CRO_BYTE(1) + +#define CRM_GET_ID_LEN 8 +#define CRM_GET_ID_MODE CRM_BYTE(1) +#define CRM_GET_ID_LENGTH CRM_DWORD(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRM_GET_ID_DATA (&CRM_WORD(4)) +#else +#define CRM_GET_ID_DATA (&CRM_BYTE(8)) +#endif + +/* SET_REQUEST */ + +#define CRO_SET_REQUEST_LEN 4 +#define CRO_SET_REQUEST_MODE CRO_BYTE(1) +#define CRO_SET_REQUEST_CONFIG_ID CRO_WORD(1) + +#define CRM_SET_REQUEST_LEN 1 + + +/* GET_SEED */ + +#define CRO_GET_SEED_LEN 3 +#define CRO_GET_SEED_MODE CRO_BYTE(1) +#define CRO_GET_SEED_RESOURCE CRO_BYTE(2) + +#define CRM_GET_SEED_LEN (CRM_GET_SEED_LENGTH+2u) +#define CRM_GET_SEED_LENGTH CRM_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRM_GET_SEED_DATA (&CRM_WORD(1)) +#else +#define CRM_GET_SEED_DATA (&CRM_BYTE(2)) +#endif + + +/* UNLOCK */ + +#define CRO_UNLOCK_LEN 8 +#define CRO_UNLOCK_LENGTH CRO_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_UNLOCK_KEY (&CRO_WORD(1)) +#else +#define CRO_UNLOCK_KEY (&CRO_BYTE(2)) +#endif + +#define CRM_UNLOCK_LEN 2 +#define CRM_UNLOCK_PROTECTION CRM_BYTE(1) + + +/* SET_MTA */ + +#define CRO_SET_MTA_LEN 8 +#define CRO_SET_MTA_EXT CRO_BYTE(3) +#define CRO_SET_MTA_ADDR CRO_DWORD(1) + +#define CRM_SET_MTA_LEN 1 + + +/* UPLOAD */ + +#define CRM_UPLOAD_MAX_SIZE ((vuint8)(kXcpMaxCTO_AG-1)) +#define CRO_UPLOAD_LEN 2 +#define CRO_UPLOAD_SIZE CRO_BYTE(1) + +#define CRM_UPLOAD_LEN 1 /* +CRO_UPLOAD_SIZE */ +#if defined ( XCP_ALLIGN_WORD ) +#define CRM_UPLOAD_DATA (&CRM_WORD(1)) +#else +#define CRM_UPLOAD_DATA (&CRM_BYTE(1)) +#endif + + +/* SHORT_UPLOAD */ + +#define CRO_SHORT_UPLOAD_LEN 8 +#define CRO_SHORT_UPLOAD_SIZE CRO_BYTE(1) +#define CRO_SHORT_UPLOAD_EXT CRO_BYTE(3) +#define CRO_SHORT_UPLOAD_ADDR CRO_DWORD(1) + +#define CRM_SHORT_UPLOAD_MAX_SIZE ((vuint8)(kXcpMaxCTO_AG-1)) + +#define CRM_SHORT_UPLOAD_LEN 1 /* +CRO_SHORT_UPLOAD_SIZE */ +#if defined ( XCP_ALLIGN_WORD ) +#define CRM_SHORT_UPLOAD_DATA (&CRM_WORD(1)) +#else +#define CRM_SHORT_UPLOAD_DATA (&CRM_BYTE(1)) +#endif + + +/* BUILD_CHECKSUM */ + +#define CRO_BUILD_CHECKSUM_LEN 8 +#define CRO_BUILD_CHECKSUM_SIZE CRO_DWORD(1) + +#define CRM_BUILD_CHECKSUM_LEN 8 +#define CRM_BUILD_CHECKSUM_TYPE CRM_BYTE(1) +#define CRM_BUILD_CHECKSUM_RESULT CRM_DWORD(1) + + +/* DOWNLOAD */ + +#define CRO_DOWNLOAD_MAX_SIZE ((vuint8)((kXcpMaxCTO-2)/kXcpAG)) + +#define CRO_DOWNLOAD_LEN 2 /* + CRO_DOWNLOAD_SIZE */ +#define CRO_DOWNLOAD_SIZE CRO_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_DOWNLOAD_DATA (&CRO_WORD(1)) +#else +#define CRO_DOWNLOAD_DATA (&CRO_BYTE(2)) +#endif + +#define CRM_DOWNLOAD_LEN 1 + + +/* DOWNLOAD_NEXT */ + +#define CRO_DOWNLOAD_NEXT_MAX_SIZE ((vuint8)((kXcpMaxCTO-2)/kXcpAG)) + +#define CRO_DOWNLOAD_NEXT_LEN 2 /* + size */ +#define CRO_DOWNLOAD_NEXT_SIZE CRO_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_DOWNLOAD_NEXT_DATA (&CRO_WORD(1)) +#else +#define CRO_DOWNLOAD_NEXT_DATA (&CRO_BYTE(2)) +#endif + +#define CRM_DOWNLOAD_NEXT_LEN 1 + + +/* DOWNLOAD_MAX */ + +#define CRO_DOWNLOAD_MAX_MAX_SIZE ((vuint8)(kXcpMaxCTO_AG-1)) + +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_DOWNLOAD_MAX_DATA (&CRO_WORD(1)) +#else +#define CRO_DOWNLOAD_MAX_DATA (&CRO_BYTE(1)) +#endif + +#define CRM_DOWNLOAD_MAX_LEN 1 + + +/* SHORT_DOWNLOAD */ + +#define CRO_SHORT_DOWNLOAD_LEN 8 +#define CRO_SHORT_DOWNLOAD_SIZE CRO_BYTE(1) +#define CRO_SHORT_DOWNLOAD_EXT CRO_BYTE(3) +#define CRO_SHORT_DOWNLOAD_ADDR CRO_DWORD(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_SHORT_DOWNLOAD_DATA (&CRO_WORD(4)) +#else +#define CRO_SHORT_DOWNLOAD_DATA (&CRO_BYTE(8)) +#endif + +#define CRM_SHORT_DOWNLOAD_MAX_SIZE ((vuint8)((kXcpMaxCTO-8)/kXcpAG)) +#define CRM_SHORT_DOWNLOAD_LEN 1 /* +CRO_SHORT_UPLOAD_SIZE */ + + +/* MODIFY_BITS */ + +#define CRO_MODIFY_BITS_LEN 6 +#define CRO_MODIFY_BITS_SHIFT CRO_BYTE(1) +#define CRO_MODIFY_BITS_AND CRO_WORD(1) +#define CRO_MODIFY_BITS_XOR CRO_WORD(2) + +#define CRM_MODIFY_BITS_LEN 1 + + +/* SET_CAL_PAGE */ + +#define CRO_SET_CAL_PAGE_LEN 4 +#define CRO_SET_CAL_PAGE_MODE CRO_BYTE(1) +#define CRO_SET_CAL_PAGE_SEGMENT CRO_BYTE(2) +#define CRO_SET_CAL_PAGE_PAGE CRO_BYTE(3) + +#define CRM_SET_CAL_PAGE_LEN 1 + + +/* GET_CAL_PAGE */ + +#define CRO_GET_CAL_PAGE_LEN 3 +#define CRO_GET_CAL_PAGE_MODE CRO_BYTE(1) +#define CRO_GET_CAL_PAGE_SEGMENT CRO_BYTE(2) + +#define CRM_GET_CAL_PAGE_LEN 4 +#define CRM_GET_CAL_PAGE_PAGE CRM_BYTE(3) + + +/* GET_PAG_PROCESSOR_INFO */ + +#define CRO_GET_PAG_PROCESSOR_INFO_LEN 1 + +#define CRM_GET_PAG_PROCESSOR_INFO_LEN 3 +#define CRM_GET_PAG_PROCESSOR_INFO_MAX_SEGMENT CRM_BYTE(1) +#define CRM_GET_PAG_PROCESSOR_INFO_PROPERTIES CRM_BYTE(2) + + +/* GET_SEGMENT_INFO */ + +#define CRO_GET_SEGMENT_INFO_LEN 5 +#define CRO_GET_SEGMENT_INFO_MODE CRO_BYTE(1) +#define CRO_GET_SEGMENT_INFO_NUMBER CRO_BYTE(2) +#define CRO_GET_SEGMENT_INFO_MAPPING_INDEX CRO_BYTE(3) +#define CRO_GET_SEGMENT_INFO_MAPPING CRO_BYTE(4) + +#define CRM_GET_SEGMENT_INFO_LEN 8 +#define CRM_GET_SEGMENT_INFO_MAX_PAGES CRM_BYTE(1) +#define CRM_GET_SEGMENT_INFO_ADDRESS_EXTENSION CRM_BYTE(2) +#define CRM_GET_SEGMENT_INFO_MAX_MAPPING CRM_BYTE(3) +#define CRM_GET_SEGMENT_INFO_COMPRESSION CRM_BYTE(4) +#define CRM_GET_SEGMENT_INFO_ENCRYPTION CRM_BYTE(5) +#define CRM_GET_SEGMENT_INFO_MAPPING_INFO CRM_DWORD(1) + + +/* GET_PAGE_INFO */ + +#define CRO_GET_PAGE_INFO_LEN 4 +#define CRO_GET_PAGE_INFO_SEGMENT_NUMBER CRO_BYTE(2) +#define CRO_GET_PAGE_INFO_PAGE_NUMBER CRO_BYTE(3) + +#define CRM_GET_PAGE_INFO_LEN 3 +#define CRM_GET_PAGE_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_PAGE_INFO_INIT_SEGMENT CRM_BYTE(2) + + +/* SET_SEGMENT_MODE */ + +#define CRO_SET_SEGMENT_MODE_LEN 3 +#define CRO_SET_SEGMENT_MODE_MODE CRO_BYTE(1) +#define CRO_SET_SEGMENT_MODE_SEGMENT CRO_BYTE(2) + +#define CRM_SET_SEGMENT_MODE_LEN 1 + + +/* GET_SEGMENT_MODE */ + +#define CRO_GET_SEGMENT_MODE_LEN 3 +#define CRO_GET_SEGMENT_MODE_SEGMENT CRO_BYTE(2) + +#define CRM_GET_SEGMENT_MODE_LEN 3 +#define CRM_GET_SEGMENT_MODE_MODE CRM_BYTE(2) + + +/* COPY_CAL_PAGE */ + +#define CRO_COPY_CAL_PAGE_LEN 5 +#define CRO_COPY_CAL_PAGE_SRC_SEGMENT CRO_BYTE(1) +#define CRO_COPY_CAL_PAGE_SRC_PAGE CRO_BYTE(2) +#define CRO_COPY_CAL_PAGE_DEST_SEGMENT CRO_BYTE(3) +#define CRO_COPY_CAL_PAGE_DEST_PAGE CRO_BYTE(4) + +#define CRM_COPY_CAL_PAGE_LEN 1 + + +/* CLEAR_DAQ_LIST */ + +#define CRO_CLEAR_DAQ_LIST_LEN 4 +#define CRO_CLEAR_DAQ_LIST_DAQ CRO_WORD(1) + +#define CRM_CLEAR_DAQ_LIST_LEN 1 + + +/* SET_DAQ_PTR */ + +#define CRO_SET_DAQ_PTR_LEN 6 +#define CRO_SET_DAQ_PTR_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_PTR_ODT CRO_BYTE(4) +#define CRO_SET_DAQ_PTR_IDX CRO_BYTE(5) + +#define CRM_SET_DAQ_PTR_LEN 1 + + +/* WRITE_DAQ */ + +#define CRO_WRITE_DAQ_LEN 8 +#define CRO_WRITE_DAQ_BITOFFSET CRO_BYTE(1) +#define CRO_WRITE_DAQ_SIZE CRO_BYTE(2) +#define CRO_WRITE_DAQ_EXT CRO_BYTE(3) +#define CRO_WRITE_DAQ_ADDR CRO_DWORD(1) + +#define CRM_WRITE_DAQ_LEN 1 + + +/* WRITE_DAQ_MULTIPLE */ +#define CRO_WRITE_DAQ_MULIPLE_LEN 8 +#define CRO_WRITE_DAQ_MULTIPLE_COMMAND CRO_BYTE(1) +#define CRO_WRITE_DAQ_MULTIPLE_NODAQ CRO_BYTE(2) +#define CRO_WRITE_DAQ_MULIPLE_BITOFFSET(i) CRO_BYTE(8 + (8*(i))) +#define CRO_WRITE_DAQ_MULIPLE_SIZE(i) CRO_BYTE(9 + (8*(i))) +#define CRO_WRITE_DAQ_MULIPLE_EXT(i) CRO_BYTE(10 + (8*(i))) +#define CRO_WRITE_DAQ_MULIPLE_ADDR(i) CRO_DWORD(1 + (2*(i))) + +#define CRM_WRITE_DAQ_MULIPLE_LEN 1 + + +/* SET_DAQ_LIST_MODE */ + +#define CRO_SET_DAQ_LIST_MODE_LEN 8 +#define CRO_SET_DAQ_LIST_MODE_MODE CRO_BYTE(1) +#define CRO_SET_DAQ_LIST_MODE_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_LIST_MODE_EVENTCHANNEL CRO_WORD(2) +#define CRO_SET_DAQ_LIST_MODE_PRESCALER CRO_BYTE(6) +#define CRO_SET_DAQ_LIST_MODE_PRIORITY CRO_BYTE(7) + +#define CRM_SET_DAQ_LIST_MODE_LEN 6 + + +/* GET_DAQ_LIST_MODE */ + +#define CRO_GET_DAQ_LIST_MODE_LEN 4 +#define CRO_GET_DAQ_LIST_MODE_DAQ CRO_WORD(1) + +#define CRM_GET_DAQ_LIST_MODE_LEN 8 +#define CRM_GET_DAQ_LIST_MODE_MODE CRM_BYTE(1) +#define CRM_GET_DAQ_LIST_MODE_EVENTCHANNEL CRM_WORD(2) +#define CRM_GET_DAQ_LIST_MODE_PRESCALER CRM_BYTE(6) +#define CRM_GET_DAQ_LIST_MODE_PRIORITY CRM_BYTE(7) + + +/* START_STOP_DAQ_LIST */ + +#define CRO_START_STOP_LEN 4 +#define CRO_START_STOP_MODE CRO_BYTE(1) +#define CRO_START_STOP_DAQ CRO_WORD(1) + +#define CRM_START_STOP_LEN 2 +#define CRM_START_STOP_FIRST_PID CRM_BYTE(1) + + +/* START_STOP_SYNCH */ + +#define CRO_START_STOP_SYNC_LEN 2 +#define CRO_START_STOP_SYNC_MODE CRO_BYTE(1) + +#define CRM_START_STOP_SYNC_LEN 1 + + +/* GET_DAQ_CLOCK */ + +#define CRO_GET_DAQ_CLOCK_LEN 1 + +#define CRM_GET_DAQ_CLOCK_LEN 8 +#define CRM_GET_DAQ_CLOCK_TIME CRM_DWORD(1) + + +/* READ_DAQ */ + +#define CRO_READ_DAQ_LEN 1 + +#define CRM_READ_DAQ_LEN 8 +#define CRM_READ_DAQ_BITOFFSET CRM_BYTE(1) +#define CRM_READ_DAQ_SIZE CRM_BYTE(2) +#define CRM_READ_DAQ_EXT CRM_BYTE(3) +#define CRM_READ_DAQ_ADDR CRM_DWORD(1) + + +/* GET_DAQ_PROCESSOR_INFO */ + +#define CRO_GET_DAQ_PROCESSOR_INFO_LEN 1 + +#define CRM_GET_DAQ_PROCESSOR_INFO_LEN 8 +#define CRM_GET_DAQ_PROCESSOR_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_PROCESSOR_INFO_MAX_DAQ CRM_WORD(1) +#define CRM_GET_DAQ_PROCESSOR_INFO_MAX_EVENT CRM_WORD(2) +#define CRM_GET_DAQ_PROCESSOR_INFO_MIN_DAQ CRM_BYTE(6) +#define CRM_GET_DAQ_PROCESSOR_INFO_DAQ_KEY_BYTE CRM_BYTE(7) + + +/* GET_DAQ_RESOLUTION_INFO */ + +#define CRO_GET_DAQ_RESOLUTION_INFO_LEN 1 + +#define CRM_GET_DAQ_RESOLUTION_INFO_LEN 8 +#define CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_DAQ CRM_BYTE(1) +#define CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_DAQ CRM_BYTE(2) +#define CRM_GET_DAQ_RESOLUTION_INFO_GRANULARITY_STIM CRM_BYTE(3) +#define CRM_GET_DAQ_RESOLUTION_INFO_MAX_SIZE_STIM CRM_BYTE(4) +#define CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_MODE CRM_BYTE(5) +#define CRM_GET_DAQ_RESOLUTION_INFO_TIMESTAMP_TICKS CRM_WORD(3) + + +/* GET_DAQ_LIST_INFO */ + +#define CRO_GET_DAQ_LIST_INFO_LEN 4 +#define CRO_GET_DAQ_LIST_INFO_DAQ CRO_WORD(1) + +#define CRM_GET_DAQ_LIST_INFO_LEN 6 +#define CRM_GET_DAQ_LIST_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_LIST_INFO_MAX_ODT CRM_BYTE(2) +#define CRM_GET_DAQ_LIST_INFO_MAX_ODT_ENTRY CRM_BYTE(3) +#define CRM_GET_DAQ_LIST_INFO_FIXED_EVENT CRM_WORD(2) + + +/* GET_DAQ_EVENT_INFO */ + +#define CRO_GET_DAQ_EVENT_INFO_LEN 4 +#define CRO_GET_DAQ_EVENT_INFO_EVENT CRO_WORD(1) + +#define CRM_GET_DAQ_EVENT_INFO_LEN 7 +#define CRM_GET_DAQ_EVENT_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_DAQ_EVENT_INFO_MAX_DAQ_LIST CRM_BYTE(2) +#define CRM_GET_DAQ_EVENT_INFO_NAME_LENGTH CRM_BYTE(3) +#define CRM_GET_DAQ_EVENT_INFO_TIME_CYCLE CRM_BYTE(4) +#define CRM_GET_DAQ_EVENT_INFO_TIME_UNIT CRM_BYTE(5) +#define CRM_GET_DAQ_EVENT_INFO_PRIORITY CRM_BYTE(6) + + +/* FREE_DAQ */ + +#define CRO_FREE_DAQ_LEN 1 + +#define CRM_FREE_DAQ_LEN 1 + + +/* ALLOC_DAQ */ + +#define CRO_ALLOC_DAQ_LEN 4 +#define CRO_ALLOC_DAQ_COUNT CRO_WORD(1) + +#define CRM_ALLOC_DAQ_LEN 1 + + +/* ALLOC_ODT */ + +#define _CRO_ALLOC_ODT_LEN 3 +#define _CRO_ALLOC_ODT_DAQ CRO_WORD(1) +#define _CRO_ALLOC_ODT_COUNT CRO_BYTE(1) + +#define CRO_ALLOC_ODT_LEN 5 +#define CRO_ALLOC_ODT_DAQ CRO_WORD(1) +#define CRO_ALLOC_ODT_COUNT CRO_BYTE(4) + +#define CRM_ALLOC_ODT_LEN 1 + + +/* ALLOC_ODT_ENTRY */ + +#define CRO_ALLOC_ODT_ENTRY_LEN 6 +#define CRO_ALLOC_ODT_ENTRY_DAQ CRO_WORD(1) +#define CRO_ALLOC_ODT_ENTRY_ODT CRO_BYTE(4) +#define CRO_ALLOC_ODT_ENTRY_COUNT CRO_BYTE(5) + +#define CRM_ALLOC_ODT_ENTRY_LEN 1 + + +/* PROGRAM_START */ + +#define CRO_PROGRAM_START_LEN 1 + +#define CRM_PROGRAM_START_LEN 7 +#define CRM_PROGRAM_COMM_MODE_PGM CRM_BYTE(2) +#define CRM_PROGRAM_MAX_CTO_PGM CRM_BYTE(3) +#define CRM_PROGRAM_MAX_BS_PGM CRM_BYTE(4) +#define CRM_PROGRAM_MIN_ST_PGM CRM_BYTE(5) +#define CRM_PROGRAM_QUEUE_SIZE_PGM CRM_BYTE(6) + + +/* PROGRAM_CLEAR */ + +#define CRO_PROGRAM_CLEAR_LEN 8 +#define CRO_PROGRAM_CLEAR_MODE CRO_BYTE(1) +#define CRO_PROGRAM_CLEAR_SIZE CRO_DWORD(1) + +#define CRM_PROGRAM_CLEAR_LEN 1 + + +/* PROGRAM */ + +#define CRO_PROGRAM_MAX_SIZE ((vuint8)((kXcpMaxCTO-2)/kXcpAG)) + +#define CRO_PROGRAM_LEN 2 /* + CRO_PROGRAM_SIZE */ +#define CRO_PROGRAM_SIZE CRO_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_PROGRAM_DATA (&CRO_WORD(1)) +#else +#define CRO_PROGRAM_DATA (&CRO_BYTE(2)) +#endif + +#define CRM_PROGRAM_LEN 1 + + +/* PROGRAM RESET */ + +#define CRO_PROGRAM_RESET_LEN 1 + +#define CRM_PROGRAM_RESET_LEN 1 + + +/*GET_PGM_PROCESSOR_INFO*/ + +#define CRO_GET_PGM_PROCESSOR_INFO_LEN 1 + +#define CRM_GET_PGM_PROCESSOR_INFO_LEN 3 +#define CRM_GET_PGM_PROCESSOR_INFO_PROPERTIES CRM_BYTE(1) +#define CRM_GET_PGM_PROCESSOR_INFO_MAX_SECTOR CRM_BYTE(2) + + +/* GET_SECTOR_INFO */ + +#define CRO_PROGRAM_GET_SECTOR_INFO_LEN 3 +#define CRO_PROGRAM_GET_SECTOR_INFO_MODE CRO_BYTE(1) +#define CRO_PROGRAM_GET_SECTOR_INFO_NUMBER CRO_BYTE(2) + +#define CRM_PROGRAM_GET_SECTOR_INFO_LEN 8 +#define CRM_PROGRAM_GET_SECTOR_CLEAR_SEQ_NUM CRM_BYTE(1) +#define CRM_PROGRAM_GET_SECTOR_PGM_SEQ_NUM CRM_BYTE(2) +#define CRM_PROGRAM_GET_SECTOR_PGM_METHOD CRM_BYTE(3) +#define CRM_PROGRAM_GET_SECTOR_SECTOR_INFO CRM_DWORD(1) + + +/* PROGRAM_PREPARE */ + +#define CRO_PROGRAM_PREPARE_LEN 4 +#define CRO_PROGRAM_PREPARE_SIZE CRO_WORD(1) + +#define CRM_PROGRAM_PREPARE_LEN 1 + + +/* PROGRAM_FORMAT */ + +#define CRO_PROGRAM_FORMAT_LEN 5 +#define CRO_PROGRAM_FORMAT_COMPRESSION_METHOD CRO_BYTE(1) +#define CRO_PROGRAM_FORMAT_ENCRYPTION_METHOD CRO_BYTE(2) +#define CRO_PROGRAM_FORMAT_PROGRAMMING_METHOD CRO_BYTE(3) +#define CRO_PROGRAM_FORMAT_ACCESS_METHOD CRO_BYTE(4) + +#define CRM_PROGRAM_FORMAT_LEN 1 + + +/* PROGRAM_NEXT */ + +#define CRO_PROGRAM_NEXT_MAX_SIZE ((vuint8)((kXcpMaxCTO-2)/kXcpAG)) + +#define CRO_PROGRAM_NEXT_LEN 2 /* + size */ +#define CRO_PROGRAM_NEXT_SIZE CRO_BYTE(1) +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_PROGRAM_NEXT_DATA (&CRO_WORD(1)) +#else +#define CRO_PROGRAM_NEXT_DATA (&CRO_BYTE(2)) +#endif + +#define CRM_PROGRAM_NEXT_LEN 3 +#define CRM_PROGRAM_NEXT_ERR_SEQUENCE CRM_BYTE(1) +#define CRM_PROGRAM_NEXT_SIZE_EXPECTED_DATA CRM_BYTE(2) + + +/* PROGRAM_MAX */ + +#define CRO_PROGRAM_MAX_MAX_SIZE ((vuint8)((kXcpMaxCTO-kXcpAG)/kXcpAG)) + +#if defined ( XCP_ALLIGN_WORD ) +#define CRO_PROGRAM_MAX_DATA (&CRO_WORD(1)) +#else +#define CRO_PROGRAM_MAX_DATA (&CRO_BYTE(1)) +#endif + +#define CRM_PROGRAM_MAX_LEN 1 + + +/* PROGRAM_VERIFY */ + +#define CRO_PROGRAM_VERIFY_LEN 8 +#define CRO_PROGRAM_VERIFY_MODE CRO_BYTE(1) +#define CRO_PROGRAM_VERIFY_TYPE CRO_WORD(1) +#define CRO_PROGRAM_VERIFY_VALUE CRO_DWORD(1) + +#define CRM_PROGRAM_VERIFY_LEN 1 + + +/* GET_SLAVE_ID */ + +#define CRO_GET_SLAVE_ID_LEN 6 +#define CRO_GET_SLAVE_ID_SUB_CODE CRO_BYTE(1) +#define CRO_GET_SLAVE_ID_X CRO_BYTE(2) +#define CRO_GET_SLAVE_ID_C CRO_BYTE(3) +#define CRO_GET_SLAVE_ID_P CRO_BYTE(4) +#define CRO_GET_SLAVE_ID_MODE CRO_BYTE(5) + +#define CRM_GET_SLAVE_ID_LEN 8 +#define CRM_GET_SLAVE_ID_X CRM_BYTE(1) +#define CRM_GET_SLAVE_ID_C CRM_BYTE(2) +#define CRM_GET_SLAVE_ID_P CRM_BYTE(3) +#define CRM_GET_SLAVE_ID_CAN_ID_CMD_STIM CRM_DWORD(1) + + +/* GET_DAQ_ID */ + +#define CRO_GET_DAQ_ID_LEN 3 +#define CRO_GET_DAQ_ID_SUB_CODE CRO_BYTE(1) +#define CRO_GET_DAQ_ID_DAQ CRO_WORD(1) + +#define CRM_GET_DAQ_ID_LEN 8 +#define CRM_GET_DAQ_ID_FIXED CRM_BYTE(1) +#define CRM_GET_DAQ_ID_ID CRM_DWORD(1) + + +/* SET_DAQ_ID */ + +#define CRO_SET_DAQ_ID_LEN 8 +#define CRO_SET_DAQ_ID_SUB_CODE CRO_BYTE(1) +#define CRO_SET_DAQ_ID_DAQ CRO_WORD(1) +#define CRO_SET_DAQ_ID_ID CRO_DWORD(1) + +#define CRM_SET_DAQ_ID_LEN 1 + +/* SET_SLAVE_PORT */ + +#define CRO_SET_SLAVE_PORT_LEN 4 +#define CRO_SET_SLAVE_PORT_SUB_CODE CRO_BYTE(1) +#define CRO_SET_SLAVE_PORT_PORT CRO_WORD(1) + +#define CRM_SET_SLAVE_PORT 1 + +#if defined ( XCP_ENABLE_GET_CONNECTION_STATE ) + #define XCP_DISCONNECTED 0u + #define XCP_CONNECTED 1u +#endif + + +/****************************************************************************/ +/* Implementation */ +/****************************************************************************/ + + + +#if defined ( XCP_ALLIGN_WORD ) + + #if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) + #define EV_BYTE(x) (xcp.Ev.EightByteField.byte_##x) + #endif + + #define CRO_BYTE(x) (pCmd->EightByteField.byte_##x) + + #define CRO_WORD(x) (pCmd->w[x]) + #define CRO_DWORD(x) (pCmd->dw[x]) + + #define CRM_BYTE(x) (xcp.Crm.EightByteField.byte_##x) + + #define CRM_WORD(x) (xcp.Crm.w[x]) + #define CRM_DWORD(x) (xcp.Crm.dw[x]) + +#else + + #if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) + #define EV_BYTE(x) (xcp.Ev.b[x]) + #endif + + #define CRO_BYTE(x) (pCmd->b[x]) + #define CRO_WORD(x) (pCmd->w[x]) + #define CRO_DWORD(x) (pCmd->dw[x]) + #define CRM_BYTE(x) (xcp.Crm.b[x]) + #define CRM_WORD(x) (xcp.Crm.w[x]) + #define CRM_DWORD(x) (xcp.Crm.dw[x]) + +#endif + + + + +/****************************************************************************/ +/* Default data type definitions */ +/****************************************************************************/ + +/* Pointer to far memory */ +#if defined ( XCP_MEMORY_FAR ) +#else + #if defined ( MEMORY_FAR ) + #define XCP_MEMORY_FAR MEMORY_FAR + #else + #if defined ( V_MEMRAM2_FAR ) + #define XCP_MEMORY_FAR V_MEMRAM2_FAR + #else + #define XCP_MEMORY_FAR + #endif + #endif +#endif + +/* Far memory qualifier for functions. */ +#if defined ( XCP_FAR ) +#else + #if defined ( C_COMP_COSMIC_MCS12X_MSCAN12 ) + /* Always use far access for ApplXcpWrite() and ApplXcpread(). */ + #define XCP_FAR @far + #else + #define XCP_FAR + #endif +#endif + +/* RAM */ +#if defined ( RAM ) +#else + #define RAM +#endif + + +/* + DAQBYTEPTR and MTABYTEPTR may be defined different to BYTEPTR to save memory + Example: + #define BYTEPTR unsigned char * + #define MTABYTEPTR huge unsigned char * + #define DAQBYTEPTR unsigned char * +*/ +#if defined ( DAQBYTEPTR ) +#else + #define DAQBYTEPTR vuint8 XCP_MEMORY_FAR * +#endif + +#if defined ( MTABYTEPTR ) +#else + #define MTABYTEPTR uint8_t XCP_MEMORY_FAR * +#endif + +/* Pointer type used to point into the xcp structure */ +#if defined ( BYTEPTR ) +#else + #define BYTEPTR vuint8 * +#endif + + +/****************************************************************************/ +/* Checks and default values */ +/****************************************************************************/ + +/* Turn off test instrumentation, if not used */ +#if !defined(XCP_ASSERT) + #define XCP_ASSERT(x) +#endif +#if !defined(XCP_PRINT) + #define XCP_PRINT(x) +#endif +#if !defined(BEGIN_PROFILE) + #define BEGIN_PROFILE(i) +#endif +#if !defined(END_PROFILE) + #define END_PROFILE(i) +#endif + +/* Check limits of the XCP imnplementation +*/ +/* +#if ( kXcpMaxCTO > 255 ) + #error "kXcpMaxCTO must be < 256" +#endif +#if ( kXcpMaxCTO < 0x08 ) + #error "kXcpMaxCTO must be > 0x07" +#endif + + +#if ( kXcpMaxDTO_max > 255 ) + #error "kXcpMaxDTO must be < 256" +#endif +#if ( kXcpMaxDTO < 0x08 ) + #error "kXcpMaxDTO must be > 0x07" +#endif +*/ +#if defined ( XCP_ENABLE_DAQ ) + +/* kXcpDaqMemSize must be defined +*/ + #if defined ( kXcpDaqMemSize ) + #else + #error "Please define kXcpDaqMemSize" + #endif + +/* Use send queue as default +*/ + #if defined ( XCP_ENABLE_SEND_QUEUE ) || defined ( XCP_DISABLE_SEND_QUEUE ) + #else + #define XCP_ENABLE_SEND_QUEUE + #endif + +/* + Max. size of an object referenced by an ODT entry + XCP_MAX_ODT_ENTRY_SIZE may be limited +*/ + #if defined ( XCP_MAX_ODT_ENTRY_SIZE ) + #else + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) + #define XCP_MAX_ODT_ENTRY_SIZE (kXcpMaxDTO-2) + #else + #define XCP_MAX_ODT_ENTRY_SIZE (kXcpMaxDTO-1) + #endif + #endif + + +#else /* XCP_ENABLE_DAQ */ +#endif /* XCP_ENABLE_DAQ */ + + + +/****************************************************************************/ +/* XCP Packet Type Definition */ +/****************************************************************************/ + +#if defined ( XCP_ALLIGN_WORD ) + +typedef struct tEightByteFieldTag +{ + vbittype byte_0 : 8; + vbittype byte_1 : 8; + vbittype byte_2 : 8; + vbittype byte_3 : 8; + vbittype byte_4 : 8; + vbittype byte_5 : 8; + vbittype byte_6 : 8; + vbittype byte_7 : 8; +} tEightByteField; + +typedef union { + tEightByteField EightByteField; + vuint8 b[kXcpMaxDTO_tot/kXcpAG]; +} tXcpDtoByteField; + +typedef struct { + tXcpDtoByteField XcpDtoByteField; + vuint8 l; +} tXcpDto; + +typedef union { + /* There might be a loss of up to 3 bytes. */ + tEightByteField EightByteField; + vuint16 b[ ((kXcpMaxCTO_tot + 3) & 0xFFC) / 2 ]; + vuint16 w[ ((kXcpMaxCTO_tot + 3) & 0xFFC) / 2 ]; + vuint32 dw[ ((kXcpMaxCTO_tot + 3) & 0xFFC) / 4 ]; +} tXcpCto; + +#else + + +typedef struct { + vuint8 b[kXcpMaxDTO]; + vuint8 l; +} tXcpDto; + +typedef union { + /* There might be a loss of up to 3 bytes. */ + vuint8 b[ ((kXcpMaxCTO + 3) & 0xFFC) ]; + vuint16 w[ ((kXcpMaxCTO + 3) & 0xFFC) / 2 ]; + vuint32 dw[ ((kXcpMaxCTO + 3) & 0xFFC) / 4 ]; +} tXcpCto; +#endif + +/****************************************************************************/ +/* DAQ Lists, Type Definition */ +/****************************************************************************/ + +/* Note: + - Adressextensions are not used for DAQ +*/ + +#if defined ( XCP_ENABLE_DAQ ) + +/* ODT */ +/* Size must be even !!! */ +typedef struct { + + vuint16 firstOdtEntry; /* Absolute */ + vuint16 lastOdtEntry; /* Absolute */ + + +} tXcpOdt; + +#if defined( XCP_ENABLE_ODT_SIZE_WORD ) +typedef vuint16 tXcpOdtIdx; +typedef vuint16 tXcpOdtCnt; +#else +typedef vuint8 tXcpOdtIdx; +typedef vuint8 tXcpOdtCnt; +#endif + +/* DAQ list */ +typedef struct { + + tXcpOdtIdx lastOdt; /* Absolute */ + tXcpOdtIdx firstOdt; /* Absolute */ + + vuint8 flags; + + #if defined ( kXcpMaxEvent ) + /* Event-Daq association array used */ + #else + vuint8 eventChannel; + #endif + + #if defined ( XCP_ENABLE_DAQ_PRESCALER ) + vuint8 prescaler; + vuint8 cycle; + #endif + +} tXcpDaqList; + +/* Dynamic DAQ list structures */ +typedef struct { + + union { + vuint8 b[kXcpDaqMemSize]; + tXcpDaqList DaqList[1]; + } u; + + vuint8 DaqCount; + tXcpOdtCnt OdtCount; /* Absolute count */ + vuint16 OdtEntryCount; /* Absolute count */ + + /* Session configuration id for resume mode */ + + /* Event-Daq association array */ + #if defined ( kXcpMaxEvent ) + vuint8 EventDaq[kXcpMaxEvent]; + #endif +} tXcpDaq; + + +#if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + #if ( kXcpDaqTimestampSize == DAQ_TIMESTAMP_BYTE ) + typedef vuint8 XcpDaqTimestampType; + #elif ( kXcpDaqTimestampSize == DAQ_TIMESTAMP_WORD ) + typedef vuint16 XcpDaqTimestampType; + #elif ( kXcpDaqTimestampSize == DAQ_TIMESTAMP_DWORD ) + typedef vuint32 XcpDaqTimestampType; + #else + #error "kXcpDaqTimestampSize not defined. Please define a valid timestamp type!" + #endif +#endif + + + /* Shortcuts */ + + /* j is absolute odt number */ + #define DaqListOdtEntryCount(j) ((xcp.pOdt[j].lastOdtEntry-xcp.pOdt[j].firstOdtEntry)+1) + #define DaqListOdtLastEntry(j) (xcp.pOdt[j].lastOdtEntry) + #define DaqListOdtFirstEntry(j) (xcp.pOdt[j].firstOdtEntry) + #define DaqListOdtStimBuffer(j) (xcp.pOdt[j].pStimBuffer) + + /* n is absolute odtEntry number */ + #define OdtEntrySize(n) (xcp.pOdtEntrySize[n]) + #define OdtEntryAddr(n) (xcp.pOdtEntryAddr[n]) + + /* i is daq number */ + #define DaqListOdtCount(i) ((xcp.Daq.u.DaqList[i].lastOdt-xcp.Daq.u.DaqList[i].firstOdt)+1) + #define DaqListLastOdt(i) xcp.Daq.u.DaqList[i].lastOdt + #define DaqListFirstOdt(i) xcp.Daq.u.DaqList[i].firstOdt + #define DaqListFirstPid(i) xcp.Daq.u.DaqList[i].firstOdt + #define DaqListFlags(i) xcp.Daq.u.DaqList[i].flags + #define DaqListEventChannel(i) xcp.Daq.u.DaqList[i].eventChannel + #define DaqListPrescaler(i) xcp.Daq.u.DaqList[i].prescaler + #define DaqListCycle(i) xcp.Daq.u.DaqList[i].cycle + + +#endif /* XCP_ENABLE_DAQ */ + + +/****************************************************************************/ +/* Checksum, Type Definition */ +/****************************************************************************/ +#if defined ( XCP_ENABLE_CHECKSUM ) + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD11 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD12 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD14 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC32 ) + typedef vuint8 tXcpChecksumAddType; /* Data type (width) of the data to be added. */ + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) + typedef vuint16 tXcpChecksumAddType; /* Data type (width) of the data to be added. */ + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) + typedef vuint32 tXcpChecksumAddType; /* Data type (width) of the data to be added. */ + #endif + + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD11 ) + typedef vuint8 tXcpChecksumSumType; /* Data type (width) of the actually checksum. */ + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD12 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) + typedef vuint16 tXcpChecksumSumType; /* Data type (width) of the actually checksum. */ + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD14 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC32 ) + typedef vuint32 tXcpChecksumSumType; /* Data type (width) of the actually checksum. */ + #endif +#endif + + +/****************************************************************************/ +/* XCP Segment CAL parameters */ +/* Sement info */ +/****************************************************************************/ + +#if defined ( XCP_ENABLE_PAGE_INFO ) +typedef struct { + vuint8 SegmentInfoMaxPages; + vuint8 SegmentInfoInitSegment; + vuint8 SegmentInfoAddressExtension; + vuint8 SegmentInfoMaxMapping; + vuint8 SegmentInfoMode; + vuint8 SegmentPageProperties[kXcpMaxPages]; + vuint8 SegmentPageAktiv[kXcpMaxPages]; /* 1=aktiv, 0=deaktiv. */ + vuint8 SegmentPageMode[kXcpMaxPages]; /* 1=ECU, 2=XCP */ + vuint32 SegmentInfoMapping; +} tXcpSegmentInfo; +#endif + + +/****************************************************************************/ +/* XCP Driver Variables, Type Definition */ +/****************************************************************************/ + +/* Return values */ +#define XCP_CMD_DENIED 0 +#define XCP_CMD_OK 1 +#define XCP_CMD_PENDING 2 +#define XCP_CMD_SYNTAX 3 +#define XCP_CMD_BUSY 4 +#define XCP_CMD_UNKNOWN 5 +#define XCP_CMD_OUT_OF_RANGE 6 +#define XCP_MODE_NOT_VALID 7 +#define XCP_CMD_ERROR 0xFF + +/* Return values for XcpEvent() */ +#define XCP_EVENT_NOP 0x00u /* Inactive (DAQ not running, Event not configured) */ +#define XCP_EVENT_DAQ 0x01u /* DAQ active */ +#define XCP_EVENT_DAQ_OVERRUN 0x02u /* DAQ queue overflow */ +#define XCP_EVENT_STIM 0x04u /* STIM active */ +#define XCP_EVENT_STIM_OVERRUN 0x08u /* STIM data not available */ + +/* Bitmasks for xcp.SendStatus */ +#define XCP_CRM_REQUEST 0x01u +#define XCP_DTO_REQUEST 0x02u +#define XCP_EVT_REQUEST 0x04u +#define XCP_CRM_PENDING 0x10u +#define XCP_DTO_PENDING 0x20u +#define XCP_EVT_PENDING 0x40u +#define XCP_SEND_PENDING (XCP_DTO_PENDING|XCP_CRM_PENDING|XCP_EVT_PENDING) + +typedef struct { + /* Crm has to be the first object of this structure !! (refer to XcpInit()) */ + + tXcpCto Crm; /* RES,ERR Message buffer */ + vuint8 CrmLen; /* RES,ERR Message length */ + +#if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT ) + tXcpCto Ev; /* EV,SERV Message buffer */ + vuint8 EvLen; /* EV,SERV Message length */ +#endif + + vuint8 SessionStatus; + + MTABYTEPTR Mta; /* Memory Transfer Address */ + + +#if defined ( XCP_ENABLE_SEED_KEY ) + vuint8 ProtectionStatus; /* Resource Protection Status */ +#endif + +#if defined ( XCP_ENABLE_CHECKSUM ) + vuint16 CheckSumSize; /* Counter for checksum calculation */ + tXcpChecksumSumType CheckSum; /* Actual checksum */ +#endif + +#if defined ( XCP_ENABLE_DAQ ) /* Data Acquisition */ + + /* + Dynamic DAQ list structures + This structure should be stored in resume mode + */ + tXcpDaq Daq; + + tXcpOdt *pOdt; + DAQBYTEPTR *pOdtEntryAddr; + vuint8 *pOdtEntrySize; + + /* Transmit Queue */ + #if defined ( XCP_ENABLE_SEND_QUEUE ) + tXcpDto *pQueue; + vuint8 QueueSize; + vuint8 QueueLen; + vuint8 QueueRp; + #endif + + /* Transmit Status */ + #if defined ( XCP_ENABLE_SEND_QUEUE) + vuint8 SendStatus; + #endif + + /* Pointer for SET_DAQ_PTR */ + vuint16 DaqListPtr; + + +#endif /* XCP_ENABLE_DAQ */ + +} tXcpData; + + +/***************************************************************************/ +/* External Declarations */ +/***************************************************************************/ + +/******************************************************************************* +* External 8 Bit Constants +*******************************************************************************/ + +V_MEMROM0 extern MEMORY_ROM vuint8 kXcpMainVersion; +V_MEMROM0 extern MEMORY_ROM vuint8 kXcpSubVersion; +V_MEMROM0 extern MEMORY_ROM vuint8 kXcpReleaseVersion; + + + +/****************************************************************************/ +/* Prototypes */ +/****************************************************************************/ + + +/* Important external functions of xcp.c */ +/*-----------------------------------------*/ + + +/* Initialization and deinitialization functions for the XCP Protocol Layer. */ +extern void XcpInit( void ); +extern void XcpExit( void ); + +/* Trigger a XCP data acquisition or stimulation event */ +/* Returns an error status XCP_EVENT_xxxx */ +extern vuint8 XcpEvent( vuint8 event ); + +/* Check if a XCP stimulation event can perform or delete the buffers */ +/* Returns 1 (TRUE) if new stimulation data is available */ + +/* Call the XCP command processor. */ +extern void XcpCommand( MEMORY_ROM vuint32* pCommand ); + +/* Transmit Notification */ +/* Confirmation of the transmit request by ApplXcpSend(). */ +/* Returns 0 when the XCP driver is idle */ +extern vuint8 XcpSendCallBack( void ); + +/* Background Loop */ +/* Return 1 (TRUE) if anything is still pending */ +/* Used only if Checksum Calculation or EEPROM Programming is required */ +extern vuint8 XcpBackground( void ); + + +/*-----------------------------------------------------------------------------------*/ +/* Functions or Macros that have to be provided externally to the XCP Protocol Layer */ +/*-----------------------------------------------------------------------------------*/ + + + + + +#if defined ( XCP_TRANSPORT_LAYER_TYPE_CAN ) + #if defined ( ApplXcpSendFlush ) + #else + #define ApplXcpSendFlush() + #endif +#endif + + +/* Transmission Request for a XCP Packet */ +#if defined ( ApplXcpSend ) +#else +extern void ApplXcpSend( vuint8 len, MEMORY_ROM BYTEPTR msg ); +#endif + +/* Flush the transmit buffer if there is one implemented in ApplXcpSend() */ +#if defined ( ApplXcpSendFlush ) +#else +extern void ApplXcpSendFlush( void ); +#endif + +/* Generate a native pointer from XCP address extension and address */ +#if defined ( ApplXcpGetPointer ) +#else +extern MTABYTEPTR ApplXcpGetPointer( vuint8 addr_ext, vuint32 addr ); +#endif + +#if defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) +extern vuint8 ApplXcpRead( vuint32 addr ); +extern void XCP_FAR ApplXcpWrite( vuint32 addr, vuint8 data ); +#endif + +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) || defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) + #if defined ( XCP_ENABLE_CHECKSUM ) + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) || \ + defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) +extern tXcpChecksumAddType ApplXcpReadChecksumValue( vuint32 addr ); + #endif + #endif +#endif + + +#if defined ( XCP_ENABLE_CALIBRATION_MEM_ACCESS_BY_APPL ) && !defined ( XCP_ENABLE_MEM_ACCESS_BY_APPL ) +extern vuint8 ApplXcpCalibrationWrite(MTABYTEPTR addr, vuint8 size, MEMORY_ROM BYTEPTR data); +extern vuint8 ApplXcpCalibrationRead(MTABYTEPTR addr, vuint8 size, BYTEPTR data); +#endif + +/* Application specific initialization function (called by XcpInit() ). */ +#if defined ( ApplXcpInit ) +#else +extern void ApplXcpInit( void ); +#endif + +/* Application specific background ground loop (called by XcpBackground() ). */ +#if defined ( ApplXcpBackground ) +#else +extern void ApplXcpBackground( void ); +#endif + +/* Enable interrupts */ +#if defined ( ApplXcpInterruptEnable ) +#else +extern void ApplXcpInterruptEnable( void ); +#endif + +/* Disable interrupts */ +#if defined ( ApplXcpInterruptDisable ) +#else +extern void ApplXcpInterruptDisable( void ); +#endif + + +/* Some available utility functions */ +/*----------------------------------*/ + +/* Force a XCP disconnect */ +extern void XcpDisconnect( void ); + +/* Send a pending XCP response packet (RES). */ +/* To be used after a XCP_CMD_PENDING from EEPROM or FLASH programming. */ +extern void XcpSendCrm( void ); + +/* Send a XCP event (EV) or service request (SERV) message */ +#if defined ( XCP_ENABLE_SEND_EVENT ) +extern void XcpSendEvent( vuint8 evc, MEMORY_ROM BYTEPTR c, vuint8 len); +#endif + +/* Send a text message */ +/* Implement print and putchar into a XCP SERV/SERV_TEXT message */ +#if defined ( XCP_ENABLE_SERV_TEXT ) + #if defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) +extern void XcpPutchar( MEMORY_ROM vuint8 c ); + #if defined ( XCP_ENABLE_SERV_TEXT_PRINT ) +extern void XcpPrint( MEMORY_ROM vuint8 *str ); + #if defined ( XCP_ENABLE_SERV_TEXT_PRINTF ) +extern void XcpPrintf( MEMORY_ROM vuint8 *str, ... ); + #endif + #endif + #endif +#endif + + +/* Functions that may have be provided externally depending on options */ +/*---------------------------------------------------------------------*/ + +/* Utility functions from xcp.c */ +/*------------------------------*/ + +/* Override option for the memory transfer function */ +/* May be used for optimization */ +/* #define XcpMemCpy, #define XcpMemSet to disable the implementation in xcp.c */ +#if defined ( XcpMemCpy ) || defined ( C_COMP_COSMIC_MCS12X_MSCAN12 ) +#else +extern void XcpMemCpy( DAQBYTEPTR dest, MEMORY_ROM DAQBYTEPTR src, vuint8 n ); +#endif +#if defined ( XcpMemSet ) +#else +extern void XcpMemSet( BYTEPTR p, vuint16 n, vuint8 b ); +#endif + +/* Send a DTO */ +/* Can be redefined to meet DMA requirements */ +#if defined ( XCP_ENABLE_DAQ ) + #if defined ( XcpSendDto ) + /* XcpSendDto is redefined */ + #else +extern void XcpSendDto( MEMORY_ROM tXcpDto *dto ); + #endif +#endif + +/* Resolve a transmit stall condition in XcpPutchar() or XcpSendEvent() */ +/* Returns true (!=0) if successfull */ +#if defined ( XCP_ENABLE_SEND_EVENT ) || defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) + #if defined ( XCP_ENABLE_SEND_QUEUE ) + #if defined ( ApplXcpSendStall ) + #else +extern vuint8 ApplXcpSendStall( void ); + #endif + #endif +#endif + +/* Check addresses for valid write access */ +/* Returns 0 (false) if access denied */ +/* Used only, if write protection of memory areas is required */ + +/* Check addresses for valid read access */ +/* Returns 0 (false) if access denied */ +/* Used only, if read protection of memory areas is required */ + +/* Check addresses for valid programming access */ +/* Returns 0 (false) if access denied */ +/* Used only, if programming protection of memory areas is required */ + +/* DAQ resume */ + +/* DAQ Timestamp */ +#if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + #if defined ( ApplXcpGetTimestamp ) + /* ApplXcpGetTimestamp is redefined */ + #else +extern XcpDaqTimestampType ApplXcpGetTimestamp( void ); +extern vuint8 *ApplXcpGetTimestamp_Address( void ); + + #endif +#endif + +/* Flash Programming by Flash Kernel */ + + +/* Flash Programming */ + + +/* RAM/ROM Switching */ +#if defined ( XCP_ENABLE_CALIBRATION_PAGE ) + +extern vuint8 ApplXcpGetCalPage( vuint8 segment, vuint8 mode ); +extern vuint8 ApplXcpSetCalPage( vuint8 segment, vuint8 page, vuint8 mode); + +/* extern void ApplXcpInitCalPage( void ); */ + #if defined ( XCP_ENABLE_PAGE_COPY ) +extern vuint8 ApplXcpCopyCalPage( vuint8 srcSeg, vuint8 srcPage, vuint8 destSeg, vuint8 destPage ); +/* Returns: + XCP_CMD_OK + XCP_CMD_PENDING - call XcpSendCrm when done + XCP_CMD_ERROR +*/ + #endif +#endif +#if defined ( XCP_ENABLE_PAGE_FREEZE ) +extern void ApplXcpSetFreezeMode( vuint8 segment, vuint8 mode ); +extern vuint8 ApplXcpGetFreezeMode( vuint8 segment ); +#endif + +/* Seed & Key */ +#if defined ( XCP_ENABLE_SEED_KEY ) + +extern vuint8 ApplXcpGetSeed( MEMORY_ROM vuint8 resource, vuint8 *seed ); +extern vuint8 ApplXcpUnlock( MEMORY_ROM vuint8 *key, MEMORY_ROM vuint8 length ); + +#endif + +/* User defined service of GET_ID to transfer MAP-file names (ESCAN00008482) */ +#if defined ( XCP_ENABLE_VECTOR_MAPNAMES ) +extern vuint32 ApplXcpGetIdData( MTABYTEPTR *pData); +#endif + +/* EEPROM Programing */ + + +/* User defined service */ +#if defined ( XCP_ENABLE_USER_COMMAND ) +/* Return values for ApplXcpUserService: + XCP_CMD_OK - Done + XCP_CMD_PENDING - Pending, call XcpSendCrm when done + XCP_CMD_SYNTAX - Error +*/ +extern vuint8 ApplXcpUserService( MEMORY_ROM BYTEPTR pCmd ); +#endif + +/* Transport Layer service */ + + +#if defined ( XCP_ENABLE_VERSION_INFO_API ) +extern void XcpGetVersionInfo(Std_VersionInfoType *XcpVerInfoPtr); +#endif + +#if defined ( XCP_ENABLE_GET_CONNECTION_STATE ) +/* Get the connection state of the XCP Protocol Layer */ +extern vuint8 XcpGetState( void ); +#endif + +#if defined ( XCP_ENABLE_GET_XCP_DATA_POINTER ) +extern void XcpGetXcpDataPointer( RAM tXcpData ** pXcpData ); +#endif + + + +#if defined ( XCP_ENABLE_TESTMODE ) + +/****************************************************************************/ +/* Test */ +/****************************************************************************/ + +extern vuint8 gDebugLevel; + + #if defined ( ApplXcpPrint ) + /* ApplXcpPrint is a macro */ + #else +extern void ApplXcpPrint( MEMORY_ROM char *str ); + #endif + +extern void XcpPrintDaqList( vuint8 daq ); +#endif /* XCP_ENABLE_TESTMODE */ + + + + +/*****************************************************************************/ +/* Consistency and limit checks ( XCP Protocol Layer specific ) */ +/*****************************************************************************/ + +/* The test mode must not be used with XCP Professional. */ + + + +/* Check consistency of DAQ switch */ + +#if defined ( XCP_ENABLE_DAQ ) && defined ( XCP_DISABLE_DAQ ) + #error "XCP consistency error: DAQ must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_DAQ ) || defined ( XCP_DISABLE_DAQ ) +#else + #error "XCP consistency error: DAQ must be enabled or disabled." +#endif + +/* Check consistency of send queue */ + +#if defined ( XCP_ENABLE_SEND_QUEUE ) && defined ( XCP_DISABLE_SEND_QUEUE ) + #error "XCP consistency error: Send queue must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SEND_QUEUE ) || defined ( XCP_DISABLE_SEND_QUEUE ) +#else + #error "XCP consistency error: Send queue must be enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SEND_QUEUE ) && defined ( XCP_DISABLE_DAQ ) + #error "XCP consistency error: Send queue cannot be used without DAQ." +#endif + +/* Check consistency of communictaion mode info */ + +#if defined ( XCP_ENABLE_COMM_MODE_INFO ) && defined ( XCP_DISABLE_COMM_MODE_INFO ) + #error "XCP consistency error: Communictaion mode info must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_COMM_MODE_INFO ) || defined ( XCP_DISABLE_COMM_MODE_INFO ) +#else + #error "XCP consistency error: Communictaion mode info must be enabled or disabled." +#endif + +/* Check service request */ + +#if defined ( XCP_ENABLE_SERV_TEXT ) && defined ( XCP_DISABLE_SERV_TEXT ) + #error "XCP consistency error: Service request must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SERV_TEXT ) || defined ( XCP_DISABLE_SERV_TEXT ) +#else + #error "XCP consistency error: Service request must be enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SERV_TEXT ) && defined ( XCP_DISABLE_SERV_TEXT_PUTCHAR ) + #error "XCP consistency error: Without XcpPutchar is no service request possible." +#endif + +/* Check service request XcpPutchar */ + +#if defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) && defined ( XCP_DISABLE_SERV_TEXT_PUTCHAR ) + #error "XCP consistency error: XcpPutchar function must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) || defined ( XCP_DISABLE_SERV_TEXT_PUTCHAR ) +#else + #error "XCP consistency error: XcpPutchar function must be enabled or disabled." +#endif +#if defined ( XCP_DISABLE_SERV_TEXT ) && defined ( XCP_ENABLE_SERV_TEXT_PUTCHAR ) + #error "XCP consistency error: XcpPutchar function can only be used with service requests." +#endif + +/* check service request XcpPutchar */ + +#if defined ( XCP_ENABLE_SERV_TEXT_PRINTF ) && defined ( XCP_DISABLE_SERV_TEXT_PRINTF ) + #error "XCP consistency error: XcpPrint function must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SERV_TEXT_PRINTF ) || defined ( XCP_DISABLE_SERV_TEXT_PRINTF ) +#else + #error "XCP consistency error: XcpPrint function must be enabled or disabled." +#endif +#if defined ( XCP_ENABLE_SERV_TEXT ) && defined ( XCP_DISABLE_SERV_TEXT_PUTCHAR ) + #error "XCP consistency error: XcpPrint requires XcpPutchar function." +#endif + +/* Check consistency of DAQ header ODT */ +#if defined(XCP_ENABLE_DAQ) + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) && defined ( XCP_DISABLE_DAQ_HDR_ODT_DAQ ) + #error "XCP consistency error: DAQ_HDR_ODT_DAQ must be either enabled or disabled." + #endif + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) || defined ( XCP_DISABLE_DAQ_HDR_ODT_DAQ ) + #else + #error "XCP consistency error: DAQ_HDR_ODT_DAQ must be enabled or disabled." + #endif +#endif + +/* Check consistency of Page switching */ + +#if defined ( XCP_ENABLE_CALIBRATION_PAGE ) && defined ( XCP_DISABLE_CALIBRATION_PAGE ) + #error "XCP consistency error: Page switching must be either enabled or disabled." +#endif +#if defined ( XCP_ENABLE_CALIBRATION_PAGE ) || defined ( XCP_DISABLE_CALIBRATION_PAGE ) +#else + #error "XCP consistency error: Page switching must be enabled or disabled." +#endif + +/* Check range of kXcpStationIdLength */ + +#if defined ( kXcpStationIdLength ) + #if ( kXcpStationIdLength > 0xFF ) + #error "XCP error: kXcpStationIdLength must be < 256." + #endif +#endif + +/* Check range of kXcpStimOdtCount */ + + +#if defined ( XCP_ENABLE_DAQ ) + + /* Check range of kXcpDaqMemSize */ + + #if defined ( kXcpDaqMemSize ) + #if ( kXcpDaqMemSize > 0xFFFF ) + #error "XCP error: kXcpDaqMemSize must be <= 0xFFFF." + #endif + #endif + + /* Check range of kXcpSendQueueMinSize. */ + + #if defined ( kXcpSendQueueMinSize ) + #if ( kXcpSendQueueMinSize > 0xFF ) + #error "XCP error: kXcpSendQueueMinSize must be <= 0xFF." + #endif + #endif + + /* Check range of kXcpMaxEvent */ + #if defined ( kXcpMaxEvent ) + #if ( kXcpMaxEvent > 0xFF ) + #error "XCP error: kXcpMaxEvent must be <= 0xFF." + #endif + #endif + + /* Check XCP_ENABLE_ODT_SIZE_WORD in combination with XCP_ENABLE_DAQ_HDR_ODT_DAQ */ + #if defined ( XCP_ENABLE_ODT_SIZE_WORD ) + #if defined ( XCP_ENABLE_DAQ_HDR_ODT_DAQ ) + #else + #error "XCP error: If XCP_ENABLE_ODT_SIZE_WORD is enabled, XCP_ENABLE_DAQ_HDR_ODT_DAQ must be enabled as well." + #endif + #endif + +#endif /* defined ( XCP_ENABLE_DAQ ) */ + +#if defined ( XCP_ENABLE_CHECKSUM ) + + /* Check configuration of kXcpChecksumMethod */ + #if defined ( kXcpChecksumMethod ) + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD11 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD12 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD14 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC32 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC16CCITT ) + #else + #error "XCP error: Checksum calculation method not supported." + #endif + #endif + + /* Check configuration of kXcpChecksumBlockSize. */ + #if defined ( kXcpChecksumBlockSize ) + #if ( kXcpChecksumBlockSize > 0xFFFF ) + #error "XCP error: Checksum block size is limited to a maximum of 0xFFFF." + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD22 ) || \ + ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD24 ) + #if ((kXcpChecksumBlockSize % 2) != 0 ) + #error "XCP error: The blocksize must be modulo 2." + #endif + #endif + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_ADD44 ) + #if ((kXcpChecksumBlockSize % 4) != 0 ) + #error "XCP error: The blocksize must be modulo 4." + #endif + #endif + #endif + + #if ( kXcpChecksumMethod == XCP_CHECKSUM_TYPE_CRC32 ) + #error "XCP error: Checksum calculation method not supported." + #endif + +#endif /* defined ( XCP_ENABLE_CHECKSUM ) */ + +#if defined ( XCP_ENABLE_DAQ_TIMESTAMP ) + + /* Check configuration of kXcpDaqTimestampUnit. */ + + #if defined ( kXcpDaqTimestampUnit ) + #if ( (kXcpDaqTimestampUnit >> 4) > 9 ) || ( (kXcpDaqTimestampUnit & 0x0F) > 0 ) + #error "XCP error: the value of kXcpDaqTimestampUnit is not valid." + #endif + #endif + + /* Check configuration of kXcpDaqTimestampTicksPerUnit. */ + + #if defined ( kXcpDaqTimestampTicksPerUnit ) + #if ( (kXcpDaqTimestampTicksPerUnit > 0xFFFF) || (kXcpDaqTimestampTicksPerUnit == 0) ) + #error "XCP error: illegal range of kXcpDaqTimestampTicksPerUnit: 0 < kXcpDaqTimestampTicksPerUnit <= 0xFFFF." + #endif + #endif + + /* Check for configuration of kXcpDaqTimestampSize */ + #if defined ( kXcpDaqTimestampSize ) + #if ( kXcpDaqTimestampSize != DAQ_TIMESTAMP_BYTE ) && ( kXcpDaqTimestampSize != DAQ_TIMESTAMP_WORD ) && ( kXcpDaqTimestampSize != DAQ_TIMESTAMP_DWORD ) + #error "XCP error: Please define kXcpDaqTimestampSize to either DAQ_TIMESTAMP_BYTE, DAQ_TIMESTAMP_WORD or DAQ_TIMESTAMP_DWORD" + #endif + #endif + +#endif + +/* Check range of service request kXcpMaxSegment. */ + +#if defined ( XCP_ENABLE_PAGE_INFO ) + #if defined ( kXcpMaxSegment ) + #if ( ( kXcpMaxSegment > 0xFF ) || ( kXcpMaxSegment == 0x00 ) ) + #error "XCP error: kXcpMaxSegment must be <= 0xFF and > 0x00." + #endif + #endif +#endif + +/* Check range of service request kXcpProgramMaxSector. */ + + + + #define C_KOMMENTAR_VECTOR + + + +#endif /* ! defined ( __XCP_H_ ) */ + diff --git a/src/xcp/XcpDriverCom.h b/src/xcp/XcpDriverCom.h new file mode 100644 index 0000000..a0950c4 --- /dev/null +++ b/src/xcp/XcpDriverCom.h @@ -0,0 +1,17 @@ +/* + * XcpDriverCom.h + * + * Created on: 30.07.2022 + * Author: flori + */ + +#ifndef XCPDRIVERCOM_H_ +#define XCPDRIVERCOM_H_ + +#define XCP_COM_AVAILABLE() Serial.available() +#define XCP_COM_READ() Serial.read() +#define XCP_COM_WRITE_BYTE(b) Serial.write(b) + + + +#endif /* XCPDRIVERCOM_H_ */ diff --git a/src/xcp/XcpFrame.h b/src/xcp/XcpFrame.h new file mode 100644 index 0000000..4e35c7c --- /dev/null +++ b/src/xcp/XcpFrame.h @@ -0,0 +1,18 @@ +#ifndef XCPFRAME_H +#define XCPFRAME_H + +#include "Arduino.h" + +#define DTOBUF_PACKETSIZE 16u /* packet size in bytes */ + +class XcpFrame +{ + public: + uint16_t len; + union{ + uint32_t u32[DTOBUF_PACKETSIZE/4u]; + uint8_t u8[DTOBUF_PACKETSIZE]; + } data; /* the xcp driver needs uint32 aligned data */ +}; + +#endif diff --git a/src/xcp/XcpFrameReceiver.cpp b/src/xcp/XcpFrameReceiver.cpp new file mode 100644 index 0000000..3650b06 --- /dev/null +++ b/src/xcp/XcpFrameReceiver.cpp @@ -0,0 +1,146 @@ +#include "XcpFrameReceiver.h" + +template class RingBuffer; + +/** + * XcpFrameReceiver : protocol class to decode frame data with SOF byte and + * byte stuffing (with preceding escape byte). A valid frame must be transmitted + * like this: + * SOF len(LSB) len(MSB) cs(LSB) cs(MSB) data0 data1 .. + * + * len: uint16 , number of data bytes + * cs : uint16 , checksum (sum over all data bytes) + * + * if there is any escape byte or SOF byte inside the len, cs, or data field + * it must be transmitted with a preceding escape byte (this does not affect the + * len or cs itself). + * + * Usage: + * 1. initialize with existing array + * 2. call hasSpace, putData to write and decode the received data and + * store it into the given array + * 3. call hasFrames, getFrame to get the decoded frames + * + */ + + +/* + * constructor: Init everything + * \param : frameArray : pointer to first element of frame array + * arraySize : number of elements inside the array + * + */ +XcpFrameReceiver::XcpFrameReceiver(XcpFrame *frameArray, uint32_t arraySize, bool useChecksum ) +{ + ringBuffer = new RingBuffer(frameArray, arraySize); + state = NONE_XCP_DATA; + frameLen = 0; + frameCount = 0; + iFrameData = 0; + pWriteFrame = NULL; + numProtocolErrors = 0; +} + +/** + * return false if the underlying buffer has no space left + */ +bool XcpFrameReceiver::hasSpace(void) +{ + return ringBuffer->canWrite(); +} + +/** + * return true if there are readable elements in the underlying buffer + */ +bool XcpFrameReceiver::hasFrames(void) +{ + return ringBuffer->canRead(); +} + +/** + * get the available number of frames that have not been read yet + */ +uint32_t XcpFrameReceiver::getNumberFrames(void) +{ + return ringBuffer->getNumberUnread(); +} + +/** + * return the frame that was received next and yet not read. + * -> call only once per receive frame (increments the index) + */ +XcpFrame *XcpFrameReceiver::getFrame(void) +{ + return ringBuffer->getReadPointer(); +} + +/** check canWrite before putting new data ! */ +void XcpFrameReceiver::putData(uint32_t lenData, uint8_t * data) +{ + uint32_t i; + pWriteFrame = ringBuffer->getWritePointer(); + + i = 0; + while (idata.u8[iFrameData++] = byte; + if (iFrameData == frameLen) + { + pWriteFrame->len = frameLen; + ringBuffer->write(); + state = NONE_XCP_DATA; + } + + break; + } +} diff --git a/src/xcp/XcpFrameReceiver.h b/src/xcp/XcpFrameReceiver.h new file mode 100644 index 0000000..6cd5b6a --- /dev/null +++ b/src/xcp/XcpFrameReceiver.h @@ -0,0 +1,61 @@ +#ifndef XCPFRAMERECEIVER_H +#define XCPFRAMERECEIVER_H + +#include "RingBuffer.h" +#include "XcpFrame.h" + + +class XcpFrameReceiver +{ + public : + static const uint8_t ESCBYTE = 0xFF; + + /* + * constructor: Init everything + */ + XcpFrameReceiver(XcpFrame *frameArray, uint32_t arraySize, bool useChecksum = true); + + /** + * return false if the back buffer has no space left + */ + bool hasSpace(void); + + /** + * return true if there are readable frames in the back buffer + */ + bool hasFrames(void); + + /** + * get the available number of frames that have not been read yet + */ + uint32_t getNumberFrames(void); + + /** + * return the frame that was received next and yet not read. + */ + XcpFrame *getFrame(void); + + /** check canWrite before putting new data ! */ + void putData(uint32_t lenData, uint8_t * data); + + private : + + + uint32_t frameCount; /** counter for every XCP ethernet frame to be compared with received counter */ + class RingBuffer *ringBuffer; + XcpFrame* pWriteFrame; + uint16_t iFrameData; /* temporary index for received Xcp Frame data */ + uint8_t frameLen; + uint32_t numProtocolErrors; + + enum receiveState { NONE_XCP_DATA, ESCAPED, XCP_DATA } state; + + /** + * destuff escape bytes, detect start of frame, forward data bytes + */ + void processByte(uint8_t byte); + +}; + + +#endif diff --git a/src/xcp/XcpPort.h b/src/xcp/XcpPort.h new file mode 100644 index 0000000..78e8fab --- /dev/null +++ b/src/xcp/XcpPort.h @@ -0,0 +1,18 @@ +/* + * XcpPort.h + * + * Created on: 30.07.2022 + * Author: flori + */ + +#ifndef XCP_XCPPORT_H_ +#define XCP_XCPPORT_H_ + +#include "xcp_typedefs.h" + +vuint8 XcpEvent( vuint8 event ); +extern void XcpInit( void ); +extern void XcpPoll(); +extern void XcpSendLoop(); + +#endif /* XCP_XCPPORT_H_ */ diff --git a/src/xcp/xcp_cfg.h b/src/xcp/xcp_cfg.h new file mode 100644 index 0000000..5344769 --- /dev/null +++ b/src/xcp/xcp_cfg.h @@ -0,0 +1,140 @@ +/* ----------------------------------------------------------------------------- + C O P Y R I G H T + ------------------------------------------------------------------------------- + Copyright (c) 2001-2006 by Vector Informatik GmbH. All rights reserved. + + This software is copyright protected and proprietary to Vector Informatik + GmbH. + + Vector Informatik GmbH grants to you only those rights as set out in the + license conditions. + + All other rights remain with Vector Informatik GmbH. + ------------------------------------------------------------------------------- + ----------------------------------------------------------------------------- */ + +#if !defined(__XCP_CFG_H__) +#define __XCP_CFG_H__ + + + + +#undef EXTERN + +/* */ +/* CPU */ +#define C_CPUTYPE_LITTLEENDIAN + +#define XCP_ENABLE_CANAPE_5_5_X_SUPPORT //nur fuer EVENT_TIME_UNIT bei GET_DAQ_EVENT_INFO + + +/* General settings */ +#define XCP_ENABLE_PARAMETER_CHECK +#define XCP_ENABLE_SEND_EVENT +#define XCP_DISABLE_TESTMODE +#define XCP_DISABLE_BOOTLOADER_DOWNLOAD +#define XCP_DISABLE_WRITE_PROTECTION +#define XCP_DISABLE_READ_PROTECTION +#define XCP_ENABLE_CONTROL +#define XCP_DISABLE_GET_XCP_DATA_POINTER +#define XCP_DISABLE_OPENCMDIF +#define XCP_ENABLE_MEM_MAPPING +#define XCP_DISABLE_VERSION_INFO_API +/* */ +/* EEPROM access */ +#define XCP_DISABLE_READ_EEPROM +#define XCP_DISABLE_WRITE_EEPROM +/* */ +/* Service request message */ +#define XCP_DISABLE_SERV_TEXT +#define XCP_DISABLE_SERV_TEXT_PUTCHAR +#define XCP_DISABLE_SERV_TEXT_PRINTF +/* */ +/* Standard commands */ +#define XCP_ENABLE_COMM_MODE_INFO +#define XCP_DISABLE_SEED_KEY +#define XCP_ENABLE_MODIFY_BITS +#define XCP_ENABLE_SHORT_DOWNLOAD +#define XCP_DISABLE_USER_COMMAND +#define XCP_DISABLE_VECTOR_MAPNAMES +#define XCP_ENABLE_TL_COMMAND +/* */ +/* Block transfer */ +#define XCP_ENABLE_BLOCK_UPLOAD +#define XCP_ENABLE_BLOCK_DOWNLOAD +/* */ +/* Checksum */ +#define XCP_DISABLE_CHECKSUM +#define XCP_DISABLE_AUTOSAR_CRC_MODULE +#define kXcpChecksumMethod XCP_CHECKSUM_TYPE_ADD12 +#define kXcpChecksumBlockSize 0 +/* */ +/* Synchronous Data Acquisition (DAQ) */ +#define XCP_ENABLE_DAQ +#define kXcpDaqMemSize 256 +#define XCP_DISABLE_STIM +#define XCP_DISABLE_UNALIGNED_MEM_ACCESS +#define XCP_ENABLE_SEND_DIRECT +#define XCP_DISABLE_SEND_QUEUE +#define kXcpStimOdtCount 0x04u +#define XCP_ENABLE_DAQ_PRESCALER +#define XCP_ENABLE_DAQ_OVERRUN_INDICATION +#define XCP_ENABLE_WRITE_DAQ_MULTIPLE + + +#undef XCP_ENABLE_DAQ_HDR_ODT_DAQ +#undef XCP_ALLIGN_WORD +#undef XCP_ENABLE_ODT_SIZE_WORD + +#define XCP_ENABLE_DAQ_RESUME +#define XCP_ENABLE_DAQ_PROCESSOR_INFO +#define XCP_ENABLE_DAQ_RESOLUTION_INFO +/* */ +// CALIBRATION +#define XCP_ENABLE_CALIBRATION + +/* Events */ +#define XCP_ENABLE_DAQ_EVENT_INFO +#define kXcpMaxEvent 4 +/* */ +/* DAQ Timestamp */ +#define XCP_ENABLE_DAQ_TIMESTAMP +#define XCP_ENABLE_DAQ_TIMESTAMP_FIXED +#define kXcpDaqTimestampUnit DAQ_TIMESTAMP_UNIT_1MS +#define kXcpDaqTimestampTicksPerUnit 1 +#define kXcpDaqTimestampSize DAQ_TIMESTAMP_WORD +/* */ +/* Page switching */ +#undef XCP_DISABLE_CALIBRATION_PAGE +#define kXcpMaxSegment 1 +#undef XCP_ENABLE_PAGE_INFO +#define kXcpMaxPages 2 +#define XCP_DISABLE_PAGE_COPY +#define XCP_DISABLE_PAGE_FREEZE +/* */ +/* Programming */ +#define XCP_DISABLE_PROGRAM +#define kXcpProgramMinStPgm 0 +#define kXcpProgramMaxSector 1 +#define XCP_DISABLE_PROGRAM_INFO +/* */ +#define CP_XCPDLL_VERSION 0x0209u +#define CP_XCPDLL_RELEASE_VERSION 0x00u +#define XCP_SEND_QUEUE_SAMPLE_ODT +//#define XCP_TRANSPORT_LAYER_TYPE_FLEXRAY_ASR +//#define XCP_TRANSPORT_LAYER_TYPE_CAN + +/* begin Fileversion check */ +#ifndef SKIP_MAGIC_NUMBER +#ifdef MAGIC_NUMBER + #if MAGIC_NUMBER != 2124540520 + #error "The magic number of the generated file is different. Please check time and date of generated files!" + #endif +#else + #define MAGIC_NUMBER 2124540520 +#endif /* MAGIC_NUMBER */ +#endif /* SKIP_MAGIC_NUMBER */ + +/* end Fileversion check */ + +#endif /* __XCP_CFG_H__ */ diff --git a/src/xcp/xcp_def.h b/src/xcp/xcp_def.h new file mode 100644 index 0000000..45e49eb --- /dev/null +++ b/src/xcp/xcp_def.h @@ -0,0 +1,172 @@ +/*---------------------------------------------------------------------------- +| File: +| XCP_DEF.H +| +| Project: +| XCP samples +| +| Description +| XCP default settings +| Don't change this file +| + ----------------------------------------------------------------------------*/ +#if defined ( __XCP_DEF_H__ ) +#else +#define __XCP_DEF_H__ + + +#ifdef VAR_DEF +#define EXTERN +#else +#define EXTERN extern +#endif + + +/*------------------------------------------------------------------------------------*/ +/* Default settings */ + +/* XCP transport layer */ +#if !defined(XCP_TRANSPORT_LAYER_VERSION) + #define XCP_TRANSPORT_LAYER_VERSION 0x0100 +#endif + + +#undef EXTERN + +#define GRANULARITY_ODT_ENTRY_SIZE_ODT 1 + +/* ROM memory qualifiers */ +#if !defined(MEMORY_ROM) + #define MEMORY_ROM const +#endif +#if !defined(V_MEMROM0) + #define V_MEMROM0 +#endif +#if !defined(MEMORY_CONST) + #define MEMORY_CONST +#endif + + +/* Alignment requirements */ +/* Specify, whether the microcontroller allows unaligned memory access or not */ +#if !defined(XCP_ENABLE_UNALIGNED_MEM_ACCESS) && !defined(XCP_DISABLE_UNALIGNED_MEM_ACCESS) + #define XCP_DISABLE_UNALIGNED_MEM_ACCESS +#endif + +/* General settings */ +#if !defined(XCP_ENABLE_PARAMETER_CHECK) && !defined(XCP_DISABLE_PARAMETER_CHECK) + #define XCP_DISABLE_PARAMETER_CHECK +#endif +#if !defined(XCP_ENABLE_COMM_MODE_INFO) && !defined(XCP_DISABLE_COMM_MODE_INFO) + #define XCP_ENABLE_COMM_MODE_INFO +#endif +#if !defined(XCP_ENABLE_USER_COMMAND) && !defined(XCP_DISABLE_USER_COMMAND) + #define XCP_DISABLE_USER_COMMAND +#endif + +/* Block transfer */ +#if !defined(XCP_ENABLE_BLOCK_UPLOAD) && !defined(XCP_DISABLE_BLOCK_UPLOAD) + #define XCP_DISABLE_BLOCK_UPLOAD +#endif +#if !defined(XCP_ENABLE_BLOCK_DOWNLOAD) && !defined(XCP_DISABLE_BLOCK_DOWNLOAD) + #define XCP_DISABLE_BLOCK_DOWNLOAD +#endif + +/* Enable transmission of event messages */ +#if !defined(XCP_ENABLE_SEND_EVENT) && !defined(XCP_DISABLE_SEND_EVENT) + #define XCP_DISABLE_SEND_EVENT +#endif + +/* Service request message */ +#if !defined(XCP_ENABLE_SERV_TEXT) && !defined(XCP_DISABLE_SERV_TEXT) + #define XCP_DISABLE_SERV_TEXT +#endif +#if !defined(XCP_ENABLE_SERV_TEXT_PUTCHAR) && !defined(XCP_DISABLE_SERV_TEXT_PUTCHAR) + #define XCP_DISABLE_SERV_TEXT_PUTCHAR +#endif +#if !defined(XCP_ENABLE_SERV_TEXT_PRINTF) && !defined(XCP_DISABLE_SERV_TEXT_PRINTF) + #define XCP_DISABLE_SERV_TEXT_PRINTF +#endif + +/* Disable/Enable Interrupts */ +/* Has to be defined only if xcpSendCallBack may interrupt xcpEvent */ +#if !defined(XcpInterruptDisable) + #define XcpInterruptDisable() +#endif +#if !defined(XcpInterruptEnable) + #define XcpInterruptEnable() +#endif + +/* Custom initialization not needed */ +#if !defined(ApplXcpInit) + #define ApplXcpInit() +#endif + +/* Custom background processing not needed */ +#if !defined(ApplXcpBackground) + #define ApplXcpBackground() +#endif + +/* Flush of transmit queue not needed */ +#if !defined(ApplXcpSendFlush) + #define ApplXcpSendFlush() +#endif + +/* XCP page switching */ +#if !defined ( XCP_ENABLE_CALIBRATION_PAGE ) && !defined ( XCP_DISABLE_CALIBRATION_PAGE ) + #define XCP_DISABLE_CALIBRATION_PAGE +#endif + +/* XCP protocol data acquisition parameters (DAQ) */ +#if defined(XCP_DISABLE_DAQ) + #define XCP_DISABLE_SEND_QUEUE + #define XCP_ENABLE_SEND_DIRECT +#else + #if !defined(XCP_ENABLE_DAQ) && !defined(XCP_DISABLE_DAQ) + #define XCP_ENABLE_DAQ + #endif + #if !defined(XCP_ENABLE_SEND_DIRECT) && !defined(XCP_ENABLE_SEND_QUEUE) + #define XCP_ENABLE_SEND_QUEUE + #define XCP_DISABLE_SEND_DIRECT + #endif + #if defined(XCP_ENABLE_SEND_QUEUE) + #define XCP_DISABLE_SEND_DIRECT + #endif + #if !defined(XCP_ENABLE_DAQ_HDR_ODT_DAQ) && !defined(XCP_DISABLE_DAQ_HDR_ODT_DAQ) + #define XCP_DISABLE_DAQ_HDR_ODT_DAQ + #endif + #if !defined(kXcpDaqMemSize) + #define kXcpDaqMemSize 256 + #endif + #if !defined(kXcpStiOdtCount) + #define kXcpStiOdtCount 1 + #endif + #if !defined(XCP_ENABLE_DAQ_PROCESSOR_INFO) && !defined(XCP_DISABLE_DAQ_PROCESSOR_INFO) + #define XCP_ENABLE_DAQ_PROCESSOR_INFO + #endif + #if !defined(XCP_ENABLE_DAQ_RESOLUTION_INFO) && !defined(XCP_DISABLE_DAQ_RESOLUTION_INFO) + #define XCP_ENABLE_DAQ_RESOLUTION_INFO + #endif + #if !defined(XCP_ENABLE_DAQ_PRESCALER) && !defined(XCP_DISABLE_DAQ_PRESCALER) + #define XCP_DISABLE_DAQ_PRESCALER + #endif + #if !defined(XCP_ENABLE_DAQ_OVERRUN_INDICATION) && !defined(XCP_DISABLE_DAQ_OVERRUN_INDICATION) + #define XCP_ENABLE_DAQ_OVERRUN_INDICATION + #endif + #if !defined(XCP_ENABLE_DAQ_RESUME) && !defined(XCP_DISABLE_DAQ_RESUME) + #define XCP_DISABLE_DAQ_RESUME + #endif + #if !defined(XCP_ENABLE_DAQ_TIMESTAMP) && !defined(XCP_DISABLE_DAQ_TIMESTAMP) + #define XCP_DISABLE_DAQ_TIMESTAMP + #endif + #if !defined(XCP_ENABLE_DAQ_EVENT_INFO) && !defined(XCP_DISABLE_DAQ_EVENT_INFO) + #define XCP_DISABLE_DAQ_EVENT_INFO + #endif +#endif +#if !defined(XCP_ENABLE_STIM) && !defined(XCP_DISABLE_STIM) + #define XCP_DISABLE_STIM +#endif + + + +#endif diff --git a/src/xcp/xcp_par.c b/src/xcp/xcp_par.c new file mode 100644 index 0000000..24ea66d --- /dev/null +++ b/src/xcp/xcp_par.c @@ -0,0 +1,37 @@ +/***************************************************************************** +| Project Name: XCP Protocol Layer +| File Name: xcp_par.c +| +| Description: Implementation of the XCP Protocol Layer +| XCP V1.0 slave device driver +| Basic Version (see feature list below) +| +| +| +|----------------------------------------------------------------------------- +| C O P Y R I G H T +|----------------------------------------------------------------------------- +| Copyright (c) 2008 by Vector Informatik GmbH. All rights reserved. +| +| This software is copyright protected and +| proporietary to Vector Informatik GmbH. +| Vector Informatik GmbH grants to you only +| those rights as set out in the license conditions. +| All other rights remain with Vector Informatik GmbH. +| +| Diese Software ist urheberrechtlich geschuetzt. +| Vector Informatik GmbH raeumt Ihnen an dieser Software nur +| die in den Lizenzbedingungen ausdruecklich genannten Rechte ein. +| Alle anderen Rechte verbleiben bei Vector Informatik GmbH. +| +|***************************************************************************/ + +#include "XcpBasic.h" + + +// Slave device id +#if defined ( kXcpStationIdLength ) + V_MEMROM0 MEMORY_ROM vuint8 kXcpStationId[kXcpStationIdLength] = kXcpStationIdString; +#endif + + diff --git a/src/xcp/xcp_par.h b/src/xcp/xcp_par.h new file mode 100644 index 0000000..e000259 --- /dev/null +++ b/src/xcp/xcp_par.h @@ -0,0 +1,41 @@ +/***************************************************************************** +| Project Name: XCP Protocol Layer +| File Name: xcp_par.h +| +| Description: Header of XCP Protocol Layer +| XCP V1.0 slave device driver +| Basic Version +| +|| +|----------------------------------------------------------------------------- +| C O P Y R I G H T +|----------------------------------------------------------------------------- +| Copyright (c) 2008 by Vector Informatik GmbH. All rights reserved. +| +| This software is copyright protected and +| proporietary to Vector Informatik GmbH. +| Vector Informatik GmbH grants to you only +| those rights as set out in the license conditions. +| All other rights remain with Vector Informatik GmbH. +| +| Diese Software ist urheberrechtlich geschuetzt. +| Vector Informatik GmbH raeumt Ihnen an dieser Software nur +| die in den Lizenzbedingungen ausdruecklich genannten Rechte ein. +| Alle anderen Rechte verbleiben bei Vector Informatik GmbH. +| +| +|***************************************************************************/ +#if defined ( __XCP_PAR_H__ ) +#else +#define __XCP_PAR_H__ + +/* XCP default settings */ +#include "xcp_def.h" + +V_MEMROM0 extern vuint8 MEMORY_ROM kXcpStationId[]; + + + + + +#endif diff --git a/src/xcp/xcp_typedefs.h b/src/xcp/xcp_typedefs.h new file mode 100644 index 0000000..9d5ad7c --- /dev/null +++ b/src/xcp/xcp_typedefs.h @@ -0,0 +1,10 @@ +#ifndef XCP_TYPEDEFS_H +#define XCP_TYPEDEFS_H + +#include "Arduino.h" + +typedef uint32_t vuint32; +typedef uint16_t vuint16; +typedef uint8_t vuint8; + +#endif diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html