®

User Guide OpenECU Developer Platform C-API Release 3.0.3-FS (r2019-3)

Copyright © 2019 Pi Innovo Table of Contents

Foreword ...... xi 1. Disclaimer ...... xi 2. Health and Safety information ...... xi 1. Introduction ...... 1 1.1. Included in your OpenECU kit ...... 1 1.1.1. Hardware ...... 2 1.1.2. ...... 2 1.2. Licensed Features ...... 2 1.3. OpenECU requirements ...... 3 1.3.1. Hardware requirements ...... 3 1.3.2. Software requirements ...... 3 1.3.3. Assumed knowledge ...... 3 1.4. Co-operational development with Pi ...... 4 1.5. Warnings and safety guidelines ...... 4 1.5.1. Verification of OpenECU by Pi Innovo ...... 5 1.6. Warning ...... 6 1.6.1. Personal safety ...... 6 1.6.2. Disclaimer ...... 6 2. Installation ...... 7 2.1. Introduction ...... 7 2.1.1. Third party tool requirements ...... 7 2.1.2. Third party tool requirements — C-API ...... 7 2.1.3. Third party tool requirements — Simulink-API ...... 8 2.1.4. Third party tool requirements — installation ...... 9 2.1.5. Third party tool requirements — compatibility ...... 10 2.2. Installing OpenECU ...... 11 2.3. License setup ...... 17 2.3.1. Floating license ...... 17 2.3.2. Node-locked license ...... 19 2.4. Removing OpenECU ...... 19 2.5. Integration notes for third party tools ...... 20 2.5.1. ...... 20 2.5.2. Microsoft ...... 20 2.5.3. XP ...... 21 2.5.4. PiSnoop ...... 21 2.5.5. ATI Vision ...... 21 2.5.6. ETAS INCA calibration tool ...... 22 2.5.7. Vector CANape ...... 22 2.5.8. Wind River (Diab) C Compiler v5.5.1.0 ...... 22 2.5.9. Wind River (Diab) C Compiler v5.8.0.0 ...... 24 2.5.10. Wind River (Diab) C Compiler v5.9.0.0 ...... 25 2.5.11. Wind River (Diab) C Compiler v5.9.4.8 ...... 25 2.5.12. GCC Compiler v4.7.3 ...... 26 2.5.13. Python ...... 27 3. Quick start ...... 28 3.1. Introduction ...... 28 3.2. Installed examples ...... 28 3.3. Exercise — Step 1 ...... 28 3.3.1. Designing the application ...... 30 3.3.2. Create the application ...... 30 3.3.3. Review the application ...... 30 3.3.4. Implement the sensor reading ...... 32 3.3.5. Implement the sensor conversion to temperature ...... 33 3.3.6. Implement the threshold comparison ...... 36 3.3.7. Implement the lamp driver ...... 36

Copyright 2019, Pi Innovo ii User Guide OpenECU Developer Platform C-API

3.3.8. Summary so far ...... 37 3.3.9. Create data dictionary and interface specification files ...... 39 3.3.10. Building the application ...... 41 3.3.11. Program the ECU ...... 42 3.3.12. Play with the application ...... 44 4. Software overview ...... 46 4.1. Introduction ...... 46 4.2. System components ...... 46 4.3. System modes ...... 48 4.4. Boot mode ...... 48 4.5. Reprogramming mode ...... 49 4.6. Application mode ...... 54 4.6.1. Building an application ...... 55 4.6.2. Interface specification ...... 58 4.6.3. Data dictionary and engineering unit files ...... 58 4.6.4. Application and library tasks ...... 58 4.6.5. Library status and error handling ...... 61 4.6.6. Compiler library support ...... 61 4.6.7. Deprecated library features ...... 62 4.6.8. Examples ...... 62 5. Library interface ...... 65 5.1. Introduction ...... 67 5.1.1. Name-spaces, naming conventions and library composition ...... 67 5.1.2. File locations ...... 68 5.1.3. Layout of each feature section ...... 69 5.1.4. Notations ...... 69 5.2. System feature (PSY) ...... 70 5.2.1. Overview ...... 70 5.2.2. System types ...... 70 5.2.3. Error log ...... 70 5.2.4. Interface index ...... 71 5.2.5. Interface detail ...... 75 5.3. System start-up and background processing (PSC) ...... 84 5.3.1. Overview ...... 84 5.3.2. Interface index ...... 87 5.3.3. Interface detail ...... 90 5.4. ECU registry information (PREG) ...... 109 5.4.1. Overview ...... 109 5.4.2. Interface index ...... 110 5.4.3. Interface detail ...... 111 5.5. System timing feature (PTM) ...... 118 5.5.1. Overview ...... 118 5.5.2. Interface index ...... 118 5.5.3. Interface detail ...... 119 5.6. Task scheduling (PKN) ...... 124 5.6.1. Tasking model ...... 125 5.6.2. Interface index ...... 129 5.6.3. Interface detail ...... 130 5.7. Library input and output configuration (PIO) ...... 137 5.7.1. Overview ...... 137 5.8. Feature for specific target configuration (PCFG) ...... 138 5.8.1. Overview ...... 138 5.8.2. M110, M220 and M461 targets ...... 139 5.8.3. M250 target ...... 139 5.8.4. M460 target ...... 139 5.8.5. M670 target ...... 139 5.8.6. Interface index ...... 139 5.8.7. Interface detail ...... 140

Copyright 2019, Pi Innovo iii User Guide OpenECU Developer Platform C-API

5.9. Analogue input/output feature (PAX) ...... 147 5.9.1. Overview ...... 147 5.9.2. Interface index ...... 151 5.9.3. Interface detail ...... 152 5.10. Digital input/output feature (PDX) ...... 160 5.10.1. Overview ...... 160 5.10.2. Interface index ...... 169 5.10.3. Interface detail ...... 171 5.11. Digital data feature (PDD) ...... 197 5.11.1. Overview ...... 197 5.11.2. Interface index ...... 197 5.11.3. Interface detail ...... 198 5.12. Output driver control feature (PSS) ...... 200 5.12.1. Overview ...... 200 5.12.2. M220 target ...... 201 5.12.3. M250 target ...... 201 5.12.4. M460 target ...... 202 5.12.5. M461 target ...... 203 5.12.6. M670 target ...... 203 5.12.7. Interface index ...... 203 5.12.8. Interface detail ...... 204 5.13. Serial peripheral feature (PSP) ...... 205 5.13.1. Overview ...... 205 5.13.2. Input and output processing ...... 205 5.13.3. Interface index ...... 206 5.13.4. Interface detail ...... 206 5.14. CJ125 device driver for UEGO measurement feature (PCJ125) ...... 207 5.14.1. Overview ...... 207 5.14.2. Initialisation ...... 207 5.14.3. Diagnostics ...... 207 5.14.4. Interface index ...... 207 5.14.5. Interface detail ...... 208 5.15. CAN messaging feature (PCX) ...... 210 5.15.1. Overview ...... 210 5.15.2. Initialisation ...... 210 5.15.3. Receiving messages ...... 210 5.15.4. Transmitting messages ...... 211 5.15.5. CAN status ...... 212 5.15.6. CAN buses ...... 212 5.15.7. Build time buffer sizing ...... 212 5.15.8. Library tasks ...... 212 5.15.9. Interface index ...... 212 5.15.10. Interface detail ...... 213 5.16. CAN Calibration Protocol (CCP) messaging feature (PCP) ...... 224 5.16.1. Overview ...... 224 5.16.2. Interface index ...... 229 5.16.3. Interface detail ...... 230 5.17. J1939 (SAE) messaging feature (PJ1939) ...... 235 5.17.1. Overview ...... 235 5.17.2. Node addressing ...... 235 5.17.3. Messaging ...... 236 5.17.4. Message bit and byte numbering ...... 237 5.17.5. PGNs ...... 238 5.17.6. Receive messages ...... 238 5.17.7. Transmit messages ...... 239 5.17.8. Core Diagnostic messages ...... 239 5.17.9. Build time buffer sizing ...... 239 5.17.10. Library tasks ...... 240

Copyright 2019, Pi Innovo iv User Guide OpenECU Developer Platform C-API

5.17.11. Interface index ...... 240 5.17.12. Interface detail ...... 245 5.18. Diagnostic Trouble Code (DTC) feature (PDTC) ...... 280 5.18.1. Overview ...... 280 5.18.2. Diagnostic trouble codes — generic ...... 281 5.18.3. Diagnostic trouble codes — J1939 ...... 281 5.18.4. Storage of data across power cycles ...... 282 5.18.5. Build time buffer sizing ...... 282 5.18.6. Interface index ...... 283 5.18.7. Interface detail ...... 284 5.19. Adaptive non-volatile memory feature (PNV) ...... 293 5.19.1. Overview ...... 293 5.19.2. Storage of data across power cycles ...... 295 5.19.3. Interface index ...... 296 5.19.4. Interface detail ...... 298 5.20. Non-volatile Filesystem feature (PFS) ...... 307 5.20.1. Overview ...... 307 5.20.2. Interface index ...... 308 5.20.3. Interface detail ...... 310 5.21. On-board external flash (PEF) ...... 320 5.21.1. Overview ...... 320 5.21.2. Interface index ...... 321 5.21.3. Interface detail ...... 321 5.22. General utilities feature (PUT) ...... 326 5.22.1. Overview ...... 326 5.22.2. Interface index ...... 328 5.22.3. Interface detail ...... 331 5.23. Angular function feature (PAN) ...... 366 5.23.1. Overview ...... 366 5.23.2. Interface index ...... 379 5.23.3. Interface detail ...... 384 5.24. Waveform properties (PROP) ...... 438 5.24.1. Overview ...... 438 5.24.2. Interface index ...... 438 5.24.3. Interface detail ...... 439 6. Extended Diagnostics Functions ...... 444 6.1. Introduction to Diagnostics ...... 444 6.2. Diagnostic Legislation ...... 445 6.3. Approach ...... 447 6.4. Diagnostic Trouble Codes and Freeze-Frames ...... 448 6.5. Diagnostic Monitors, Tests and Performance Ratios ...... 449 6.6. Worked Example - building a diagnostic system ...... 450 6.6.1. Step 1 — Test Conditions at the Monitor level ...... 450 6.6.2. Step 2 — Individual Flow Tests ...... 451 6.6.3. J1979/ISO 15031 Scan tool request/response ...... 452 6.7. Extended Diagnostic Functions ...... 454 6.7.1. J1939 Extended Diagnostics feature (PJ1939) ...... 454 6.7.2. Diagnostics (ISO-15765 and KWP2000) feature (PDG) ...... 511 6.7.3. Diagnostic Trouble Code Extended (DTC) feature (PDTC) ...... 532 6.7.4. Freeze Frame feature (PFF) ...... 564 6.7.5. Parameter Identifier feature (PPID) ...... 567 6.7.6. In-Use Performance Ratio feature (PPR) ...... 580 7. Support tools ...... 599 7.1. Interface and DDE tool ...... 599 7.1.1. Simple interface file example ...... 599 7.1.2. Running the interface tool ...... 601 7.1.3. Warning and error messages ...... 609 7.1.4. Interface file contents ...... 610

Copyright 2019, Pi Innovo v User Guide OpenECU Developer Platform C-API

7.1.5. DDE specification ...... 647 7.1.6. Units file ...... 653 7.1.7. Automatic ASAP2 entries ...... 653 7.1.8. OpenECU ...... 661 7.2. Supporting build scripts ...... 662 7.2.1. Creating a binary image with a supported compiler ...... 663 A. Reference documentation ...... 665 A.1. ECU hardware reference documentation ...... 665 B. OpenECU error and warning codes ...... 666 B.1. Interface tool messages ...... 666 B.1.1. Command line option messages ...... 666 B.1.2. File handling messages ...... 669 B.1.3. Interface file messages ...... 670 B.1.4. DDE processing messages ...... 671 B.1.5. Automatic DDE generation messages ...... 687 B.1.6. Code generation messages ...... 688 B.1.7. ASAP2 generation messages ...... 702 B.1.8. ELF to DDE generation messages ...... 706 B.1.9. Data type checks between ELF and DDE messages ...... 706 C. Supporting tools ...... 707 C.1. Introduction ...... 707 C.2. PiSnoop ...... 707 C.2.1. Example Screenshots ...... 708 C.3. ATI Vision ...... 709 C.3.1. Creating a new project and strategy in ATI Vision ...... 709 C.3.2. Downloading an application with an ATI Vision strategy ...... 716 C.3.3. Configuring two OpenECUs on the same CAN bus with ATI Vision ... 721 C.3.4. Configuring CCP seed/key security with ATI Vision ...... 724 C.4. ETAS INCA ...... 724 C.5. Vector CANape ...... 734 C.5.1. Configuring CCP seed/key security with Vector CANape ...... 741 C.6. FreeCCP ...... 742 C.6.1. Programming an OpenECU ...... 742 C.6.2. Choosing the CAN card device (Kvaser) ...... 742 C.6.3. Choosing the CAN card device (Vector) ...... 742 C.6.4. Choosing the CCP settings ...... 743 C.6.5. Checking that the OpenECU device is active ...... 743 D. Memory configurations ...... 744 E. ASAP2 compliance ...... 746 F. CCP compliance ...... 747 F.1. EXCHANGE_ID message handling ...... 748 G. CCP troubleshooting guide ...... 751 G.1. Anatomy of an ATI Hub ...... 751 G.2. No communication between PC and ATI Hub ...... 752 G.2.1. Symptoms ...... 752 G.2.2. Possible causes ...... 752 G.3. No communication between PC and OpenECU ...... 753 G.3.1. Symptoms ...... 753 G.3.2. Possible causes ...... 753 H. Crank wheel signal decoding ...... 758 H.1. Variable reluctance signal ...... 758 H.2. Hall-effect signal ...... 759 H.3. Tooth edge processing ...... 759 H.4. Crank decoding states ...... 762 I. Change log ...... 769 I.1...... 769 J. Glossary of terms ...... 773 K. Contact information ...... 775

Copyright 2019, Pi Innovo vi List of Figures

3.1. Quick start loom ...... 29 3.2. Transfer function for temperature sensor ...... 33 4.1. System components ...... 46 4.2. System modes ...... 48 4.3. System modes for M220, M250, M460 and M461 ...... 51 4.4. System modes for M110, M221, M560, M680 and M670 ...... 52 4.5. System initialisation ...... 54 4.6. Building an application (in outline) ...... 56 5.1. Tasking model states ...... 125 5.2. Task pre-emption ...... 126 5.3. Task pre-emption with resource locking ...... 128 5.4. TLE8242-2 Dither ...... 148 5.5. TLE8242-2 constant current control diagram ...... 149 5.6. TLE8242-2 KP and KI equations ...... 150 5.7. Direct and indirect analogue outputs ...... 150 5.8. Quadrature encoder and generated signals ...... 162 5.9. Direction of encoder and generated signals ...... 162 5.10. Pulse count example ...... 163 5.11. SENT frame ...... 163 5.12. Peak-hold injector output ...... 166 5.13. Output of H-Bridge during mode transition ...... 168 5.14. Signal update rates ...... 168 5.15. CAN bit sample point ...... 210 5.16. ASAM MCD-MC1 interaction ...... 225 5.17. CCP messaging ...... 225 5.18. J1939 activation state machine ...... 281 5.19. Map look-up ...... 326 5.20. Map look-up with interpolation ...... 327 5.21. Definition of 0° crank (VR sensor input) ...... 367 5.22. Definition of 0° crank (Hall-effect sensor input) ...... 367 5.23. TDC-firing events relative to 0° crank ...... 368 5.24. Task execution relative to cylinder's TDC-firing event ...... 368 5.25. Analogue inputs sampled relative to angular model iteration ...... 368 5.26. Multiple injection pulses ...... 371 5.27. Injection constraints ...... 372 5.28. Main injection event ...... 373 5.29. Injector pulse duration is composed of dead time and flow time ...... 373 5.30. Clipped injection event ...... 373 5.31. Injection events in 360° mode ...... 374 5.32. Post injection events ...... 374 5.33. Spark event relative to cylinder's TDC-firing angle ...... 375 5.34. Output pulse - Angle-Time Duration (turn-on/turn-off) ...... 376 5.35. Output pulse - Angle-Time Duration (turn-on/no-action) ...... 376 5.36. Output pulse - Angle-Angle Duration (turn-off/toggle) ...... 376 5.37. Output pulse - Angle-Angle Duration (turn-on/turn-off) ...... 376 5.38. Output data updated during an event, end modification allowed ...... 377 5.39. Output data updated during an event, end modification not allowed ...... 378 5.40. Output event with overlap between two events ...... 378 5.41. Output event starting within minimum off time ...... 379 6.1. Functional Levels within a Diagnostics System ...... 445 6.2. Scan tool link via Platform ...... 448 6.3. Routine control usage flowchart ...... 515 6.4. Platform OBD state machine — no transitions between Previously Active and Pending ...... 533

Copyright 2019, Pi Innovo vii User Guide OpenECU Developer Platform C-API

6.5. Platform OBD state machine — transitions between Previously Active and Pending ...... 534 6.6. ISO DTC state machine — no transitions from Inactive to Pending ...... 536 6.7. ISO DTC state machine — transitions from Inactive to Pending ...... 536 7.1. Building the interface code ...... 601 7.2. Finishing a build ...... 662 7.3. Building the binary images ...... 663

Copyright 2019, Pi Innovo viii List of Tables

2.1. Third party tool compatibility ...... 10 2.2. Install components ...... 13 3.1. FEPS voltages ...... 44 4.1. FEPS voltages ...... 53 4.2. CCP defaults ...... 54 4.3. Library and application tasks ...... 58 5.1. Library composition ...... 67 5.2. Interval notation ...... 70 5.3. Registry entries ...... 110 5.4. DTC initialisation values ...... 282 5.5. Pin actions...... 379 6.1. Diagnostic Service Comparisons ...... 446 6.2. PDG supported services ...... 452 6.3. PDG supported services ...... 512 6.4. DTC initialisation values ...... 537 7.1. CCP privilege levels ...... 620 7.2. UDS DTCFormatIdentifier options ...... 625 7.3. Value ranges for J1939 name statements ...... 630 7.4. Value ranges for J1939 PDUs ...... 630 7.5. Value ranges for J1939 PDUs ...... 636 7.6. Bit information for the lamps to be set per DTC ...... 637 7.7. Bit information per lamp type ...... 638 7.8. Data dictionary columns (prefix-style) ...... 648 7.9. Variable naming convention (prefix-style) ...... 649 7.10. 1-d map lookup naming convention (prefix-style) ...... 650 7.11. 2-d map lookup naming convention (prefix-style) ...... 650 7.12. Data dictionary columns (C-style) ...... 650 7.13. Classes of DDE ...... 652 7.14. Examples of C-style DDE names ...... 652 7.15. Automatic ASAP2 entries for boot build information ...... 654 7.16. Automatic ASAP2 entries for reprogramming build information (M220, M221, M250, M460, M461, M550, M670) ...... 654 7.17. Automatic ASAP2 entries for platform build information ...... 655 7.18. Automatic ASAP2 entries for application build information ...... 656 7.19. Automatic ASAP2 entries for application rate task timing information ...... 656 7.20. Automatic ASAP2 entries for auxiliary task timing information ...... 657 7.21. Automatic ASAP2 entries for CPU loading information ...... 657 7.22. Automatic ASAP2 entries for eTPU loading information ...... 658 7.23. Automatic ASAP2 entries for maximum application rate task timing information ... 658 7.24. Automatic ASAP2 entries for run-time information ...... 658 7.25. Automatic ASAP2 entries for reset information (M110, M220, M250, M460, M461) ...... 659 7.26. Automatic ASAP2 entries for number of instances of period overruns or skips of periodic tasks ...... 659 7.27. Automatic ASAP2 entries for memory use information ...... 659 7.28. Automatic ASAP2 entries for memory error correction events ...... 659 7.29. Automatic ASAP2 entries for floating point conditions ...... 660 7.30. Automatic ASAP2 entries for J1939 related information ...... 661 7.31. Software component versions (for M560-000) ...... 661 D.1. Memory configurations supported ...... 744 D.2. Memory configurations supported ...... 744 D.3. Memory configurations supported ...... 745 F.1. Supported CCP commands ...... 747 F.2. Supported CCP commands (in older versions of ECUs) ...... 748 F.3. Original EXCHANGE_ID message ...... 748

Copyright 2019, Pi Innovo ix User Guide OpenECU Developer Platform C-API

F.4. Modified EXCHANGE_ID message ...... 748 F.5. EXCHANGE_ID selection values ...... 749 F.6. EXCHANGE_ID manufacturing data key values and binary format ...... 749 I.1. Release summary for v3.0.3-r2019-3 ...... 769

Copyright 2019, Pi Innovo x Foreword

Before using OpenECU, it is very important to read and understand the warning and safety information given in Section 1.5, “Warnings and safety guidelines” and in Section 1.6, “Warning”.

Pi, the Pi logo and OpenECU are trademarks of Pi Innovo Ltd. Microsoft, Windows, Excel, Word, Vision, CANape and INCA are all registered trademarks of their respective owners. 1. Disclaimer

Pi Innovo makes no representation or warranties of any kind whatsoever with respect to the contents hereof, and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Pi Innovo shall not be liable for any errors contained herein, or for incidental or consequential damages in connection with the furnishing, performance or use of the software, associated hardware, or this written material.

Pi Innovo reserves the right to revise this publication from time to time, and to make changes in the content hereof without obligation to notify any person of such revision or changes.

A copy of the Pi Innovo Terms and Conditions of Sale is available on request, and includes a declaration of the warranty and limitation of liability which apply to all Pi Innovo products and services. 2. Health and Safety information

Under the terms of European and UK Health and Safety Legislation, Pi Innovo is required to classify any hazardous materials in the products it supplies and to provide relevant safety information to users.

Any hazardous materials in Pi products are clearly marked with appropriate symbols. Product Safety Data Sheets relating to these materials are available on request.

Copyright 2019, Pi Innovo xi Chapter 1. Introduction

1.1. Included in your OpenECU kit ...... 1 1.1.1. Hardware ...... 2 1.1.2. Software ...... 2 1.2. Licensed Features ...... 2 1.3. OpenECU requirements ...... 3 1.3.1. Hardware requirements ...... 3 1.3.2. Software requirements ...... 3 1.3.3. Assumed knowledge ...... 3 1.4. Co-operational development with Pi ...... 4 1.5. Warnings and safety guidelines ...... 4 1.5.1. Verification of OpenECU by Pi Innovo ...... 5 1.6. Warning ...... 6 1.6.1. Personal safety ...... 6 1.6.2. Disclaimer ...... 6

Thank you for choosing Pi Innovo's OpenECU platform.

Pi Innovo's OpenECU platform offers a new solution to engine and vehicle control system development. Based on Pi's extensive experience of ECU development, and backed by Pi's unrivalled capabilities in project and customer support, OpenECU helps you get quickly to what you need: working, robust control systems.

By using production ECU hardware as an auto-code platform, you gain all the advantages of auto-coding and rapid prototyping, but with hardware that meets full production environmental and packaging requirements (see Section A.1, “ECU hardware reference documentation” for environmental and packaging details).

The OpenECU system consists of:

• a range of production ECU hardware modules for engines with up to 8 cylinders (or more with multiple modules);

• an optional range of tested engine and vehicle control strategies, from individual functional blocks to complete strategy suites;

• a comprehensive range of support and consultancy services, ranging from sensor selection and system design advice through to complete bespoke system development.

Applications of the OpenECU platform include:

• engine control system development;

• chassis control system development;

• after treatment control system development;

• transmission control system development;

• hybrid powertrain control system development;

• vehicle fleet trials.

For support contact information, please see the last page of this manual. 1.1. Included in your OpenECU kit

There are several OpenECU packages available from Pi, which can include the following items.

Copyright 2019, Pi Innovo 1 Introduction

1.1.1. Hardware

The following items of hardware are available as part of OpenECU:

Electronic Control Unit (ECU) This is the computer that monitors and controls all aspects of the electronic system's behaviour. The built file from your application is programmed into the ECU. There are four different models of ECU currently available — 4 in-line cylinder and V8 cylinder, in both development and fleet models (see Section A.1, “ECU hardware reference documentation” for further details).

Connectors All the connectors and terminals required to connect the ECU, the calibration tool and your PC together.

Tools You will require an appropriate crimping tool for the ECU connectors. Pi Innovo will give you details on request. 1.1.2. Software

The following items of software are available as part of OpenECU:

OpenECU C Application Programming Interface (API) A documented C-API to the OpenECU library which allows control of the ECU from an application. The C-API broadly provides the same functionality as the OpenECU Simulink blockset.

And the following items of software are required but not provided as part of OpenECU.

Calibration Tool This electronic tool is used to program the auto-generated code into the ECU, and to monitor (and, in some cases, alter) the values of certain parameters while the ECU is running. Pi's own PiSnoop product is one option, along with several industry-standard alternatives, and we will be able to recommend a suitable product on request.

Compiler A tool which takes application code and turns it into an executable image that can be run on OpenECU hardware. 1.2. Licensed Features

OpenECU allows for several different options enabling different features. The licensing system retains control of the ability to use these features depending on what the customer has purchased.

The current set of available features is:

• OPENECU

The main feature. Enabled when you purchase any version of OpenECU

• CAPI_BUILD

Allows for building OpenECU applications with the C-API.

• EXT_DIAG

Extended diagnostics features.

Copyright 2019, Pi Innovo 2 Introduction

• Allows use of the Extended diagnostics blockset in Simulink models.

• Allows use of the Extended diagnostics library functions at run time in OpenECU applications

See Chapter 6, Extended Diagnostics Functions. 1.3. OpenECU requirements

To make the best use of OpenECU, certain hardware, software and knowledge requirements need to be fulfilled, as described below. 1.3.1. Hardware requirements

To run the Pi OpenECU software, you will need an IBM-compatible PC with the specifications listed below.

• CPU: a modern Intel or AMD x86 32-bit or 64-bit processor. • RAM: 2 GiB minimum, but more recommended (larger applications will require more RAM). • Free hard disk space: 2 GiB. • Peripheral hardware: keyboard, mouse, DVD/CD-ROM drive (for installation from CD media), at least 8-bit graphics adapter and display (for at least 256 colours).

Either the physical system or a system simulator, is ultimately required to test and calibrate your ECU and the system model you have created to run on it. A suitable Calibration/ reprogramming communications tool is also required conforming to the ASAP2 standard. 1.3.2. Software requirements

You will need the following software pre-installed on your PC:

• Operating system: Microsoft Windows 10 or Microsoft Windows7 SP1 32-bit or 64-bit.

• Wind River Diab compiler; version 5.5.1.0 (M220, M221, M250, M460 and M461); or version 5.8.0.0 (M220, M221, M250, M460 and M461); or version 5.9.0.0 (M220, M221, M250, M460, M461, and M670); or version 5.9.4.8 (M560 and M580). Only the C language version is required (note, C++ is not yet supported).

• Calibration tool: PiSnoop, ATI Vision™ (version 2.5 through 5.1.2), ETAS INCA (version 5.1.2 through 7.2.7) or Vector CANape (version 8.0 through 16.0).

Note

OpenECU developer software does not support earlier versions of Windows than XP (SP3), , or .

See the Chapter 2, Installation for full details of the software required. 1.3.3. Assumed knowledge

This manual describes how to use the C-API to create your own designs, but does not include a tutorial about C or embedded systems.

A working knowledge of design modelling and system dynamics principles in an engineering environment is required to make the best use of OpenECU. Ultimately, it is the quality of your own system designs that will be reflected in the quality of your system control strategy.

Copyright 2019, Pi Innovo 3 Introduction

Note also that there are serious hardware and personal safety considerations involved in developing automotive control systems. Please make sure that you read and understand the notes given in Section 1.5, “Warnings and safety guidelines” to reduce the chance of any such hazards. 1.4. Co-operational development with Pi

Pi Innovo has over 14 years of experience designing powertrain controllers, working closely with customers to get to the best possible control system solution. Millions of cars and trucks on the road use Pi-designed engine control.

OpenECU comes with a wide range of options for customer and project support, allowing you to draw on over 500 man-years of control system design experience. Whichever option you choose, you can count on real commitment from Pi to provide what you need, and to go the extra mile.

For contact information, refer to Appendix K, Contact information. 1.5. Warnings and safety guidelines

It is very important to read and understand the following warnings and safety guidelines. Inappropriate use of the OpenECU system can lead to loss of data, damage to software and hardware, and possible personal injury if safe vehicle operation is compromised.

The safe operation of OpenECU is the responsibility of the those using it. The level of risk associated with the user's application must be ascertained and appropriate mitigation devices used to reduce the potential risks to an acceptable level. These mitigation devices may include a system 'kill switch', driver training, backup systems and use of the vehicle in safe environments.

A structured approach to testing is recommended, particularly before the product is used in environments where it may be in contact with members of the public (e.g. the public highway). This testing may include HIL, static vehicle system test and/or vehicle test in a test track environment.

Pi Innovo supplies OpenECU on the basis that:

• The responsibility for ensuring that the use of OpenECU is safe lies with the customer.

• The customer will include appropriate mitigation devices as identified by the hazard analysis they perform (such as engine kill switch, back up devices).

• All users must be competent to make appropriate safety judgements.

• The user will read all OpenECU documentation (including this document) to ensure its safe use.

• Use of OpenECU in a safety-related system must conform to the Safety Manual for the specific controller hardware.

• OpenECU software has been developed according to ISO 26262 to support functional safety and can provide a basis for achieving compliance according to ISO 26262 for selected Hardware and Software versions. Talk to us about how this can fit into your functional safety system.

Pi Innovo also strongly recommends that:

Copyright 2019, Pi Innovo 4 Introduction

• Applications be developed using a process suitable for the application.

• HIL testing be used prior vehicle testing.

• "Off public highway" vehicle testing be performed prior to road testing. 1.5.1. Verification of OpenECU by Pi Innovo

Pi Innovo considers the safety and quality of its products to be of paramount importance. The integrity of the product can be considered by assessing the three 'components' which comprise the system.

Systems, rather than software, have a Safety Integrity Level (SIL). The SIL of the customer's resultant system will have to be assessed and defined by their knowledge of the processes used to develop all the components (including those supplied by Pi) comprising the complete system. 1.5.1.1. Hardware

The hardware is a production unit (see Section A.1, “ECU hardware reference documentation” for module environmental specifications). However different applications will have different requirements for output monitoring. Those outputs that are selected (by the customer) to drive safety related outputs should include output monitor circuits. The use of outputs for critical devices which do not contain a monitor feedback is strongly discouraged. 1.5.1.2. Platform

The platform comprises functionality which allows the high level strategy to operate in the specific hardware target (electronic box). It includes:

• The operating system (RTOS) to schedule tasks, process interrupts and manage the internal stack etc..

• The hardware drivers enabling the inputs to be read, and the outputs driven.

• The calibration tool support, CAN support and module reprogramming.

OpenECU has been developed using a lean SIL0 process enabling its rapid introduction to the market place. This process included internal review, module testing and considerable vehicle testing. It is considered to be a reliable and robust platform on which to build vehicle control applications.

The configuration of the platform is the customer's responsibility. It is entirely possible, through careless configuration, to 'cross wire' inputs or outputs for example. This could, for example, lead to injector 1 firing when you intended injector 2 to fire. The mis-calibration of analogue inputs could lead to undesired behaviour such as steering angle or accelerator pedal position to be mis-calculated.

Documented vehicle prove out tests should mitigate against this leading to severe outcomes. 1.5.1.3. Strategy

The strategy may be developed entirely by the customer, or be a development by the customer of generic libraries supplied by Pi Innovo. In either case the integrity of the resultant strategy model must be the responsibility of the customer.

Pi's generic libraries have been extensively validated via module testing, HIL system testing and vehicle testing but have not undergone unit testing.

Copyright 2019, Pi Innovo 5 Introduction

1.6. Warning

The supplied libraries have been validated for a specific application and a specific hardware set. The user MUST validate the correct function of the strategies in their application. 1.6.1. Personal safety

The process of testing automotive systems can involve many personal safety hazards — high-speed machinery, extremely flammable and potentially explosive fuels, and the possibility of loss of vehicle control is a combination that can be fatal if sensible precautions are not followed.

As the system designer and tester, it is your responsibility to ensure that your working practices are specifically designed to minimise or eliminate the possibility of personal injury, and to incorporate into your designs such fail-safe functionality as is necessary. This includes the avoidance of certain dynamical situations such as open throttles and other 'positive feedback' scenarios where control of the system may be lost. 1.6.2. Disclaimer

Pi Innovo makes no representation or warranties of any kind whatsoever with respect to the contents hereof, and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Pi Innovo shall not be liable for any errors contained herein, or for incidental or consequential damages in connection with the furnishing, performance or use of the software, associated hardware, or this written material.

Pi Innovo reserves the right to revise this publication from time to time, and to make changes in the content hereof without obligation to notify any person of such revision or changes.

A copy of the Pi Innovo Terms and Conditions of Sale is available on request, and includes a declaration of the warranty and limitation of liability which apply to all Pi Innovo products and services.

Copyright 2019, Pi Innovo 6 Chapter 2. Installation

2.1. Introduction ...... 7 2.1.1. Third party tool requirements ...... 7 2.1.2. Third party tool requirements — C-API ...... 7 2.1.3. Third party tool requirements — Simulink-API ...... 8 2.1.4. Third party tool requirements — installation ...... 9 2.1.5. Third party tool requirements — compatibility ...... 10 2.2. Installing OpenECU ...... 11 2.3. License setup ...... 17 2.3.1. Floating license ...... 17 2.3.2. Node-locked license ...... 19 2.4. Removing OpenECU ...... 19 2.5. Integration notes for third party tools ...... 20 2.5.1. Microsoft Windows 10 ...... 20 2.5.2. Microsoft Windows 7 ...... 20 2.5.3. Microsoft Windows XP ...... 21 2.5.4. PiSnoop ...... 21 2.5.5. ATI Vision ...... 21 2.5.6. ETAS INCA calibration tool ...... 22 2.5.7. Vector CANape ...... 22 2.5.8. Wind River (Diab) C Compiler v5.5.1.0 ...... 22 2.5.9. Wind River (Diab) C Compiler v5.8.0.0 ...... 24 2.5.10. Wind River (Diab) C Compiler v5.9.0.0 ...... 25 2.5.11. Wind River (Diab) C Compiler v5.9.4.8 ...... 25 2.5.12. GCC Compiler v4.7.3 ...... 26 2.5.13. Python ...... 27 2.1. Introduction

This chapter describes the installation process for the OpenECU C-API package and its dependencies. 2.1.1. Third party tool requirements

OpenECU developer software has been tested to work with Windows 10. OpenECU is compatible with Windows 7 SP1 (32-bit and 64-bit) and Windows XP SP3, but support for these operating systems is deprecated. OpenECU is not compatible with Windows Vista or Windows 8. 2.1.2. Third party tool requirements — C-API

For C based development, OpenECU requires (at a minimum) one of the following compiler tools:

• Wind River Diab compiler

• GCC Compiler

Note

GCC is an optional component in the OpenECU installation (installed by default). Additionally, GCC support is currently in a beta stage. As such, there a number of

Copyright 2019, Pi Innovo 7 Installation

known limitations for compiling an OpenECU application with GCC. Please see the “Integration notes for third party tools” of the “Release notes” for a list of known issues building with GCC for further details.

To program and calibrate an OpenECU with an application, OpenECU integrates with the following calibration tools. Only one calibration tool is required:

• PiSnoop

• ATI VISION

• ETAS INCA

• Vector CANape 2.1.3. Third party tool requirements — Simulink-API

For Simulink model based development, OpenECU requires (at a minimum) the following MathWorks tools:

• MATLAB (base product)

• Simulink (to develop the models)

• Simulink Coder (to generate C code from the models)

• MATLAB Coder (Simulink Coder depends on this)

In addition, if you need to add state diagrams to the model, then you will also need:

• Stateflow (to develop state flow diagrams inside your model) Simulink Coder generates C code from the state flow diagrams inside your model.

Simulink Coder generates C code which does not lend itself to efficient repeatable testing. When creating a production version of your product, you may need better control of the structure of the C code generated from the model to reduce the cost of testing the C code against any industry standards. Under these circumstances you will also need:

• Embedded Coder (to generate C code from the models)

To compile the generated C code (from either Simulink Coder or Embedded Coder), you will need one of the following compilers:

• Wind River Diab compiler

• GCC compiler (free compiler but with known issues)

To program and calibrate an OpenECU with an application, OpenECU integrates with the following calibration tools. Only one calibration tool is required:

• PiSnoop

• ATI VISION

• ETAS INCA

• Vector CANape

Copyright 2019, Pi Innovo 8 Installation

2.1.4. Third party tool requirements — installation

OpenECU works with a number of applications (both required and optional) supplied by other companies. If you intend to use OpenECU with one of the following tools, it is best to install them before OpenECU. The installer will then integrate the OpenECU developer software with these applications.

• MATLAB versions:

32-bit: R2013a, R2013b, R2014a, R2014b, R2015a, R2015b 64-bit: R2013b, R2014a, R2014b, R2015a, R2015b, R2016a, R2016b, R2017a, R2017b, R2018a, R2018b

• ETAS INCA calibration tool (version 7.2)

OpenECU works with a number of other applications, but these need not be installed prior to the OpenECU developer software.

• Simulink Coder, formerly Real-Time Workshop, (optional) versions:

32-bit: R2013a, R2013b, R2014a, R2014b, R2015a, R2015b 64-bit: R2013b, R2014a, R2014b, R2015a, R2015b, R2016a, R2016b, R2017a, R2017b, R2018a, R2018b

• Embedded Coder, formerly Real-Time Workshop Embedded Coder, (optional) versions:

32-bit: R2013a, R2013b, R2014a, R2014b, R2015a, R2015b 64-bit: R2013b, R2014a, R2014b, R2015a, R2015b, R2016a, R2016b, R2017a, R2017b, R2018a, R2018b

• Stateflow versions:

32-bit: R2013a, R2013b, R2014a, R2014b, R2015a, R2015b 64-bit: R2013b, R2014a, R2014b, R2015a, R2015b, R2016a, R2016b, R2017a, R2017b, R2018a, R2018b

• Wind River (Diab) C compiler (versions 5.5.1.0, 5.8.0.0 and 5.9.0.0) for M110, M220, M221, M250, M460 and M461 targets

• Wind River (Diab) C compiler (version 5.9.0.0) for M670 targets

• Wind River (Diab) C compiler (version 5.9.4.8) for M560 and 580 targets

• GCC Compiler (version 4.7.3 free compiler option) for M110, M220, M250, M460, M461 and M670 targets

Note

GCC is an optional component in the OpenECU installation (installed by default)

• PiSnoop (any version)

• ATI Vision calibration tool (version 2.5 through 4.0)

• Vector CANape calibration tool (version 8.0 through 13.0)

The applications above have been listed with a version or release number. These are the versions or releases that OpenECU has been tested against. It may be that OpenECU will

Copyright 2019, Pi Innovo 9 Installation

work with other versions of these applications, but it is recommended against and Pi may not provide technical support if these versions or releases are not used. 2.1.5. Third party tool requirements — compatibility

In summary, the following third party tools are compatible with this version of OpenECU:

Table 2.1. Third party tool compatibility

Third party tool Compatible versions Operating systems Microsoft Windows a Win10 (64-bit) Win7 SP1 (32-bit) (deprecated) Win7 SP1 (64-bit) (deprecated) XP SP3 (32-bit) (deprecated) Modelling and code generation tools MathWorks MATLAB R2013a, R2013b, R2014a, R2014b, R2015a, R2015b (32-bit) R2013b, R2014a, R2014b, R2015a, R2015b, R2016a, R2016b, MathWorks Simulink R2017a, R2017b, R2018a, R2018b (64-bit) MathWorks MATLAB Coder MathWorks Simulink Coder b MathWorks Embedded Coder Compiler tools c Wind River Diab C compiler v5.5.1.0, v5.8.0.0, v5.9.0.0 for M110, M220, M221, M250, M460 and M461 targets v5.9.0.0 for M670 target v5.9.4.8 for M560 and M580 target GCC Compiler d v4.7.3 for M110, M220, M250, M460, M461 and M670 targets Reprogramming, data logging and calibration tools e PiSnoop Any version ATI Vision f g v2.5 through v5.1.2 ETAS INCA v7.2.7 Vector CANape v8.0 through v16.0 a OpenECU developer software has been tested to work with Windows 10. OpenECU is compatible with Windows 7 SP1 (32- bit and 64-bit) and Windows XP SP3, but support for these operating systems is deprecated. OpenECU is not compatible with Windows Vista or Windows 8.

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host . If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives. b Mathworks Simulink Coder includes functionality of RTW and Stateflow Coder. c All OpenECU targets use Freescale PowerPC microcontrollers. The M110, M220, M221, M250, M460 and M461 use an MPC5534 microcontroller, the M670 uses an MPC5674F microcontroller. The M560 and M580 use an MPC5746C for the primary microcontroller and SPC560P34 for the secondary microcontroller.

See the Technicical Specification for your target for more information. d OpenECU has only been tested using GCC Compiler version 4.7.3 and is in the beta stage. As such, there are a number of known issues to keep in mind when compiling an OpenECU application using GCC. For further details, please see "Integration notes for third party tools" for a list of known issues. e These tools have been tested for reprogramming, data logging, and calibration. Some of them have many other features which have not been tested with OpenECU. f The OpenECU method of configuring ATI Vision uses standardised ASAP2 files. As a result, all future versions of Vision are expected to be backwardly compatible (e.g., version 3.7 and version 4.0 are known to be compatible). g The following Vision toolkits are typically used when working with OpenECU: Data Acquisition Toolkit, Calibration Toolkit, Universal ECU Interface Standard Toolkit, APOLLO Data Analysis Toolkit, CAN Interface Toolkit and HORIZON Scripting/Remote

Copyright 2019, Pi Innovo 10 Installation

API Toolkit. In particular, the HORIZON Scripting/Remote API Toolkit is required if OpenECU builds are to generate Vision strategy files (.vst).

Some third party tools have been marked deprecated and support for these tools will be removed in a future release of OpenECU.

Third party tool Replacement MathWorks MATLAB R2013a MATLAB latest version (see Pi Innovo's website [http://www.pi- innovo.com/support-center/compatibility] for a complete list of MathWorks MATLAB R2013b supported versions of MATLAB). MathWorks MATLAB R2014a MathWorks MATLAB R2014b WindRiver Diab 5.5.1.0 WindRiver Diab 5.8.0 and 5.9.0 2.2. Installing OpenECU

The installer program, openecu_platform_3_0_3_FS_r2019-3.exe, installs all the necessary files for the OpenECU platform. This file can be obtained from the Pi Document and Download Center web page [http://www.pi-innovo.com/downloads].

The installation process for the OpenECU developer software is performed by a wizard. To run the wizard, execute the appropriate installer program. The installation can be stopped at any point by selecting the Cancel button.

The installer requires that the user has administrative rights to make changes on the computer. If a user without rights is trying to execute the installer a dialog box will be displayed and the installation stops. Login with an administrator account or contact your network administrator and try again.

If a version of an OpenECU installer is already running, a dialog box will appear saying so. Select OK (which stops the current installer) and change to the other OpenECU installer to continue.

The installation process starts with an introduction. Select Next to continue.

Copyright 2019, Pi Innovo 11 Installation

The next windows to appear present the license agreement for using OpenECU developer software and related software. Read the license agreements and if acceptable, select I accept the terms of the License Agreement and then Next. If not acceptable, do not install the software.

Copyright 2019, Pi Innovo 12 Installation

The next window to appear provides a number of components that can be installed or patched.

The following table breaks out each of the components: Table 2.2. Install components Component Required Installed Description by default Platform Yes Yes A selection of packages to install, including the C-API and Sim-API components. OpenECU Yes Yes Install the Simulink interface to OpenECU, Sim-API documentation and support packages. Blockset Yes Yes Install the OpenECU blockset.

Copyright 2019, Pi Innovo 13 Installation

Component Required Installed Description by default Sim-API (optional) Yes Install the OpenECU blockset, ECU Technical Manuals Specifications and other documentation in (HTML) HTML format. Sim-API (optional) Yes Install the OpenECU blockset, ECU Technical Manuals Specifications and other documentation in PDF (PDF) format. Sim-API (optional) Yes Install some examples of how to use the Examples OpenECU blockset. OpenECU C- Yes Yes Install the OpenECU C-API files and libraries. API C-API Yes Yes Install the C interface to OpenECU, documentation and support packages. C-API (optional) Yes Install the OpenECU C-API User Guide, Manuals ECU Technical Specifications and other (HTML) documentation in HTML format. C-API (optional) Yes Install the OpenECU C-API User Guide, Manuals ECU Technical Specifications and other (PDF) documentation in PDF format. C-API (optional) Yes Install some examples of how to use the Examples OpenECU C interface. Extended (optional) No Install the On-Board Diagnostic (OBD) library. Diagnostics This library is available at extra cost. Features Python Yes Yes Install the Python application. This application is used to provide build support when generating and compiling the model source code. Tools (optional) No Installs additional OpenECU tools. GCC (optional) Yes Installs the GNU Compiler Collection (v4.7.3) and related tools for OpenECU targets. lmadmin (optional) No Installs the installers for the lmadmin license installer server from flexera. FreeCCP (optional) No Installs the FreeCCP programming tool (note that this tool is provided without support or warranty). Integration (optional) Yes Options to have the OpenECU installer integrate OpenECU with third party tools, like MATLAB and INCA. MATLAB (optional) Yes During installation, the OpenECU blockset is Integration integrated into MATLAB's PATH. INCA-ProF (optional) No During installation, INCA-ProF is update to Integration understand how to program an OpenECU. Start Menu (optional) Yes During installation, the Window's Start menu Shortcuts is updated to include shortcuts to installed components.

Adjust the component selection as required (especially if you require the installer to update an installed copy of ETAS INCA) and select the Next button.

Copyright 2019, Pi Innovo 14 Installation

The next window asks for a destination path to be specified. By default, the installer presents a path to your local drive.

Warning

If the default path is changed, ensure that only digits, upper and lower case letters and the _ character are used to specify directory names. An installation path that includes any space characters will cause problems later on.

If the INCA-ProF integration component was selected, the next window presented provides a list of installed versions of INCA.

Select which versions of INCA will be used with OpenECU and select the Next button. If no version should be updated select None.

Copyright 2019, Pi Innovo 15 Installation

Note

If any version of INCA is selected, then the installer will add OpenECU integration to all versions of INCA. This is simply a consequence of the way INCA works.

If no versions of INCA were found, the next window presents details on how to achieve this by hand (more details given in Section 2.5.6, “ETAS INCA calibration tool”). The instructions should be carried out when INCA-ProF runs.

If the Start Menu Shortcuts component was selected, then the next window presented asks the user to select where in the Start menu the OpenECU items will be added. During install, the installer adds short cuts to the documentation components selected and to the OpenECU uninstall application.

Copyright 2019, Pi Innovo 16 Installation

Once installation has completed, the user is provided an option to read the getting started guide, the release notes and to visit the OpenECU web site.

Getting started guide

If you are a first time user of OpenECU, it is strongly recommend following the getting started guide, which covers what tools can be used with OpenECU and how to configure OpenECU and those tools to work together.

Release notes

If you are installing a new version of OpenECU, it is strongly recommended that you read the release notes. Some releases of OpenECU change the functionality of features which may have an impact on existing applications. 2.3. License setup

Machine identification generated by the license tools is required to activate an OpenECU platform license.

This section is a quick setup guide to get OpenECU working with your license. Consult the license administration guide for more information on license management and administration. This document is provided with the installation at "[install path]\doc_user \License-Administration-Guide.pdf". 2.3.1. Floating license

To setup a floating license, the vender daemon will have to be run on the designated license server as well as have a license file on that machine. This section describes setting up the vendor daemon for a floating license. 2.3.1.1. Server

• After installing the platform, copy the files in "[install path]\tools\flexera\i86_n3\" to your designated license server. On that machine, run lmtools.exe.

Copyright 2019, Pi Innovo 17 Installation

• Select the "System Settings tab", check "Include Domain", and press the button that says "Save HOSTID Info to a File".

• Email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send you a valid license file. (Or if you have already completed the purchase, reply to the welcome email with this information)

• It is recommended that lmadmin license server manager be used to serve licenses. Run the lmadmin installer to install the software. Once the installation is complete, copy the vender daemon, openecu.exe, into the install directory, "C:\Program Files (x86)\FlexNet Publisher License Server Manager\".

• Start the license server manager. You can then use the web interface to upload the license file and start serving your license.

Note

If a license has not yet been purchased, email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send a valid license file. If the purchace has already been completed, reply to the welcome email with this information.

• It is recommended that lmadmin license server manager be used to serve licenses. Run the lmadmin installer and start the license server manager. The web interface can then be used to upload the license file and start serving your license.

Note

Details on installing and using the lmadmin tool are in Chapter 9 of the License Administration Guide, "[install path]\doc_user\License-Administration-Guide.pdf".

Note

lmgrd is also provided with the platform as an alternative to lmadmin; consult Chapter 10 of the License Administration guide for details on its use.

Copyright 2019, Pi Innovo 18 Installation

2.3.1.2. Client

• On the user development machine, set the environment variable OPENECU_LICENSE_FILE to @to tell the OpenECU platform to look for a floating license from the license server. 2.3.2. Node-locked license

To setup a node-locked license, a license file must be placed on the development machine.

• After installing the platform, run the file: '[install path]\tools\flexera\i86_n3\lmtools.exe'

• Select the "System Settings tab", check "Include Domain", and Press the button that says "Save HOSTID Info to a File" (see screen shot above)

• Email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send you a valid license file. (Or if you have already completed the purchase, reply to the welcome email with this information) If a license has not yet been purchased, email the file to Pi Innovo with the purchase order. When the purchase is complete, Pi will send a valid license file. If the purchace has already been completed, reply to the welcome email with this information.

• Copy the file to the directory "C:\openecu" or update the OPENECU_LICENSE_FILE environment variable with the location of your file. 2.4. Removing OpenECU

Navigate through the Windows All Programs Start Menu shortcuts and find the OpenECU Developer Software directory. Select the version of OpenECU to remove and run the uninstaller.

The uninstaller requires that the user has administrative rights to make changes on the computer. If a user without rights is trying to execute the uninstaller a dialog box will be displayed and the uninstaller stops. Login with an administrator account or contact your network administrator and try again.

If a version of an OpenECU uninstaller is already running, a dialog box will appear saying so. Select OK and change to the other OpenECU uninstaller to continue.

The uninstaller presents the location of the previous install to remove. Select the Uninstall button to continue (this will remove that version of OpenECU) or select the Cancel button to stop the uninstall.

Copyright 2019, Pi Innovo 19 Installation

Note

The OpenECU uninstaller does not remove the INCA-ProF configuration files for CCP.

2.5. Integration notes for third party tools 2.5.1. Microsoft Windows 10 2.5.1.1. Integration

The installer integrates the OpenECU package with Windows 10 by modifying the Start menu, by modifying some registry items and by copying files to a local drive. 2.5.1.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives. 2.5.2. Microsoft Windows 7 2.5.2.1. Integration

The installer integrates the OpenECU package with Windows 7 SP1 by modifying the Start menu, by modifying some registry items and by copying files to a local drive. 2.5.2.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted

Copyright 2019, Pi Innovo 20 Installation

drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives. 2.5.3. Microsoft Windows XP 2.5.3.1. Integration

The installer integrates the OpenECU package with Windows XP SP3 by modifying the Start menu, by modifying some registry items and by copying files to a local drive. 2.5.3.2. Known defects/issues

OpenECU developer software may not function correctly on encrypted drives. OpenECU developer software must be able to create files on the host file system. If using an encrypted drive, be sure that permission settings will allow OpenECU to create files. Pi Innovo cannot provide support for issues with encrypted drives. 2.5.4. PiSnoop 2.5.4.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating PiSnoop and OpenECU. 2.5.4.2. Known defects/issues

None. 2.5.5. ATI Vision 2.5.5.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating Vision and OpenECU. 2.5.5.2. Known defects/issues

• Open: integration issues with OpenECU while creating a Vision VST (strategy) file.

There have been integration issues between Vision and OpenECU, when the user requests a build create a Vision VST (strategy) file. If OpenECU cannot create a strategy file, then it may be necessary to register the COM interface for Vision by running the RegisterCOMInterface.bat file included in the install of ATI Vision.

• Open: does not operate correctly with encrypted hard drives.

There have been reports of Vision interacting poorly with encrypted hard drives. At the moment, it is not clear what the problem might be. On one occasion, Pi worked with ATI and a customer and determined a work around that is not understood. The work around was to rename the executable file for Vision to something longer than 11 characters.

• Open: some earlier versions do not support CCP seed/key correctly.

ATI Vision 2006 (v3.2) is the earliest version for which CCP seed/key security has been validated by Pi Innovo. Earlier versions may support CCP seed/key security (see the relevant Vision documentation) but bugs in the CCP implementation on various targets are known to exist. ATI have recommended that earlier versions should not be used, or should be used with caution.

Copyright 2019, Pi Innovo 21 Installation

2.5.6. ETAS INCA calibration tool 2.5.6.1. Integration

The installer integrates the OpenECU package with the ETAS INCA tool. However, if for any reason the installer could not find an installed version of INCA, the user can manually integrate the necessary ProF component.

The INCA-ProF tool programs OpenECU over CCP using a set of configuration files. In order to manually integrate these configuration files, the user must run INCA, open an experiment, select manage memory then flash programming.

The user is then presented with a dialog box to browse ProF configurations, or a ProF settings dialog box (in which case the user must select Configure...).

With the browse ProF configurations dialog box, select the "Install..." button and browse to the install location of OpenECU:

[install path]\tools_integration\inca_prof

and select OK. This will have manually installed the INCA-ProF configuration file for OpenECU.

Note

If manually integrating and the ProF files cannot be found in the location above, then re- run the OpenECU installer and select the Integration -> INCA-ProF Integration option and try again.

2.5.6.2. Known defects/issues

None. 2.5.7. Vector CANape 2.5.7.1. Integration

Unlike some other calibration tools, during installation there is nothing special to be done when integrating CANape and OpenECU. 2.5.7.2. Known defects/issues

None. 2.5.8. Wind River (Diab) C Compiler v5.5.1.0 2.5.8.1. Installation

The Wind River (Diab) compiler 5.5.1.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

• On Choose your Activation Type window, select one of the following options:

• Permanent activation if you have been assigned with a license file from Wind River, usually named WRSLicence.lic. The full path should point to the license file.

Copyright 2019, Pi Innovo 22 Installation

• Temporary activation if you wish to use the Wind River (Diab) compiler on an evaluation basis, or temporary basis until a permanent license is provided. • A reboot may be required to complete installation of the Wind River (Diab) compiler. • If using one version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_5_1_0 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory. • If using more than one version of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_5_1_0 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

E.g., D:\Progra~1\diab\5_5_1_0\win32\bin\ 2.5.8.2. Known defects

• Closed: incorrect generation of object code for “float <= float” comparisons.

The compiler incorrectly generates object code for “float <= float” comparisons, turning the comparison into “float > float”. This issue has been resolved by removing the - Xieee754-pedantic command line option to the compiler command line option to the build configuration files.

• Open: incorrect generation of object code for long C functions.

The compiler incorrectly generates jump instructions in the object code if the jump destination address differs from the address of the jump instruction by more than 15 bits (signed). No warning or error is generated by the compiler. The result is a model which does not behave as expected when run on target (usually the ECU appears as if it is continually resetting).

Workaround (C-API): Break up large functions into small sub-functions.

• Open: generation of non-existent labels.

The compiler can generate non-existent labels such as ".L1013" when compiling code involving large structures, such as those generated by TargetLink. The code then fails to link because the labels are not defined. This has not yet been seen with Simulink builds but it may possibly be seen in future.

Workaround: if this problem is encountered, a patched version of the compiler is available from Wind River for customers who have compiler support (quote service request 1054126).

• Open: incorrect rounding on conversion from float to integer types.

The compiler rounds values when converting from floating point to integer, e.g. from "float" to "signed long" (in terms of native types, otherwise known as F32 and S32 in the OpenECU environment). For example, 3.6 as a float is rounded to 4 as an integer, but the C standard requires that the fractional part is truncated, so a converted value of 3 would be correct. Similarly -3.6 is rounded to -4 instead of being truncated to -3. This defect is fixed in version 5.8.0.0 of the compiler.

Workaround: if this problem is encountered, a patched version of the compiler is available from Wind River for customers who have compiler support (quote service request 864470). 2.5.8.3. Known issues

• Closed: Can't use Simulink look up blocks

Copyright 2019, Pi Innovo 23 Installation

There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

'[model-name].c', line [line-num]: warning (dcc:1792): trying to assign 'ptr to volatile' to 'ptr'

This has now been fixed, see F-CR 13325 in the release notes.

• Closed: compiling the main model file can take a long time.

Small models compile in a short period of time, but once the code presented to the compiler exceeds a limit, the compiler takes a long time to compile the main model file (model- name.c).

Workaround: the compiler sets aside an amount of memory for the compilation phase and if the size of the model code exceeds the limit, the compilation slows down. This can be avoided by increasing the size of the compiler's buffer using a command line option. Add the pcomp_CompileOptions block to the model, set the mode parameter to Add to options and set the compiler options parameter to -Xparse-size=100000. If the compilation is still slow, increase the option value further. 2.5.9. Wind River (Diab) C Compiler v5.8.0.0 2.5.9.1. Installation

The Wind River (Diab) compiler 5.8.0.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

• Follow the guidance given in Section 2.5.8, “Wind River (Diab) C Compiler v5.5.1.0”. • If using a single version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_8 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory. • If using multiple versions of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_8 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

E.g., D:\Progra~1\diab\5_8_0_0\win32\bin\ 2.5.9.2. Known defects

None identified. 2.5.9.3. Known issues

• Closed: Can't use Simulink look up blocks

There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

'[model-name].c', line [line-num]: warning (dcc:1792): trying to assign 'ptr to volatile' to 'ptr'

This has now been fixed, see F-CR 13325 in the release notes.

Copyright 2019, Pi Innovo 24 Installation

2.5.10. Wind River (Diab) C Compiler v5.9.0.0 2.5.10.1. Installation

The Wind River (Diab) compiler 5.9.0.0 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

• Follow the guidance given in Section 2.5.8, “Wind River (Diab) C Compiler v5.5.1.0”. • If using a single version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_9 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory. • If using multiple versions of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_9 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

E.g., D:\Progra~1\diab\5_9_0_0\win32\bin\ 2.5.10.2. Known defects

None identified. 2.5.10.3. Known issues

• Closed: Can't use Simulink look up blocks

There has been a known issue which restricts the compiler to use Simulink lookup block. When using Simulink lookup blocks, the Diab compiler would stop compilation with this error message:

'[model-name].c', line [line-num]: warning (dcc:1792): trying to assign 'ptr to volatile' to 'ptr'

This has now been fixed, see F-CR 13325 in the release notes.

• Open: Error message 0169

The Diab 5.9.0.0 compiler generates object files that cause the Diab

ddump command to generate the following error message during an application build.

Error 0169 at offset NNNNNNNN: Unexpected EOF.

The error appears to be benign and can be ignored. Currently, there is no known workaround. 2.5.11. Wind River (Diab) C Compiler v5.9.4.8 2.5.11.1. Installation

The Wind River (Diab) compiler 5.9.4.8 can be installed by running the file setup.exe from the supplied media — several options will be presented during the compiler install and the following responses should be used:

• Follow the guidance given in Section 2.5.8, “Wind River (Diab) C Compiler v5.5.1.0”.

Copyright 2019, Pi Innovo 25 Installation

• If using a single version of the Wind River (Diab) compiler, either setup the OPENECU_DIAB_5_9_4_8 environment variable as described in the next point, or adjust Window's system path to include the absolute path to the compiler's bin directory. • If using multiple versions of the Wind River (Diab) compiler (for instance, when you are using two or more versions of OpenECU which require different versions of the Wind River (Diab) compiler), the environment variable OPENECU_DIAB_5_9_4_8 must be set to the absolute path to the compiler's bin directory. This macro must terminate in a “\” and must use the DOS 8.3 short naming convention.

E.g., D:\Progra~1\diab\5_9_4_8\win32\bin\ 2.5.11.2. Known defects

There is a compiler defect in which the optimizer may ignore local variable assignments under certain cases. Compiler diab_5_9_4_8_patch_TCDIAB-14743 is available from the Pi Innovo website. 2.5.11.3. Known issues

None identified. 2.5.12. GCC Compiler v4.7.3

GCC, also known as the GNU Compiler Collection, is a free compiler system produced by the GNU Project supporting various programming languages. The Foundation (FSF) distributes GCC under the GNU Public License (GNU GPL). GCC has been adopted as the standard compiler by most modern Unix-like computer operating system and has also been ported to a wide variety of processor architectures and is available for most embedded platforms.

GCC is used with permission under the GPL Version 3. If GCC is installed with OpenECU, the license file can be found in the [install path]\tools\gcc\ppc\docs directory of the OpenECU install. If desired, a copy of the GCC source code can be found and downloaded from the Pi Innovo website.

Support for GCC is currently in beta and as such, the user may run into issues which can cause an application to fail to build or run correctly on target. Listed below are a set of known issues when building an application using GCC. See Appendix K, Contact information for details on how to get in contact with OpenECU support if support is needed for using GCC.

GCC is not recommended for production programs at this time. 2.5.12.1. Installation

GCC is an optional component in the OpenECU installation and is installed by default. 2.5.12.2. Known defects

None identified. 2.5.12.3. Known issues

• Open: Applications built with the GCC compiler do not support the diagnostics feature at this time. Applications using the diagnostics feature will not compile.

• Information: compiler warnings when using Simulink look up blocks.

When building a model that uses Simulink look up blocks, the compiler will emit diagnostic messages similar to the following. These can be ignored.

Copyright 2019, Pi Innovo 26 Installation

[file-line]: warning: passing argument 2 of '[lookup function]' discards 'volatile' qualifier from pointer target type [enabled by default] [file-line]: note: expected 'const real_T *' but argument is of type 'const volatile real_T *'

• Information: GCC only supports non-VLE code. Therefore, the compiled code will be larger. In general, GCC applications will be about 50% bigger than code generated by Diab.

• Information: The GNU linker locates data slightly differently than the Diab linker in the final images. RAM and Flash memory utilization may be different for the same application compiled by different compilers.

• Open: Applications built with GCC in general exhibit higher CPU loading than applications build with Diab. 2.5.13. Python

Python is general purpose, high level interpreted programming language, distributed under the PSF license which allows use in non open-source commercial applications. The license can be found in the [install path]\tools\python\license.txt file. 2.5.13.1. Installation

Python is a required component of the OpenECU installation. 2.5.13.2. Known defects

None identified. 2.5.13.3. Known issues

• Open: When using OpenECU, Python may raise an error about an incorrect DLL. For example, “The procedure entry point for X could not be located in the dynamic link library py[name].dll”. This can occur if another application installed on the same machine as OpenECU has also installed Python (for instance, dSpace ControlDesk).

Workaround: Browse to the Windows system directory. Depending on the version of Windows, this will be one of:

c:\windows\system32; or c:\windows\syswow64

Locate the DLL referred to in the error message. The file will start with the characters “py” and end with “.dll”. Group all Python DLLs and move them to a temporary location, then restart OpenECU.

Temporarily moving DLLs will cause the other application to run incorrectly (and if DLLs unrelated to Python are inadvertantly moved, then the applications that rely on those DLLs may not run correctly). You can resolve this by returning the moved DLLs to their original location, or possibly moving the DLLs to the location of the installed applications.

Note

The OpenECU installation of Python does not write files to the Windows directories, or modify global registry entries relating to Python. As such, the OpenECU installation of Python is entirely local to OpenECU and will not affect other packages.

Copyright 2019, Pi Innovo 27 Chapter 3. Quick start

3.1. Introduction ...... 28 3.2. Installed examples ...... 28 3.3. Exercise — Step 1 ...... 28 3.3.1. Designing the application ...... 30 3.3.2. Create the application ...... 30 3.3.3. Review the application ...... 30 3.3.4. Implement the sensor reading ...... 32 3.3.5. Implement the sensor conversion to temperature ...... 33 3.3.6. Implement the threshold comparison ...... 36 3.3.7. Implement the lamp driver ...... 36 3.3.8. Summary so far ...... 37 3.3.9. Create data dictionary and interface specification files ...... 39 3.3.10. Building the application ...... 41 3.3.11. Program the ECU ...... 42 3.3.12. Play with the application ...... 44 3.1. Introduction

This chapter gives you a quick introduction to creating an OpenECU application written in C, and an introduction to programming an OpenECU device.

The step1 exercise in Section 3.3, “Exercise — Step 1” describes how to incorporate the OpenECU C-API library into your own application designs, and how to test and calibrate your models on the ECU. The exercise requires the following resources:

• a working knowledge of C, coding for embedded systems, and the notion of real-time tasks; • a complete installation of Pi's OpenECU C-API package: see Chapter 2, Installation; • a complete installation of supporting tools (e.g., compiler, calibration tool, etc.: see Chapter 2, Installation and Appendix C, Supporting tools); 3.2. Installed examples

The installation of OpenECU comes with a number of explanatory examples of how to use OpenECU, including a completed step1 example (see Section 3.3, “Exercise — Step 1”) configured for various ECUs. See Section 4.6.8, “Examples” and Section 4.6.8.1, “Building the examples” for further details. 3.3. Exercise — Step 1 Create a temperature limit warning

This exercise describes how to build, program, and test an application that monitors a temperature sensor and activates a warning lamp if a temperature threshold is breached. The application uses a single analogue input to measure the temperature, and a single PWM output to activate a warning lamp connected to the power supply.

The exercise requires the OpenECU to be connected to various devices and components as pictured in Figure 3.1, “Quick start loom”.

Copyright 2019, Pi Innovo 28 Quick start

Figure 3.1. Quick start loom

FEPS 17-19V, 0V

IGN Power supply VPWR 12V DC GND 0V

Calibration CAN0-L, CAN0-H CAN OpenECU 2 Tool

5V supply Analogue input Pot Resistor Sensor GND LED PWM output

M460 CAN0-L CAN0-H Terminated? M220 M250 M461 M550 M670 M220 A43 A28 No FEPS A27 A27 A2 Y22 Y22 M250 A43 A28 No VPWR A2 A2 A20 Y3 Y3 M460 A37 A36 Yes GND A31 A31 C1 Y2 Y2 M461 A37 A36 Yes IGN A26 A26 A12 Y25 Y25 M550 Y11 Y12 Yes CAN0-L A43 A43 A37 Y11 Y11 M670 Y11 Y12 Yes CAN0-H A28 A28 A36 Y12 Y12 5V supply A25 A25 C8 Y8 Y8 External CAN termination required on Analogue input A19 A19 A28 Y31 Y31 loom if CAN bus not terminated Sensor GND A40 A40 C9 Y9 Y9 PWM output A37 A18 A15 Y29 Y29

By following the instructions below, you will complete the application design, create C code, build the application and test the application running on the ECU.

Copyright 2019, Pi Innovo 29 Quick start

3.3.1. Designing the application

Before any engineering project reaches the design stage, several detailed planning stages should be carried out to define suitable functional requirements and specifications. Once you have a detailed target for your design, you can then start to create an implementation of the application.

For this example, we'll skip the functional specification stage for brevity. The application will read an analogue input every 100 milliseconds, transform the input into a temperature reading, check for sensor faults, and turn on a lamp if the temperature exceeds a limit. We have designed and partially implemented the application for you — you need only finish the implementation as described below. 3.3.2. Create the application

To create the application, copy the [installation directory]\examples\c_api \step1_quick_start directory to somewhere local on your machine. Avoid placing the copy in a directory which contains a space in the path name. The copy has the following directories:

build The build directory contains a batch file which will compile and link the completed step1 implementation.

We'll see how to build the application in Section 3.3.10, “Building the application”.

interface_specification The interface_specification directory the initial implementation of two files: step1_[target-ecu].capi which describes supporting functionality the OpenECU library will provide to the application (for instance, what CCP settings are required to communicate with the calibration tool); and step1.dde which contains a description of the C variables in the step1 implementation which will be exposed to the calibration tool.

We'll see how to write these files in Section 3.3.9, “Create data dictionary and interface specification files”.

loom_specification The loom_specification directory contains a copy of the diagram given in Figure 3.1, “Quick start loom”.

src The src directory contains the initial implementation of the step1 application. We'll see how to implement the functionality of the temperature limit warning in Section 3.3.3, “Review the application”. 3.3.3. Review the application

Open the src\step1_[target-name].c file in a text editor. The file contains a few variables and functions. The M460 version is shown in summary here (and indeed all subsequent examples reflect the M460, there will be some differences to files targeting other ECUs):

#include "openecu.h"

/*...*/

#include "step1_m460_api.h"

Copyright 2019, Pi Innovo 30 Quick start

static S16 stp_adc_raw; static F32 stp_adc_eng;

static OE_CAL F32 stpc_adc_limit = 90.0;

void psc_initialise_app(void) { (void) pcx_config(PIO_CAN_A37_A36, PIO_CBAUD_500_KBPS); (void) pcx_config(PIO_CAN_C37_C36, PIO_CBAUD_500_KBPS);

/* Delete this comment and conditionals below when filling out this * example from the User Guide. */ #if (1) #error "There is more to do here, see the User Guide." #endif }

void stp_task_100ms(void) { /* Delete this comment and conditionals below when filling out this * example from the User Guide. */ #if (1) #error "There is more to do here, see the User Guide." #endif }

void psc_background_app(void) { }

The source file starts by including openecu.h, which itself includes numerous other OpenECU header files. These header files provide declarations for the OpenECU library, including macros, variables and functions which give the application access the functionality of the ECU.

The OpenECU library isolates the application from the target hardware and provides the framework for allowing the application to perform work on a periodic (and sometimes on an event) basis. You can read more about the library in Chapter 4, Software overview.

The last include file is generated by the interface tool. The interface tool reads an interface specification (which is described in more detail for this exercise in Section 3.3.9, “Create data dictionary and interface specification files”) and generates source code which is compiled and linked with the application and OpenECU library. The source code provides the source definitions to glue the application and library together.

The C variable stp_adc_raw is used to hold the A/D conversion of the temperature sensor. The use of adc is a reference to the pin on the ECU connector (see the loom specification in Figure 3.1, “Quick start loom” to review how the ECU will be connected to power, to communications, to the temperature sensor and to the warning lamp).

The C variable stp_adc_eng is used to hold the result of converting stp_adc_raw into a temperature. It has units °C.

The C variable stpc_adc_limit is a calibration. A calibration is a C variable which can be modified by a calibration tool, without having to recompile the application. Calibrations are typically editable with a calibration tool (there is an introduction to the more common calibration tools in Appendix C, Supporting tools), and some ECUs support editing calibrations while the application is running (useful for tuning your application).

Calibrations used in OpenECU should have the OE_CAL macro for variables that are meant to be declared as volatile const. This is to ensure that calibrations are put into calibration flash in memory. If this macro is not used for calibrations, you may not be able to access calibrations in your calibration tool.

Copyright 2019, Pi Innovo 31 Quick start

Calibration parameters which are used as the defaults for adaptive parameters must use the OE_ADAP macro instead of OE_CAL for proper operation. Failure to use OE_ADAP in a parameter used with one of the PNV function may result in unexpected module resets or other undefined behaviour. See the C-API nvm_demo source code in the examples folder of the OpenECU installation directory for more information.

This variable is the calibratable temperature limit, above which the application will turn on the warning lamp. The variable has units of °C.

Note

Notice how the name of this variable and the others make use of a prefix, either stpc or stp. All variables in an OpenECU application which will be read or written by a calibration tool need to adhere to this naming policy (which is covered in detail outside of this exercise in Section 7.1.5.2, “DDE naming rules (prefix_style)”). Other variables, private to the application, do not need to follow the naming policy.

The C function psc_initialise_app() is called by the OpenECU library during initialisation. The function currently calls the library to initialise the CAN buses and we'll later add more code to perform additional initialisation.

You can read about the initialisation sequence in Section 4.6, “Application mode”.

The C function psc_initialise_app() initialises the CAN buses by calling the OpenECU library pcx_config() function. The function takes two parameters: the first specifies the CAN bus to configure; and the second specifies the baud rate for the CAN bus. In both cases, the parameters use macros from the pio.h header file. We'll see how similar macros are used in other situations as the exercise progresses.

The function returns a code indicating success or failure of the operation. For this exercise, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

These blocks will throw a compiler error at build time. They are to prevent the compiler from building the quick start without reading this user guide. They should be deleted in order to build the project

The C function stp_task_100ms() performs the main functionality of the application. The interface specification instructs the library to call this function every 100 milliseconds (we'll see more about the interface specification for this exercise in Section 3.3.9, “Create data dictionary and interface specification files”. At the moment, the function does nothing — we'll expand on it in just a moment.

The C function psc_background_app() is called by the library when the processor is not running anything else. For the purposes of this exercise, we won't need it to do anything but you read more about the background function in Section 5.3.1.2, “System background processing”.

We need to extend the basic functionality of the application to read an analogue input, process it into a temperature reading, and set the state of a PWM output based on the temperature calibration. 3.3.4. Implement the sensor reading

The input portion of the application means reading an analogue input and converting the result to a temperature. Add the following code to the stp_task_100ms() function.

(void) pax_adc_input (PIO_AIN_A28 , &stp_adc_raw , FALSE );

Copyright 2019, Pi Innovo 32 Quick start

The function returns a code indicating success or failure of the operation. For this exercise, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

The OpenECU library provides a function called pax_adc_input() to convert the voltage in of a connector pin to the range [0, 4096], where 0 corresponds to ground, and 4096 corresponds to full scale voltage. The full scale voltage depends on the connector pin chosen — A28 in this case corresponds to 5V full scale. The full scale range for each pin is detailed in the ECU's technical specification (Section A.1, “ECU hardware reference documentation”).

The first parameter to the function specifies the channel to convert. As with the CAN bus configuration example, the referenced hardware element is given as a macro. In this case, the macro specifies that the function must provide the result of reading pin A28.

The second parameter to the function specifies the variable to write the result of reading pin A28. We covered variable stp_adc_raw earlier.

The third and final parameter to the function specifies whether the channel given by the first parameter should be initialised or not. In this case, we need to read pin A28, hence the FALSE value. We'll cover initialisation shortly.

We also need to initialise the library to read pin A28, add the following code to function psc_initialise_app().

(void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, TRUE);

Initialisation uses the same function and parameters except for the last. The final parameter, set to TRUE this time, tells the function to initialise pin A28 to be processed as an analogue input.

With these changes in place, the application can now initialise the temperature sensor input pin and reads the temperature sensor every 100 milliseconds. We now need to convert the reading into a sensible engineering value. 3.3.5. Implement the sensor conversion to temperature

Temperature sensors, and other sensors in general, can often generate a non-linear response to the physical characteristic under measurement. For the purposes of this exercise, we'll assume the temperature sensor is non-linear, and has a response similar to the following:

Figure 3.2. Transfer function for temperature sensor

Copyright 2019, Pi Innovo 33 Quick start

The OpenECU library directly supports converting linear and non-linear analogue readings to engineering values with the put_process_analog_input() function. Add the following code immediately below the call to put_adc_in().

put_process_analog_input(stp_adc_raw, 0.1, &stp_adc_eng, &stp_adc_confirmed_raw_min_flt, &stp_adc_confirmed_raw_max_flt, &stp_adc_confirmed_slew_rate_flt, &stp_adc_confirmed_eng_min_flt, &stp_adc_confirmed_eng_max_flt, &stp_adc_transient_flt, &stp_adc_process_analog_input_pai_cal, &stp_adc_process_analog_input_pai_wrk );

The first parameter provides the function with the A/D conversion of the input. It is this value which is converted to engineering units.

The second parameter specifies how long it has been since the last call to put_process_analog_input() for pin A28. As the function is called from stp_task_100ms() which runs every 100 milliseconds, 100 milliseconds is specified.

The third parameter points to a variable which is written with the result of converting stp_adc_raw to engineering units.

The fourth through to the ninth parameters point to variables which are written with the results of fault checking the input and conversion process. For the purposes of this exercise, the code won't act on any of the fault flags, but you will probably want to address any detected faults in your own applications.

The tenth parameter points to a work space which the function uses to record information between calls to put_process_analog_input().

The eleventh parameter points to a group of calibrations which define how the

The function call references numerous variables which have not yet been declared. Add the following code after the declaration of stpc_adc_limit.

static BOOL stp_adc_confirmed_raw_min_flt; static BOOL stp_adc_confirmed_raw_max_flt; static BOOL stp_adc_confirmed_slew_rate_flt; static BOOL stp_adc_confirmed_eng_min_flt; static BOOL stp_adc_confirmed_eng_max_flt; static BOOL stp_adc_transient_flt;

which declares the fault flags passed to put_process_analog_input(). We also need to declare the work space and calibration structures. Add the following code immediately after the fault variables:

static PUT_ANALOGUE_WORKSPACE_T stp_adc_process_analog_input_pai_wrk; static const PUT_ANALOGUE_CAL_DATA_T stp_adc_process_analog_input_pai_cal = { &stpc_adc_min_raw_value, &stpc_adc_max_raw_value, &stp_adc_eng_lookup_axis_size, stpc_adc_eng_lookup_x_axis, stpc_adc_eng_lookup_z_data, &stpc_adc_min_eng_value, &stpc_adc_max_eng_value, &stpc_adc_leaky_bucket_rise_rate, &stpc_adc_leaky_bucket_fall_rate, &stpc_adc_leaky_bucket_flt_clear_level, &stpc_adc_default_output_value, &stpc_adc_max_slew_rate };

Copyright 2019, Pi Innovo 34 Quick start

The structure is essentially a set of pointers to calibrations. The calibrations can themselves be changed by a calibration tool while the application is running. The calibration detail the different transformations and checks applied to the A/D reading.

These specify the minimum and maximum allowable value for the A/D conversion, which in this exercise is stp_adc_raw. If stp_adc_raw is outside the range given by these calibrations, then put_process_analog_input() will record a fault.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_min_raw_value = 90; static OE_CAL F32 stpc_adc_max_raw_value = 4000;

For this exercise, the raw A/D limits do not bound the full scale, and it will be possible to see the raw fault flags become set if the temperature sensor is shorted to ground or to 5V.

These specify how the A/D conversion is transformed into an engineering value. The x_axis and z_data match the transfer function for the temperature sensor given in Figure 3.2, “Transfer function for temperature sensor”.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static const S32 stp_adc_eng_lookup_axis_size = 6; static OE_CAL F32 stpc_adc_eng_lookup_x_axis[] = {163, 917, 1671, 2424, 3178, 3932 }; static OE_CAL F32 stpc_adc_eng_lookup_z_data[] = {135, 96, 74, 55, 20, -42 };

What these lines of code say, is that an A/D range of [163, 3932] will be mapped onto an engineering range of [-42, 135]°C, following the curve given in the transfer graph.

These specify the minimum and maximum allowable value for the engineering value. If the engineering value is outside the range given by these calibrations, then put_process_analog_input() will record a fault.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_min_eng_value = -40; static OE_CAL F32 stpc_adc_max_eng_value = 130;

For this exercise, the engineering limits do not bound the full range of the transfer function declared above (range [-42, 135]°C), and it will be possible to see the engineering fault flags become set if the temperature sensor voltage is close to 0V or 5V.

These specify how a detected fault will be validated. For this exercise, it is not important to understand the fault mechanism (although you can read more about it in Section 5.22.1.6, “Leaky bucket fault detection”).

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_leaky_bucket_rise_rate = 0.5; static OE_CAL F32 stpc_adc_leaky_bucket_fall_rate = 0.25; static OE_CAL F32 stpc_adc_leaky_bucket_flt_clear_level = 0.5;

This specifies the engineering value to use if a fault is validated by the leaky bucket. Its a mechanism where by a default engineering value can be used if the temperature sensor is found to be at fault.

Copyright 2019, Pi Innovo 35 Quick start

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_default_output_value = 60;

For this exercise, it will be possible to see the engineering value default to 60°C if a raw or engineering fault is present for some time.

This specifies the maximum rate of change of the A/D reading. If the rate of change exceeds the limit, a fault is reported. For the purposes of this exercise, we'll set the maximum to a large value to prevent a slew rate fault being reported.

Add the following code before the definition of stp_adc_process_analog_input_pai_cal.

static OE_CAL F32 stpc_adc_max_slew_rate = 10000000;

We also need to initialise the workspace used for processing the analogue input, add the following code to function psc_initialise_app().

put_process_analog_input_init(&stp_adc_process_analog_input_pai_wrk); 3.3.6. Implement the threshold comparison

To be able to turn the warning lamp on or off, the application must decide whether the processed temperature input has exceeded a limit. We already have the processed temperature value (stp_adc_eng) and a calibratable temperature limit (stpc_adc_limit), comparing the two is simple. Add the following code to the end of function stp_task_100ms().

stp_adc_state = (stp_adc_eng > stpc_adc_limit);

This code introduces a new variable, stp_adc_state. It holds the boolean result of the comparison, 0 if the temperature limit has not been exceeded, 1 if the temperature limit has been exceeded. Add the following code after the definition of stp_adc_eng.

static BOOL stp_adc_state; 3.3.7. Implement the lamp driver

Finally, the application must drive the lamp on or off based on the comparison. Add the following code to the end of function stp_task_100ms().

(void) pdx_pwm_output (PIO_POT_A15, 1000, stp_adc_state, 0, FALSE);

The function returns a code indicating success or failure of the operation. For this exercise, just like the call to pax_adc_input() earlier, we'll ignore the return value (by casting it to void), but in your applications, you'll probably want to check the return code.

The OpenECU library provides a function called pdx_pwm_output() drive a pin at a given frequency and duty cycle, essentially generating pulses. The application only needs to turn the lamp on or off so the PWM function may seem like an odd function to choose. It has been chosen to show that some OpenECU library functions can be used for multiple purposes. In this case, the PWM function can generate a low signal without

Copyright 2019, Pi Innovo 36 Quick start

pulses if the duty cycle is set to 0, and a high signal without pulses if the duty cycle is set to 1. Duty cycles of 0 and 1 exactly match the comparison value calculated earlier.

Note that the actual state of the output (low versus high) depends on the particular pin used and if the pin is configured for a high-side or low-side control. In this example, M460 pin A15 is a low-side only output, so a duty cycle of 0 will have the output off (high voltage if connected to a load) and a duty cycle of 1 will have the output pulled to ground.

The first parameter to the function specifies the channel to drive. As with the pax_adc_input() function, the referenced hardware element is given as a macro. In this case, the macro specifies that the function must drive pin A15.

The second parameter to the function specifies the rate at which pulses should be generated. For this exercise, we don't need pulses to be generated but simply need a constant low or high signal, so any valid frequency which is at least as quick as the task itself will do.

The third parameter to the function specifies the proportion of the frequency which must be pulsed high. Again, for this exercise, we don't need pulses to be generated but simply need a constant low or high signal. In this case, the PWM function can generate a low signal without pulses if the duty cycle is set to 0, and a high signal without pulses if the duty cycle is set to 1. Duty cycles of 0 and 1 exactly match the comparison value stp_adc_state.

The fourth parameter to the function specifies a phase offset that can be set for a given channel relative to other channels with the same frequency. In this case, just set this to zero.

The fifth and final parameter to the function specifies whether the channel given by the first parameter should be initialised or not. In this case, we'll need to drive A15, hence the FALSE value. We'll cover initialisation shortly.

We also need to initialise the library to drive pin A15, add the following code to the end of function psc_initialise_app().

(void) pdx_pwm_output(PIO_POT_A15, 1000, 0, 0, TRUE);

Most OpenECU hardware implements a switch to control whether an output driver can be turned on or not (although some do not, for instance, the M461). The switch can be used as a secondary system to prevent accidental changes to the output drivers. However, for the purposes of this exercise there is no need for this level of functionality, instead, we simply need to ensure that pin A15 can be driven. Add the following code to the end of function psc_initialise_app() if the ECU target supports the function (see pss_set_safety_switch()). for more).

pss_set_safety_switch(TRUE); 3.3.8. Summary so far

Having followed the instructions you will have a simple application which reads an analogue temperature sensor and turns on a lamp if the temperature exceeds a calibratable limit. Your code should now look something like the following.

#include "openecu.h"

#include "step1_m460_api.h"

static S16 stp_adc_raw; static F32 stp_adc_eng; static BOOL stp_adc_state;

static OE_CAL F32 stpc_adc_limit = 90.0;

static BOOL stp_adc_confirmed_raw_min_flt;

Copyright 2019, Pi Innovo 37 Quick start

static BOOL stp_adc_confirmed_raw_max_flt; static BOOL stp_adc_confirmed_slew_rate_flt; static BOOL stp_adc_confirmed_eng_min_flt; static BOOL stp_adc_confirmed_eng_max_flt; static BOOL stp_adc_transient_flt;

static OE_CAL F32 stpc_adc_min_raw_value = 90; static OE_CAL F32 stpc_adc_max_raw_value = 4000; static const S32 stp_adc_eng_lookup_axis_size = 6; static OE_CAL F32 stpc_adc_eng_lookup_x_axis[] = { 163, 917, 1671, 2424, 3178, 3932 }; static OE_CAL F32 stpc_adc_eng_lookup_z_data[] = { 135, 96, 74, 55, 20, -42 }; static OE_CAL F32 stpc_adc_min_eng_value = -40; static OE_CAL F32 stpc_adc_max_eng_value = 130; static OE_CAL F32 stpc_adc_leaky_bucket_rise_rate = 0.5; static OE_CAL F32 stpc_adc_leaky_bucket_fall_rate = 0.25; static OE_CAL F32 stpc_adc_leaky_bucket_flt_clear_level = 0.5; static OE_CAL F32 stpc_adc_default_output_value = 60; static OE_CAL F32 stpc_adc_max_slew_rate = 10000000;

static PUT_ANALOGUE_WORKSPACE_T stp_adc_process_analog_input_pai_wrk; static const PUT_ANALOGUE_CAL_DATA_T stp_adc_process_analog_input_pai_cal = { &stpc_adc_min_raw_value, &stpc_adc_max_raw_value, &stp_adc_eng_lookup_axis_size, stpc_adc_eng_lookup_x_axis, stpc_adc_eng_lookup_z_data, &stpc_adc_min_eng_value, &stpc_adc_max_eng_value, &stpc_adc_leaky_bucket_rise_rate, &stpc_adc_leaky_bucket_fall_rate, &stpc_adc_leaky_bucket_flt_clear_level, &stpc_adc_default_output_value, &stpc_adc_max_slew_rate };

void psc_initialise_app(void) { (void) pcx_config(PIO_CAN_A37_A36, PIO_CBAUD_500_KBPS); (void) pcx_config(PIO_CAN_C37_C36, PIO_CBAUD_500_KBPS);

(void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, TRUE);

put_process_analog_input_init(&stp_adc_process_analog_input_pai_wrk);

(void) pdx_pwm_output(PIO_POT_A15, 1000, 0, 0, TRUE);

pss_set_safety_switch(TRUE); }

void stp_task_100ms(void) { (void) pax_adc_input(PIO_AIN_A28, &stp_adc_raw, FALSE);

put_process_analog_input(stp_adc_raw, 0.1, &stp_adc_eng, &stp_adc_confirmed_raw_min_flt, &stp_adc_confirmed_raw_max_flt, &stp_adc_confirmed_slew_rate_flt, &stp_adc_confirmed_eng_min_flt, &stp_adc_confirmed_eng_max_flt, &stp_adc_transient_flt, &stp_adc_process_analog_input_pai_cal, &stp_adc_process_analog_input_pai_wrk);

stp_adc_state = (stp_adc_eng > stpc_adc_limit);

(void) pdx_pwm_output (PIO_POT_A15, 1000, stp_adc_state, 0, FALSE); }

void psc_background_app(void) { }

Copyright 2019, Pi Innovo 38 Quick start

Before we build the application and link it with the OpenECU library we need to specify how the library and application will work together. For instance, we need to tell the library that function stp_task_100ms must be called every 100 milliseconds. We do this by writing a data dictionary file and an interface specification file. 3.3.9. Create data dictionary and interface specification files

There are two aspects to linking an application with the OpenECU library:

Data dictionary file Used to explain the C variables that will be accessible by a calibration tool while the application is running on an ECU. For this exercise, we'll define data dictionary elements (DDEs) for most of the global variables in the code, so that, for instance, the processed temperature (stp_adc_eng) can be viewed in real-time.

Interface specification file Used to detail information about the application and how it will use the library. The interface specification file is converted into supporting C code to be built with the application and linked to the OpenECU library. For instance, one of the functions of the interface specification file is to declare the application tasks, which in this exercise, consists of stp_task_100ms called every 100 milliseconds.

Both the data dictionary file (or files) and the interface specification file are read by a tool which generates:

• Additional code files which must be linked with the application and OpenECU library to create a binary image to program an ECU with; and

• An ASAP2 file which can be read by a calibration tool to provide access to the application's C variables while the application runs on an ECU. 3.3.9.1. Review the data dictionary file

When the application was created during Section 3.3.2, “Create the application”, a complete data dictionary file was copied. Edit the file interface_specification\step1.dde in a text editor and you'll find it contains numerous lines including:

Name Units Class Accuracy Min Max Description

stp_adc_raw A/D counts d 1 0 4096 Temp. pin A28 as A/D...

Each line is either a comment line (starting with either “**” or “--”) or a line specifying data as a set of columns, each column separated by a single TAB character.

The column specification line consists of a set of named columns, each separated by a single TAB character. The columns can be re-arranged so long as Name remains the first.

The Name column gives the name of the C variable. In this case, stp_adc_raw refers to the C variable of the same name, the variable is used to store the A/D reading of pin A28.

The Units column gives the units to be applied to the value of stp_adc_raw. The units are displayed by calibration tools, but in general, are otherwise ignored by OpenECU and other tools.

The Class column gives the ASAP2 type used for the C variable. Here, the variable is a displayable, that is, something which is stored in RAM and writable by the application, so the class is set to d (for displayable).

Copyright 2019, Pi Innovo 39 Quick start

The Min and Max columns give the minimum and maximum range the C variable should contain. The range is loosely used by a few tools, but does not in any way restrict what the code can do. For instance, if the range is [0, 4096] but the code assigns value 10000 to the variable, then the variable will be written with 10000 and if the calibration tool is viewing the variable at the time, it may flag the variable as being out of range.

The other lines in the data dictionary file make up comments and other data definitions for both displayables (readable variables) and calibrations (writable variables declared volatile const).

More detailed information about the structure of the data dictionary file can be found in Section 4.6.3, “Data dictionary and engineering unit files”. 3.3.9.2. Review the interface specification file

When the application was created during Section 3.3.2, “Create the application”, a complete data dictionary file was copied. Edit the file interface_specification \step1_[target-ecu].capi in a text editor. The interface file contains various statements, some of which we'll take a closer look at.

target-ecu { hw-part-number = "01T-068144"; hw-issue-number = 1; hw-option = "000"; }

Specifies that the application will be run on an M460 Developer ECU Issue 1.

application { major-version = 1; minor-version = 0; subminor-version = 0;

description = "Step-1 example for the C-API."; copyright = "Copyright 2015, Pi Innovo"; name = "Step1 v%-major%.%ver-minor%.%ver-subminor%, %target%";

os-native { stack-size = 8192;

task { name = stp_task; priority = 1; period = 100; function = stp_task_100ms; } } }

Specifies version, name, description and copyright information which is embedded into the source code and is programmed onto the target ECU with the application. The information can be read out of the target ECU later.

In particular, note that the name statement can take tokens, single words starting and ending with the “%” character. See Section 7.1.4.8, “Compound statement: application” for a complete list of tokens.

Specifies the overall stack size to be allocated to the application and OpenECU library. A simple application like the one presented in this exercise typically uses less than 1KB of stack, the 5KB specified here could be reduced if necessary.

Specifies that one function called stp_task_100ms must be called every 100 milliseconds. That is sufficient for this exercise, but other tasks can be specified. When

Copyright 2019, Pi Innovo 40 Quick start

more than one task is specified, the relative priority of each dictates the running order of the functions (see Section 5.6.1.2, “Preemptive scheduling” for more details).

ccp-messaging { cro = 1785; dto = 1784; station-address = 0; can-bus = 0; baud = 500;

enabled-during-application-mode = true; }

Specifies the calibration communication protocol (CCP) parameters for communication between the calibration tool and application running on the target ECU. The values presented here are the default set that each target ECU is delivered with re- programmed. We'll see how to program an ECU in Section 3.3.11, “Program the ECU”.

ddes { include-dde-tabbed "../interface_specification/step1.dde";

generate-library-ddes = true; }

Specifies the data dictionary files which describe the application C variables of interest. 3.3.10. Building the application

The following sections detail how to build the application. Building the application can be done using either the Diab Compiler, or by using GCC. Please follow the steps relevant to your compiler. 3.3.10.1. Build the application using a Diab Compiler

The description that follows assumes the example is being built using the Wind River Diab compiler, v5.5.1.0. If you are using another supported compiler, you will need to select files or settings to match your target and compiler combination.

When the application was created during Section 3.3.2, “Create the application”, a simple batch file was copied. Edit the file build\build_[target-ecu]_diab_5_5_1_0.bat. Change the line:

SET OPENECU_DIAB=

to match the installed location of the compiler. The location must end in a trailing directory slash (the “\” character). For instance, if the compiler was installed at c:\diab \5.5.1.0\win32\bin, then the line should be set to:

SET OPENECU_DIAB=c:\diab\5.5.1.0\win32\bin\

Once edited, the build can be run by executing the batch file. The result of a successful build produces a number of files in the same directory as the build directory.

• step1_[target-ecu]_vision.a2l — the ATI Vision specific ASAP2 file for the build application; • step1_[target-ecu]_image_small.s37 — the image bytes to program into the OpenECU in Motorola S-record format (small representing the minimum amount of code and data bytes to program the OpenECU device) — suitable for the ATI Vision calibration tool.

Copyright 2019, Pi Innovo 41 Quick start

If the build fails for any reason, go back through the stages of the example and identify any corrections, or look at the installed and completed step1 application to identify any differences. 3.3.10.2. Build the application using the GCC Compiler

The description that follows assumes the example is being built using the GCC Compiler v4.7.3 that comes packaged in your OpenECU installation. Please see Section 2.1.5, “Third party tool requirements — compatibility” for a list of supported targets for GCC. If you are using another supported compiler, you will need to select files or settings to match your target and compiler combination.

When the application was created during Section 3.3.2, “Create the application”, a simple batch file was copied. Use the file build\build_[target-ecu]_gcc_4_7_3.bat.

The build can be run by executing the batch file. The result of a successful build produces a number of files in the same directory as the build directory.

• step1_[target-ecu]_vision.a2l — the ATI Vision specific ASAP2 file for the build application; • step1_[target-ecu]_image_small.s37 — the image bytes to program into the OpenECU in Motorola S-record format (small representing the minimum amount of code and data bytes to program the OpenECU device) — suitable for the ATI Vision calibration tool.

If the build fails for any reason, go back through the stages of the example and identify any corrections, or look at the installed and completed step1 application to identify any differences. 3.3.11. Program the ECU

The OpenECU is programmed with any CCP compliant tool. Specific instructions for ATI Vision, Vector CANape and ETAS INCA calibration tools are provided in Appendix C, Supporting tools.

At a minimum, the OpenECU device will need to be powered and be connected to the CCP tool over CAN as shown in the following diagram.

Copyright 2019, Pi Innovo 42 Quick start

FEPS 17-19V, 0V

IGN Power supply VPWR 12V DC OpenECU GND 0V

Calibration CAN0-L, CAN0-H CAN 2 Tool

M220 M460 CAN0-L CAN0-H Terminated? M221 M250 M461 M550 M670 M220 A43 A28 No FEPS A27 A27 A2 Y22 Y22 M250 A43 A28 No VPWR A2 A2 A20 Y3 Y3 M460 A37 A36 Yes GND A31 A31 C1 Y2 Y2 M461 A37 A36 Yes IGN - A26 A12 Y25 Y25 M550 Y11 Y12 Yes CAN0-L A43 A43 A37 Y11 Y11 M670 Y11 Y12 Yes CAN0-H A28 A28 A36 Y12 Y12 External CAN termination required on loom if CAN bus not terminated

Copyright 2019, Pi Innovo 43 Quick start

The OpenECU device can be programmed by following these steps:

1. Apply a positive FEPS voltage, as given in the following table and then power cycle the ECU (the FEPS signal may not be detected if applied simultaneously with the ECU power). Upon detecting the FEPS signal the ECU is placed into its reprogramming mode, where it does not run the application and responds only to reprogramming commands.

2. Program the ECU following the instructions in Appendix C, Supporting tools.

3. Once programmed, ground the FEPS pin and power cycle the ECU. This places the ECU in its application mode, where the ECU runs the programmed application.

Table 3.1. FEPS voltages

M220 M460 M461 M560 M580 M110 M221 M250 M670 Result 0V 0V 0V 0V FEPS pin is grounded. On power up, the ECU attempts to run the last programmed application in application mode. If a application has not been programmed, the ECU enters reprogramming mode. — > +36V > +13V > +17V FEPS pin is positive. On power up, the ECU enters reprogramming mode. If a application has previously been programmed, the ECU uses the CCP settings of the application. Otherwise, the ECU uses the default CCP settings. < -16V < -16V < -18V < -16V FEPS pin is negative. On power up, the ECU enters reprogramming mode. The ECU uses the default CCP settings and ignores any CCP settings stored in any programmed application. 3.3.12. Play with the application

Once programmed, ground the FEPS pin, power cycle the ECU, and the application will start. With your calibration tool, you will be able to view the stp_adc_raw and stp_adc_eng variables and see them vary as the voltage applied to pin A28 is varied.

Varying the voltage so stp_adc_eng exceeds the value for stpc_adc_limit (which defaults to 90°C) will cause the output driver for A15 to turn on and light the warning lamp.

Grounding the A28 pin will cause the application to determine there is a fault with the temperature sensor, and reported through the stp_adc_confirmed_raw_min_flt and/ or stp_adc_confirmed_eng_min_flt variables.

There are some automatically added data definitions you can view which provides some information about the application (you can find a complete list in Section 7.1.7, “Automatic ASAP2 entries”).

mpl_run_time A counter which the library increments every second the application is running. During reset, the counter is set to zero.

mpl_cpu_loaded The percentage of the CPU used during the last 50 milliseconds. Provides an indication of how hard the application is working.

Copyright 2019, Pi Innovo 44 Quick start

mpl_tt_stp_task The time in microseconds the step1 task took to run every 100 milliseconds.

Copyright 2019, Pi Innovo 45 Chapter 4. Software overview

4.1. Introduction ...... 46 4.2. System components ...... 46 4.3. System modes ...... 48 4.4. Boot mode ...... 48 4.5. Reprogramming mode ...... 49 4.6. Application mode ...... 54 4.6.1. Building an application ...... 55 4.6.2. Interface specification ...... 58 4.6.3. Data dictionary and engineering unit files ...... 58 4.6.4. Application and library tasks ...... 58 4.6.5. Library status and error handling ...... 61 4.6.6. Compiler library support ...... 61 4.6.7. Deprecated library features ...... 62 4.6.8. Examples ...... 62 4.1. Introduction 4.2. System components

In Figure 4.1, “System components”, each of the different system components is shown in relation to the others. Components in yellow are supplied by Pi, components in white are supplied by the customer.

Figure 4.1. System components

ECU

Bootloader

Library Reprogrammer Application Sensors / Actuators

Communication busses

Calibration Bus analysis Other bus tool tool(s) devices

An ECU is composed of the bootloader, the reprogrammer, the library and the application code.

Copyright 2019, Pi Innovo 46 Software overview

Bootloader The bootloader handles the ECU start-up and determines which system mode (Section 4.3, “System modes”) to enter. The bootloader component is programmed into the ECU when the ECU is manufactured.

Reprogrammer The reprogrammer handles requests to reprogram the application code using the CAN calibration protocol (see Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)”). The reprogrammer component is reprogrammed into the ECU before the ECU is manufactured.

Library The library provides start-up, communication, I/O and non-volatile memory functionality usable by the application code. The library component is linked with the application code before being programmed into the ECU.

Application The application uses the library to access the sensors and actuators, and to access other devices via communication buses.

The ECU comes in two types: fleet units and developer units. The main difference between the fleet unit and the developer unit, is that the developer has the capability to adjust calibrations while the application is running. Calibrations are essentially C variables and support is included for single calibrations through to 1d and 2d table calibrations.

Components external to the ECU include:

Sensors/actuators The application can read sensors and drive actuators through the ECU hardware using the library. The sensors and actuators need to match the electrical specification of the ECU (see Section A.1, “ECU hardware reference documentation” for details on each supported ECU).

Physical communication buses The application can receive and transmit messages on the communication buses using the library. Library support ranges from single messages to complete protocol handling (e.g., CCP or J1939).

Calibration tool A (usually) PC based tool which interacts with the ECU to read and modify variables while the application is running (modification of variables only supported on developer units). Appendix C, Supporting tools provides an overview of the supported calibration tools.

The calibration tool also has the ability to reprogram the application when the ECU is running the reprogrammer.

Bus analysis tool A (usually) PC based tool which can analyse the various messages and protocols on the bus, useful for diagnosis. Some tools also support transmission of messages to simulate other bus devices.

Other bus devices Usually smart sensors or actuators, possible other ECUs, all of which need to communicate between each other to achieve the system behaviour required.

Copyright 2019, Pi Innovo 47 Software overview

4.3. System modes

In Figure 4.2, “System modes”, each of the major system modes is shown. When the ECU is turned on (or is recovering from a powered reset), the bootloader decides which major mode to enter based on external inputs to the ECU.

Figure 4.2. System modes

Boot mode

Bootloader

Determine which mode to enter.

Library Reprogrammer Application

Reprogramming mode Application mode

Boot mode Boot mode starts after reset, performs some tests and, if successful, determines what mode to enter (see Section 4.4, “Boot mode”).

Reprogramming mode Reprogramming mode is entered if the FEPS pin is asserted before the ECU is powered up, if there is an invalid application image in memory, or for certain targets if the ECU is running the application and allowing reprogramming while a reprogramming request is received (FEPS-less) (see Section 4.5, “Reprogramming mode”).

Entering reprogramming mode causes the ECU to listen to the communication buses for reprogramming instructions. The ECU does not run the application.

Application mode Application mode is entered if the FEPS pin is not asserted and if there is a valid application image in memory (see Section 4.6, “Application mode”).

Entering application mode causes the ECU to run the application. The ECU listens to the communications buses for reprogramming instructions, but the application can inhibit reprogramming from occurring if necessary. 4.4. Boot mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader performs various tests. These include:

Copyright 2019, Pi Innovo 48 Software overview

• Tests on memory devices, looking for hard faults such as shorts on address lines, or memory locations which cannot hold their contents;

• Tests on the code to run, looking for hard faults in the contents of code and data;

• Tests on the frequency of reset, looking for unexpected resets which occur back to back in a short period of time.

If the tests fail then the bootloader will either reset or attempt to enter reprogramming mode, flashing a code to indicate the cause (see the technical specification for each ECU for details about code flashing). If the tests pass, then the bootloader will determine what mode to enter next (see Section 4.5, “Reprogramming mode” and Section 4.6, “Application mode” for details on how each mode is chosen). 4.5. Reprogramming mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader will enter reprogramming mode if the FEPS pin is asserted, if there is an invalid application image in memory, or for certain targets if the ECU is running the application and allowing reprogramming while a reprogramming request is received (FEPS-less).

In reprogramming mode, the ECU listens to the communications buses for instructions to reprogram. Specifically, the ECU listens for CCP commands using either the application CCP settings (if a valid application image is in memory) or the default CCP settings otherwise.

The OpenECU is programmed with any CCP compliant tool. Specific instructions for ATI Vision, Vector CANape and ETAS INCA calibration tools are provided in Appendix C, Supporting tools. If you have another CCP compliant tool, please refer to the manufacturer's instructions for further details in programming and refer to Appendix F, CCP compliance which details how OpenECU complies with the CCP 2.1 standard.

At a minimum, the OpenECU device will need to be powered and be connected to the CCP tool over CAN 0 or CAN A (whichever the target ECU makes available). In some cases the OpenECU module will need to have the FEPS line connected to a power supply capable of up to 19 volts (depending on target), as shown in the following diagram.

Note

The FEPS voltage must be asserted before the ECU is powered up. Powering the FEPS input and ECU simultaneously (i.e. shorting the FEPS and VPWR inputs) may result in reprogramming mode not being detected.

Copyright 2019, Pi Innovo 49 Software overview

FEPS 17-19V, 0V

IGN Power supply VPWR 12V DC OpenECU GND 0V

Calibration CAN0-L, CAN0-H CAN 2 Tool

M220 M460 CAN0-L CAN0-H Terminated? M221 M250 M461 M550 M670 M220 A43 A28 No FEPS A27 A27 A2 Y22 Y22 M250 A43 A28 No VPWR A2 A2 A20 Y3 Y3 M460 A37 A36 Yes GND A31 A31 C1 Y2 Y2 M461 A37 A36 Yes IGN - A26 A12 Y25 Y25 M550 Y11 Y12 Yes CAN0-L A43 A43 A37 Y11 Y11 M670 Y11 Y12 Yes CAN0-H A28 A28 A36 Y12 Y12 External CAN termination required on loom if CAN bus not terminated

Copyright 2019, Pi Innovo 50 Software overview

OpenECU operates in three system modes:

Boot mode This is the mode initiated when the ECU is turned on (or recovering from a powered reset). Boot mode choose whether to enter reprogramming mode or application mode.

Reprogramming mode This is the mode required to reprogram the OpenECU with the CCP tool. This mode is entered differently depending on the ECU. All OpenECU modules can be made to enter this mode by asserting the FEPS pin with a positive voltage (above the required threshold) and power cycling the OpenECU device.

Application mode This is the mode required to run the application on OpenECU. Start this mode by grounding the FEPS pin and power cycle the OpenECU device.

How reprogramming and application mode is entered differs slightly between groups of ECUs due to differences in the electronics. For the M220, M250, M460 and M461 targets, the next illustration shows how each mode is entered.

Figure 4.3. System modes for M220, M250, M460 and M461

ECU powers up; or ECU resets / Enter boot mode

Application checksum validates; and FEPS grounded / Enter application mode Boot mode

Application checksum invalid; or FEPS has pos or neg voltage / Enter reprogramming mode

Reprogramming Application mode mode Reprogramming request received; and application allows reprogramming; / Enter reprogramming mode

For the M221, M560, M680 and M670 targets, the next illustration shows how each mode is entered.

Copyright 2019, Pi Innovo 51 Software overview

Figure 4.4. System modes for M110, M221, M560, M680 and M670

ECU powers up (ignition or wake-on-CAN); or ECU resets / Enter boot mode

Application checksum validates; and FEPS grounded / Enter application mode Boot mode

Application checksum invalid; or FEPS has pos or neg voltage / Enter reprogramming mode

Reprogramming Application CAN messages time out time messages CAN / resets ECU mode mode Reprogramming request received; and application allows reprogramming; / Enter reprogramming mode

There are a number of ways in which an ECU can be reprogrammed:

Reprogramming — ECU not previously programmed Reprogramming the ECU without an application can be done with or without FEPS on the M110, M220, M221, M250, M460, M461, M560, M680 and M670.

Without a programmed application, reprogramming mode will use the default CCP settings as defined in Table 4.2, “CCP defaults”. As explained in the table, these settings will vary depending on the version of firmware that is programmed into the ECU.

Reprogramming without FEPS — ECU previously programmed (M110, M220, M221, M250, M460, M461, M560, M680 and M670 only) Once an M110, M220, M221, M250, M460, M461, M560, M680 or M670 ECU has been programmed with a valid application, that ECU can be reprogrammed without having to apply FEPS.

With a programmed application, reprogramming mode will use the CCP settings defined by the application already programmed. If an application with different CCP settings is programmed then the new CCP settings are used after the ECU is power cycled.

Reprogramming with FEPS — ECU previously programmed (M220, M221, M250, M460, M461, M560, M680 and M670 only) All OpenECU targets can be programmed by first applying FEPS and then cycling power to the ECU to enter reprogramming mode.

Furthermore, if the application is running and the application is not inhibiting programming then, without cycling power, the ECU can be programmed by applying FEPS and starting programming.

Copyright 2019, Pi Innovo 52 Software overview

With a programmed application, reprogramming mode will use the CCP settings defined by the application already programmed. If an application with different CCP settings is programmed then the new CCP settings are used after the ECU is power cycled.

Forced reprogramming with negative FEPS (M110, M220, M221, M250, M460, M461, M560, M680 and M670 only) The M220, M221, M250, M460, M461, M560, M680 and M670 ECUs can be made to use the default CCP settings instead of the application settings by applying a negative voltage to FEPS and then cycling power to the ECU. Reprogramming mode will then use the default settings for CCP.

The defined CCP settings are defined in Table 4.2, “CCP defaults”. As explained in the table, these settings will vary depending on the version of firmware that is programmed into the ECU.

Once programmed, an ECU will remain in reprogramming mode until the power is cycled. After the power cycle, the ECU will determine which mode to enter based on the FEPS voltage. To start the application after programming, ensure FEPS is grounded and power cycle the ECU.

The FEPS pin is asserted by applying a voltage to the pin. The required voltage varies between ECUs.

Table 4.1. FEPS voltages

M220 M460 M461 M560 M580 M110 M221 M250 M670 Result 0V 0V 0V 0V FEPS pin is grounded. On power up, the ECU attempts to run the last programmed application in application mode. If a application has not been programmed, the ECU enters reprogramming mode. — > +36V > +13V > +17V FEPS pin is positive. On power up, the ECU enters reprogramming mode. If a application has previously been programmed, the ECU uses the CCP settings of the application. Otherwise, the ECU uses the default CCP settings. < -16V < -16V < -18V < -16V FEPS pin is negative. On power up, the ECU enters reprogramming mode. The ECU uses the default CCP settings and ignores any CCP settings stored in any programmed application.

As a shortcut, FEPS may be applied while the model is running and, without power cycling the device, be reprogrammed via a CCP compliant tool. When reprogramming starts, the OpenECU device switches from application mode to reprogramming mode. It may be undesirable to allow this method due to safety reasons, so the pcp_inhibit_reprogramming() function can switch this method off.

If the OpenECU device has never been programmed before, it uses the CCP settings given in Table 4.2, “CCP defaults”. The CCP compliant tool must use the same settings. Once the OpenECU device has been reprogrammed with an application that uses different CCP settings, the CCP compliant tool must be changed to use these settings.

Copyright 2019, Pi Innovo 53 Software overview

Table 4.2. CCP defaults

CCP setting Default value CRO message identifier 1785 DTO message identifier 1784 Station identifier 0 CAN bus identifier CAN 0 CAN bus baud-rate 250kBps or 500kBps a a The default baud-rate for CCP will depend on which version of firmware was flashed into the ECU. All ECUs (such as M220-000 or M250-000) use 500 kBps default baud rate, except for the M461-000 which uses 250 kBps. Refer to Section 7.1.8, “OpenECU software versioning” for details. 4.6. Application mode

When the ECU is turned on (or is recovering from a powered reset), the bootloader will enter application mode if the FEPS pin is not asserted and if there is a valid application image in memory.

When application mode is entered, the library co-ordinates the sequence of initialisation as shown in Figure 4.5, “System initialisation”.

Figure 4.5. System initialisation

1

Bootloader

Bootloader determines to enter application mode

2 Library pre Reprogrammer initialisation

3 Application initialisation

4 Library post initialisation

5

Application run

Copyright 2019, Pi Innovo 54 Software overview

Perhaps the best way to understand how the different components of the OpenECU library interact with the application, is to look at how an application is built into a binary image for reprogramming, and into a data description file for calibration tools.

1. Bootloader — determine which major system mode to enter. When entering application mode, the bootloader changes program flow to the library pre-initialisation phase.

2. Library pre-initialisation — occurs after the bootloader has decided to enter the application mode. During pre-initialisation, the library configures the ECU's hardware in a largely generic way and initialises the C run-time environment.

Hardware configuration includes decoding the reason for reset (which can be inspected by the application by calling psc_decode_reset()).

Initialising the C run-time environment includes clearing C objects with no initialiser to zero, setting C objects with initialisers, and setting up the system stack. The system stack is explained in more detail in Section 5.6.1.3, “Stack sharing”. The size of used stack can be retrieved during application run by calling psc_get_used_stack_size().

3. Application initialisation — occurs after library pre-initialisation, this is the point in time when the application can initialise itself and declare information to the library for post initialisation.

The library invokes the application defined function psc_initialise_app() during application initialisation. The application can initialise any data structures necessary for the application to perform, as well as configuring some aspects of the library. For instance, during application initialisation, the application must declare CAN messages it will receive and transmit (e.g., see ???) or initialise ECU pins for use (e.g., see pdx_digital_output()).

4. Library post-initialisation — occurs after application initialisation to complete any hardware setup (especially any dependent on information declared during application initialisation) then starts the task scheduler.

Note

Typically, library and application initialisation are complete within a few hundred milliseconds of powering up the ECU. A rough guide to the boot time of the ECU can be retrieved by calling psc_decode_reset().

Once the scheduler has started, the application can perform its processing each time one of the application tasks runs.

5. Application run — occurs after library post-initialisation is complete. During application run, both application and library tasks are scheduled in a fixed-priority scheme (see Section 5.6, “Task scheduling (PKN)” for details about task scheduling). 4.6.1. Building an application

With application source code, interface specification and data dictionary files in place, the application can be built and linked with the OpenECU and compiler libraries to generate a binary image which can be programmed and run on an OpenECU. Figure 4.6, “Building an application (in outline)” shows in outline how a build is achieved.

Copyright 2019, Pi Innovo 55 Software overview

Figure 4.6. Building an application (in outline)

Inputs from application Inputs from elsewhere

Data Interface Application OpenECU dictionary description source library files file code file

Compiler 1 library files

Linker Interface script source files code

2

Object files

Intermediate build steps build Intermediate 3

ELF or ELF MAP file file

5 4

Target Target ASAP2 image file file

Final outputs from build process

The build process has a number of inputs:

Data dictionary files The data dictionary files describe the data variables of the application code. Data variables are all C global variables, either RAM or ROM based. For each data variable which must be accessible from the calibration tool, there is a corresponding data dictionary element (DDE) which details attributes of the data variable, like description, type, units, and so on. See Section 4.6.3, “Data dictionary and engineering unit files” and Section 7.1.5, “DDE specification” for more.

Interface description file The OpenECU library has a number of function interfaces and data interfaces. The data interfaces are largely exposed so that the build application can closely control the amount of memory the library uses.

Copyright 2019, Pi Innovo 56 Software overview

Some of the data interfaces are hard to write and maintain by hand, so there is an interface tool which will read an interface description file and generate the data interface code. See Section 4.6.2, “Interface specification” and Section 7.1, “Interface and DDE tool” for more.

Application source code Source code for the application.

OpenECU library file A compiler specific library file for OpenECU. The library file is linked with the application object files to create a binary image for execution on the target.

There is a library file for each target and compiler supported by OpenECU. It is important to link the correct library to match the compiler and target, otherwise the ECU may not operate correctly (see Section 5.1.2, “File locations”).

Compiler library file The compiler's own support libraries (e.g., implementation of the C standard library or compiler specific extensions). See Section 4.6.6, “Compiler library support” for more.

Linker script files The scripts tell the compiler how to combine the application object files, interface object files and libraries to create the binary image to run on the target ECU. This includes details about the layout of memory and how object file sections are allocated to memory.

The inputs are processed in a number of steps to create intermediate objects:

1. Runs the interface tool to generate information about the target and DDEs used in step 5, and to generate the data and task interface code between the application and library.

2. Runs the compiler for the interface code and application code files. The compiler generates object files used in the link stage.

3. Runs the linker to combine the object files from the application and interface tool, as well as the compiler's library and OpenECU libraries, to generate an ELF file.

4. Runs support tools and scripts to extract a binary image of the application from the ELF file. At this stage, the binary image is modified with check- sums and auxiliary data to support robust operation on the ECU. See Section 7.2, “Supporting build scripts” for details.

5. Runs a support tool to extract information from the ELF file (optional). Then runs the interface tool again to generate an ASAP2 file from the target and DDE information from the interface specification. The ASAP2 file is used during reprogramming and calibration of the ECU.

From those intermediate steps, the final set of objects are created:

Target ASAP2 file An ASAP2 file details the memory areas used by the binary application image as well as how DDEs have been allocated to memory. The ASAP2 file is used by PC based tools to reprogram an ECU or to calibrate an ECU. See Appendix C, Supporting tools for more.

Copyright 2019, Pi Innovo 57 Software overview

Target image file The target image file contains the binary image of the application code and data. Once an ECU is programmed with the image file, the application can be executed. See Appendix C, Supporting tools for more.

The C-API examples supplied with OpenECU show how each of these stages can be implemented in a simple fashion using batch files (see Section 4.6.8.1, “Building the examples”). These are the minimum steps required to build and can be copied if required. But an application may have additional stages to implement and there is no reason why a more sophisticated system (like make or SCons for example) might not be used. 4.6.2. Interface specification

As described already, the library has both data and function parts to its API. Some of the data components are hard to write and maintain by hand and so there is an interface tool which takes a simple description of the interface between the application and library, and generates the data components as required. This helps simplify the coding required to link the application and library together.

The interface tool and format of the interface specification file is given in detail in Section 7.1, “Interface and DDE tool”.

The interface specification also specifies the data dictionaries used to describe application data variables. 4.6.3. Data dictionary and engineering unit files

The OpenECU library can interact with calibration tools to read and write application data while the application is executing on the target. To support the interface between the calibration tool and the application, a data description file is required so the calibration tool understands how the application memory is laid out.

To support the interaction between the calibration tool and application, the interface tool can read a description of the application data and generate the data description file for the calibration tool. The application data is described in a set of data dictionary files explained in more detail in Section 7.1.5, “DDE specification” and the resulting data description file used by the calibration tool can also be used for reprogramming the ECU. 4.6.4. Application and library tasks

The framework of OpenECU requires application processing to occur in one or more tasks. These tasks are declared in the interface specification file, each declaring an application function to call and a priority to schedule the task relative to others.

In order to support the services provided by the library (e.g., J1939 messaging), the library defines a number of auxiliary tasks. These tasks have a unique priority relative to each other and the application tasks, as shown in Table 4.3, “Library and application tasks”.

Table 4.3. Library and application tasks

Priority Task Trigger Targets Description 18+n Module 10ms M220, Handles protection mechanisms to protection periodic M221, avoid ECU damage. task M250, M460, M461, M560, M680 and M670

Copyright 2019, Pi Innovo 58 Software overview

Priority Task Trigger Targets Description 17+n TPU task Sporadic M220, Handles the event processing required M221, of the TPU peripheral on some ECUs. M250, M560, M680 and M670 16+n Power 100ms M221, Handles the power hold processing on managementperiodic M560, some ECUs. task M680 and M670 15+n Flash code 100ms M220, Handles the Flash code output pin on task periodic M221, some ECUs. M250, M460, M461, M560, M680 and M670 14+n High-Side 100ms M560, Handles the high side output pin(s) on ASIC task periodic M680 and some ECUs. M670 13+n SPI Sporadic M220, Handles SPI messaging between messaging M221, peripherals on-board the ECU. task M250, M460, M461, M560, M680 and M670 12+n CAN 2ms All Handles CAN messaging. messaging periodic (event) task burst 11+n J1939 5ms All Handles J1939 messaging. messaging periodic task 10+n PFF task 10ms All Handles freeze frame processing. periodic 9+n PFS task 10ms All Handles non-volatile filesystem. periodic 8+n PISO 5ms All Handles ISO-15765 messaging. messaging periodic task 7+n PDG 10ms All Handles ISO-15765 based diagnostics messaging periodic messaging. task 6..6+n Application Periodic All Handles application processing. tasks 5 PDTC task 100ms All Handles diagnostic trouble code processing.

Copyright 2019, Pi Innovo 59 Software overview

Priority Task Trigger Targets Description 4 CAN 2ms All Handles CAN messaging. messaging periodic task burst 3 SPI task 1000ms M220, Handles SPI messaging utility periodic M221, functions. M250, M460, M461, M560, M680 and M670 2 Watchdog 200ms All Handles the processor watchdog. task periodic 1 CCP task 5ms All Handles the CAN Calibration Protocol periodic messaging to and from the calibration tool.

Tasks can have different triggers. Triggers make the task become ready to run. The highest priority task ready to run is given the CPU.

Sporadic The task becomes ready to run based on an event. The event is generally not periodic, but may be periodic under some conditions.

TDC firing The task becomes ready to run based on the angle of the engine relative to each cylinder. See Section 5.23, “Angular function feature (PAN)” for more about supported engine functionality.

Periodic The task becomes ready to run on a periodic basis.

Periodic (burst) The task becomes ready to run based on an event. Once ready, the task becomes periodic for a number of iterations, before stopping and waiting for another event.

Note

The scheduler deals with both application and library tasks. It is possible for a high priority application task to use the processor for as long as it needs and there is no protection offered by the library to prevent tasks from using up more processor time than they should.

The application tasks are scheduled to relative to the library tasks such that a long running task may cause a lower priority library task to become unduly delayed.

An example of this would be the CCP task which runs every 5ms. It is conceivable that an application task may take longer than 5ms to complete and that is a desirable property of the application. However, when the application task takes longer than 5ms, the CCP task becomes delayed by the application task.

The design of the library tries to mitigate the consequences of delayed library tasks. Delaying the library CCP task may cause a burst of DAQ messages to the calibration tool to become delayed and the calibration tool may complain, but delaying the CCP task will not cause the I/O functionality to become delayed or mis-behave.

Copyright 2019, Pi Innovo 60 Software overview

However, mitigation is all that the library can achieve if the application uses large amounts of the processor, and, for this reason the design of the application must take this into account by keeping the application tasks short. For instance, by splitting long running tasks up into discrete parts which are scheduled on successive task invocations.

See the API documentation for the scheduler feature for more (Section 5.6, “Task scheduling (PKN)”).

4.6.5. Library status and error handling

As the application performs work, it may call the library to access the hardware or perform a function. Depending on the current state of the ECU or the data passed to the library function, the library may or may not be able to perform as required. The library employs two mechanisms to report status and error information when interacting with the application.

Function return values In this case, the function returns an value which indicates the success or not of the call. The application can read the return value and made decisions based on the status of the function.

System feature In this case, the function calls the system feature (see Section 5.2, “System feature (PSY)”) to record that an error has occurred. The system feature records these errors and makes them available to the application via psy_get_error()).

The error handling mechanisms are not mutually exclusive — a function may return a status value and raise an error in the system log. For each library function, the documentation in the sub-sections of Chapter 5, Library interface detail how a function handles errors.

Note

Error checking within the library is not comprehensive, based largely on a design decision to keep the library small and efficient. It is possible to setup or pass invalid data to the library and the library will not raise an error. This is especially true of pointer based function arguments or of build time data structures.

It is the responsibility of the application to interact with the library API correctly.

4.6.6. Compiler library support

The compiler library implements the C standard library as well as any additional functions and data the compiler may require. The OpenECU library relies on some of the standard C library functions and therefore the C library must be included in a build.

OpenECU does the least necessary to make the compiler library work for the functions OpenECU requires. Any additional setup, for instance, to allow memory allocation to work via malloc() and free(), must be performed by the application.

Note

Most compilers supply their implementation of the C standard library as a set of object files. See the compiler documentation for a list of library names.

Copyright 2019, Pi Innovo 61 Software overview

4.6.7. Deprecated library features

To allow for change in the library, some API features can become marked as deprecated. API features become deprecated when newer features replace older features, or because a change in API naming makes the API more consistent. For instance, when the library is updated to automatically perform a function that the application was required to perform then that function will become marked as deprecated.

As well as being marked deprecated in the documentation, the library header files mark deprecated functions by wrapping them in pre-processor conditional statements. For instance, the API function pss_set_switch() was deprecated (replaced by function pss_set_safety_switch()) and declared in the library header files as:

#if !defined(CFG_DONT_USE_DEPRECATED) /* Deprecated, see pss_set_safety_switch(). */ extern void pss_set_switch ( BOOL pssf_enable ); #else #define pss_set_switch(pssf_enable) pss_set_switch_is_deprecated_see_user_guide() #endif

By defining the CFG_DONT_USE_DEPRECATED macro in the compile command, the compiler pre-processor will replace deprecated API functions with functions which do not exist in the library resulting in a build which does not link. For instance, using the example above, calling pss_set_switch() results in the Diab linker generating the following error:

dld: warning: Undefined symbol 'pss_set_switch_is_deprecated_see_user_guide' in file '[file-name].o' dld: error: Undefined symbols found - no output written

4.6.8. Examples

As part of the install process, a number of examples which use the library are installed, ready to be built.

[install location]\examples\c_api\angular_demo Demonstrates how to use the angular feature for engine control described in Section 5.23, “Angular function feature (PAN)”, including crank and cam trigger wheel configuration, angle based task triggering, and injection and coil pulse generation.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\can_demo Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify CAN buses and baud rates when calling the library.

Demonstrates how to use the CAN feature described in Section 5.15, “CAN messaging feature (PCX)” to receive and transmit CAN messages, unpack and pack data into messages, and monitor the CAN bus status.

Demonstrates how to use the J1939 feature described in Section 5.17, “J1939 (SAE) messaging feature (PJ1939)” to receive and transmit J1939 messages, unpack and pack data into messages and manipulate diagnostic trouble codes (DTCs).

See the example's read-me.txt file for further details.

Copyright 2019, Pi Innovo 62 Software overview

[install location]\examples\c_api\hbridge_demo Demonstrates how to drive the hbridge outputs by using the digital input/ output feature described in Section 5.10, “Digital input/output feature (PDX)”.

Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify input and output channels when calling the library.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\io_demo Demonstrates how to use the input and output configuration feature described in Section 5.7, “Library input and output configuration (PIO)” to specify input and output channels when calling the library.

Demonstrates how to use the analogue input/output feature described in Section 5.9, “Analogue input/output feature (PAX)” to read and process analogue inputs.

Demonstrates how to use the digital input/output feature described in Section 5.10, “Digital input/output feature (PDX)” to read and drive various signal types.

Demonstrates how to use the safety switch feature described in Section 5.12, “Output driver control feature (PSS)” to control whether the output drivers are enabled or not.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\nvm_util_demo Demonstrates how to use the non-volatile memory feature described in Section 5.19, “Adaptive non-volatile memory feature (PNV)” to store and recall information from non-volatile memory, such as array updates and adaptive table lookup and interpolations.

See the example's read-me.txt file for further details.

[install location]\examples\c_api\step1_completed Demonstrates a simple application which reads an analogue input and if it is above a calibratable threshold, turns on a digital output. This is the completed application from Chapter 3, Quick start.

[install location]\examples\c_api\step1_quick_start A copy of the step1 completed example, used in Chapter 3, Quick start to familiarise new users with the C-API.

[install location]\examples\c_api\util_demo Demonstrates how to use the utility feature described in Section 5.22, “General utilities feature (PUT)” perform auxiliary functions, such as table lookup with interpolation and digital input debounce.

See the example's read-me.txt file for further details.

Each example has the same directory layout. The directories store different types of files and includes a simple batch file to build the example.

build\* Contains a simple batch file for each supported compiler on a given target. See Section 4.6.8.1, “Building the examples” for further details.

Copyright 2019, Pi Innovo 63 Software overview

interface_specification\* Contains the interface specification and DDEs for the application. The interface specification is processed by the build batch files as described in Section 4.6.1, “Building an application”.

loom_specification\* Contains a bitmap diagram showing how a target ECU should be connected to power, the calibration tool and any other additional equipment for the example to work.

src\* Contains the source files for the application. The source files processed by the build batch files as described in Section 4.6.1, “Building an application”. 4.6.8.1. Building the examples

Each of the examples comes with a batch file which builds the example for a given compiler and target ECU. The batch files are kept as simple as possible to help understand the sequence of commands which goes into building an application.

To build an example using the GCC compiler, no edits are required in the batch file in order to run.

To build an example using the Diab compiler, locate and edit the appropriate batch file (based on Diab compiler and target ECU required). Check the following environment variable at the start of the batch file points to your compiler version, change the path if necessary, then run the batch file from the command line.

OPENECU_DIAB The path to the Diab compiler tool as stored on the build machine, e.g., [diab install location]\diab\5.5.1.0\win32\bin\. The environment variable must end with a directory slash.

The environment variable can be a path to the Diab compiler or a reference to another environment variable, e.g., %OPENECU_DIAB_5_8%. See section Section 2.5.9, “Wind River (Diab) C Compiler v5.8.0.0” for a description of the OPENECU_DIAB_5_8 environment variable.

For instance, to build the step1 completed example for an M220 ECU using Diab 5.5.1.0, at the command prompt, issue the following commands:

cd [install location]\examples\c_api

cd step1_completed\build

build_m220_diab_5_5_1_0.bat

Copyright 2019, Pi Innovo 64 Chapter 5. Library interface

5.1. Introduction ...... 67 5.1.1. Name-spaces, naming conventions and library composition ...... 67 5.1.2. File locations ...... 68 5.1.3. Layout of each feature section ...... 69 5.1.4. Notations ...... 69 5.2. System feature (PSY) ...... 70 5.2.1. Overview ...... 70 5.2.2. System types ...... 70 5.2.3. Error log ...... 70 5.2.4. Interface index ...... 71 5.2.5. Interface detail ...... 75 5.3. System start-up and background processing (PSC) ...... 84 5.3.1. Overview ...... 84 5.3.2. Interface index ...... 87 5.3.3. Interface detail ...... 90 5.4. ECU registry information (PREG) ...... 109 5.4.1. Overview ...... 109 5.4.2. Interface index ...... 110 5.4.3. Interface detail ...... 111 5.5. System timing feature (PTM) ...... 118 5.5.1. Overview ...... 118 5.5.2. Interface index ...... 118 5.5.3. Interface detail ...... 119 5.6. Task scheduling (PKN) ...... 124 5.6.1. Tasking model ...... 125 5.6.2. Interface index ...... 129 5.6.3. Interface detail ...... 130 5.7. Library input and output configuration (PIO) ...... 137 5.7.1. Overview ...... 137 5.8. Feature for specific target configuration (PCFG) ...... 138 5.8.1. Overview ...... 138 5.8.2. M110, M220 and M461 targets ...... 139 5.8.3. M250 target ...... 139 5.8.4. M460 target ...... 139 5.8.5. M670 target ...... 139 5.8.6. Interface index ...... 139 5.8.7. Interface detail ...... 140 5.9. Analogue input/output feature (PAX) ...... 147 5.9.1. Overview ...... 147 5.9.2. Interface index ...... 151 5.9.3. Interface detail ...... 152 5.10. Digital input/output feature (PDX) ...... 160 5.10.1. Overview ...... 160 5.10.2. Interface index ...... 169 5.10.3. Interface detail ...... 171 5.11. Digital data feature (PDD) ...... 197 5.11.1. Overview ...... 197 5.11.2. Interface index ...... 197 5.11.3. Interface detail ...... 198 5.12. Output driver control feature (PSS) ...... 200 5.12.1. Overview ...... 200 5.12.2. M220 target ...... 201 5.12.3. M250 target ...... 201 5.12.4. M460 target ...... 202 5.12.5. M461 target ...... 203

Copyright 2019, Pi Innovo 65 Library interface

5.12.6. M670 target ...... 203 5.12.7. Interface index ...... 203 5.12.8. Interface detail ...... 204 5.13. Serial peripheral feature (PSP) ...... 205 5.13.1. Overview ...... 205 5.13.2. Input and output processing ...... 205 5.13.3. Interface index ...... 206 5.13.4. Interface detail ...... 206 5.14. CJ125 device driver for UEGO measurement feature (PCJ125) ...... 207 5.14.1. Overview ...... 207 5.14.2. Initialisation ...... 207 5.14.3. Diagnostics ...... 207 5.14.4. Interface index ...... 207 5.14.5. Interface detail ...... 208 5.15. CAN messaging feature (PCX) ...... 210 5.15.1. Overview ...... 210 5.15.2. Initialisation ...... 210 5.15.3. Receiving messages ...... 210 5.15.4. Transmitting messages ...... 211 5.15.5. CAN status ...... 212 5.15.6. CAN buses ...... 212 5.15.7. Build time buffer sizing ...... 212 5.15.8. Library tasks ...... 212 5.15.9. Interface index ...... 212 5.15.10. Interface detail ...... 213 5.16. CAN Calibration Protocol (CCP) messaging feature (PCP) ...... 224 5.16.1. Overview ...... 224 5.16.2. Interface index ...... 229 5.16.3. Interface detail ...... 230 5.17. J1939 (SAE) messaging feature (PJ1939) ...... 235 5.17.1. Overview ...... 235 5.17.2. Node addressing ...... 235 5.17.3. Messaging ...... 236 5.17.4. Message bit and byte numbering ...... 237 5.17.5. PGNs ...... 238 5.17.6. Receive messages ...... 238 5.17.7. Transmit messages ...... 239 5.17.8. Core Diagnostic messages ...... 239 5.17.9. Build time buffer sizing ...... 239 5.17.10. Library tasks ...... 240 5.17.11. Interface index ...... 240 5.17.12. Interface detail ...... 245 5.18. Diagnostic Trouble Code (DTC) feature (PDTC) ...... 280 5.18.1. Overview ...... 280 5.18.2. Diagnostic trouble codes — generic ...... 281 5.18.3. Diagnostic trouble codes — J1939 ...... 281 5.18.4. Storage of data across power cycles ...... 282 5.18.5. Build time buffer sizing ...... 282 5.18.6. Interface index ...... 283 5.18.7. Interface detail ...... 284 5.19. Adaptive non-volatile memory feature (PNV) ...... 293 5.19.1. Overview ...... 293 5.19.2. Storage of data across power cycles ...... 295 5.19.3. Interface index ...... 296 5.19.4. Interface detail ...... 298 5.20. Non-volatile Filesystem feature (PFS) ...... 307 5.20.1. Overview ...... 307 5.20.2. Interface index ...... 308

Copyright 2019, Pi Innovo 66 Library interface

5.20.3. Interface detail ...... 310 5.21. On-board external flash (PEF) ...... 320 5.21.1. Overview ...... 320 5.21.2. Interface index ...... 321 5.21.3. Interface detail ...... 321 5.22. General utilities feature (PUT) ...... 326 5.22.1. Overview ...... 326 5.22.2. Interface index ...... 328 5.22.3. Interface detail ...... 331 5.23. Angular function feature (PAN) ...... 366 5.23.1. Overview ...... 366 5.23.2. Interface index ...... 379 5.23.3. Interface detail ...... 384 5.24. Waveform properties (PROP) ...... 438 5.24.1. Overview ...... 438 5.24.2. Interface index ...... 438 5.24.3. Interface detail ...... 439 5.1. Introduction 5.1.1. Name-spaces, naming conventions and library composition

Based on the C language, there are a limited number of global name-spaces for identifiers. To avoid clashes with application identifiers which share the same global name-spaces, the library uses a standard naming convention (covered in detail in Section 7.1.5.2, “DDE naming rules (prefix_style)”).

In short, the library uses a 3, 4 or 5 character prefix for all function and data identifiers. Each prefix identifies an area of functionality that the library covers, e.g., PDX for digital I/O or PJ1939 for J1939 messaging. This prefix scheme is similar to the DDE naming scheme covered in Section 7.1.5.2, “DDE naming rules (prefix_style)”.

The current composition of functionality is broken down into a set of features, each with a unique prefix, as shown in Table 5.1, “Library composition”.

Table 5.1. Library composition

Prefix Description Public PSY System feature — definition of integer types and system error logging. PSC System start-up and background processing — handles hardware and library pre and post initialisation, starting application run and implementing the background processing function. PREG ECU registry information — handles retrieval of data specific to the ECU, such as date of manufacturing or the serial number. PTM System timing — provides access to second, millisecond and microsecond timers. PKN Task scheduling — schedules library and application tasks in a fixed pre- emptive fashion. PIO Library input and output configuration — provides macros for logical channels for each type of input and output, macros for supported CAN buses and baud rates, and so on.

Copyright 2019, Pi Innovo 67 Library interface

Prefix Description PCFG ECU specific configuration — provides functions specific to some ECUs for utilising functionality not available on other ECUs. PAX Analogue input and output — provides access to analogue based input and output signals (e.g., analogue inputs and constant current outputs). PDX Digital input and output — provides access to digital based input and output signals (e.g., frequency inputs and stepper motor outputs). PDD Digital data — provides access to digital data based signals PAN Angular input and output — provides access to crank, cam, ignition and injector functionality. PSS Output driver control and diagnostics — provides access to the overall output driver switch. PCX CAN messaging — provides access to receive and transmit CAN messages on a periodic basis, and some utility functions to pack and unpack data in messages. PCP CAN calibration protocol messaging — provides basic access to the underlying CCP implementation for interaction with reprogramming and calibration tools. PJ1939 SAE J1939 messaging — provides access to receive and transmit J1939 messages on a periodic basis, handling the transport protocol and address claim negotiations. PDTC Diagnostic trouble codes — handles a simplistic model of diagnostic trouble codes for J1939 messaging. PPR In-Use Performance Ratio (IUPR) calculation — Tracks IUPR and other related information for Diagnostic Test Entities (DTEs)belonging to Diagnostic Monitor Entities (DMEs) and makes them available to report over ISO and J1939 protocols. PNV Non-volatile and adaptive memory — handles storage of data parameters across power cycles and provides some utility functions for adaptive data and maps. PFS Non-volatile filesystem — handles underlying storage of both library and application-specific data in flash memory on supported targets. PEF External flash — handles access to serial flash fitted to some ECUs. PCJ125 CJ125 lambda sensor ASIC — handles access to this device on some ECUs. PNTK NTK lambda sensor ASIC — handles access to this device on some ECUs. PUT General utilities — provides a set of functions for performing some typical functions on an ECU, e.g., table look-up and interpolation. Private Numerous other features are used by the library internally and are not exposed through the C-API. 5.1.2. File locations

The library is provided as a set of C include files and a library object file to be linked with the final application. There is a library object for each target and each compiler supported for that target. These files are located relative to the install location of OpenECU.

Copyright 2019, Pi Innovo 68 Library interface

[install location]\targets \[ecu]\[ecu]_[option]\[processor]_lib\include\*.h Location of library include files.

[install location]\targets \[ecu]\[ecu]_[option]\[processor]_lib\*.a Location of library object files, one for each supported compiler.

where: [install location] refers to the install location of OpenECU; [ecu] refers to the target ECU for the application; [option] refers to the specific ECU option for the application; and [processor] refers to the ECU's target processor (some ECUs have more than one processor populated).

For instance, when building for a M250 target ECU using Diab v5.5.1.0, the library header files and library object file are located at:

[install location]\targets\m250\m250_000\mpc5534_lib\include\*.h [install location]\targets\m250\m250_000\mpc5534_lib\platform_diab_5_5_1_0.a

When compiling with GCC specifically, the libary object files will not follow the same naming convention mentioned above. Since GCC does not support non-VLE code, the platform is rebuilt, using Diab v5.9 but using non-VLE compiler options. Therefore the library object files are not named using the GCC compiler, but rather with the Diab Compiler (with no_vle specified). The library header files and library object files are located at:

[install location]\targets\m250\m250_000\mpc5534_lib\include\*.h [install location]\targets\m250\m250_000\mpc5534_lib\platform_no_vle_diab_5_5_1_0.a

5.1.3. Layout of each feature section

Each feature is detailed in a separate section from other features. Each feature section is broken down as follows:

Overview section The overview section explains the feature functionality with enough detail to understand what the feature can achieve and how to interface with it at the function level.

Feature index section The feature index section provides a table of macros, enums, structs, typedefs, variables and functions exposed by the feature, along with a summary of the object's description. Each object is linked to the object's detail given in the feature detail section.

Feature detail section The feature detail section provides a series of sub-sections, one for each of macros, types, variables and functions. Each sub-section describes the object is detail, linking to related objects as necessary.

The C object names (for macros, typedefs, variables and so on) are fully linked, allowing for quick browsing. 5.1.4. Notations 5.1.4.1. Range notation

Some function parameters and variables have a valid numerical range or size of array. If so, the range and size information is given beside the object's description using internal notation.

Copyright 2019, Pi Innovo 69 Library interface

Table 5.2. Interval notation

Notation Range (x, y) x < value < y [x, y) x <= value < y (x, y] x < value <= y [x, y] x <= value <= y

Some objects are not clipped to a range but folded into a range using modulo arithmetic and where this occurs, the description includes details. 5.1.4.2. Fixed point notation

Some function parameters and variables are represented using fixed point numbers rather than floating point numbers. A fixed point number has a fixed number of digits after the radix point (e.g., after the decimal point '.' in floating point decimal notation) in a given base.

Fixed point numbers are expressed as @ fraction units per LSB in the documentation. For instance, the notation @ 0.5 °C per LSB means the least significant bit of the fixed point number represents 0.5 °C. Hence, the value 1 represents 0.5 °C, value 2 represents 1 °C, value 3 represent 1.5 °C and so on. 5.2. System feature (PSY) 5.2.1. Overview

The system feature (PSY) provides the base set of types for the library and a simple logging mechanism for recording conditions that the library believes to be in error. 5.2.2. System types

The library types (BOOL, S8, U8, S16, U16, S32, U32, U64, F32, F64) are to be used when interfacing with the library. Whether that be parameter types, return types, or member types of structures. Each represents an integer or floating point type of a minimum bit width (but the actual underlying type may implement a larger bit width).

The library also defines the NULL, pointer, as well as the TRUE, and FALSE booleans as macros, if those macros have not already been defined. 5.2.3. Error log

As described in Section 4.6.5, “Library status and error handling”, the library records some errors in a log. The system feature gives access to the log for debugging purposes. The log consists of a fixed size array, where each element stores a reference to the feature which raised the error and a code for the error. Once the log is full, further errors raised by the library are discarded.

The feature reference matches one of the feature macros (e.g., PSY_PAX for the analogue input/output feature). The code for an error matches one of the corresponding feature's Pxxx_ERROR_CODE_T enumeration (e.g., PAX_ERROR_CODE_T).

The application can access elements of the log through the psy_get_error() function. The number of reported errors can be determined by calling psy_get_num_errors().

Copyright 2019, Pi Innovo 70 Library interface

5.2.4. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and psy.h Macros PSY_MAX_NUM_STORED_ERRORS

The maximum number of different errors that are simultaneously stored. PSY_PBT

This is the error log identifier for the PBT (boot) feature. PSY_PSY

This is the error log identifier for the PSY (system) feature. PSY_PTPU

This is the error log identifier for the PTPU (TPU or eTPU) feature. PSY_PSC

This is the error log identifier for the PSC (startup and idle) feature. PSY_PAX

This is the error log identifier for the PAX (analogue I/ O) feature. PSY_PCX

This is the error log identifier for the PCX (CAN messaging) feature. PSY_PDX

This is the error log identifier for the PDX (digital I/O) feature. PSY_PUT

This is the error log identifier for the PUT (general utility) feature. PSY_PSP

This is the error log identifier for the PSP (SPI messaging) feature. PSY_PNV

This is the error log identifier for the PNV (adaptive non-volatile) feature. PSY_PRS

Copyright 2019, Pi Innovo 71 Library interface

Type Identifier This is the error log identifier for the PRS (RS232) feature. PSY_PCP

This is the error log identifier for the PCP (CCP scheduling) feature. PSY_PKN

This is the error log identifier for the PKN (scheduler) feature. PSY_PMIOS

This is the error log identifier for the PMIOS (MIOS or eMIOS) feature. PSY_PFL

This is the error log identifier for the PFL (Flash memory) feature. PSY_PCCP

This is the error log identifier for the PCCP (CCP messaging) feature. PSY_PQADC

This is the error log identifier for the PQADC (QADC or eQADC) feature. PSY_PDTC

This is the error log identifier for the PDTC (diagnostic trouble code) feature. PSY_PJ1939

This is the error log identifier for the PJ1939 (SAE J1939 messaging) feature. PSY_PSPI

This is the error log identifier for the PSPI (SPI messaging) feature. PSY_PDG

This is the error log identifier for the PDG (ISO diagnostics) feature. PSY_PFF

This is the error log identifier for the PFF (freeze frame) feature. PSY_PEM

This is the error log identifier for the PEM (emulutor and memory) feature. PSY_PFS

Copyright 2019, Pi Innovo 72 Library interface

Type Identifier This is the error log identifier for the PFS (filesystem) feature. PSY_PROP

This is the error log identifier for the waveform properties (PROP) feature. PSY_PDD

This is the error log identifier for the PDD (digital data) feature. PSY_PAN

This is the error log identifier for the PAN (angular) feature. PSY_PPP

This is the error log identifier for the PPP (Tunes) feature. PSY_PPM

This is the error log identifier for the PPM (power management) feature. PSY_PSS

This is the error log identifier for the PSS (system safety) feature. PSY_PFC

This is the error log identifier for the PFC (flash code) feature. PSY_PXS

This is the error log identifier for the PXS (extreme switch) feature. PSY_PDC

This is the error log identifier for the PDC (daughter card) feature. PSY_PISO

This is the error log identifier for the PISO (ISO 15765) feature. PSY_APP

This is the error log identifier for the application. PSY_PCFG

This is the error log identifier for the PCFG feature. PSY_PSMC

This is the error log identifier for the PSMC feature. NULL

Copyright 2019, Pi Innovo 73 Library interface

Type Identifier Ensure the NULL pointer is defined (if it is not already) FALSE

Ensure FALSE is defined (if it is not already) TRUE

Ensure TRUE is defined (if it is not already) Data types PSY_ERROR_LOG_T

The type for an error log. S8

This typedef declares a signed 8 bit integer. U8

This typedef declares an unsigned 8 bit integer. BOOL

This typedef declares a boolean integer. S16

This typedef declares a signed 16 bit integer. U16

This typedef declares an unsigned 16 bit integer. S32

This typedef declares a signed 32 bit integer. U32

This typedef declares an unsigned 32 bit integer. S64

This typedef declares a signed 64 bit integer. U64

This typedef declares an unsigned 64 bit integer. INT

This typedef declares a signed 32 bit integer. UINT

This typedef declares an unsigned 32 bit integer. F32

This typedef declares a 32 bit floating point. FREAL

This typedef declares a 32 bit floating point. F64

Copyright 2019, Pi Innovo 74 Library interface

Type Identifier This typedef declares a 64 bit floating point. Functions U8 psy_get_num_errors

Returns the number of errors detected by the platform software. BOOL psy_get_error

Gets the information related to an error. 5.2.5. Interface detail 5.2.5.1. Macros 5.2.5.1.1. PSY_MAX_NUM_STORED_ERRORS

Definition: #define PSY_MAX_NUM_STORED_ERRORS 16

Description:

The maximum number of different errors that are simultaneously stored.

The errors can be accessed by calling psy_get_error(). 5.2.5.1.2. PSY_PBT

Definition: #define PSY_PBT (U8)1

Description:

This is the error log identifier for the PBT (boot) feature. 5.2.5.1.3. PSY_PSY

Definition: #define PSY_PSY (U8)2

Description:

This is the error log identifier for the PSY (system) feature. 5.2.5.1.4. PSY_PTPU

Definition: #define PSY_PTPU (U8)3

Description:

This is the error log identifier for the PTPU (TPU or eTPU) feature. 5.2.5.1.5. PSY_PSC

Definition: #define PSY_PSC (U8)4

Description:

This is the error log identifier for the PSC (startup and idle) feature.

Copyright 2019, Pi Innovo 75 Library interface

5.2.5.1.6. PSY_PAX

Definition: #define PSY_PAX (U8)5

Description:

This is the error log identifier for the PAX (analogue I/O) feature. 5.2.5.1.7. PSY_PCX

Definition: #define PSY_PCX (U8)6

Description:

This is the error log identifier for the PCX (CAN messaging) feature. 5.2.5.1.8. PSY_PDX

Definition: #define PSY_PDX (U8)8

Description:

This is the error log identifier for the PDX (digital I/O) feature. 5.2.5.1.9. PSY_PUT

Definition: #define PSY_PUT (U8)9

Description:

This is the error log identifier for the PUT (general utility) feature. 5.2.5.1.10. PSY_PSP

Definition: #define PSY_PSP (U8)10

Description:

This is the error log identifier for the PSP (SPI messaging) feature. 5.2.5.1.11. PSY_PNV

Definition: #define PSY_PNV (U8)11

Description:

This is the error log identifier for the PNV (adaptive non-volatile) feature. 5.2.5.1.12. PSY_PRS

Definition: #define PSY_PRS (U8)12

Description:

This is the error log identifier for the PRS (RS232) feature.

Copyright 2019, Pi Innovo 76 Library interface

5.2.5.1.13. PSY_PCP

Definition: #define PSY_PCP (U8)13

Description:

This is the error log identifier for the PCP (CCP scheduling) feature. 5.2.5.1.14. PSY_PKN

Definition: #define PSY_PKN (U8)14

Description:

This is the error log identifier for the PKN (scheduler) feature. 5.2.5.1.15. PSY_PMIOS

Definition: #define PSY_PMIOS (U8)15

Description:

This is the error log identifier for the PMIOS (MIOS or eMIOS) feature. 5.2.5.1.16. PSY_PFL

Definition: #define PSY_PFL (U8)16

Description:

This is the error log identifier for the PFL (Flash memory) feature. 5.2.5.1.17. PSY_PCCP

Definition: #define PSY_PCCP (U8)17

Description:

This is the error log identifier for the PCCP (CCP messaging) feature. 5.2.5.1.18. PSY_PQADC

Definition: #define PSY_PQADC (U8)18

Description:

This is the error log identifier for the PQADC (QADC or eQADC) feature. 5.2.5.1.19. PSY_PDTC

Definition: #define PSY_PDTC (U8)19

Description:

This is the error log identifier for the PDTC (diagnostic trouble code) feature.

Copyright 2019, Pi Innovo 77 Library interface

5.2.5.1.20. PSY_PJ1939

Definition: #define PSY_PJ1939 (U8)20

Description:

This is the error log identifier for the PJ1939 (SAE J1939 messaging) feature.

5.2.5.1.21. PSY_PSPI

Definition: #define PSY_PSPI (U8)21

Description:

This is the error log identifier for the PSPI (SPI messaging) feature.

5.2.5.1.22. PSY_PDG

Definition: #define PSY_PDG (U8)22

Description:

This is the error log identifier for the PDG (ISO diagnostics) feature.

5.2.5.1.23. PSY_PFF

Definition: #define PSY_PFF (U8)23

Description:

This is the error log identifier for the PFF (freeze frame) feature.

5.2.5.1.24. PSY_PEM

Definition: #define PSY_PEM (U8)24

Description:

This is the error log identifier for the PEM (emulutor and memory) feature.

5.2.5.1.25. PSY_PFS

Definition: #define PSY_PFS (U8)25

Description:

This is the error log identifier for the PFS (filesystem) feature.

5.2.5.1.26. PSY_PROP

Definition: #define PSY_PROP (U8)26

Copyright 2019, Pi Innovo 78 Library interface

Description:

This is the error log identifier for the waveform properties (PROP) feature. 5.2.5.1.27. PSY_PDD

Definition: #define PSY_PDD (U8)27

Description:

This is the error log identifier for the PDD (digital data) feature. 5.2.5.1.28. PSY_PAN

Definition: #define PSY_PAN (U8)28

Description:

This is the error log identifier for the PAN (angular) feature. 5.2.5.1.29. PSY_PPP

Definition: #define PSY_PPP (U8)29

Description:

This is the error log identifier for the PPP (Tunes) feature. 5.2.5.1.30. PSY_PPM

Definition: #define PSY_PPM (U8)30

Description:

This is the error log identifier for the PPM (power management) feature. 5.2.5.1.31. PSY_PSS

Definition: #define PSY_PSS (U8)31

Description:

This is the error log identifier for the PSS (system safety) feature. 5.2.5.1.32. PSY_PFC

Definition: #define PSY_PFC (U8)32

Description:

This is the error log identifier for the PFC (flash code) feature. 5.2.5.1.33. PSY_PXS

Definition: #define PSY_PXS (U8)33

Copyright 2019, Pi Innovo 79 Library interface

Description:

This is the error log identifier for the PXS (extreme switch) feature. 5.2.5.1.34. PSY_PDC

Definition: #define PSY_PDC (U8)34

Description:

This is the error log identifier for the PDC (daughter card) feature. 5.2.5.1.35. PSY_PISO

Definition: #define PSY_PISO (U8)35

Description:

This is the error log identifier for the PISO (ISO 15765) feature. 5.2.5.1.36. PSY_APP

Definition: #define PSY_APP (U8)36

Description:

This is the error log identifier for the application. 5.2.5.1.37. PSY_PCFG

Definition: #define PSY_PCFG (U8)37

Description:

This is the error log identifier for the PCFG feature. 5.2.5.1.38. PSY_PSMC

Definition: #define PSY_PSMC (U8)38

Description:

This is the error log identifier for the PSMC feature. 5.2.5.1.39. NULL

Definition: #define NULL ((void *) 0)

Description:

Ensure the NULL pointer is defined (if it is not already) 5.2.5.1.40. FALSE

Definition: #define FALSE ((BOOL)0)

Copyright 2019, Pi Innovo 80 Library interface

Description:

Ensure FALSE is defined (if it is not already) 5.2.5.1.41. TRUE

Definition: #define TRUE ((BOOL)1)

Description:

Ensure TRUE is defined (if it is not already) 5.2.5.2. Data types

5.2.5.2.1. PSY_ERROR_LOG_T

Summary: The type for an error log.

Members:

U8 PSY_ERROR_LOG_T::feature_id This is the feature identifier for the declared error (e.g., PSY_PFL).

Range: [0, 255] unitless

U16 PSY_ERROR_LOG_T::error_id This is the identifier for the declared error.

Range: [0, 65535]

Description:

The type for an error log.

This type declares a structure containing information relating to a system error (detected by the platform software). 5.2.5.2.2. S8

Definition: typedef signed char S8

Description: This typedef declares a signed 8 bit integer. 5.2.5.2.3. U8

Definition: typedef unsigned char U8

Description: This typedef declares an unsigned 8 bit integer. 5.2.5.2.4. BOOL

Definition: typedef unsigned char BOOL

Description: This typedef declares a boolean integer.

Copyright 2019, Pi Innovo 81 Library interface

5.2.5.2.5. S16

Definition: typedef signed short S16

Description: This typedef declares a signed 16 bit integer.

5.2.5.2.6. U16

Definition: typedef unsigned short U16

Description: This typedef declares an unsigned 16 bit integer.

5.2.5.2.7. S32

Definition: typedef signed long S32

Description: This typedef declares a signed 32 bit integer.

5.2.5.2.8. U32

Definition: typedef unsigned long U32

Description: This typedef declares an unsigned 32 bit integer.

5.2.5.2.9. S64

Definition: typedef signed long long S64

Description: This typedef declares a signed 64 bit integer.

5.2.5.2.10. U64

Definition: typedef unsigned long long U64

Description: This typedef declares an unsigned 64 bit integer.

5.2.5.2.11. INT

Definition: typedef int INT

Description: This typedef declares a signed 32 bit integer.

5.2.5.2.12. UINT

Definition: typedef unsigned long UINT

Copyright 2019, Pi Innovo 82 Library interface

Description: This typedef declares an unsigned 32 bit integer. 5.2.5.2.13. F32

Definition: typedef float F32

Description: This typedef declares a 32 bit floating point. 5.2.5.2.14. FREAL

Definition: typedef float FREAL

Description: This typedef declares a 32 bit floating point. 5.2.5.2.15. F64

Definition: typedef double F64

Description: This typedef declares a 64 bit floating point. 5.2.5.3. Functions 5.2.5.3.1. psy_get_num_errors()

Definition: U8 psy_get_num_errors(void)

Supported targets: All targets

Required license: None (Main library).

Description: Returns the number of errors detected by the platform software.

Note

System errors are stored in RAM and are recovered across a reset if possible.

Return: Number of declared errors. Range: [0, PSY_MAX_NUM_STORED_ERRORS] errors 5.2.5.3.2. psy_get_error()

Definition: BOOL psy_get_error(U8 psyf_error_index, PSY_ERROR_LOG_T *psyf_log)

Supported targets: All targets

Copyright 2019, Pi Innovo 83 Library interface

Required license: None (Main library).

Description: Gets the information related to an error.

Note

System errors are stored in RAM and are recovered across a reset if possible.

Arg (data in): psyf_error_index The index into the error log to retrieve error information from. Range: [0, PSY_MAX_NUM_STORED_ERRORS - 1] unitless

Arg (data out): psyf_log Pointer to store for error information. Cannot be NULL.

Return: True if the error information could be retrieved, false otherwise. 5.3. System start-up and background processing (PSC) 5.3.1. Overview

5.3.1.1. System initialisation

The feature handles the C run-time environment, library and application initialisation. See Section 4.6, “Application mode” for further details. The application must define the psc_initialise_app() function which is called between pre and post initialisation. 5.3.1.2. System background processing

Once initialisation is complete, application run starts. This involves starting the scheduler, which in turn causes library and application tasks to run; and involves calling the background processing functions. Background processing occurs when no other task is running or is ready to run (i.e., when the CPU would otherwise be idle).

The library will call the applications background processing function (psc_background_app()) when it can. The library makes no guarantees that the application background processing function is called, only that if there is CPU idle time when tasks are not running, then an attempt to call the application background processing will eventually be made.

The platform itself performs various operations in the background including checks on RAM hardware. If a RAM error is detected, an unrecoverable error is raised (resulting in ECU reset) because program execution is otherwise likely to fail in an unpredictable manner.

Similarly non-volatile data is revalidated in the background and treated as if it is no longer available if validation fails. Thus if run-time memory corruption occurs affecting non-volatile data, any subsequent attempt to read that data will be handled in the same way as if the data were not present (default used instead).

Background checking for code or calibration corruption works through the Calibration Verification Number computation on supported targets with the OBD library option. Ensure

Copyright 2019, Pi Innovo 84 Library interface

that the CVN is recomputed continually if run-time corruption checking is required. If it is detected, an unrecoverable error is raised (resulting in ECU reset). This is in addition to boot- time checksum validation. 5.3.1.3. System reset

A controlled system reset occurs when the ECU is turned on, or when the ECU software invokes a reset. A reset causes the bootloader to determine which major system mode to enter (see Section 4.3, “System modes” for more).

The reason for a reset can be determined during application run by calling psc_decode_reset(), which also provides a rough guide to the duration between reset and the start of application run. 5.3.1.4. System up-time (run-time)

The feature maintains a second timer, called the run-timer or up-timer. The current value of the run-timer is returned by calling psc_get_run_time(). It is cleared to zero during library pre- initialisation and incremented every second during application run. The run timer can be used as an indication of how long the system has been running in application mode without a reset. 5.3.1.5. System loading

The feature maintains an estimate of the CPU utilisation. The current CPU loading is returned by calling psc_get_cpu_loading(). The CPU load is calculated every 50 milliseconds during background processing (or longer if any set of tasks cause the background processing to be delayed). The CPU loading is essentially the time used by running tasks over the 50ms period, expressed as a percentage.

The feature also records the highest estimate of CPU utilisation. The highest recorded CPU loading is returned by calling psc_get_max_cpu_loading().

For some target ECUs, this feature maintains an estimate of the eTPU utilisation (the eTPU is used for simple and complex I/O operations, such as crank wheel decoding). As with the CPU, the eTPU loading is calculated every 50 milliseconds during background processing (or longer if any set of tasks cause the background processing to be delayed). Call psc_get_etpu_loading() or psc_get_max_etpu_loading() to retrieve the latest eTPU loading, and maximum eTPU loading seen since reset. 5.3.1.6. System stack

The system stack is configured during library pre-initialisation. The system stack is shared between background processing, library and application tasks (see Section 5.6.1.3, “Stack sharing” for more detail on how the stack is shared).

During pre-initialisation, the memory area allocated to the system stack is filled with a pre- determined set of bit patterns. As the stack becomes used, these bit patterns are over-written, and the library determines the amount of used stack by scanning through the memory area to find the point where the bit patterns have been overwritten. This scanning is performed as background processing, and the last calculated system stack use is returned from calling psc_get_used_stack_size().

Note

On supported ECUs, an overflow of the system stack is trapped by this feature. Rather than allow a stack overflow to overwrite valid system variables, resulting in possibly undefined or unexpected behaviour, this feature traps the error, records the issue and resets the ECU.

Copyright 2019, Pi Innovo 85 Library interface

5.3.1.7. System watchdog handling

The library provides for a simple system which kicks the ECU watchdog periodically. If the watchdog task is starved of CPU time, the ECU watchdog will eventually trigger causing a reset.

Target ECU Watchdog duration Maximum kick period M110, M220, M221, [~419, ~838] milliseconds a 200 milliseconds M250, M460, M461 M560, M680, M670 [~508, ~1016] milliseconds a 200 milliseconds a The range reflects the configuration of the processor's watchdog, which uses two time out periods before resetting the processor. The library automatically kicks the watchdog at the maximum period for the target ECU. But the application may take control of the watchdog by using the watchdog statement (see Section 7.1.4.9, “Compound statement: os-native”) and calling psc_kick_watchdog() as necessary whilst the application runs. 5.3.1.8. System identification

The feature provides a number of variables which can identify the application. The variables contain version numbers, build dates and part numbers. Part numbers are provided for the bootloader components and the library. These variables are added to the ASAP2 file (Target ASAP2 file) which provides for inspection of the application identification while the ECU is running in application mode using a calibration tool (see Section 7.1.7, “Automatic ASAP2 entries” for more).

The application can retreive the bootloader components and the library version numbers, build dates and part numbers by invoking the following functions: psc_get_boot_version(), psc_get_boot_build_date(), psc_get_boot_part_number(), psc_get_prg_version(), psc_get_prg_build_date(), psc_get_prg_part_number(), psc_get_platform_version() , psc_get_platform_build_date(), psc_get_platform_part_number() . There is also a set of functions that can be used to dynamically retrieve the application version and build date: psc_get_application_version() and psc_get_application_build_date(). 5.3.1.9. Library header

The library contains a 1KB header. The header contains information about the processor initialisation, library entry point and various other data, but also contains a check-sum. The check-sum is tested by the bootloader when choosing the system mode to enter (see Section 4.3, “System modes”). The check-sum is set when the application is built — see the batch files for each example to see how this is achieved (see Section 4.6.8, “Examples”). 5.3.1.10. Memory tests

Each ECU implements an internal memory test during startup to check for hard memory faults. Hard memory faults are memory faults that have become permanent such as a shorted address line, or a memory cell that cannot change state. RAM is tested by performing a destructive walking one's test on the address and data lines and a memory recall test on the memory cells. ROM is tested by calculating a checksum of the contents. If a hard memory fault is detected, then the ECU will reset itself to force safety related outputs to a default state.

Some ECUs also implement a continuous internal memory test during runtime to check for soft memory faults. Soft memory faults are transient memory faults, such as might occur when a memory cell changes state due to stray electron releases. The error correction module hardware is capable of detecting and correcting errors that are limited to a single bit wrong in a 64-bit double word. If more than one bit is wrong in a 64-bit double word, then the hardware can detect the error, but it cannot be corrected. If an uncorrectable soft memory fault is detected, then the ECU will reset itself to force safety related outputs to a default state.

Copyright 2019, Pi Innovo 86 Library interface

The application can retrieve the status of the continuous internal memory soft error test as well as the address of the last detected correctable error by invoking the following functions:

• psc_int_ram_test_progress() • psc_int_rom_test_progress() • psc_int_ram_test_error_detected() • psc_int_rom_test_error_detected() 5.3.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and psc.h Enumerations PSC_ERROR_CODE_T

Error values for debugging when an error is found by the system start and idle feature (PSC), the feature calls a system error log function with an enumeration from this type. PSC_RC_T

An enumerated type which contains success and failure codes returned by some system start and idle feature (PSC) functions. Variables const U8 psc_watchdog_task_enabled

This determines whether the watchdog task is active or not. const BOOL psc_mem_runtime_checks_enabled

This determines whether run-time background memory checks are active or not. const U16 psc_app_major_ver_num

This is the major version number of the application. const U16 psc_app_minor_ver_num

This is the minor version number of the application. const U16 psc_app_sub_minor_ver_num

This is the subminor version number of the application. const U8 psc_app_name

This is the name of the application. const U8 psc_app_desc

This is a description of the application. const U8 psc_app_copyright

This is a copyright notice for the application.

Copyright 2019, Pi Innovo 87 Library interface

Type Identifier const PHDR_HEADER_T psc_platform_header

The application data header which contains details of CPU initialisation, CCP settings, application version info, etc. Functions void psc_initialise_app

This function is invoked from the library between pre- initialisation and post-initialisation. void psc_background_app

This function is invoked by the library when no tasks are running. U8 psc_get_cpu_loading

Return the last calculated CPU loading. U8 psc_get_max_cpu_loading

Return the maximum CPU loading recorded since reset. PSC_RC_T psc_decode_reset

Determine the reason for the last reset and the duration from reset to the start of the application code. void psc_store_suicide_note

Store data across a reset. U32 psc_get_suicide_note

Recover data stored across a reset. U32 psc_get_reset_count

Return the reset count. U32 psc_get_unstable_reset_count

Return the reset count. PSC_RC_T psc_get_etpu_loading

Return the last calculated eTPU loading for an eTPU device. PSC_RC_T psc_get_max_etpu_loading

Return the maximum eTPU loading recorded since reset for an eTPU device. PSC_RC_T psc_get_hw_version

Return the hardware version information. PSC_RC_T psc_get_boot_version

Return the boot code version information. PSC_RC_T psc_get_boot_build_date

Copyright 2019, Pi Innovo 88 Library interface

Type Identifier Return the boot code build date information. PSC_RC_T psc_get_boot_part_number

Return the boot code part number information. PSC_RC_T psc_get_prg_version

Return the reprogramming code version information. PSC_RC_T psc_get_prg_build_date

Return the reprogramming code build date information. PSC_RC_T psc_get_prg_part_number

Return the reprogramming code part number information. PSC_RC_T psc_get_platform_version

Return the platform code version information. PSC_RC_T psc_get_platform_build_date

Return the platform code build date information. PSC_RC_T psc_get_platform_part_number

Return the platform code part number information. PSC_RC_T psc_get_application_version

Return the application version information. PSC_RC_T psc_get_application_build_date

Return the application build date information. PSC_RC_T psc_int_ram_test_progress

Report the current progress of the internal RAM test. PSC_RC_T psc_int_rom_test_progress

Report the current progress of the internal ROM test. PSC_RC_T psc_int_ram_test_error_detected

Report the last recorded recoverable error detected during the internal RAM test. PSC_RC_T psc_int_rom_test_error_detected

Report the last recorded recoverable error detected during the internal ROM test. U32 psc_get_run_time

Get the run time of the ECU (the time the ECU has been powered without reset or loss of power). U32 psc_get_used_stack_size

Report the amount of stack used by the application and library code. void psc_watchdog_task

Copyright 2019, Pi Innovo 89 Library interface

Type Identifier The watchdog handling task. void psc_kick_watchdog

Kick the watchdog to prevent the watchdog causing a reset. 5.3.3. Interface detail 5.3.3.1. Enumerations

5.3.3.1.1. PSC_ERROR_CODE_T

Summary: Error values for debugging when an error is found by the system start and idle feature (PSC), the feature calls a system error log function with an enumeration from this type.

Enumerations:

PSC_DECODE_RESET_INVALID_ARG Error raised if the decode reset function finds an invalid argument.

PSC_ERR_FORCED_RESET Error raised if the platform library forces a reset of the ECU.

PSC_ERR_VERSION_INVALID_PARAM Error raised if at least one of the version pointer arguments to a version function is invalid.

PSC_ERR_BUILD_DATE_INVALID_PARAM Error raised if at least one of the build date pointer arguments to a version function is invalid.

PSC_ERR_PART_NUMBER_INVALID_PARAM Error raised if at least one of the part number pointer arguments to a part-number function is invalid.

PSC_UNEXPECTED_CVN_CHANGE Error raised if the Calibration Verification Number calculation found an unexpected change in flash memory contents.

PSC_ERR_CELL_RETENTION Error raised if internal RAM failure detected.

PSC_ERR_ADDRESS_BUS Error raised if overspill RAM failure detected.

PSC_ERR_DATA_BUS Error raised if external RAM 1 failure detected.

PSC_ERR_HW_VERSION_UNKNOWN Error raised if hardware version is unknown. 5.3.3.1.2. PSC_RC_T

Summary: An enumerated type which contains success and failure codes returned by some system start and idle feature (PSC) functions.

Copyright 2019, Pi Innovo 90 Library interface

Enumerations:

PSC_RC_OK Return code if everything progressed as expected.

PSC_RC_BAD_ARGS Return code if at least one of the arguments could not be used. 5.3.3.2. Variables

5.3.3.2.1. psc_watchdog_task_enabled

Definition: const U8 psc_watchdog_task_enabled

Description: This determines whether the watchdog task is active or not.

Set true to enable the watchdog task (which automatically kicks the watchdog on a periodic basis) or set false to disable the watchdog task (and handle watchdog functionality from within the application).

5.3.3.2.2. psc_mem_runtime_checks_enabled

Definition: const BOOL psc_mem_runtime_checks_enabled

Description: This determines whether run-time background memory checks are active or not.

Set true to enable the background tests of RAM, flash and non-volatile memory.

5.3.3.2.3. psc_app_major_ver_num

Definition: const U16 psc_app_major_ver_num

Description: This is the major version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image. Range: [0, 65535] unitless

5.3.3.2.4. psc_app_minor_ver_num

Definition: const U16 psc_app_minor_ver_num

Description: This is the minor version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

Copyright 2019, Pi Innovo 91 Library interface

Range: [0, 65535] unitless

5.3.3.2.5. psc_app_sub_minor_ver_num

Definition: const U16 psc_app_sub_minor_ver_num

Description: This is the subminor version number of the application.

The complete version number takes the form major.minor.subminor. The application version number is referenced in the application header (psc_platform_header) and can be extracted from the final build image. Range: [0, 65535] unitless.

5.3.3.2.6. psc_app_name

Definition: const U8 psc_app_name[]

Description: This is the name of the application.

The name is a null-terminated string of ASCII characters. The name is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.7. psc_app_desc

Definition: const U8 psc_app_desc[]

Description: This is a description of the application.

The description is a null-terminated string of ASCII characters. The description is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.8. psc_app_copyright

Definition: const U8 psc_app_copyright[]

Description: This is a copyright notice for the application.

The copyright notice is a null-terminated string of ASCII characters. The copyright notice is referenced in the application header (psc_platform_header) and can be extracted from the final build image.

5.3.3.2.9. psc_platform_header

Definition: const PHDR_HEADER_T psc_platform_header

Description: The application data header which contains details of CPU initialisation, CCP settings, application version info, etc.

Copyright 2019, Pi Innovo 92 Library interface

5.3.3.3. Functions 5.3.3.3.1. psc_initialise_app()

Definition: void psc_initialise_app(void)

Supported targets: All targets

Required license: None (Main library).

Description: This function is invoked from the library between pre-initialisation and post-initialisation.

The application must define this function. The application may use the function to initialise itself and configure the library (e.g., by calling pcx_declare_message()).

5.3.3.3.2. psc_background_app()

Definition: void psc_background_app(void)

Supported targets: All targets

Required license: None (Main library).

Description: This function is invoked by the library when no tasks are running.

The application must define this function. The application may use the function to perform any time or event independent processing.

5.3.3.3.3. psc_get_cpu_loading()

Definition: U8 psc_get_cpu_loading(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return the last calculated CPU loading.

Return: The last calculated CPU loading. Range: [0, 100] % 5.3.3.3.4. psc_get_max_cpu_loading()

Definition: U8 psc_get_max_cpu_loading(void)

Copyright 2019, Pi Innovo 93 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Return the maximum CPU loading recorded since reset.

Return: The maximum value of any previously calculated CPU loading since reset. Range: [0, 100] %

5.3.3.3.5. psc_decode_reset()

Definition: PSC_RC_T psc_decode_reset(U8 *pscf_power_reset, U8 *pscf_watchdog_reset, U8 *pscf_access_reset, U8 *pscf_fp_reset, U8 *pscf_mem_reset, U8 *pscf_forced_reset, U8 *pscf_other_reset, F32 *pscf_boot_duration)

Supported targets: All targets

Required license: None (Main library).

Description: Determine the reason for the last reset and the duration from reset to the start of the application code.

Arg (data out): pscf_power_reset Pointer to where the boolean result of whether the reset occurred due to a power cycle will be written. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_watchdog_reset Pointer to where the boolean result of whether the reset occurred due to a watchdog timeout will be written. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_access_reset Pointer to where the boolean result of whether the reset occurred due to an illegal memory access will be written. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_fp_reset Pointer to where the boolean result of whether the reset occurred due to a floating point exception will be written. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_mem_reset Pointer to where the Boolean result of whether the reset occurred due to an unrecoverable corruption of internal memory. Cannot be NULL.

Copyright 2019, Pi Innovo 94 Library interface

Arg (data out): pscf_forced_reset Pointer to where the boolean result of whether the reset occurred due to a forced reset will be written. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_other_reset Pointer to where the boolean result of whether an undetermined reset occurred. Set true if the reset could not be determined, false otherwise. Cannot be NULL.

Arg (data out): pscf_boot_duration A pointer to where the boot duration in seconds will be written. The boot duration is a rough estimate of time between the boot code starting to run and the scheduler starting all tasks (including the application tasks). Cannot be NULL.

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.6. psc_store_suicide_note()

Definition: void psc_store_suicide_note(U32 pscf_note)

Supported targets: All targets

Required license: None (Main library).

Description: Store data across a reset.

The function stores a value that will survive a reset. This can be read back when the ECU restarts using the psc_get_suicide_note function.

Note

Data saved this way will not survive a power-cycle.

This function should not be called. It is intended only for testing purposes, and may be removed in future releases.

Arg (data in): pscf_note The data to save. 5.3.3.3.7. psc_get_suicide_note()

Definition: U32 psc_get_suicide_note(void)

Supported targets: All targets

Required license: None (Main library).

Copyright 2019, Pi Innovo 95 Library interface

Description: Recover data stored across a reset.

The function returns the last value stored using the psc_store_suicide_note function. The data is reset to 0 during a power- on reset.

Note

This function should not be called. It is intended only for testing purposes, and may be removed in future releases.

Return: The data previously stored using the psc_store_suicide_note function. 5.3.3.3.8. psc_get_reset_count()

Definition: U32 psc_get_reset_count(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return the reset count.

The function returns the free running count of the number of powered resets.

Note

The count is reset to one upon power cycle.

5.3.3.3.9. psc_get_unstable_reset_count()

Definition: U32 psc_get_unstable_reset_count(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return the reset count.

The function returns the limited counter of powered resets that occur within 60 seconds of initialisation. It is cleared once the application been running for at least 60 seconds. If the unstable reset counter reaches 5, then the module will be forced in to reprogramming mode.

Note

The count is reset to one upon power cycle.

Copyright 2019, Pi Innovo 96 Library interface

5.3.3.3.10. psc_get_etpu_loading()

Definition: PSC_RC_T psc_get_etpu_loading(PIO_ETPU_DEVICE_T pscf_etpu_device, U8 *pscf_etpu_loading)

Supported targets:

Required license: None (Main library).

Description: Return the last calculated eTPU loading for an eTPU device.

Arg (data in): pscf_etpu_device Identifies the eTPU device to report on. Use the macros included by the pio.h file, of the form PIO_ETPU_DEVICE_[NAME].

Arg (data out): pscf_etpu_loading The last calculated eTPU loading for the requested eTPU device. Range: [0, 100] %

Return:

• PSC_RC_OK - if successful

• PSC_RC_BAD_ARGS - if wrong eTPU device 5.3.3.3.11. psc_get_max_etpu_loading()

Definition: PSC_RC_T psc_get_max_etpu_loading(PIO_ETPU_DEVICE_T pscf_etpu_device, U8 *pscf_etpu_loading)

Supported targets:

Required license: None (Main library).

Description: Return the maximum eTPU loading recorded since reset for an eTPU device.

Arg (data in): pscf_etpu_device Identifies the eTPU device to report on. Use the macros included by the pio.h file, of the form PIO_ETPU_DEVICE_[NAME].

Arg (data out): pscf_etpu_loading The maximum value of any previously calculated eTPU loading since reset for the requested eTPU device. Range: [0, 100] %

Return:

• PSC_RC_OK - if successful

• PSC_RC_BAD_ARGS - if wrong eTPU device 5.3.3.3.12. psc_get_hw_version()

Definition: PSC_RC_T psc_get_hw_version(S16 *pscf_hw_ver)

Copyright 2019, Pi Innovo 97 Library interface

Supported targets:

Required license: None (Main library).

Description: Return the hardware version information.

Return the detected version number for the hardware from the PCB.

Can raise the following errors: PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_hw_ver Pointer to a variable the function will write the hardware version to. Cannot be NULL. Range: [-1, 100], -1 if hardware version is unknown

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.13. psc_get_boot_version()

Definition: PSC_RC_T psc_get_boot_version(U16 *pscf_major_ver, U16 *pscf_minor_ver, U16 *pscf_sub_minor_ver)

Supported targets: All targets

Required license: None (Main library).

Description: Return the boot code version information.

Return the major, minor and sub-minor version numbers for boot code programmed into the ECU.

Can raise the following errors: PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver Pointer to a variable the function will write the major version to. Cannot be NULL.

Arg (data out): pscf_minor_ver Pointer to a variable the function will write the minor version to. Cannot be NULL.

Arg (data out): pscf_sub_minor_ver Pointer to a variable the function will write the sub-minor version to. Cannot be NULL.

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error

Copyright 2019, Pi Innovo 98 Library interface

5.3.3.3.14. psc_get_boot_build_date()

Definition: PSC_RC_T psc_get_boot_build_date(U16 *pscf_year, U16 *pscf_month, U16 *pscf_day)

Supported targets: All targets

Required license: None (Main library).

Description: Return the boot code build date information.

Return the year, month and day of the build date for boot code programmed into the ECU.

Can raise the following errors: PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year Pointer to a variable the function will write the build year to. Cannot be NULL. Range: 0, 65535

Arg (data out): pscf_month Pointer to a variable the function will write the build month to. Cannot be NULL. Range: [1, 12] (representing January through December)

Arg (data out): pscf_day Pointer to a variable the function will write the build day to. Cannot be NULL. Range: [1, 31]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.15. psc_get_boot_part_number()

Definition: PSC_RC_T psc_get_boot_part_number(U8 *pscf_group, U8 *pscf_letter, U32 *pscf_id, U16 *pscf_issue)

Supported targets: All targets

Required license: None (Main library).

Description: Return the boot code part number information.

Return the group ID number, group ID letter, part ID number and issue ID number of the boot code programmed into the ECU.

Can raise the following errors: PSC_ERR_PART_NUMBER_INVALID_PARAM.

Copyright 2019, Pi Innovo 99 Library interface

Arg (data out): pscf_group Pointer to a variable the function will write the group id number to. Cannot be NULL. Range: 0, 99

Arg (data out): pscf_letter Pointer to a variable the function will write the group letter to. Cannot be NULL. Range: 0, 255

Arg (data out): pscf_id Pointer to a variable the function will write the part id number to. Cannot be NULL. Range: 0, 999999

Arg (data out): pscf_issue Pointer to a variable the function will write the part issue number to. Cannot be NULL. Range: [0, 65535]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.16. psc_get_prg_version()

Definition: PSC_RC_T psc_get_prg_version(U16 *pscf_major_ver, U16 *pscf_minor_ver, U16 *pscf_sub_minor_ver)

Supported targets: All targets

Required license: None (Main library).

Description: Return the reprogramming code version information.

Return the major, minor and sub-minor version numbers for reprogramming code programmed into the ECU.

Can raise the following errors: PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver Pointer to a variable the function will write the major version to. Cannot be NULL.

Arg (data out): pscf_minor_ver Pointer to a variable the function will write the minor version to. Cannot be NULL.

Arg (data out): pscf_sub_minor_ver Pointer to a variable the function will write the sub-minor version to. Cannot be NULL.

Return:

• PSC_RC_OK - if successful action

Copyright 2019, Pi Innovo 100 Library interface

• PSC_RC_BAD_ARGS - if configuration error

5.3.3.3.17. psc_get_prg_build_date()

Definition: PSC_RC_T psc_get_prg_build_date(U16 *pscf_year, U16 *pscf_month, U16 *pscf_day)

Supported targets: All targets

Required license: None (Main library).

Description: Return the reprogramming code build date information.

Return the year, month and day of the build date for reprogramming code programmed into the ECU.

Can raise the following errors: PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year Pointer to a variable the function will write the build year to. Cannot be NULL. Range: 0, 65535

Arg (data out): pscf_month Pointer to a variable the function will write the build month to. Cannot be NULL. Range: [1, 12] (representing January through December)

Arg (data out): pscf_day Pointer to a variable the function will write the build day to. Cannot be NULL. Range: [1, 31]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error

5.3.3.3.18. psc_get_prg_part_number()

Definition: PSC_RC_T psc_get_prg_part_number(U8 *pscf_group, U8 *pscf_letter, U32 *pscf_id, U16 *pscf_issue)

Supported targets: All targets

Required license: None (Main library).

Description: Return the reprogramming code part number information.

Return the group ID number, group ID letter, part ID number and issue ID number of the reprogramming code programmed into the ECU.

Copyright 2019, Pi Innovo 101 Library interface

Can raise the following errors: PSC_ERR_PART_NUMBER_INVALID_PARAM.

Arg (data out): pscf_group Pointer to a variable the function will write the group id number to. Cannot be NULL. Range: 0, 99

Arg (data out): pscf_letter Pointer to a variable the function will write the group letter to. Cannot be NULL. Range: 0, 255

Arg (data out): pscf_id Pointer to a variable the function will write the part id number to. Cannot be NULL. Range: 0, 999999

Arg (data out): pscf_issue Pointer to a variable the function will write the part issue number to. Cannot be NULL. Range: [0, 65535]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.19. psc_get_platform_version()

Definition: PSC_RC_T psc_get_platform_version(U16 *pscf_major_ver, U16 *pscf_minor_ver, U16 *pscf_sub_minor_ver)

Supported targets: All targets

Required license: None (Main library).

Description: Return the platform code version information.

Return the major, minor and sub-minor version numbers for platform code programmed into the ECU.

Can raise the following errors: PSC_ERR_VERSION_INVALID_PARAM.

Arg (data out): pscf_major_ver Pointer to a variable the function will write the major version to. Cannot be NULL.

Arg (data out): pscf_minor_ver Pointer to a variable the function will write the minor version to. Cannot be NULL.

Arg (data out): pscf_sub_minor_ver Pointer to a variable the function will write the sub-minor version to. Cannot be NULL.

Copyright 2019, Pi Innovo 102 Library interface

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.20. psc_get_platform_build_date()

Definition: PSC_RC_T psc_get_platform_build_date(U16 *pscf_year, U16 *pscf_month, U16 *pscf_day)

Supported targets: All targets

Required license: None (Main library).

Description: Return the platform code build date information.

Return the year, month and day of the build date for platform code programmed into the ECU.

Can raise the following errors: PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data out): pscf_year Pointer to a variable the function will write the build year to. Cannot be NULL. Range: 0, 65535

Arg (data out): pscf_month Pointer to a variable the function will write the build month to. Cannot be NULL. Range: [1, 12] (representing January through December)

Arg (data out): pscf_day Pointer to a variable the function will write the build day to. Cannot be NULL. Range: [1, 31]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.21. psc_get_platform_part_number()

Definition: PSC_RC_T psc_get_platform_part_number(U8 *pscf_group, U8 *pscf_letter, U32 *pscf_id, U16 *pscf_issue)

Supported targets: All targets

Required license: None (Main library).

Description: Return the platform code part number information.

Copyright 2019, Pi Innovo 103 Library interface

Return the group ID number, group ID letter, part ID number and issue ID number of the platform code programmed into the ECU.

Can raise the following errors: PSC_ERR_PART_NUMBER_INVALID_PARAM.

Arg (data out): pscf_group Pointer to a variable the function will write the group id number to. Cannot be NULL. Range: 0, 99

Arg (data out): pscf_letter Pointer to a variable the function will write the group letter to. Cannot be NULL. Range: 0, 255

Arg (data out): pscf_id Pointer to a variable the function will write the part id number to. Cannot be NULL. Range: 0, 999999

Arg (data out): pscf_issue Pointer to a variable the function will write the part issue number to. Cannot be NULL. Range: [0, 65535]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.22. psc_get_application_version()

Definition: PSC_RC_T psc_get_application_version(U16 *pscf_major_ver, U16 *pscf_minor_ver, U16 *pscf_sub_minor_ver)

Supported targets: All targets

Required license: None (Main library).

Description: Return the application version information.

Return the major, minor and sub-minor version numbers for application programmed into the ECU.

Can raise the following errors: PSC_ERR_VERSION_INVALID_PARAM.

Arg (data in): pscf_major_ver Pointer to a variable the function will write the major version to. Cannot be NULL.

Arg (data in): pscf_minor_ver Pointer to a variable the function will write the minor version to. Cannot be NULL.

Arg (data in): pscf_sub_minor_ver Pointer to a variable the function will write the sub-minor version to.

Copyright 2019, Pi Innovo 104 Library interface

Cannot be NULL.

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.23. psc_get_application_build_date()

Definition: PSC_RC_T psc_get_application_build_date(U16 *pscf_year, U16 *pscf_month, U16 *pscf_day)

Supported targets: All targets

Required license: None (Main library).

Description: Return the application build date information.

Return the year, month and day of the build date for the application programmed into the ECU.

Can raise the following errors: PSC_ERR_BUILD_DATE_INVALID_PARAM.

Arg (data in): pscf_year Pointer to a variable the function will write the build year to. Cannot be NULL. Range: 0, 65535

Arg (data in): pscf_month Pointer to a variable the function will write the build month to. Cannot be NULL. Range: [1, 12] (representing January through December)

Arg (data in): pscf_day Pointer to a variable the function will write the build day to. Cannot be NULL. Range: [1, 31]

Return:

• PSC_RC_OK - if successful action

• PSC_RC_BAD_ARGS - if configuration error 5.3.3.3.24. psc_int_ram_test_progress()

Definition: PSC_RC_T psc_int_ram_test_progress(U32 *pscf_start_address, U32 *pscf_end_address, U32 *pscf_current_address)

Supported targets:

Required license: None (Main library).

Description: Report the current progress of the internal RAM test.

Copyright 2019, Pi Innovo 105 Library interface

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64- bit accesses are automatically corrected and are reported through the associated error reporting function. Two bit or greater errors are not recoverable and will immediately trigger a reset. The application may determine the reason for the reset.

Arg (data out): pscf_start_address Pointer to where to write the first address of the internal RAM test. Cannot be NULL.

Arg (data out): pscf_end_address Pointer to where to write the end address of the internal RAM test. Cannot be NULL.

Arg (data out): pscf_current_address Pointer to where to write the current address of the internal RAM test. Cannot be NULL.

Return:

• PSC_RC_OK - if parameters are not NULL.

• PSC_RC_BAD_ARGS - if one or more parameters are NULL. 5.3.3.3.25. psc_int_rom_test_progress()

Definition: PSC_RC_T psc_int_rom_test_progress(U32 *pscf_start_address, U32 *pscf_end_address, U32 *pscf_current_address)

Supported targets:

Required license: None (Main library).

Description: Report the current progress of the internal ROM test.

The internal RAM test continuously cycles through the internal ROM and checks for errors. One bit errors that are detected in aligned 64- bit accesses are automatically corrected and are reported through the associated error reporting function. Two bit or greater errors are not recoverable and will immediately trigger a reset. The application may determine the reason for the reset.

Arg (data out): pscf_start_address Pointer to where to write the first address of the internal ROM test. Cannot be NULL.

Arg (data out): pscf_end_address Pointer to where to write the end address of the internal ROM test. Cannot be NULL.

Arg (data out): pscf_current_address Pointer to where to write the current address of the internal ROM test. Cannot be NULL.

Return:

• PSC_RC_OK - if parameters are not NULL.

Copyright 2019, Pi Innovo 106 Library interface

• PSC_RC_BAD_ARGS - if one or more parameters are NULL. 5.3.3.3.26. psc_int_ram_test_error_detected()

Definition: PSC_RC_T psc_int_ram_test_error_detected(BOOL *pscf_error_detected, U32 *pscf_error_address)

Supported targets:

Required license: None (Main library).

Description: Report the last recorded recoverable error detected during the internal RAM test.

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64- bit accesses are automatically corrected and are reported through this interface.

Arg (data out): pscf_error_detected Pointer to where to write the boolean result of whether a recoverable internal RAM fault has been detected. Set true if so, false otherwise. Cannot be NULL.

Arg (data out): pscf_error_address Pointer to where to write the address of the last recoverable internal RAM fault. Cannot be NULL.

Return:

• PSC_RC_OK - if parameters are not NULL.

• PSC_RC_BAD_ARGS - if one or more parameters are NULL. 5.3.3.3.27. psc_int_rom_test_error_detected()

Definition: PSC_RC_T psc_int_rom_test_error_detected(BOOL *pscf_error_detected, U32 *pscf_error_address)

Supported targets:

Required license: None (Main library).

Description: Report the last recorded recoverable error detected during the internal ROM test.

The internal RAM test continuously cycles through the internal RAM and checks for errors. One bit errors that are detected in aligned 64- bit accesses are automatically corrected and are reported through this interface.

Arg (data out): pscf_error_detected Pointer to where to write the boolean result of whether a recoverable internal ROM fault has been detected. Set true if so, false otherwise. Cannot be NULL.

Copyright 2019, Pi Innovo 107 Library interface

Arg (data out): pscf_error_address Pointer to where to write the address of the last recoverable internal ROM fault. Cannot be NULL.

Return:

• PSC_RC_OK - if parameters are not NULL.

• PSC_RC_BAD_ARGS - if one or more parameters are NULL.

5.3.3.3.28. psc_get_run_time()

Definition: U32 psc_get_run_time(void)

Supported targets: All targets

Required license: None (Main library).

Description: Get the run time of the ECU (the time the ECU has been powered without reset or loss of power).

Return: The run time. Range: [0, 4294967295] seconds

5.3.3.3.29. psc_get_used_stack_size()

Definition: U32 psc_get_used_stack_size(void)

Supported targets: All targets

Required license: None (Main library).

Description: Report the amount of stack used by the application and library code.

Return: The size of stack used by the application and library code. Range: [0, 4294967295] bytes

5.3.3.3.30. psc_watchdog_task()

Definition: void psc_watchdog_task(void)

Supported targets: All targets

Required license: None (Main library).

Description: The watchdog handling task.

Copyright 2019, Pi Innovo 108 Library interface

This is the entry point for the watchdog handling task. The task ensures the watchdog does not timeout and cause a reset (which can be determined by calling psc_decode_reset()).

The watchdog handling task is assigned a low priority relative to other tasks. This includes the application tasks. It is important that application tasks do not run for longer than the watchdog timeout period, otherwise the ECU will reset.

The watchdog task is enabled when psc_watchdog_task_enabled is set true. If set false, the application may control when the watchdog is kicked by calling psc_kick_watchdog() (or not).

Note

The watchdog handling task must be scheduled every 200 milliseconds. The period of the watchdog is hard coded by the library and cannot be modified by the application.

5.3.3.3.31. psc_kick_watchdog()

Definition: void psc_kick_watchdog(void)

Supported targets: All targets

Required license: None (Main library).

Description: Kick the watchdog to prevent the watchdog causing a reset.

Kick the main processor's watchdog to prevent a reset. This function should only be called when the watchdog task is disabled (by setting psc_watchdog_task_enabled false).

Note

The watchdog handling must be scheduled periodically greater than 200 milliseconds. The period of the watchdog is hard coded by the library and cannot be modified by the application. 5.4. ECU registry information (PREG) 5.4.1. Overview

The feature provides access to the ECU's registry. The registry represents data that is specific to the ECU, such as the ECU's date of manufacture or serial number. Read access to the registry is provided through the preg_retrieve_value_from_key() function. Write access is not permitted.

The registry contains various pieces of structured data, represented as a set of key-value pairs. To read the registry, an appropriate key is passed to preg_retrieve_value_from_key(). In turn the function searches the registry for a matching key and if found, extracts the value part of the pair into a buffer provided by the caller.

Copyright 2019, Pi Innovo 109 Library interface

Table 5.3. Registry entries

Key Enumeration Serial number PREG_KEY_SERIAL_NUM Date of manufacture PREG_KEY_DATE_OF_MANUFACTURE Engineering part number PREG_KEY_ENG_PART_NUM Hardware issue and modification level PREG_KEY_HW_ISSUE_MOD_NUM Factory part number PREG_KEY_FACTORY_PART_NUM Factory part number build type PREG_KEY_FACTORY_BUILD_TYPE

For a description of each key-value pair, see the enumeration and structures referred to in the previous table.

Note

Not all ECUs have registry information programmed. The preg_is_data_available() function will return whether registry information is available or not.

5.4.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and preg.h Enumerations PREG_RC_T

An enumerated type which contains success and failure codes returned by some registry feature (PREG) functions. PREG_KEY_T

An enumerated type which represents each of the keys supported by this feature. Data types PREG_VALUE_SERIAL_NUM_T

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM. PREG_VALUE_SERIAL_NUM_LONG_T

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM_LONG. PREG_VALUE_DATE_OF_MANUFACTURE_T

A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE. PREG_VALUE_ENG_PART_NUM_T

Copyright 2019, Pi Innovo 110 Library interface

Type Identifier A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM. PREG_VALUE_HW_ISSUE_MOD_NUM_T

A structure which represents the structured data for the ECU's issue-mod key, see PREG_KEY_HW_ISSUE_MOD_NUM. PREG_VALUE_FACTORY_PART_NUM_T

A structure which represents the structured data for the ECU's factory part number key,. PREG_VALUE_FACTORY_BUILD_TYPE_T

A structure which represents the structured data for the ECU's factory part number build type key, see PREG_KEY_FACTORY_BUILD_TYPE. PREG_VALUE_DEV_HW_T

A structure which represents the structured data for the ECU's developer hardware configuration see PREG_KEY_DEV_HW. Functions BOOL preg_is_data_available

Determine whether the registry is available or not. PREG_RC_T preg_retrieve_value_from_key

Retrieve the value for a registry key. PREG_SEEK_RC_T preg_seek_key

trys to find the key PREG_SEEK_RC_T preg_write_key_data_to_ram

writes the data to the selected key PREG_SEEK_RC_T preg_write_ram_data_to_flash

writes the RAM buffer to the shadow area 5.4.3. Interface detail 5.4.3.1. Enumerations

5.4.3.1.1. PREG_RC_T

Summary: An enumerated type which contains success and failure codes returned by some registry feature (PREG) functions.

Enumerations:

PREG_RC_OK Return code if everything progressed as expected.

Copyright 2019, Pi Innovo 111 Library interface

PREG_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PREG_RC_INVALID_KEY Return code if the key argument is not one recognised by the feature.

PREG_RC_NOT_FOUND Return code if the key argument could not be found in the registry when retrieving the key's value.

5.4.3.1.2. PREG_KEY_T

Summary: An enumerated type which represents each of the keys supported by this feature.

Enumerations:

PREG_KEY_SERIAL_NUM The key for the ECU's serial number, see PREG_VALUE_SERIAL_NUM_T for the associated data.

PREG_KEY_DATE_OF_MANUFACTURE The key for the ECU's date of manufacture, see PREG_VALUE_DATE_OF_MANUFACTURE_T for the associated data.

PREG_KEY_ENG_PART_NUM The key for the ECU's engineering part number, see PREG_VALUE_ENG_PART_NUM_T for the associated data.

PREG_KEY_HW_ISSUE_MOD_NUM The key for the ECU's mod and issue number, see PREG_VALUE_HW_ISSUE_MOD_NUM_T for the associated data.

PREG_KEY_FACTORY_PART_NUM The key for the ECU's factory part number, see PREG_VALUE_FACTORY_PART_NUM_T for the associated data.

PREG_KEY_FACTORY_BUILD_TYPE The key for the ECU's factory part number build type, see PREG_VALUE_FACTORY_BUILD_TYPE_T for the associated data.

PREG_KEY_RESERVED_1

PREG_KEY_SERIAL_NUM_LONG The key for the ECU's long serial number, see PREG_VALUE_SERIAL_NUM_LONG_T for the associated data.

PREG_KEY_RESERVED_3

PREG_KEY_RESERVED_4

PREG_KEY_DEV_HW The key for the ECU's ECU's developer hardware configuration, see PREG_VALUE_DEV_HW_T for the associated data.

Description: An enumerated type which represents each of the keys supported by this feature.

Copyright 2019, Pi Innovo 112 Library interface

A key is a reference associated to some structured data. For instance, the PREG_KEY_SERIAL_NUM key is associated with the ECU's 32-bit serial number. 5.4.3.2. Data types 5.4.3.2.1. PREG_VALUE_SERIAL_NUM_T

Summary: A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM.

Members:

U32 PREG_VALUE_SERIAL_NUM_T::serial_num The serial number is a 32-bit positive integer.

Description:

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM.

The serial number is a 32-bit positive integer. Serial numbers across different families of ECUs do not overlap. 5.4.3.2.2. PREG_VALUE_SERIAL_NUM_LONG_T

Summary: A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM_LONG.

Members:

U64 PREG_VALUE_SERIAL_NUM_LONG_T::serial_num The serial number is a 48-bit positive integer.

Description:

A structure which represents the data for the ECU's serial number key, see PREG_KEY_SERIAL_NUM_LONG.

The serial number is a 48-bit positive integer. Serial numbers across different families of ECUs do not overlap. 5.4.3.2.3. PREG_VALUE_DATE_OF_MANUFACTURE_T

Summary: A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE.

Members:

U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::shift The team shift at time of manufacture.

Range: [1, 3]

U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::day The day of the month of manufacture.

Range: [1, 31]

U8 PREG_VALUE_DATE_OF_MANUFACTURE_T::month The month of manufacture.

Copyright 2019, Pi Innovo 113 Library interface

Range: [1, 12]

U16 PREG_VALUE_DATE_OF_MANUFACTURE_T::year The year of manufacture.

Range: [2010, ..]

Description:

A structure which represents the structured data for the ECU's date of manufacture key, see PREG_KEY_DATE_OF_MANUFACTURE.

The date is composed as (shift) dd:mm:yyyy, where the shift identifies the team involved in the manufacturing process. 5.4.3.2.4. PREG_VALUE_ENG_PART_NUM_T

Summary: A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM.

Members:

U8 PREG_VALUE_ENG_PART_NUM_T::prefix The part number prefix.

Range: [0, 99]

U8 PREG_VALUE_ENG_PART_NUM_T::letter The part number letter represented as an ASCII character.

Range: [A, Z]

U32 PREG_VALUE_ENG_PART_NUM_T::eng_part_num The engineering part number.

Range: [0, 999999]

Description:

A structure which represents the structured data for the ECU's engineering part number key, see PREG_KEY_ENG_PART_NUM.

The engineering part number matches the pattern: prefix letter engineering-part-number. For instance, the engineering part number assigned to the M250-000 is '01T068165', where '01' represents the prefix, 'T' represents the letter and '068165' represents the engineering part number. 5.4.3.2.5. PREG_VALUE_HW_ISSUE_MOD_NUM_T

Summary: A structure which represents the structured data for the ECU's issue- mod key, see PREG_KEY_HW_ISSUE_MOD_NUM.

Members:

U8 PREG_VALUE_HW_ISSUE_MOD_NUM_T::issue The PCB issue level.

Range: [0, 255]

U8 PREG_VALUE_HW_ISSUE_MOD_NUM_T::mod The PCB modification level.

Copyright 2019, Pi Innovo 114 Library interface

Range: [0, 255]

Description:

A structure which represents the structured data for the ECU's issue- mod key, see PREG_KEY_HW_ISSUE_MOD_NUM.

The issue level represents a specific design of PCB. Changes to the issue level may have an effect on the platform library.

The modification level represents what changes were performed to the PCB after manufacturing to correct issue level design mistakes. Changes to the modification level should not have an effect on the platform library. 5.4.3.2.6. PREG_VALUE_FACTORY_PART_NUM_T

Summary: A structure which represents the structured data for the ECU's factory part number key,.

Members:

U16 PREG_VALUE_FACTORY_PART_NUM_T::part_num[2] Each numeric part of the factory part number.

Range: [0, 65535]

U8 PREG_VALUE_FACTORY_PART_NUM_T::letter[2] The identifier which separates each factory part number, represented as ASCII characters.

Range: [A, Z]

Description:

A structure which represents the structured data for the ECU's factory part number key,.

For instance, the factory part number could be '450FT1034', where '450' represents the part_num[0], 'F' represents the letter[0], 'T' represents the letter[1], and '1034' represents the part_num[1]. see PREG_KEY_FACTORY_PART_NUM. 5.4.3.2.7. PREG_VALUE_FACTORY_BUILD_TYPE_T

Summary: A structure which represents the structured data for the ECU's factory part number build type key, see PREG_KEY_FACTORY_BUILD_TYPE.

Members:

U8 PREG_VALUE_FACTORY_BUILD_TYPE_T::build_type[2] The factory part number build type, represented as ASCII characters.

Range: [A, Z] 5.4.3.2.8. PREG_VALUE_DEV_HW_T

Summary: A structure which represents the structured data for the ECU's developer hardware configuration see PREG_KEY_DEV_HW.

Copyright 2019, Pi Innovo 115 Library interface

Members:

BOOL PREG_VALUE_DEV_HW_T::xetk_present The ETAS XETK memory emulator is present on the ECU Range: [0, 1]. 5.4.3.3. Functions 5.4.3.3.1. preg_is_data_available()

Definition: BOOL preg_is_data_available(void)

Supported targets: All targets

Required license: None (Main library).

Description: Determine whether the registry is available or not.

Note that not all ECUs have registry information available. Early builds of some ECUs have no registry information programmed.

Return: True if registry data available, false otherwise. 5.4.3.3.2. preg_retrieve_value_from_key()

Definition: PREG_RC_T preg_retrieve_value_from_key(PREG_KEY_T pregf_key, void *pregf_value_buffer)

Supported targets: All targets

Required license: None (Main library).

Description: Retrieve the value for a registry key.

Search through the registry for a matching key and if found, write the value data for the key to the supplied buffer.

The function performs a linear search and as such, should be called only when necessary to reduce CPU overhead.

Arg (data in): pregf_key The key to retrieve information about. Must be one of the PREG_KEY_T enumerations.

Arg (data out): pregf_value_buffer A pointer to an object declared of suitable type for the key. The object is written with the data values related to the key if the key is found in the registry. The object for a key can be derived from the key enumeration literal. Keys that match PREG_KEY_* correspond to struct types named PREG_VALUE_*_T. For instance, if pregf_key is set to PREG_KEY_SERIAL_NUM then pregf_value_buffer must point to an object of type PREG_VALUE_SERIAL_NUM_T.

Copyright 2019, Pi Innovo 116 Library interface

Cannot be NULL.

Return:

• PREG_RC_OK if value retrieved from registry

• another enumeration from PREG_RC_T otherwise. 5.4.3.3.3. preg_seek_key()

Definition: PREG_SEEK_RC_T preg_seek_key(U16 pregf_seek_key_ID, U16 *pregf_key_offset, U8 *pregf_key_data)

Description: trys to find the key

Arg (data in): pregf_seek_key_ID The requested value for the registry ID.

Arg (data in): pregf_key_offset A pointer to and object declareed of suitable type. The object is set to offset if it does not equal NULL. Where the offset is the number of bits between the requested key value and the closest found key.

Arg (data in): pregf_key_data The data of the key if a value PREG_SEEK_RC_OK is returned and the key is found.

Return:

• seek_key_state with PREG_SEEK_RC_OK if the key is found, PREG_SEEK_RC_NOT_FOUND if key is not found, or PREG_SEEK_RC_OUT_OF_SPACE 5.4.3.3.4. preg_write_key_data_to_ram()

Definition: PREG_SEEK_RC_T preg_write_key_data_to_ram(U16 pregf_key_ID, U8 *pregf_key_data)

Description: writes the data to the selected key

Arg (data in): pregf_key_ID The value of the registry ID.

Arg (data out): pregf_key_data A pointer to the value of the data of the registry key.

Return:

• PREG_SEEK_RC_NOT_FOUND if the key could not be found for the key ID specified in preg_key_ID.

• PREG_SEEK_RC_OK if the key was properly found.

• PREG_SEEK_RC_OUT_OF_SPACE if there is no room.

• PREG_SEEK_RC_NO_KEY_SELECTED if the has not been sought. 5.4.3.3.5. preg_write_ram_data_to_flash()

Definition: PREG_SEEK_RC_T preg_write_ram_data_to_flash(void)

Copyright 2019, Pi Innovo 117 Library interface

Description: writes the RAM buffer to the shadow area

Return:

• PREG_SEEK_RC_OK if the reprogramming was successful.

• PREG_SEEK_RC_NO_KEY_SELECTED if there was an issue with programming. 5.5. System timing feature (PTM) 5.5.1. Overview

The system timing feature provides access to second, millisecond and microsecond timers through the ptm_get_s_time() , ptm_get_ms_time() and ptm_get_us_time() functions. All timers wrap to zero when they increment past their maximum value.

The feature provides access to a timer running at the processor's clock rate (or multiple there of) through the ptm_get_sys_time() function. The return value from this function can be converted to microseconds by dividing it by PTM_SYS_TIME_TO_US.

The feature provides functions to calculate the difference in time between the current time and the return value from a previous call to read a timer (ptm_s_time_diff(), ptm_ms_time_diff(), ptm_us_time_diff() and ptm_sys_time_diff()). The results of calling these functions is undefined if more time has past than the timer can record. 5.5.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and ptm.h Macros PTM_SYS_TIME_TO_US

This is the division factor to convert from system time (returned by calling ptm_get_sys_time()) into microseconds. Functions U32 ptm_get_sys_time

Return a free running 32-bit system timer. U32 ptm_sys_time_diff

Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time(). U32 ptm_sys_time_diff_update

Return the difference between the current system timer and a snapshot of that timer from a call to

Copyright 2019, Pi Innovo 118 Library interface

Type Identifier ptm_get_sys_time() and ptm_sys_time_diff_update(), updating the snapshot for the next call. U32 ptm_get_s_time

Return a free running 32-bit second timer. U32 ptm_s_time_diff

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time(). U32 ptm_s_time_diff_update

Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time() and ptm_s_time_diff_update(), updating the snapshot for the next call. U32 ptm_get_ms_time

Return a free running 32-bit millisecond timer. U32 ptm_ms_time_diff

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time(). U32 ptm_ms_time_diff_update

Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time() and ptm_ms_time_diff_update(), updating the snapshot for the next call. U32 ptm_get_us_time

Return a free running 32-bit microsecond timer. U32 ptm_us_time_diff

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time(). U32 ptm_us_time_diff_update

Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time() and ptm_us_time_diff_update(), updating the snapshot for the next call. 5.5.3. Interface detail 5.5.3.1. Macros

5.5.3.1.1. PTM_SYS_TIME_TO_US

Definition: #define PTM_SYS_TIME_TO_US (PTM_INT_SYS_TIME_TO_US)

Copyright 2019, Pi Innovo 119 Library interface

Description:

This is the division factor to convert from system time (returned by calling ptm_get_sys_time()) into microseconds. 5.5.3.2. Functions

5.5.3.2.1. ptm_get_sys_time()

Definition: U32 ptm_get_sys_time(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return a free running 32-bit system timer.

The system timer is a free running 32-bit timer. The timer increments, and wraps to zero when it overflows rather than saturating. The timer can be converted to microseconds by dividing by PTM_SYS_TIME_TO_US.

Return: The current value of the system timer. Range: [0, 4294967295] ticks

5.5.3.2.2. ptm_sys_time_diff()

Definition: U32 ptm_sys_time_diff(U32 ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time().

Arg (data in): ptmf_time The result of calling ptm_get_sys_time(). Range: [0, 4294967295] ticks

Return: The difference in time between the current value of the system timer and ptmf_time. Range: [0, 4294967295] ticks

5.5.3.2.3. ptm_sys_time_diff_update()

Definition: U32 ptm_sys_time_diff_update(U32 *ptmf_time)

Supported targets: All targets

Copyright 2019, Pi Innovo 120 Library interface

Required license: None (Main library).

Description: Return the difference between the current system timer and a snapshot of that timer from a call to ptm_get_sys_time() and ptm_sys_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time Pointer to the last snapshot of time (either by calling ptm_get_sys_time() initially, or ptm_sys_time_diff_update() subsequently). Range: [0, 4294967295] ticks

Return: The difference in time between the current value of the system timer and ptmf_time. Range: [0, 4294967295] ticks 5.5.3.2.4. ptm_get_s_time()

Definition: U32 ptm_get_s_time(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return a free running 32-bit second timer.

The second timer is a free running 32-bit timer. The timer increments each second and wraps to zero when it overflows rather than saturating.

Return: The current value of the second timer. Range: [0, 4294967295] seconds 5.5.3.2.5. ptm_s_time_diff()

Definition: U32 ptm_s_time_diff(U32 ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time().

Arg (data in): ptmf_time The result of calling ptm_get_s_time(). Range: [0, 4294967295] seconds

Return: The difference in time between the current value of the second timer and ptmf_time.

Copyright 2019, Pi Innovo 121 Library interface

Range: [0, 4294967295] seconds 5.5.3.2.6. ptm_s_time_diff_update()

Definition: U32 ptm_s_time_diff_update(U32 *ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current second timer and a snapshot of that timer from a call to ptm_get_s_time() and ptm_s_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time Pointer to the last snapshot of time (either by calling ptm_get_s_time() initially, or ptm_s_time_diff_update() subsequently). Range: [0, 4294967295] seconds

Return: The difference in time between the current value of the second timer and ptmf_time. Range: [0, 4294967295] seconds 5.5.3.2.7. ptm_get_ms_time()

Definition: U32 ptm_get_ms_time(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return a free running 32-bit millisecond timer.

The millisecond timer is a free running 32-bit timer. The timer increments each millisecond and wraps to zero when it overflows rather than saturating.

Return: The current value of the millisecond timer. Range: [0, 4294967295] milliseconds 5.5.3.2.8. ptm_ms_time_diff()

Definition: U32 ptm_ms_time_diff(U32 ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Copyright 2019, Pi Innovo 122 Library interface

Description: Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time().

Arg (data in): ptmf_time The result of calling ptm_get_ms_time(). Range: [0, 4294967295] milliseconds

Return: The difference in time between the current value of the millisecond timer and ptmf_time. Range: [0, 4294967295] milliseconds

5.5.3.2.9. ptm_ms_time_diff_update()

Definition: U32 ptm_ms_time_diff_update(U32 *ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current millisecond timer and a snapshot of that timer from a call to ptm_get_ms_time() and ptm_ms_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time Pointer to the last snapshot of time (either by calling ptm_get_ms_time() initially, or ptm_ms_time_diff_update() subsequently). Range: [0, 4294967295] milliseconds

Return: The difference in time between the current value of the millisecond timer and ptmf_time. Range: [0, 4294967295] milliseconds

5.5.3.2.10. ptm_get_us_time()

Definition: U32 ptm_get_us_time(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return a free running 32-bit microsecond timer.

The microsecond timer is a free running 32-bit timer. The timer increments each microsecond and wraps to zero when it overflows rather than saturating.

Return: The current value of the microsecond timer.

Copyright 2019, Pi Innovo 123 Library interface

Range: [0, 4294967295] microseconds 5.5.3.2.11. ptm_us_time_diff()

Definition: U32 ptm_us_time_diff(U32 ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time().

Arg (data in): ptmf_time The result of calling ptm_get_us_time(). Range: [0, 4294967295] microseconds

Return: The difference in time between the current value of the microsecond timer and ptmf_time. Range: [0, 4294967295] microseconds 5.5.3.2.12. ptm_us_time_diff_update()

Definition: U32 ptm_us_time_diff_update(U32 *ptmf_time)

Supported targets: All targets

Required license: None (Main library).

Description: Return the difference between the current microsecond timer and a snapshot of that timer from a call to ptm_get_us_time() and ptm_us_time_diff_update(), updating the snapshot for the next call.

Arg (data in): ptmf_time Pointer to the last snapshot of time (either by calling ptm_get_us_time() initially, or ptm_us_time_diff_update() subsequently). Range: [0, 4294967295] microseconds

Return: The difference in time between the current value of the microsecond timer and ptmf_time. Range: [0, 4294967295] microseconds 5.6. Task scheduling (PKN)

The task scheduling feature has the following responsibilities:

• non-nested interrupt dispatching (see Section 5.6.1.1, “Interrupt handling”);

• fixed priority pre-emptive task dispatching (see Section 5.6.1.2, “Preemptive scheduling”);

Copyright 2019, Pi Innovo 124 Library interface

• task timing (see Section 5.6.1.4, “Task timing”);

• resource locking between tasks (see Section 5.6.1.6, “Resource locking”);

• stack handling (see Section 5.6.1.3, “Stack sharing”).

The scheduling feature allows library and application tasks to be scheduled together. See Section 4.6.4, “Application and library tasks” for a list of the pre-defined library tasks and library resources. 5.6.1. Tasking model

The tasking model used by the feature can be represented as a series of state changes.

Figure 5.1. Tasking model states

Waiting

Ready Running

Terminated

All tasks are implemented as single-shot C functions, so each time a task runs it terminates and does not wait. Tasks start by becoming ready due to the periodicity of the task (handled by the scheduler) or due to another task or interrupt making it ready. When tasks are ready to run, they are executed in order from highest to lowest priority with pre-emption if necessary. 5.6.1.1. Interrupt handling

The scheduler feature handles interrupts in a non-nested manner. As the interrupt routines are kept as short as possible, they have a small timing impact on library and application tasks and do not introduce unnecessary latency between themselves.

The scheduler uses one interrupt source as a regular 1 millisecond tick. From this tick, all tasks with timing properties as scheduled.

Note

Interrupt handling is not exposed at the C interface level.

5.6.1.2. Preemptive scheduling

Each task has a priority relative to other tasks. Tasks with a low priority can (with a few exceptions) be interrupted immediately by tasks with a higher priority when those higher priority tasks become ready to run. This scheduling scheme is called fixed pre-emptive

Copyright 2019, Pi Innovo 125 Library interface

scheduling and can be analysed for various properties if need be (e.g., will a task complete before a given dead-line all the time regardless of other task activities).

Tasks are single-shot in nature, represented by a single C function. For example, a 10 millisecond task would be handled by a C function as follows:

void application_10ms_task(void) { /* Perform application processing. */ return; }

The task function takes no arguments and returns void. The function is invoked by the scheduler and performs the functionality of the application every 10 milliseconds before returning. On return, the scheduler determines if there are any lower priority tasks ready to run (or to continue to run) and schedules those according to their priority (highest to lowest). When no tasks are running, the scheduler allows the library background function to continue to run (the application can make use of this background function to perform its own processing if necessary).

Before a task returns, if a higher priority task becomes ready to run then the scheduler will pre-empt the task function (effectively stopping it) and start to run the function of the higher priority task, before returning to the original function to continue processing. In this fashion, processing which must occur on a more frequent basis can be assigned to a higher priority task and take precedence over less important processing.

Figure 5.2. Task pre-emption

Scheduler Highest priority

Task 2 High priority tb tc

Task 1 Low priority ta td

Background processing Time

Task becomes read to run.

Task completes and returns to scheduler.

The diagram shows the background processing function, a low and high priority task function, and the scheduler function. Shaded areas show when a function is running. Initially the background processing function is running. At time ta the low priority task becomes ready to run, the scheduler pre-empts the background function and starts the low priority task function. At time tb the high priority task becomes ready to run, the scheduler pre-empts the low priority task function and starts the high priority task function. At time tc the high priority task completes and the scheduler continues the low priority task function. At time td the low priority task completes and the scheduler continues the background processing function.

Shown on the same time-line, its easy to see how the processor is divided into running different task functions.

Copyright 2019, Pi Innovo 126 Library interface

Background processing ta tb tc td Time

Task becomes ready to run.

Task completes and returns to scheduler.

Scheduler – highest priority

Task 2 – high priority

Task 1 – low priority

Background processing

5.6.1.3. Stack sharing

The stack is setup during library pre-initialisation. By using a single shot function tasking model, context switch RAM usage is keep to a minimum, and all tasks share the same system stack. As a new task is scheduled to run, the context of the previous task or of the background processing function is stored on the stack, then the task function is called. This scheme makes for efficient use of stack on resource limited ECUs.

On some target ECUs, this means stack overflow can be caught immediately as an exception by the processor and handled appropriately. 5.6.1.4. Task timing

As the product is delivered as a library, the final overall task timing cannot be known in advance. To facilitate development, the feature times tasks as they run to record the last execution period and the maximum seen since power on (see pkn_task_start_time[], pkn_task_accum_time[], pkn_task_duration_time[] and pkn_max_task_duration_time[]).

The task duration may include pre-emption time from other tasks, so when the scheduler switches tasks, it adjusts the pre-empted task accordingly so that each task time recorded is the time it would have taken that task to run without pre-emption.

Note

This adjustment does not compensate for pre-emption from interrupts. As interrupts are short, no effort is made to adjust the task time to account for interrupts. Consequently, the task times will increase as the interrupt rates increase;

5.6.1.5. Task context switches

When the scheduler changes between tasks, the scheduler saves the integer and floating point processor context as defined by the application interface for the target ECU's processor. Tasks are free to use the processor's general registers as necessary. 5.6.1.6. Resource locking

The scheduler provides a mechanism for a task to lock a resource, thus preventing other tasks from accessing the same resource. The locking mechanism is implemented using the Immediate Priority Ceiling Protocol (IPCP). The protocol ensures that deadlock cannot occur if certain rules are followed (see Section 5.6.1.7, “Resource locking rules”).

Copyright 2019, Pi Innovo 127 Library interface

The scheduler keeps track of the currently running task with a ceiling. The ceiling is initially the priority level of the task that runs. Only tasks with priority above the ceiling can pre- empt the currently running task (equal priority tasks and lower priority tasks cannot). Calls to pkn_acquire_resource() and pkn_release_resource() adjust the priority ceiling.

Figure 5.3. Task pre-emption with resource locking

Scheduler Highest priority

Task 2 High priority

Task 1 Low priority ta tb tc td

Background processing Time

Task becomes read to run.

Task completes and returns to scheduler.

In this example, there are two tasks which both access the same resource. The diagram shows the background processing function is running initially. At time ta the low priority task becomes ready to run, the scheduler pre-empts the background function and starts the low priority task function. At time tb the low priority task locks a resource that both the high and low priority task share. At time tc the high priority task becomes ready to run but the scheduler does not start it because a resource shared by the high priority task is locked. At time td the low priority task releases the resource lock and because the high priority task is ready to run, the scheduler pre-empts the low-priority function and starts the high priority task function. The resource which was locked by the low priority function was modified by the low priority task only, the other task which could have modified the resource was prevented form running by the scheduler.

When a task wishes to lock a resource, the scheduler must ensure that only that task runs while accessing the resource. It does so by knowing in advance which tasks will access any resource. When any task requests a lock of the resource, the scheduler raises the ceiling priority to the highest priority of any task accessing that resource. This ensures that the task requesting the resource will not be pre-empted by any task also wishing to use the resource. 5.6.1.7. Resource locking rules

The IPCP only works correctly when certain rules are followed:

• resources must be locked by a task in a nested structure, i.e., acquire r1, acquire r2, do work, release r2, release r1;

• a task must not acquire a resource if it already holds that resource;

• a task must not release a resource without acquiring it first.

If these rules are not followed, then it is possible that the scheduler will not honour correct resource locking.

Copyright 2019, Pi Innovo 128 Library interface

5.6.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pkn.h Enumerations PKN_ERROR_CODE_T

Error values for debugging when an error is found in a call to the scheduler feature (PKN), the scheduler calls a system error log function with an enumeration from this type. Data types PKN_TASKSET_T

The type for a group of tasks. PKN_TASK_HANDLE_T

This type specifies a task handle. PKN_PERIODIC_TASK_HANDLE_T

This type specifies a periodic task handle. PKN_RESOURCE_HANDLE_T

This type specifies a resource handle. PKN_ILEVEL_T

This type specifies an atomic word large enough to hold the bit pattern for all interrupt levels. Functions void pkn_acquire_resource

Acquire a resource and raise the priority of this task so that others cannot acquire the same resource. void pkn_release_resource

Release a resource and lower the priority to the calling task's actual priority (or dispatch any ready tasks with higher priority). void pkn_ready_task

Make a task ready to run. U32 pkn_get_task_duration

Return the last measured duration of a task. U32 pkn_get_max_task_duration

Return the maximum duration of a task since the scheduler was initialised. U8 pkn_get_task_overrun_count

Copyright 2019, Pi Innovo 129 Library interface

Type Identifier Return the number of times the task has overrun. U8 pkn_get_task_skip_count

Return the number of times the task has been skipped. 5.6.3. Interface detail 5.6.3.1. Enumerations 5.6.3.1.1. PKN_ERROR_CODE_T

Summary: Error values for debugging when an error is found in a call to the scheduler feature (PKN), the scheduler calls a system error log function with an enumeration from this type.

Enumerations:

PKN_ERR_KERNEL_STARTED_BELOW_KERNEL_LEVEL Error raised if the scheduler is started under the wrong interrupt conditions (internal error).

PKN_ERR_INVALID_RESOURCE_HANDLE Error raised if the scheduler finds the resource does not exist in the internal resource array.

PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE Error raised if the scheduler finds the calling task was not declared as acquiring the resource.

PKN_ERR_INVALID_TASK_HANDLE Error raised if the scheduler finds the task handle does not exist in the internal task array.

PKN_ERR_INVALID_PERIODIC_TASK_HANDLE Error raised if the scheduler finds the task handle does not exist in the internal periodic task array.

PKN_ERR_PERIODIC_TASK_HAS_NO_PERIOD Error raised if the scheduler detected a periodic task that has a period of zero milliseconds.

PKN_ERR_UNEXPECTED_EXCEPTION Error raised if the scheduler traps an unexpected processor exception.

PKN_ERR_UNEXPECTED_INTERRUPT Error raised if the scheduler traps an unexpected processor interrupt. 5.6.3.2. Data types 5.6.3.2.1. PKN_TASKSET_T

Definition: typedef U32 PKN_TASKSET_T

Description: The type for a group of tasks.

Copyright 2019, Pi Innovo 130 Library interface

A task is a group of functionality that can be run when the task becomes ready. A task can become ready periodically (e.g., scheduled every x ms) or sporadically (e.g., when a sporadic interrupt is processed).

A task has a fixed priority level and tasks ready to run are executed in a pre-emptive fashion where each task release is single shot (think of nested interrupt levels).

A task set is a set of tasks with a common property, e.g., a set of tasks ready to run, or a set of tasks with priority lower than the currently running task.

A task set is represented as a bit set of task bit patterns. Each task is assigned a single bit position in the representation and can be identified by isolating the bit.

As the tasks have a priority ordering, the order of the bits assigned to tasks take the same ordering.

E.g., the highest priority task takes the MS bit (note: PPC bit numbering):

MSB LSB bit 0 bit 31

1 0 0 0 0 0 0 0 0 0

and the second highest priority task takes the second MS bit:

MSB LSB bit 0 bit 31

0 1 0 0 0 0 0 0 0 0

and so on.

A task set or more than one task is then simply the bitwise OR of each task's bit pattern.

E.g., the task set of the second highest task and fourth highest task is represented as:

MSB LSB bit 0 bit 31

0 1 0 1 0 0 0 0 0 0

The bit pattern representation makes finding the highest priority task of a task set easy to find. On the PPC architecture, the count leading zeros machine instruction cntlzw returns the bit position of the MS set bit or 32 if no set bits exist.

When running a task, pre-emption from another source can cause a higher priority task to become ready. The kernel will pre-empt the running task and start running the higher priority task.

To make it easy to determine if a new higher priority task has been make ready to run, the kernel keeps a record of the priority that the current task is running at. This is called the task's ceiling.

Copyright 2019, Pi Innovo 131 Library interface

The ceiling is represented as a task set of the currently running task and all lower priority tasks.

E.g., if the fourth highest priority task is running, then the ceiling task set would be:

MSB LSB bit 0 bit 31

0 0 0 1 1 1 1 1 1 1

This representation of the ceiling makes it simple to determine is a higher priority task is ready to run. If the ready taskset is greater is value than the ceiling, then there is at least one task with priority higher than the ceiling.

E.g., consider a running task with the fourth highest priority level when the second highest priority task becomes ready to run.

This type specifies an atomic word large enough to hold a task set for up to 32 tasks. 5.6.3.2.2. PKN_TASK_HANDLE_T

Definition: typedef const PKN_TASK_T* const PKN_TASK_HANDLE_T

Description: This type specifies a task handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

The implementation of handles uses pointers for efficiency. 5.6.3.2.3. PKN_PERIODIC_TASK_HANDLE_T

Definition: typedef const PKN_PERIODIC_TASK_T* const PKN_PERIODIC_TASK_HANDLE_T

Description: This type specifies a periodic task handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

The implementation of handles uses pointers for efficiency. 5.6.3.2.4. PKN_RESOURCE_HANDLE_T

Definition: typedef const PKN_RESOURCE_T* const PKN_RESOURCE_HANDLE_T

Description: This type specifies a resource handle.

A handle is presented to the kernel API whenever the user requires some action to occur on the handle's object.

Copyright 2019, Pi Innovo 132 Library interface

The implementation of handles uses pointers for efficiency. 5.6.3.2.5. PKN_ILEVEL_T

Definition: typedef U32 PKN_ILEVEL_T

Description: This type specifies an atomic word large enough to hold the bit pattern for all interrupt levels.

The kernel has the concept of a suspended kernel or a running kernel.

When the kernel is suspended, there will be no API calls to the kernel from application code. This is achieved by raising the interrupt level high enough that no preemption of the kernel by an exception that calls the kernel will occur.

When the kernel is running, there will be API calls to the kernel from application code. This is achieved by lowering the interrupt level enough that preemption of tasks and non-critical kernel code can occur. 5.6.3.3. Functions

5.6.3.3.1. pkn_acquire_resource()

Definition: void pkn_acquire_resource(const PKN_RESOURCE_HANDLE_T pknf_r_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Acquire a resource and raise the priority of this task so that others cannot acquire the same resource.

Implements part of the Immediate Priority Ceiling Protocol (IPCP) for resource control. The function locks a resource by raising the priority of the current task to the priority of the highest task that will lock the resource.

Callable by application when tasking given the following constraints:

• resources must be locked by a task in a nested structure, i.e., acquire r1, acquire r2, ...., release r2, release r1, to satisfy the priority ceiling protocol;

• a task must not acquire a resource if it already holds that resource;

• a task must not release a resource without acquiring it first.

If a task finishes without releasing its acquired resources, the scheduler automatically releases any acquired.

Can raise the following errors: PKN_ERR_INVALID_RESOURCE_HANDLE, PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE.

Copyright 2019, Pi Innovo 133 Library interface

Arg (data in): pknf_r_hd A pointer to a resource. The resource itself specifies which tasks can acquire this resource, the ceiling of those tasks and a pointer to a buffer to store context. Cannot be NULL. 5.6.3.3.2. pkn_release_resource()

Definition: void pkn_release_resource(const PKN_RESOURCE_HANDLE_T pknf_r_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Release a resource and lower the priority to the calling task's actual priority (or dispatch any ready tasks with higher priority).

Implements part of the Immediate Priority Ceiling Protocol (IPCP) for resource control. It unlocks a resource by lowering the priority of the current task to the priority that locked it and if necessary, dispatches any tasks with higher priority that were made ready while the resource was locked.

Can raise the following errors: PKN_ERR_INVALID_RESOURCE_HANDLE, PKN_ERR_TASK_NOT_DECLARED_AS_ACQUIRING_RESOURCE.

Callable in the same context as pkn_acquire_resource().

Arg (data in): pknf_r_hd A pointer to a resource. The resource itself specifies which tasks can acquire this resource, the ceiling of those tasks and a pointer to a buffer to store context. Cannot be NULL. 5.6.3.3.3. pkn_ready_task()

Definition: void pkn_ready_task(const PKN_TASK_HANDLE_T pknf_t_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Make a task ready to run.

Make a task ready to run when not handling an interrupt. The task will be dispatched if it has higher priority than the calling task. The task will not be dispatched immediately if the priority of the task to make ready is lower than the current, but will be dispatched after all higher priority tasks have completed.

Can raise the following errors: PKN_ERR_INVALID_TASK_HANDLE.

Copyright 2019, Pi Innovo 134 Library interface

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs. Cannot be NULL. 5.6.3.3.4. pkn_get_task_duration()

Definition: U32 pkn_get_task_duration(const PKN_TASK_HANDLE_T pknf_t_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Return the last measured duration of a task.

Return the last measured duration of a task in microseconds. The duration may include the duration of the task and the duration of any interrupts that occurred while the task was running, but does not include the duration of any tasks that pre-empted the task while it was running.

Can raise the following errors: PKN_ERR_INVALID_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs. Cannot be NULL.

Return: The last measured duration of a task in microseconds Range: [0, 4294967295] microseconds. 5.6.3.3.5. pkn_get_max_task_duration()

Definition: U32 pkn_get_max_task_duration(const PKN_TASK_HANDLE_T pknf_t_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Return the maximum duration of a task since the scheduler was initialised.

Return the maximum measured duration of a task in microseconds. The duration may include the duration of the task and the duration of any interrupts that occurred while the task was running, but does not include the duration of any tasks that pre-empted the task while it was running.

Can raise the following errors: PKN_ERR_INVALID_TASK_HANDLE.

Copyright 2019, Pi Innovo 135 Library interface

Callable by the application at the tasking level.

Arg (data in): pknf_t_hd A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs. Cannot be NULL.

Return: The maximum measured duration of a task in microseconds Range: [0, 4294967295] microseconds. 5.6.3.3.6. pkn_get_task_overrun_count()

Definition: U8 pkn_get_task_overrun_count(const PKN_PERIODIC_TASK_HANDLE_T pknf_pt_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Return the number of times the task has overrun.

When a periodic task comes up to be scheduled and still running, then the overrun count for that task is incremented.

Can raise the following errors: PKN_ERR_INVALID_PERIODIC_TASK_HANDLE.

Callable by the application at the tasking level.

Arg (data in): pknf_pt_hd A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs. Cannot be NULL.

Return: The number of times the task has overrun. Range: [0, 255] count. 5.6.3.3.7. pkn_get_task_skip_count()

Definition: U8 pkn_get_task_skip_count(const PKN_PERIODIC_TASK_HANDLE_T pknf_pt_hd)

Supported targets: All targets

Required license: None (Main library).

Description: Return the number of times the task has been skipped.

When a task is made ready to run, but is already ready to run and hasn't started the previous invocation, then the skip count for that task is incremented.

Can raise the following errors: PKN_ERR_INVALID_PERIODIC_TASK_HANDLE.

Copyright 2019, Pi Innovo 136 Library interface

Callable by the application at the tasking level.

Arg (data in): pknf_pt_hd A pointer to a task structure. The task specifies the priority it should run at as well as the function to call when the task runs. Cannot be NULL.

Return: The number of times the task has been skipped. Range: [0, 255] count. 5.7. Library input and output configuration (PIO) 5.7.1. Overview

The PIO feature provides a set of macros to be used when calling some of the C-API functions. The macros vary based on the target the application code is written for. An example would be configuring a CAN bus during application initialisation:

/* Call the library to initialise the CAN buses, ignoring the return value. */ (void) pcx_config(PIO_CAN_A28_A43 , PIO_CBAUD_500_KBPS );

The macro PIO_CAN_A28_A43 (for the M220 target) selects the first CAN bus. The ECU connector pins are included in the macro name (A28_A43) so there is a simple relationship between macro and pin.

The macro PIO_CBAUD_500_KBPS (for the M220 target) selects a baud rate of 500 kBps for the first CAN bus.

The macro names are formed so that they are easily associated with their use.

ECU configuration Take the form PIO_CFG_[ITEM] for parameters which can be used to change the behaviour of the ECU. For instance PIO_CFG_HEGO_FILTER_160HZ selects a 160Hz filter for the HEGO analogue input pins supported by an ECU.

CAN buses and baud rates Take the form PIO_CAN_[PIN-NAMES] for CAN buses, and the form PIO_CBAUD_[BAUD]_KBPS for baud rates.

Analogue inputs Take the form PIO_AIN_[PIN-NAME] for connector pins, the form PIO_AIN_INT_[FUNCTION] for internal inputs, the form PIO_AIN_[PIN- NAME]_MONITOR for internal monitor inputs.

Digital inputs Take the form PIO_DIN_[PIN-NAME] for connector pins, the form PIO_DIN_INT_[FUNCTION] for internal inputs, the form PIO_DIN_[PIN- NAME]_MONITOR for internal monitor inputs.

Frequency inputs Take the form PIO_FIN_[PIN-NAME] for connector pins, the form PIO_FIN_INT_[FUNCTION] for internal inputs, the form PIO_FIN_[PIN- NAME]_MONITOR for internal monitor inputs.

Period inputs Take the form PIO_PIN_[PIN-NAME] for connector pins, the form PIO_PIN_INT_[FUNCTION] for internal inputs, the form PIO_PIN_[PIN- NAME]_MONITOR for internal monitor inputs.

Copyright 2019, Pi Innovo 137 Library interface

Quadrature inputs Take the form PIO_QDIN_[PIN-NAME] or PIO_QFIN_[PIN-NAME] for connector pins, the form PIO_QDIN_INT_[FUNCTION] or PIO_QFIN_INT_[FUNCTION] for internal inputs, or the form PIO_QDIN_[PIN-NAME]_MONITOR or PIO_QFIN_[PIN- NAME]_MONITOR for internal monitor inputs. Pins using QDIN do not support frequency measurement, pins using QFIN support frequency measurement.

Constant current outputs Take the form PIO_CCOT_[PIN-NAME] for connector pins, the form PIO_CCOT_INT_[FUNCTION] for internal outputs, the form PIO_CCOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Digital outputs Take the form PIO_DOT_[PIN-NAME] for connector pins, the form PIO_DOT_INT_[FUNCTION] for internal outputs, the form PIO_DOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Ignition (angular) outputs Take the form PIO_IGNOT_[PIN-NAME] for connector pins, the form PIO_IGNOT_INT_[FUNCTION] for internal outputs, the form PIO_IGNOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Injection (angular) outputs Take the form PIO_INJOT_[PIN-NAME] for connector pins, the form PIO_INJOT_INT_[FUNCTION] for internal outputs, the form PIO_INJOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

PWM outputs Take the form PIO_POT_[PIN-NAME] for connector pins, the form PIO_POT_INT_[FUNCTION] for internal outputs, the form PIO_POT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Synchronised PWM outputs Take the form PIO_SPOT_[PIN-NAME] for connector pins, the form PIO_SPOT_INT_[FUNCTION] for internal outputs, the form PIO_SPOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Stepper motor outputs Take the form PIO_SMOT_[PIN-NAME] for connector pins, the form PIO_SMOT_INT_[FUNCTION] for internal outputs, the form PIO_SMOT_[PIN- NAME]_[FUNCTION] for internal outputs related to connector pins.

Note

Not all targets are capable of supporting each of the input and output types listed above. In this case, the PIO header files explicitly state there is no support and do not provide any macros for that I/O type.

Unlike other features, the interface to the PIO feature varies per target. For this reason, there is no interface detail in this user guide, refer instead to the PIO header files. 5.8. Feature for specific target configuration (PCFG) 5.8.1. Overview

This feature provides a way to define ECU specific configuration settings for some ECUs that are not available on all ECUs.

Copyright 2019, Pi Innovo 138 Library interface

5.8.2. M110, M220 and M461 targets

No target specific configuration is available for this target. 5.8.3. M250 target

The configuration of pins A32, A33 and A34 as injectors or a PWM outputs can be achieved by calling pcfg_setup_m250() during application initialisation. If the pin is configured as a PWM output then the current trip level can also be selected. The library configures pin appropriately during library post-initialisation.

The M250-00Z comes with an IMU attached which contains three gyroscopes and an accelerometer. To configure the sample rates of the gyroscopes and the accelerometer to something other than their default values, call the function pcfg_imu_rate() during application initialisation. 5.8.4. M460 target

The configuration of pin A31 as an injector or a PWM output can be achieved by calling pcfg_setup_m460() during application initialisation. If the pin is configured as a PWM output then the current trip level can also be selected. The library configures pin appropriately during library post-initialisation. 5.8.5. M670 target

Certain frequency inputs can be configured by calling pcfg_setup_pwm_clock_m670() during application initialisation. This function will configure the pin's timebase to control the resolution of the input. 5.8.6. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pcfg.h Enumerations PCFG_RC_T

An enumerated type which contains success and failure codes returned by some ECU configuration feature (PCFG) functions. PCFG_ERROR_CODE_T

Error values for debugging when an error is found when executing the PCFG feature, the API calls a function with an enumeration from this type. Functions PCFG_RC_T pcfg_imu_rate

Function to configure the sampling rate of an IMU channel.

Copyright 2019, Pi Innovo 139 Library interface

Type Identifier PCFG_RC_T pcfg_setup_m250

Set the configuration for channel A32, A33 and A34 (either as injector or PWM output). void pcfg_softswitch_m460

Set the configuration for channel A31 (either as injector or PWM output) (deprecated). PCFG_RC_T pcfg_setup_m460

Set the configuration for channel A31 (either as injector or PWM output). PCFG_RC_T pcfg_setup_pwm_clock_m5xx

Set the clock configuration for frequency input channels. PCFG_RC_T pcfg_set_global_mios_prescaler_m5xx

Set the clock configuration for global MIOS frequency. PCFG_RC_T pcfg_setup_pwm_clock_m670

Set the clock configuration for frequency input channels. 5.8.7. Interface detail 5.8.7.1. Enumerations

5.8.7.1.1. PCFG_RC_T

Summary: An enumerated type which contains success and failure codes returned by some ECU configuration feature (PCFG) functions.

Enumerations:

PCFG_RC_OK Return code if everything progressed as expected.

PCFG_RC_SAMPLE_RATE_TOO_LOW Return code if the desired sample rate is too low.

PCFG_RC_SAMPLE_RATE_TOO_HIGH Return code if the desired sample rate is too high.

PCFG_RC_INVALID_CHAN Return code if an internal error occurred which was the result of a software error.

PCFG_RC_BAD_ARGS_HEGO Return code if at least one of the arguments relating to the HEGO filter selection could not be used.

PCFG_RC_BAD_ARGS_TYPE Return code if at least one of the arguments relating to the pin type selection could not be used (M460).

Copyright 2019, Pi Innovo 140 Library interface

PCFG_RC_BAD_ARGS_HYST Return code if at least one of the arguments relating to the pin hysteresis selection could not be used.

PCFG_RC_BAD_ARGS_NOM_CT Return code if at least one of the arguments relating to the spark nominal current-trip selection could not be used.

PCFG_RC_BAD_ARGS_MAX_CT Return code if at least one of the arguments relating to the spark maximum current-trip selection could not be used.

PCFG_RC_BAD_ARGS_INJ_CT Return code if at least one of the arguments relating to the current- trip selection or current threshold could not be used (M460, M461).

PCFG_RC_BAD_ARGS_MIOS_CLK Return code if at least one of the arguments relating to the MIOS clock selection could not be used (M670).

5.8.7.1.2. PCFG_ERROR_CODE_T

Summary: Error values for debugging when an error is found when executing the PCFG feature, the API calls a function with an enumeration from this type.

Enumerations:

PCFG_INTERNAL_SW_ERROR Error raised when an internal is detected.

Contact Pi Innovo support if encountered. 5.8.7.2. Functions

5.8.7.2.1. pcfg_imu_rate()

Definition: PCFG_RC_T pcfg_imu_rate(PIO_CFG_SAMPLE_RATE_CHAN_T pcfgf_chan, U16 pcfgf_sample_rate)

Required license: None (Main library).

Description: Function to configure the sampling rate of an IMU channel.

Supported by targets: M250-00Z.

Arg (data in): pcfgf_chan The IMU channel needed to configure the sampling rate. This generally will include an accelerometer and a gyroscope. Use the macros included by pio.h defined in the in the enum PIO_CFG_SAMPLE_RATE_CHAN_T.

Arg (data in): pcfgf_sample_rate The sample rate to be set for the accelerometer or the gyroscope on the M250. Note that the default sample rate on the accelerometer is

Copyright 2019, Pi Innovo 141 Library interface

40Hz and the default sample rate on the gyroscope is 2048 samples per second. Range (accelerometer): The accelerometer only has four options for the sample rate: 40Hz, 160Hz, 640Hz, 2560Hz Range (gyroscope): [4 256] or 2048 Samples Per Second

Note

This function will choose the closest sample rate value to the desired sample rate value.

Return:

• PCFG_RC_OK - successful action

• PCFG_RC_INVALID_CHAN - channel not supported

• PCFG_RC_SAMPLE_RATE_TOO_HIGH - sample rate is too high

• PCFG_RC_SAMPLE_RATE_TOO_LOW - sample rate is too low 5.8.7.2.2. pcfg_setup_m250()

Definition: PCFG_RC_T pcfg_setup_m250(PIO_CFG_OUTPUT_TYPE_T pcfgf_output_type_a32, PIO_CFG_CURRENT_TRIP_T pcfgf_current_trip_level_a32, PIO_CFG_OUTPUT_TYPE_T pcfgf_output_type_a33, PIO_CFG_CURRENT_TRIP_T pcfgf_current_trip_level_a33, PIO_CFG_OUTPUT_TYPE_T pcfgf_output_type_a34, PIO_CFG_CURRENT_TRIP_T pcfgf_current_trip_level_a34)

Supported targets:

Required license: None (Main library).

Description: Set the configuration for channel A32, A33 and A34 (either as injector or PWM output).

Configure the output type for pin A32, A33 and A34 pins, either injector or PWM. When the output has PWM type, the current trip level of the output can be selected (current trip level is not selectable for injector types).

If this function is not called during initialisation, pins A32, A33 and A34 default to PWM type with a current trip level of 5A.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): pcfgf_output_type_a32 PIO_CFG_OUTPUT_TYPE_INJ to set A32 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A32 channel as a PWM output or digital output.

Copyright 2019, Pi Innovo 142 Library interface

Arg (data in): pcfgf_current_trip_level_a32 PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A32 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A32 to ~2A. Valid only if pcfgf_output_type_a32 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Arg (data in): pcfgf_output_type_a33 PIO_CFG_OUTPUT_TYPE_INJ to set A33 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A33 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a33 PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A33 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A33 to ~2A. Valid only if pcfgf_output_type_a33 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Arg (data in): pcfgf_output_type_a34 PIO_CFG_OUTPUT_TYPE_INJ to set A34 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A34 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a34 PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A34 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A34 to ~2A. Valid only if pcfgf_output_type_a34 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Return:

• PCFG_RC_OK - if successful action

• PCFG_RC_BAD_ARGS_TYPE - if configuration error on pin type parameter

• PCFG_RC_BAD_ARGS_INJ_CT - if configuration error on current trip parameter 5.8.7.2.3. pcfg_softswitch_m460()

Definition: void pcfg_softswitch_m460(BOOL pcfgf_softswitch_state)

Supported targets:

Required license: None (Main library).

Description: Set the configuration for channel A31 (either as injector or PWM output) (deprecated).

Similar in functionality to pcfg_setup_m460(). This function became deprecated in version 1.8.0 and will be removed in a future release. The function is currently retained to provide backwards compatibility to previous releases.

Warning

The function must be called during application initialisation and never during application run.

Copyright 2019, Pi Innovo 143 Library interface

Arg (data in): pcfgf_softswitch_state TRUE to set A31 channel as an injector output, FALSE to set A31 channel as a PWM output with a current trip level of ~5A. 5.8.7.2.4. pcfg_setup_m460()

Definition: PCFG_RC_T pcfg_setup_m460(PIO_CFG_OUTPUT_TYPE_T pcfgf_output_type_a31, PIO_CFG_CURRENT_TRIP_T pcfgf_current_trip_level_a31)

Supported targets:

Required license: None (Main library).

Description: Set the configuration for channel A31 (either as injector or PWM output).

Configure the output type for pin A31, either injector or PWM. When the output has PWM type, the current trip level of the output can be selected (current trip level is not selectable for injector types).

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): pcfgf_output_type_a31 PIO_CFG_OUTPUT_TYPE_INJ to set A31 channel as an injector output, PIO_CFG_OUTPUT_TYPE_PWM to set A31 channel as a PWM output or digital output.

Arg (data in): pcfgf_current_trip_level_a31 PIO_CFG_CURRENT_TRIP_5A to set current trip level for pin A31 to ~5A; PIO_CFG_CURRENT_TRIP_2A to set current trip level for pin A31 to ~2A. Valid only if pcfgf_output_type_a31 is set to PIO_CFG_OUTPUT_TYPE_PWM.

Return:

• PCFG_RC_OK - if successful action

• PCFG_RC_BAD_ARGS_TYPE - if configuration error on pin type parameter

• PCFG_RC_BAD_ARGS_INJ_CT - if configuration error on current trip parameter 5.8.7.2.5. pcfg_setup_pwm_clock_m5xx()

Definition: PCFG_RC_T pcfg_setup_pwm_clock_m5xx(PDX_LCHAN_T pcfgf_mios_chan, PIO_CFG_MIOS_CLOCK_SELECT_T pcfgf_clock_select)

Supported targets:

Required license: None (Main library).

Copyright 2019, Pi Innovo 144 Library interface

Description: Set the clock configuration for frequency input channels.

For MIOS-controlled digital I/O, multiple clock speeds can be chosen, based on a global time base of 1.6 MHz or 400 kHz:

• Slow clock: 400 kHz/100 kHz timebase.

• Medium Slow Clock: 533 kHz/133 kHz timebase.

• Medium Clock: 800 kHz/200 kHz timebase.

• Fast Clock: 1.6 Mhz/400 kHz timebase.

If this function is not called during initialisation before the channel's corresponding initialisation function is called, then it will by default use the slow clock.

Warning

The function must be called during application initialisation before the initialisation function is called for that channel.

Arg (data in): pcfgf_mios_chan The channel to be configured with a particular clock selection. Only eMIOS-based channels are configurable.

Arg (data in): pcfgf_clock_select PIO_CFG_MIOS_CLOCK_SELECT_SLOW to set channel to use the slow clock PIO_CFG_MIOS_CLOCK_SELECT_MEDSLOW to set channel to use the medium slow clock PIO_CFG_MIOS_CLOCK_SELECT_MED to set channel to use the medium clock PIO_CFG_MIOS_CLOCK_SELECT_FAST to set channel to use the fast clock

Return:

• PCFG_RC_OK - if successful action

• PCFG_RC_INVALID_CHAN - if configuration error on pin selection

• PCFG_RC_BAD_ARGS_MIOS_CLK - if configuration error on clock speed parameter

5.8.7.2.6. pcfg_set_global_mios_prescaler_m5xx()

Definition: PCFG_RC_T pcfg_set_global_mios_prescaler_m5xx(PIO_CFG_MIOS_GLOBAL_SELECT_T pcfgf_global_pre)

Supported targets:

Required license: None (Main library).

Description: Set the clock configuration for global MIOS frequency.

Copyright 2019, Pi Innovo 145 Library interface

For MIOS-controlled digital I/O, an 80KHz peripheral clock can be divided to provide a MIOS global clock of 1.6 MHz or 400 kHz:

If this function is not called during initialisation before the channel's corresponding initialisation function is called, then it will by default use the slow clock.

Warning

The function must be called during application initialisation before the initialisation function is called for that channel.

Arg (data in): pcfgf_global_pre PIO_CFG_MIOS_GLOBAL_SLOW to set a divider of 200 PIO_CFG_MIOS_GLOBAL_FAST to set a divider of 50

Return:

• PCFG_RC_OK - if successful action

• PCFG_RC_BAD_ARGS_MIOS_CLK - if configuration error on clock speed parameter

5.8.7.2.7. pcfg_setup_pwm_clock_m670()

Definition: PCFG_RC_T pcfg_setup_pwm_clock_m670(PDX_LCHAN_T pcfgf_mios_chan, PIO_CFG_MIOS_CLOCK_SELECT_T pcfgf_clock_select)

Supported targets:

Required license: None (Main library).

Description: Set the clock configuration for frequency input channels.

For MIOS-controlled digital I/O, multiple clock speeds can be chosen:

• Slow clock: 4.125Mhz timebase.

• Medium Clock: 8.25Mhz timebase. For inputs 0.75 Hz to 2500 Hz with a minimum resolution of at least 0.5 Hz

• Fast Clock: 16.5Mhz timebase. For inputs 1.6 kHz to 60 kHz with a minimum resolution of at least 218 Hz.

If this function is not called during initialisation before the channel's corresponding initialisation function is called, then it will by default use the slow clock.

Warning

The function must be called during application initialisation before the initialisation function is called for that channel.

Copyright 2019, Pi Innovo 146 Library interface

Arg (data in): pcfgf_mios_chan The channel to be configured with a particular clock selection. Only eMIOS-based channels are configurable.

Arg (data in): pcfgf_clock_select PIO_CFG_MIOS_CLOCK_SELECT_SLOW to set channel to use the slow clock PIO_CFG_MIOS_CLOCK_SELECT_MED to set channel to use the medium clock PIO_CFG_MIOS_CLOCK_SELECT_FAST to set channel to use the fast clock

Return:

• PCFG_RC_OK - if successful action

• PCFG_RC_INVALID_CHAN - if configuration error on pin selection

• PCFG_RC_BAD_ARGS_MIOS_CLK - if configuration error on clock speed parameter 5.9. Analogue input/output feature (PAX) 5.9.1. Overview 5.9.1.1. Hardware effects on signals

The functions work at the level of the micro-processor pin but the input and output circuitry of the ECU may change the characteristics of the signal. For instance, the input circuitry may include filtering. See the technical specification in Section A.1, “ECU hardware reference documentation” for a description of how the input and output circuitry works for an ECU. 5.9.1.2. Analogue input

The library supports reading the state of an analogue input as seen at the micro-processor pin (see pax_adc_input()). Across the target ECUs some A/D converters have different resolutions. To avoid ambiguity as code is ported between targets, the result of an A/D conversion is always scaled to the range [-1, 1] @ 1/4096 A/D counts per bit (i.e., as if the A/D conversion was 12-bit in range) with the exception of the values coming off of the IMU on the M250-00Z which may have a wider scaling range. Please see the M250 technical specification for further details regarding the scaling. The application must scale the raw A/D conversion to engineering units, and the utility functions put_cal_map_1d_f32(), put_leaky_bucket_f32(), or put_process_analog_input() can all help.

On all modules, the worst case conversion time for an A/D value is ~500µs. Thus, when the software asks for a A/D conversion, the A/D value may be up to 500µs old.

Most target ECUs provide internal signals for determining the reference voltage used for conversion, and this can be used for ratio-metric inputs. 5.9.1.3. Analogue output

The library supports writing an analog output via a SPI analogue output device. Please see pax_dac_output() for details. The analogue output functionality is currently only supported on the M221.

The analogue output function uses the SPI device to talk from the ECU to a digital potentiometer which sets the analogue output resistance. The output is set by passing a value of 0 to 1 which represents the fraction of the total output resistance range as defined by the circuit. For details on the output resistance, see the technical specification for the target hardware that you are using.

Copyright 2019, Pi Innovo 147 Library interface

5.9.1.4. Constant current output

The library supports driving constant current output (see pax_cc_output()). Across the target ECUs some constant current output devices have different resolutions. 5.9.1.5. Constant current dither

The library supports a hardware controlled dither for TLE8242-2 outputs (see pax_cc_config_tle8242()). The dither waveform is specified by the number of dither steps and the size of each step. Each output pulse advances the dither waveform by one step. The following diagram demonstrates the relationship between the pulse period, number of dither steps, and the dither step size.

Figure 5.4. TLE8242-2 Dither

Pulse Period

Pulse Output

Dither Step

Dither Waveform ¼ Dither Waveform

Setpoint

Dither Step Size Pulse Start Pulse

Time

Copyright 2019, Pi Innovo 148 Library interface

5.9.1.6. Constant current PI control

The library supports configurable hardware PI control for TLE8242-2 outputs (see pax_cc_config_tle8242()). Each channel of the TLE8242-2 device includes a separate PI controller with programmable gain values KP and KI. The Infineon TLE7242 KI KP Application note describes a method to determine acceptable KP and KI values. A summary is included here; Please refer the the Infineon application note for additional details.

Acceptable KP and KI values may be determined by modeling the control system with a linear continuous time model.

Figure 5.5. TLE8242-2 constant current control diagram

Parameters required to calculate KP and KI

VBAT Supply voltage of the load.

Rc Resistance of the load.

Lc Inductance of the load measured at the pulse frequency.

Rsense Sense resistance value. This value is determined by the OpenECU hardware. It is 100 mR for all outputs.

Fclk Master clock frequency of the TLE8242-2 device. The frequency is set to 22 MHz by the OpenECU platform.

FPWM Pulse frequency of the output channel.

Procedure to calculate KP and KI

Determine Pulse Frequency Set pulse frequency to the upper limit unless some constraint of the load requires it to be lower.

Determine the damping ratio of the system Start with 0.707. Increase toward 1 to reduce overshoot. Decrease to improve rise time. The damping ratio is denoted by zeta in the supplied equations.

Determine the undamped natural frequency Calculate according to equation 1. Decreasing will result in longer settling time and increased dither amplitude attenuation. Increasing will lead to poor matching of the linear model to the system.

Calculate KP' and KI' Calculate according to equations 2 and 3. If KP' is less than zero, then the pulse frequency is too low.

Copyright 2019, Pi Innovo 149 Library interface

Calculate KP and KI Calculate according to equations 4 and 5. If KP or KI is greater than 4095, then the undamped natural frequency must be decreased.

Figure 5.6. TLE8242-2 KP and KI equations

5.9.1.7. External devices

There are two types of I/O on OpenECU hardware: direct and indirect I/O.

Figure 5.7. Direct and indirect analogue outputs

Direct output signal Output circuitry

To external actuators Processor Output Output device circuitry Serial Direct communications output signal

Internal to ECU External to ECU

Direct I/O Direct I/O takes place on demand. The application calls the necessary function and the function takes a measurement or sets a driver accordingly.

Indirect I/O Indirect I/O is delayed. The application calls the necessary function but the data to be read or set is actioned some time after the function returns.

Indirect I/O always occurs when there is an device between the processor and the pin. The device communicates to the processor across a serial link and it is this communication which introduces the delay. Serial communication is initiated at the end of any task which accesses the device to perform an I/O operation. This is accomplished by calling psp_spi_trigger()

Copyright 2019, Pi Innovo 150 Library interface

at the end of each application task. Only I/O channels noted as serial in the technical specification (see Section A.1, “ECU hardware reference documentation”) are affected. 5.9.1.8. Monitors

Each target ECU provides some measure of feedback for a subset of the output pins. For instance, measuring the reference voltage for A/D conversions to determine if the reference voltage generator has failed. A complete list of the monitors can be found in the technical specifications (see Section A.1, “ECU hardware reference documentation”). Each monitor is read by using one of the existing feature functions, e.g., by calling pax_adc_input() to read the analogue voltage of a monitor. 5.9.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pax.h Enumerations PAX_RC_T

An enumerated type which contains success and failure codes returned by some analogue input feature (PAX) functions. PAX_ERROR_CODE_T

Error values for debugging when an error is found when calling the analogue input feature (PAX), the API calls a function with an enumeration from this type. Data types PAX_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets. Functions PAX_RC_T pax_adc_input

Function to initialise or read an analogue input channel. PAX_RC_T pax_cc_output

Function to initialise or drive a constant current output channel. PAX_RC_T pax_dac_output

Function to drive an analogue output channel. void pax_set_input_update_rate

Set the rate at which a serial based analogue input channel will be read (deprecated). void pax_set_output_update_rate

Set the rate at which a serial based analogue output channel will be updated (deprecated).

Copyright 2019, Pi Innovo 151 Library interface

Type Identifier PAX_RC_T pax_cc_config_tle8242

Configures a TLE8242-2 peripheral constant current output channel. PAX_RC_T pax_cc_select_meas_chan_tle8242

Selects a TLE8242-2 peripheral constant current channel for measurement. PAX_RC_T pax_cc_read_meas_chan_tle8242

Reports measurements for a previously selected TLE8242-2 peripheral constant current channel. PAX_RC_T pax_cc_autozero_tle8242

Commands a TLE8242-2 peripheral constant current channel to autozero. 5.9.3. Interface detail 5.9.3.1. Enumerations

5.9.3.1.1. PAX_RC_T

Summary: An enumerated type which contains success and failure codes returned by some analogue input feature (PAX) functions.

Enumerations:

PAX_RC_OK Return code if everything progressed as expected.

PAX_RC_SW_ERROR Return code if an internal error occurred which was the result of a software error.

PAX_RC_HW_ERROR Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PAX_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PAX_RC_FREQ_ERROR Return code if the requested frequency of current modulation is out of range.

PAX_RC_OFFSET_ERROR Return code if the requested pulse phase offset is out of range.

PAX_RC_DITHER_ERROR Return code if the requested dither is invalid.

PAX_RC_CONTROL_LOOP_ERROR Return code if one or more of the control loop parameters are out of range.

Copyright 2019, Pi Innovo 152 Library interface

5.9.3.1.2. PAX_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the analogue input feature (PAX), the API calls a function with an enumeration from this type.

Enumerations:

PAX_ADC_INPUT_INVALID_ARG Error raised if the analogue input function finds an invalid argument.

PAX_CC_OUTPUT_INVALID_ARG Error raised if the constant current output function finds an invalid argument.

PAX_CHANNEL_INVALID Error raised if the analogue channel 'n' is not supported.

'n' is (error_code - PAX_CHANNEL_INVALID).

PAX_ADC_INPUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as an analogue input.

'n' is (error_code - PAX_ADC_INPUT_CHANNEL_UNSUPPORTED).

PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as an current output.

'n' is (error_code - PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED).

PAX_AOT_OUTPUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as an analogue output.

'n' is (error_code - PAX_AOT_OUTPUT_CHANNEL_UNSUPPORTED). 5.9.3.2. Data types

5.9.3.2.1. PAX_LCHAN_T

Definition: typedef U16 PAX_LCHAN_T

Description: This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target. 5.9.3.3. Functions

5.9.3.3.1. pax_adc_input()

Definition: PAX_RC_T pax_adc_input(PAX_LCHAN_T paxf_lchan, S16 *paxf_adc, BOOL paxf_init)

Copyright 2019, Pi Innovo 153 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or read an analogue input channel.

This function initialises or reads an analogue input channel. If the input arguments are valid, the function writes the conversion result that reflects the conversion for the specified channel through paxf_adc. If the input arguments are invalid, the function does not modify the conversion result.

Can raise the following errors: PAX_CHANNEL_INVALID, PAX_ADC_INPUT_CHANNEL_UNSUPPORTED and PAX_ADC_INPUT_INVALID_ARG

Note

Consider hardware effects such as filtering, etc..

Arg (data in): paxf_lchan The channel number of the analogue input channel to be read. Use the macros included by the pio.h file, of the form PIO_AIN_[NAME].

Arg (data out): paxf_adc Pointer to the conversion result for the analogue input channel. Can be NULL during application initialisation. Cannot be NULL during application run. Range: [-1, 1] @ 1/4096 A/D counts per LSB

Note

Note that some of the values supplied by the IMU on the M250-00Z have a different range of representation. The gyroscope value and gyroscope angle provide a 14-bit signed value and a 14-bit unsigned value respectively.

Arg (data in): paxf_init True if the channel is to be initialised, false otherwise.

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_BAD_ARGS - if an internal error has occurred

• PAX_RC_SW_ERROR - if a recoverable error has been raised.

5.9.3.3.2. pax_cc_output()

Definition: PAX_RC_T pax_cc_output(PAX_LCHAN_T paxf_lchan, S16 paxf_cc, BOOL paxf_init)

Copyright 2019, Pi Innovo 154 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or drive a constant current output channel.

This function initialises or drives a constant current output channel.

Can raise the following errors: PAX_CHANNEL_INVALID and PAX_CC_OUTPUT_CHANNEL_UNSUPPORTED

Note

Consider hardware effects such as low-side/high-side driven, filtering, etc..

Arg (data in): paxf_lchan The channel number of the constant current output channel to drive. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data in): paxf_cc The required current to be driven, given as a unit range. Consider hardware effects such as low-side/high-side driven, etc.. Range: [0, 2] A @ 1 mA per LSB (for M670 targets)

Arg (data in): paxf_init True if the channel is to be initialised, false otherwise.

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

• PAX_RC_BAD_ARGS - if pax_lchan argument is incorrect 5.9.3.3.3. pax_dac_output()

Definition: PAX_RC_T pax_dac_output(PAX_LCHAN_T paxf_lchan, S16 paxf_dac_level, BOOL paxf_init)

Supported targets:

Required license: None (Main library).

Description: Function to drive an analogue output channel.

Note

Consider hardware effects such as low-side/high-side driven, filtering, etc.

Copyright 2019, Pi Innovo 155 Library interface

Arg (data in): paxf_lchan The channel number of the analog output channel to write. Use the macros included by the pio.h file, of the form PIO_AOT_[NAME].

Arg (data in): paxf_dac_level The required analog output level fo 12bit DAC output. Range: [-1, 1] @ 1/4096 A/D counts per LSB

Arg (data in): paxf_init True if the channel is to be initialised, false otherwise.

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

• PAX_RC_BAD_ARGS - if pax_lchan argument is incorrect 5.9.3.3.4. pax_set_input_update_rate()

Definition: void pax_set_input_update_rate(PAX_LCHAN_T paxf_lchan)

Supported targets: All targets

Required license: None (Main library).

Description: Set the rate at which a serial based analogue input channel will be read (deprecated).

Became deprecated in version 1.8.0. This function will be removed in a future release. This function is no longer necessary, please remove from use in application code.

Arg (data in): paxf_lchan The channel number of the analogue channel to read. Use the macros included by the pio.h file, of the form PIO_[NAME]. 5.9.3.3.5. pax_set_output_update_rate()

Definition: void pax_set_output_update_rate(PAX_LCHAN_T paxf_lchan)

Supported targets: All targets

Required license: None (Main library).

Description: Set the rate at which a serial based analogue output channel will be updated (deprecated).

Became deprecated in version 1.8.0. This function will be removed in a future release. This function is no longer necessary, please remove from use in application code.

Copyright 2019, Pi Innovo 156 Library interface

Arg (data in): paxf_lchan The channel number of the analogue channel to drive. Use the macros included by the pio.h file, of the form PIO_[NAME].

5.9.3.3.6. pax_cc_config_tle8242()

Definition: PAX_RC_T pax_cc_config_tle8242(PAX_LCHAN_T paxf_lchan, F32 paxf_freq, F32 paxf_pulse_offset, U16 paxf_kp, U16 paxf_ki, U16 paxf_dither_steps, U16 paxf_dither_step_size)

Supported targets:

Required license: None (Main library).

Description: Configures a TLE8242-2 peripheral constant current output channel.

The current setpoint is established through the common pax_cc_output() interface function. Additional configuration specific to the TLE8242-2 is managed through this function. The setpoint and configuration for a channel must be carried out in the same task to ensure data coherence.

Can raise the following errors: PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan The channel number of the constant current output channel to configure. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data in): paxf_freq The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. Range: [10.5, 4000] Hz

Arg (data in): paxf_pulse_offset The desired phase offset of the output relative to the TLE8242-2 phase sync signal. If the offset is initialised to a non zero value, then the outputs will hold until the phase sync signal is pulsed. The phase sync signal may be pulsed during runtime to syncronise outputs. If the software cannot match the desired pulse offset, the offset will be adjusted to as close a match as possible within 1/32 increments of the pulse period. Range: [0, 31/32 of pulse period] ms

Arg (data in): paxf_kp The desired proportional coefficient of the PI control loop that determines the duty cycle of the constant current output. The supplied value is passed directly to the TLE8242-2 KP register without scaling applied. Range: [0, 4095] unitless

Arg (data in): paxf_ki The desired integral coefficient of the PI control loop that determines the duty cycle of the constant current output. The supplied value is passed directly to the TLE8242-2 KI register without scaling applied.

Copyright 2019, Pi Innovo 157 Library interface

Range: [0, 4095] unitless

Arg (data in): paxf_dither_steps The desired number of dither steps (one per PWM period) between the centre current value and the maximum, at which the steps reverse direction, etc. Hence the total dither cycle waveform period is the PWM period x 4 x this parameter (see diagram in the user guide section "Constant current dither"). If the software cannot match the number of dither steps, the number of steps will be adjusted to as close a match as possible. Range: [0, 31] steps per 1/4 dither cycle.

Arg (data in): paxf_dither_step_size The desired dither step size. If the software cannot match the desired dither step size, the step size will be adjusted to as close a match as possible. Range: [0, 500] mA

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

• PAX_RC_BAD_ARGS - if pax_lchan argument is incorrect

5.9.3.3.7. pax_cc_select_meas_chan_tle8242()

Definition: PAX_RC_T pax_cc_select_meas_chan_tle8242(PAX_LCHAN_T paxf_lchan)

Supported targets:

Required license: None (Main library).

Description: Selects a TLE8242-2 peripheral constant current channel for measurement.

This interface allow the caller to select the TLE8242-2 output for measurement of minimum, maximum, and average current. TLE8242-2 channels cannot be measured in parallel.

Can raise the following errors: PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan The channel number of the constant current output channel to configure. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

Copyright 2019, Pi Innovo 158 Library interface

5.9.3.3.8. pax_cc_read_meas_chan_tle8242()

Definition: PAX_RC_T pax_cc_read_meas_chan_tle8242(BOOL *paxf_valid, F32 *paxf_min_current, F32 *paxf_max_current, F32 *paxf_avg_current)

Supported targets:

Required license: None (Main library).

Description: Reports measurements for a previously selected TLE8242-2 peripheral constant current channel.

This interface fetches the measurements for a TLE8242-2 output. The results are not valid until the current dither cycle has completed. TLE8242-2 channels cannot be measured in parallel.

Arg (data out): paxf_valid Flag indicating that the dither cycle has completed and the results are valid.

Arg (data out): paxf_min_current Minimum current over the last dither cycle for the selected channel. Range: [0, 2000] mA

Arg (data out): paxf_max_current Maximum current over the last dither cycle for the selected channel. Range: [0, 2000] mA

Arg (data out): paxf_avg_current Average current over the last dither cycle for the selected channel. Range: [0, 2000] mA

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

• PAX_RC_BAD_ARGS - if any arguments are NULL pointers

5.9.3.3.9. pax_cc_autozero_tle8242()

Definition: PAX_RC_T pax_cc_autozero_tle8242(PAX_LCHAN_T paxf_lchan, BOOL *paxf_autozero_done)

Supported targets:

Required license: None (Main library).

Description: Commands a TLE8242-2 peripheral constant current channel to autozero.

This interface allow the caller to initiate autozero of a TLE8242-2 device channel. The current setpoint must be set to zero before triggering the autozero feature. TLE8242-2 channels cannot be autozeroed in parallel.

Copyright 2019, Pi Innovo 159 Library interface

Can raise the following errors: PAX_CHANNEL_INVALID

Arg (data in): paxf_lchan The channel number of the constant current output channel to zero. Use the macros included by the pio.h file, of the form PIO_CCOT_[NAME].

Arg (data out): paxf_autozero_done Flag indicating that the autozero has completed. The function must be polled during subsequent task iterations to determine that autozero has completed.

Return:

• PAX_RC_OK - if normal operation

• PAX_RC_SW_ERROR - if a recoverable error has been raised

• PAX_RC_BAD_ARGS - if any arguments are invalid 5.10. Digital input/output feature (PDX) 5.10.1. Overview

The library supports various functions to access I/O pins, a summary of which is given below. 5.10.1.1. Hardware effects on signals

The functions work at the level of the micro-processor pin but the input and output circuitry of the ECU may invert the sense of the signal — see the technical specification for a description of how the input circuitry works for an ECU (Section A.1, “ECU hardware reference documentation”).

The input circuitry may include filtering which can affect the input signal. The filter may introduce a limit of frequency range (the signal may undetectable outside of the filters range) and may also introduce signal phase. For rising and falling edges of the signal, the phase may be different, hence the measured high and low time of a pulse train, for example, may not be as expected without the ECU's input circuitry. Again, see the technical specification for a description of how the input circuitry works for an ECU. 5.10.1.2. Digital input

The library supports reading the state of a digital input as seen at the micro- processor pin (see pdx_digital_input()). The utility functions put_debounce_by_cycles() and put_debounce_by_time() can be used to debounce the signal state. 5.10.1.3. Frequency input

The library supports reading the frequency of a digital input as seen at the micro-processor pin (see pdx_frequency_input()). 5.10.1.4. PWM input

The library supports reading the frequency and duty cycle of a digital input as seen at the micro-processor pin (see pdx_pwm_input()). The function measures the time of each high and low (or low and high) pulse to determine the frequency of the input signal.

Copyright 2019, Pi Innovo 160 Library interface

First pulse Second pulse time time

Input signal

active low if invert is 0 Cycle time (1/Frequency)

First pulse Second pulse time time

Input signal

active high if invert is 1 Cycle time (1/Frequency)

Note

Whether the block measures a low pulse followed by a high pulse, or a high pulse followed by a low pulse is determined during initialisation of the input channel.

The function measures the durations of the first and second pulses and derives the duty cycle (first pulse time divided by the cycle time). Very small duty cycles (less than 1% or greater than 99%) will not be measured accurately or at all.

The function accumulates the count of complete periods modulo 21777216. The application calculated difference of counts between iterations of the block could be used to diagnose unexpected changes in the signal.

Input signal

Cycle/period count 0 1 2

Start of Start of Start of period period period

The function measures the period duration and determines whether the signal has taken longer than the timeout duration. The function accumulates the count of time out events and indicates if the signal is timed out when the function is called.

Input signal

Time out count 0 1 2

Block iterates Signal Signal Block iterates no timeout yet times out times out time out count is 2 and recorded signal shown as not currently timed out

Copyright 2019, Pi Innovo 161 Library interface

5.10.1.5. Quadrature input

The library supports the decoding of quadrature signals from a quadrature encoder (see pdx_quad_input()). A quadrature encoder generates a pulse train from two sensors which pick up markings on the encoder disk.

Figure 5.8. Quadrature encoder and generated signals

Primary and secondary sensors detect encoder disk markings.

Primary channel The sensor signals are conditioned by the encoder and sensed by OpenECU. Secondary channel Encorder disk, rotating forwards. Primary and secondary channel edges 90° out of phase. Decoding the phase of the edges determines the rotation of the encoder.

The sensors and markings are arranged so that when the encoder is turning, the sensor signals generate two pulse trains 90° out of phase. If the disk is turning in a forwards direction, the primary channel edges will lead the secondary channel edges. If the disk is turning in a backwards direction then the primary channel edges will lag the secondary channel edges. If there are no signal edges on either channel after a period of time, then the encoder has stopped turning (or is turning slowly enough to be considered stationary).

Figure 5.9. Direction of encoder and generated signals

Primary channel shows leading edges. Primary channel shows lagging edges. Forwards direction Backwards direction

Primary channel

Secondary channel

No pulses on either channel. Stopped.

The quadrature decode functions measure the primary and secondary channels, determine the direction at each pulse and count the pulses. If the encoder is turning forwards then for each edge on the primary and secondary channels, the functions increment the count. If the encoder is turning backwards then for each edge on the primary and secondary channels, the functions decrement the count. When either function is called, the function outputs the count of pulses and resets the count to zero.

For instance, if the encoder turns forwards for nine edges between calls to the function, the pulse count from the functions will be nine. If the encoder turns forwards for six edges and then backwards for two edges between calls of the functions, the pulse count from the functions will be four.

Copyright 2019, Pi Innovo 162 Library interface

Figure 5.10. Pulse count example

Primary channel shows Primary channel shows Primary channel shows leading edges. leading edges. lagging edges. Forwards direction Forwards direction Backwards direction

Primary channel

Secondary channel

Edge count 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 5 4

Function call Function call Function call Function call reset count to zero reset count to zero reset count to zero reset count to zero

Note

Some encoders provide an index signal and some encoders provide complement signals of the primary and secondary signals, both for the purposes of improving reliability. This function does not decode these signals.

A second function (see pdx_quad_freq_input()) provides the same functionality but also measures the duration of each pulse from the encoder primary and secondary channels and returns the last measured frequency of each channel. 5.10.1.6. SENT input (SAE J2716)

The library supports the decoding of SENT sensors for fast data from individual frames (see pdx_sent_input()) and for slow data from sequential frames (see pdx_sent_serial_input()). A SENT sensor encodes data into frames using variable width pulses:

Figure 5.11. SENT frame

Previous frame Status Data 2 Data 4 Data 6 Pause Pause (optional) 12 ticks 17 ticks 14 ticks 12 ticks (optional) or CRC value 0 value 5 value 2 value 0

Calibration / Data 1 Data 3 Data 5 CRC synchronisation pulse 27 ticks 22 ticks 20 ticks 21 ticks 56 SENT ticks value 15 value 10 value 8 value

Overall SENT frame – 154 to 270 SENT ticks (depending on data values), followed by optional pause pulse between frames

The library synchronises to the calibration pulse and decodes the remaining frame pulses based on the expected calibration pulse width time and the actual pulse width time. Across sequential valid SENT frames, the library will extract any serial data from the status nibble.

The library performs various diagnostics:

• checks the SENT sensor clock variance by allowing no more than ±25% of the expected calibration pulse width

Copyright 2019, Pi Innovo 163 Library interface

• checks frame to frame variability of the calibration pulse (allowing a change in width no more than 1.5625%)

• checks the expected number of fast data nibbles is received

• checks the frame CRC and slow serial CRC 5.10.1.7. Digital output

The library supports setting the state of a digital output (see pdx_digital_output()). 5.10.1.8. PWM output

The library supports setting the frequency and duty cycle of a PWM output (see pdx_pwm_output()), where duty cycle is defined as the High time divided by the Cycle time for a given channel.

High time

Output channel signal Low time

Cycle time (1/Frequency)

High time

Inverted output channel signal

Low time

Cycle time (1/Frequency)

The utility function put_dutycycle_processing() supports scaling and clipping of the duty cycle, and inversion of the PWM signal.

The channel output can be offset from other PWM channels of the same frequency. The Offset argument is used to delay the start of the PWM cycle, so that the PWM pulse will not occur at the same time as other PWM signals of the same frequency.

Other channel (with same frequency) signal

Channel signal

Offset delay time

5.10.1.9. Synchronised PWM output

The library supports the generation of a synchronised PWM signal using two output pins (see pdx_spwm_output()). The second output pin is synchronised to the first and optionally has a programmable delay. The frequency and duty cycle are independent for each pin and can be changed between calls to the function.

The duty cycle is the High time divided by the Cycle time for a given channel.

Copyright 2019, Pi Innovo 164 Library interface

High time

Master channel signal Low time

High time

Slave channel signal Low time

Cycle time (1/Frequency)

The slave channel is generated relative to the master channel pulse (in this instance, both the master and slave channels are generated with the same frequency).

Master channel signal

Slave channel signal

Synchronisation Synchronisation point point

The slave pulse can be delayed relative to the master pulse by setting the parameter {Slave delay} to a non-zero value.

Master channel signal

Slave channel signal

Slave delay time

In all cases, only one pulse per cycle is generated by both the master and slave channels. For instance, if the frequency of the slave channel was twice that of the master channel, only one pulse would be generated by the slave channel.

Master channel signal

Slave channel signal

Frequency of slave channel twice that of master channel, but only one slave pulse generated.

The Master channel output (and thus the slave) can be offset from other PWM channels of the same frequency. The Master Offset argument is used to delay the start of the PWM cycle, so that the PWM pulse will not occur at the same time as other PWM signals of the same frequency.

Copyright 2019, Pi Innovo 165 Library interface

Other channel (with same frequency) signal

Master channel signal

Slave channel signal

5.10.1.10. Peak and hold injector output

The library supports the generation of a signal to control a peak and hold injector (see pdx_phinj_output()). This consists of a stepped current signal generated at the selected injector frequency, in which the current is firstly controlled to the peak current threshold for the duration determined by the peak duty cycle, after which it is controlled to the hold current threshold for the remaining duration of the peak-hold duty cycle (i.e. the duration of the peak- hold duty cycle minus the peak duty cycle), after which the current falls to zero until the beginning of the next cycle.

The injector frequency, peak duty cycle, peak-hold duty cycle and injector clock frequency are all passed as arguments to this function and can be changed between calls.

Figure 5.12. Peak-hold injector output

Peak current

Hold current

Injector current

Peak channel

Peak and hold channel

Injector clock

Cycle time = 1/Injector frequency

The injector frequency is 1 / Cycle time. The peak duty is the Peak current duration divided by the Cycle time. The peak-hold duty is the sum of the Peak current duration and the Hold current duration, divided by the Cycle time. The actual peak-hold duty is constrained to be at least as great as the peak duty.

The channel output can be offset from other injector channels of the same frequency. The Offset parameter is used to delay the start of the injector cycle, so that the injector will not activate at the same time as other injector signals of the same frequency.

Copyright 2019, Pi Innovo 166 Library interface

Other channel (with same frequency) signal

Channel signal

Offset time

The utility function put_dutycycle_processing() can be used to scale and clip the duty cycle inputs prior to calling this function, but no inversion should be applied. 5.10.1.11. H-Bridge output

The library support setting the mode, frequency and duty-cycle of H-Bridge output (see pdx_hbridge_output()), where channel pins are driven accordingly.

The H-Bridge output function controls a load connected between the two ECU pins in the desired mode. Four modes are provided allowing the H-Bridge output to have no drive (all switches open), brake (high-side switches closed), forward or reverse (one side is connected to high-side while the other is PWM'ed to ground at a programmable frequency and duty- cycle).

The duty-cycle used in forward and reverse mode is defined as the proportion of time where the load is driven (low-side switch is grounded).

The block supports 0% and 100% duty cycles.

Warning

To avoid unexpected behavior, H-bridges should be set to NO DRIVE mode before flashing the ECU. This can be done by commanding the actuators to NO DRIVE any time the engine is not turning.

Note

Some of the PWM output channels do not produce an accurate waveform when the duty cycle is either very small (e.g., 0.5%) or very large (e.g., 99.5%). All H-bridge output channels cope with 0% and 100% duty cycles correctly.

For the M250 target specifically, in order to avoid shoot-through and damage to the ECU when the mode switches, a 100us dead-time is inserted in the PWM signal for one task cycle at the beginning of mode-transition. Additionally, this dead-time insertion will only occur if the duty cycle that is commanded has a low time of less than 100us.

Copyright 2019, Pi Innovo 167 Library interface

For this reason, it will not be possible to command a 100% duty cycle during mode- transition for one task period. See diagram below for further detail.

Figure 5.13. Output of H-Bridge during mode transition

Application task requests mode change Application task requests from No-drive to Forwards same mode, Forwards

100us

A30

A1

A30 is requested to have a high duty cycle, After one task iteration is complete and but it is extended to 100 microsecond off the mode is unchanged, the duty cycle is time (dead time) for one task duration. restored (dead-time removed).

Correspondingly, A1 would have 100% duty cycle, but is forced to 100 microseconds dead time for the same task Iteration.

5.10.1.12. External devices

There are two types of I/O on OpenECU hardware: direct and indirect I/O.

Figure 5.14. Signal update rates

Direct output signal Output circuitry

To external actuators Processor Output Output device circuitry Serial Direct communications output signal

Internal to ECU External to ECU

Direct I/O Direct I/O takes place on demand. The application calls the necessary function and the function takes a measurement or sets a driver accordingly.

Indirect I/O Indirect I/O is delayed. The application calls the necessary function but the data to be read or set is actioned some time after the function returns.

Indirect I/O always occurs when there is an device between the processor and the pin. The device communicates to the processor across a serial link and it is this communication which introduces the delay. Serial communication is initiated at the end of any task which accesses the device to perform an I/O operation. This is accomplished by calling psp_spi_trigger() at

Copyright 2019, Pi Innovo 168 Library interface

the end of each application task. Only I/O channels noted as in the technical specification (see Section A.1, “ECU hardware reference documentation”) are affected. 5.10.1.13. Monitors

Each target ECU provides some measure of feedback for a subset of the output pins. For instance, measuring the actual state of a digital output to determine whether the output is shorted. A complete list of the monitors can be found in the technical specifications (see Section A.1, “ECU hardware reference documentation”). Each monitor is read by using one of the existing feature functions, e.g., by calling pdx_digital_input() to read the digital state of a monitor. 5.10.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pdx.h Enumerations PDX_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PDX) functions. PDX_ERROR_CODE_T

Error values for debugging when an error is found when calling the digital input feature (PDX), the API calls a function with an enumeration from this type. PDX_SENT_SERIAL_FORMAT_T

This enumeration gives the format of the SENT serial data. Data types PDX_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets. PDX_LCHAN_MONITOR_T

This declares a type with enough value range to represent the groups of output-and-monitor channels for all targets. PDX_LCHAN_PHINJ_T

This declares a type with enough value range to represent logical peak and hold injector channels for all targets. PDX_LCHAN_HBRIDGE_T

This declares a type with enough value range to represent logical H-Bridge channel groups for all targets.

Copyright 2019, Pi Innovo 169 Library interface

Type Identifier Functions PDX_RC_T pdx_digital_input

Function to initialise or read a digital input channel. PDX_RC_T pdx_digital_monitor_input

Function to initialise or read the status of a digital output monitor. PDX_RC_T pdx_digital_output

Function to initialise or drive a digital output channel. PDX_RC_T pdx_frequency_input

Function to initialise or read a frequency input channel. PDX_RC_T pdx_hbridge_output

Function to initialise or drive an H-Bridge output channel. PDX_RC_T pdx_phinj_output

Function to initialise or drive a peak and hold injector output channel. PDX_RC_T pdx_pwm_input

Function to initialise or read a PWM input channel. PDX_RC_T pdx_pwm_output

Function to initialise or drive a PWM output channel. PDX_RC_T pdx_quad_freq_input

Function to initialise or read a quadrature and frequency input channel. PDX_RC_T pdx_quad_input

Function to initialise or read a quadrature input channel. PDX_RC_T pdx_sent_input

Function to initialise and read a SENT input channel, fast channel signals. PDX_RC_T pdx_sent_serial_input

Function to read a SENT input channel, slow channel signals. PDX_RC_T pdx_spwm_output

Function to initialise or drive a synchronised PWM output channel.

Copyright 2019, Pi Innovo 170 Library interface

5.10.3. Interface detail 5.10.3.1. Enumerations

5.10.3.1.1. PDX_RC_T

Summary: An enumerated type which contains success and failure codes returned by some digital input feature (PDX) functions.

Enumerations:

PDX_RC_OK Return code if everything progressed as expected.

PDX_RC_SW_ERROR Return code if an internal error occurred which was the result of a software error.

PDX_RC_HW_ERROR Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PDX_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PDX_RC_FREQ_TOO_LOW Return code if frequency argument is too low.

PDX_RC_FREQ_TOO_HIGH Return code if frequency argument is too large.

PDX_RC_DUTY_OUT_OF_RANGE Return code if duty cycle argument is out of range, [0, 1].

PDX_RC_SDM_ALLOC_ERROR Return code if could not allocate eTPU SDM for function (internal error).

PDX_RC_INACTIVE Return code if input or output device was unresponsive.

PDX_RC_NOT_CONFIGURED Return code if output not configured.

PDX_RC_INVALID_MODE Return code if mode is not supported.

PDX_RC_PEAK_HOLD_TOO_LOW Return code if peak-hold duty cycle is less than peak duty cycle.

PDX_RC_CLIPPED_TO_RANGE Return code if one or more arguments were clipped to range. 5.10.3.1.2. PDX_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the digital input feature (PDX), the API calls a function with an enumeration from this type.

Copyright 2019, Pi Innovo 171 Library interface

Enumerations:

PDX_DO_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a digital output.

'n' is (error_code - PDX_DO_CHANNEL_UNSUPPORTED).

PDX_DIG_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a digital input.

'n' is (error_code - PDX_DIG_IN_CHANNEL_UNSUPPORTED).

PDX_FREQ_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a frequency input.

'n' is (error_code - PDX_FREQ_IN_CHANNEL_UNSUPPORTED).

PDX_PERIOD_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a period input.

'n' is (error_code - PDX_PERIOD_IN_CHANNEL_UNSUPPORTED).

PDX_QDEC_FREQ_IN_INVALID_ARG Error raised if the quadrature and frequency input function has an invalid argument.

PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a quadrature and frequency input.

'n' is (error_code - PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED).

PDX_TPU_QFI_CHANNEL_DEVICE_ERROR Error raised in quadrature and frequency input, if the primary channel 'n' and the secondary channel are not on the same device.

'n' is (error_code - PDX_TPU_QFI_CHANNEL_DEVICE_ERROR).

PDX_QDEC_IN_INVALID_ARG Error raised if the quadrature input function has an invalid argument.

PDX_QDEC_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a quadrature input.

'n' is (error_code - PDX_QDEC_IN_CHANNEL_UNSUPPORTED).

PDX_TPU_QI_CHANNEL_DEVICE_ERROR Error raised in quadrature input, if the primary channel 'n' and the secondary channel are not on the same device.

'n' is (error_code - PDX_TPU_QI_CHANNEL_DEVICE_ERROR).

PDX_PWM_OUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a PWM output.

'n' is (error_code - PDX_PWM_OUT_CHANNEL_UNSUPPORTED).

PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a synchronised PWM output.

Copyright 2019, Pi Innovo 172 Library interface

'n' is (error_code - PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED).

PDX_TPU_SPO_CHANNEL_DEVICE_ERROR Error raised in synchronised PWM output, if the primary channel 'n' and the secondary channel are not on the same device.

'n' is (error_code - PDX_TPU_SPO_CHANNEL_DEVICE_ERROR).

PDX_PWM_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a PWM input.

'n' is (error_code - PDX_PWM_IN_CHANNEL_UNSUPPORTED).

PDX_CHANNEL_INVALID Error raised if the digital channel 'n' is not supported.

'n' is (error_code - PDX_CHANNEL_INVALID).

PDX_TLE4953_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a TLE-4953 input.

'n' is (error_code - PDX_TLE4953_CHANNEL_UNSUPPORTED).

PDX_HBRIDGE_INVALID_MODE Error raised if the H-bridge mode has an invalid value.

PDX_HBRIDGE_CHANNEL_MISMATCH Error raised if the H-bridge channels are not on the same device.

PDX_HBRIDGE_DECODE_ERROR Error raised if something went wrong when decoding a device and/ or channel necessary for H-bridge operation.

PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED Error raised if channel group 'n' cannot be used as an H-bridge output.

'n' is (error_code - PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED).

PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a digital data input.

'n' is (error_code - PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED).

PDX_SENT_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a SENT input.

'n' is (error_code - PDX_SENT_IN_CHANNEL_UNSUPPORTED). 5.10.3.1.3. PDX_SENT_SERIAL_FORMAT_T

Summary: This enumeration gives the format of the SENT serial data.

Enumerations:

PDX_SENT_SERIAL_SHORT The serial data is short, over 16 consecutive SENT frames.

Copyright 2019, Pi Innovo 173 Library interface

4-bits message ID and 8-bits data.

PDX_SENT_SERIAL_ENHANCED_1 The serial data is enhanced format 1, over 18 consecutive SENT frames.

8-bits message ID and 12-bits data.

PDX_SENT_SERIAL_ENHANCED_2 The serial data is enhanced format 2, over 18 consecutive SENT frames.

4-bits message ID and 16-bits data. 5.10.3.2. Data types

5.10.3.2.1. PDX_LCHAN_T

Definition: typedef U16 PDX_LCHAN_T

Description: This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.2. PDX_LCHAN_MONITOR_T

Definition: typedef U16 PDX_LCHAN_MONITOR_T

Description: This declares a type with enough value range to represent the groups of output-and-monitor channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.3. PDX_LCHAN_PHINJ_T

Definition: typedef U8 PDX_LCHAN_PHINJ_T

Description: This declares a type with enough value range to represent logical peak and hold injector channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.10.3.2.4. PDX_LCHAN_HBRIDGE_T

Definition: typedef U16 PDX_LCHAN_HBRIDGE_T

Description: This declares a type with enough value range to represent logical H- Bridge channel groups for all targets.

See pio.h for a list of relevant channels for a specific target.

Copyright 2019, Pi Innovo 174 Library interface

5.10.3.3. Functions

5.10.3.3.1. pdx_digital_input()

Definition: PDX_RC_T pdx_digital_input(PDX_LCHAN_T pdxf_lchan, U8 *pdxf_state, BOOL pdxf_init)

Supported targets: M560-000 and M560-000

Required license: None (Main library).

Description: Function to initialise or read a digital input channel.

Note

Consider hardware effects such as inversion, etc.. Can raise the following errors: PDX_DIG_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a digital input. Use the macros included by the pio.h file, of the form PIO_DIN_[NAME].

Arg (data out): pdxf_state The state of the digital input is written through this pointer. Consider hardware effects such as inversion, etc.. Cannot be NULL. Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - if successful action

• PDX_RC_SW_ERROR - if channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - if configuration error

• PDX_RC_SDM_ALLOC_ERROR - if error allocating RAM for SDM

5.10.3.3.2. pdx_digital_monitor_input()

Definition: PDX_RC_T pdx_digital_monitor_input(PDX_LCHAN_T pdxf_lchan, F32 pdxf_rise_time, BOOL *pdxf_valid, U32 *pdxf_rise_fail_count, U32 *pdxf_fall_fail_count, BOOL pdxf_init)

Supported targets:

Copyright 2019, Pi Innovo 175 Library interface

Required license: None (Main library).

Description: Function to initialise or read the status of a digital output monitor.

Can raise the following errors: PDX_DIG_MONITOR_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The channel to use as a digital output monitor. Use the macros included by the pio.h file, of the form PIO_DMIN_[NAME].

Arg (data in): pdxf_rise_time The time after the output has been commanded high when the state of the monitor input channel is to be tested. The value passed here is clipped to range if necessary. Note that the corresponding fall-time is hard-coded and not accessible to the application via this function. Range: [0, 2000000] us

Arg (data out): pdxf_valid The validity flag for the monitor channel is written through this pointer. Monitors are only supported for certain output functions, and if an unsupported output function is in use on the corresponding output channel then this flag will read FALSE. Currently supported functions are spark and PWM outputs. Cannot be NULL. Range: [0, 16777215]

Arg (data out): pdxf_rise_fail_count The number of times that the output failed to rise within the time specified by the pdxf_rise_time parameter is written through this pointer. Cannot be NULL. Range: [0, 16777215]

Arg (data out): pdxf_fall_fail_count The number of times that the output failed to fall within the allowed time is written through this pointer. Cannot be NULL. Range: [0, 16777215]

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - if successful action

• PDX_RC_SW_ERROR - if channel not supported

• PDX_RC_BAD_ARGS - if configuration error

5.10.3.3.3. pdx_digital_output()

Definition: PDX_RC_T pdx_digital_output(PDX_LCHAN_T pdxf_lchan, U8 pdxf_state, BOOL pdxf_init)

Copyright 2019, Pi Innovo 176 Library interface

Supported targets: M560-000 and M560-000

Required license: None (Main library).

Description: Function to initialise or drive a digital output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc..

If the output pin can be configured for either a low-side or high-side output, the polarity of the output is generally controlled by calling pdx_digital_output() using the channel with a name of the form PIO_DOT_XXX_SELECT_HIGH_SIDE . See the technical reference for the targets for specific information. Can raise the following errors: PDX_CHANNEL_INVALID + pdxf_lchan , or PDX_DO_CHANNEL_UNSUPPORTED + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a digital output. Use the macros included by the pio.h file, of the form PIO_DOT_[NAME].

Arg (data in): pdxf_state The state to which the digital output should be driven. A state of 0 means the output is inactive, where 1 means active (non-inverted). For low-side outputs, active means pulled to ground; high-side, pulled to supply voltage. The inactive state is high impedence. Consider hardware effects such as inversion, low-side/high-side driven, etc.. Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.10.3.3.4. pdx_frequency_input()

Definition: PDX_RC_T pdx_frequency_input(PDX_LCHAN_T pdxf_lchan, U16 pdxf_config, U8 pdxf_count, F32 *pdxf_freq, U16 pdxf_last_edges, U16 *pdxf_this_edges, U32 pdxf_last_time, U32 *pdxf_this_time, U32 pdxf_timeout, BOOL *pdxf_timed_out, BOOL pdxf_init)

Copyright 2019, Pi Innovo 177 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or read a frequency input channel.

This function returns the latest measured frequency of a pulse train input. The function relies on a hardware peripheral to measure the input and present the information on request.

The frequency input is read falling edge to falling edge (unless the pdxf_config parameter specifies otherwise).

Note

Consider hardware effects such as inversion, filtering, etc.. Can raise the following errors: PDX_FREQ_IN_CHANNEL_UNSUPPORTED + pdxf_lchan , or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a frequency input. Use the macros included by the pio.h file, of the form PIO_FIN_[NAME].

Arg (data in): pdxf_config A configuration parameter used to initialise certain channels on some ECUs, use PIO_CONFIG_FIN.

Arg (data in): pdxf_count A configuration parameter used to initialise certain channels on some ECUs, use PIO_COUNT_FIN.

Arg (data out): pdxf_freq The measured frequency is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written. The range of the frequency is limited in various ways.

• The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

• The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

• The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification. Cannot be NULL. Range: [0.5, ...] Hz

Copyright 2019, Pi Innovo 178 Library interface

Arg (data in): pdxf_last_edges A count of edges seen by the frequency input function last time this function was called (or zero if this is the first time the function has been called). The counter wraps modulo 65536 and is used to determine whether the signal has timed out or not. Range: [0, 65535] edges

Arg (data out): pdxf_this_edges The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_last_edges next time the function is called. Cannot be NULL. Range: [0, 65535] edges

Arg (data in): pdxf_last_time The time of the last call to this frequency input function (or zero if it is the first call). It is used to determine whether the signal has timed out or not. Range: [0, 4294967295] microseconds

Arg (data out): pdxf_this_time The time of this call is written through this pointer. It is the value to be passed as pdxf_last_time next time the function is called. Cannot be NULL. Range: [0, 4294967295] microseconds

Arg (data in): pdxf_timeout The duration of the input signal timeout period. Range: [100, 2000000] microseconds

Arg (data out): pdxf_timed_out Set if the input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered. Cannot be NULL. Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.10.3.3.5. pdx_hbridge_output()

Definition: PDX_RC_T pdx_hbridge_output(PDX_LCHAN_HBRIDGE_T pdxf_lchan_hbridge, PIO_HBRIDGE_MODE_T pdxf_mode, F32 pdxf_freq, F32 pdxf_duty, PIO_HBRIDGE_MODE_T *pdxf_last_mode_ptr, BOOL pdxf_init)

Copyright 2019, Pi Innovo 179 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or drive an H-Bridge output channel.

Note

On the M250, for the case when the mode is transitioning, a 100% duty cycle can not be achieved until one task cycle has passed. This can result in the driven duty cycle being different from the requested duty cycle. See the H-Bridge section of the user guide for further detail.

On the M250, there is a dead-time insertion on mode changes. Can raise the following errors: PDX_CHANNEL_INVALID , or PDX_HBRIDGE_INVALID_MODE , or PDX_HBRIDGE_CHANNEL_MISMATCH , or PDX_HBRIDGE_CHANNEL_GROUP_UNSUPPORTED + pdxf_lchan_hbridge

Arg (data in): pdxf_lchan_hbridge The group of channels used to control the H-Bridge. Use the macros included by the pio.h file, of the form PIO_HBOT_[NAME]

Arg (data in): pdxf_mode The H-bridge mode to use. Any of:

• PIO_HBRIDGE_MODE_NO_DRIVE - No Drive

• PIO_HBRIDGE_MODE_BRAKE - Brake

• PIO_HBRIDGE_MODE_FORWARD - Forward drive

• PIO_HBRIDGE_MODE_REVERSE - Reverse drive

Arg (data in): pdxf_freq The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. Range: [0.5, 10000] Hz

Arg (data in): pdxf_duty The desired duty cycle of the PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled when the H-Bridge is not switching sides - see Note below) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise. Range: [0, 1] unitless

Arg (data in,out): pdxf_last_mode_ptr The value of pdxf_mode for this call is written through this pointer. It is the value to be passed as pdxf_mode next time the function is called.

Copyright 2019, Pi Innovo 180 Library interface

Cannot be NULL.

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel group not supported or channels not on same device

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_FREQ_TOO_HIGH - frequency is higher than supported frequency

• PDX_RC_FREQ_TOO_LOW - frequency is lower than supported frequency

• PDX_RC_DUTY_OUT_OF_RANGE - duty cycle is outside [0, 1] range

5.10.3.3.6. pdx_phinj_output()

Definition: PDX_RC_T pdx_phinj_output(PDX_LCHAN_PHINJ_T pdxf_lchan_phinj, F32 pdxf_inj_freq, F32 pdxf_peak_duty, F32 pdxf_pkhold_duty, F32 pdxf_clock_freq, F32 pdxf_offset, BOOL pdxf_init)

Supported targets: None at the moment

Required license: None (Main library).

Description: Function to initialise or drive a peak and hold injector output channel.

Can raise the following errors: PDX_CHANNEL_INVALID + pdxf_master_lchan

Arg (data in): pdxf_lchan_phinj The logical channel associated with the peak and hold injector output. Use the macros included by the pio.h file, of the form PIO_PHINJOT_[NAME]. Note that this selects channels for the peak, peak-hold and injector clock outputs.

Arg (data in): pdxf_inj_freq The desired frequency of the peak and hold injector output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. Range: [0.1, 1000] Hz

Arg (data in): pdxf_peak_duty The desired peak duty cycle of the peak and hold injector output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately

Copyright 2019, Pi Innovo 181 Library interface

(although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise. Range: [0, 1] unitless

Arg (data in): pdxf_pkhold_duty The desired peak-hold duty cycle of the peak and hold injector output. This must not be less than the peak duty cycle: if it is it will be set to match the peak duty cycle. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise.

Arg (data in): pdxf_clock_freq The desired frequency of the peak and hold injector clock. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. Range: [1, 10000] Hz

Arg (data in): pdxf_offset The desired phase offset of the injector output, relative to other injector output channels that have been configured with the same frequency. Range: [0, 10000] ms

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - if successful action

• PDX_RC_BAD_ARGS - if configuration error

• PDX_RC_PEAK_HOLD_TOO_LOW - if the peak-hold duty is less than the peak duty

5.10.3.3.7. pdx_pwm_input()

Definition: PDX_RC_T pdx_pwm_input(PDX_LCHAN_T pdxf_lchan, U8 pdxf_invert, F32 *pdxf_freq, F32 *pdxf_dc, U32 *pdxf_first_duration, U32 *pdxf_second_duration, U32 *pdxf_period_count, U32 pdxf_timeout, U32 *pdxf_timeout_count, BOOL *pdxf_timed_out, BOOL *pdxf_pin_state, BOOL pdxf_init)

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or read a PWM input channel.

This function measures the time of each high and low (or low and high) pulse to determine the frequency and duty cycle of the input signal.

Copyright 2019, Pi Innovo 182 Library interface

Very small duty cycles (less than 1% or greater than 99%) will not be measured accurately or at all.

The function accumulates the count of complete periods modulo 16777216. The application calculated difference of counts between iterations of the block could be used to diagnose unexpected changes in the signal.

The function measures the period duration and determines whether the signal has taken longer than the timeout duration. The function accumulates the count of time out events and indicates if the signal is timed out when the function is called.

The function relies on a hardware peripheral to measure the signal and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc.. Can raise the following errors: PDX_PWM_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a PWM input. Use the macros included by the pio.h file, of the form PIO_PWIN_[NAME].

Arg (data in): pdxf_invert Set to 0 to start measuring PWM input signal on a rising edge (first pulse is high), set to 1 to start measuring PWM input signal on a falling edge (first pulse is low). Parameter valid only during initialisation. Range: 0 or 1

Arg (data out): pdxf_dc The duty cycle of the last measured period. If a timeout has occurred, this remains as the duty cycle of the last measured period (or zero if a measurement has not yet been taken). Cannot be NULL. Range: [0, 1]

Arg (data out): pdxf_freq The frequency of the last measured period. If a timeout has occurred, this remains as the frequency of the last measured period (or zero if a measurement has not yet been taken). The range of the frequency is limited in various ways.

• The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

• The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

• The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the

Copyright 2019, Pi Innovo 183 Library interface

frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification. Cannot be NULL. Range: 0 Hz and [0.5, ...] Hz (minimum)

Arg (data out): pdxf_first_duration The duration of the first pulse in the last measured period (either high or low). If a timeout has occurred, this remains as the last measured first pulse duration (or zero if a measurement has not yet been taken). Cannot be NULL. Range: [0, 4294967296] microseconds

Arg (data out): pdxf_second_duration The duration of the second pulse in the last measured period (inverse of first pulse). If a timeout has occurred, this remains as the last measured second pulse duration (or zero if a measurement has not yet been taken). Cannot be NULL. Range: [0, 4294967296] microseconds

Arg (data out): pdxf_period_count A count of periods seen by the PWM input function. The counter wraps modulo 16777216. Cannot be NULL. Range: [0, 16777216] periods

Note

pdxf_period_count is not supported on M5xx targets

Arg (data in): pdxf_timeout The duration of the PWM input signal timeout period. Parameter valid only during initialisation. Range: [100, 2000000] microseconds

Arg (data out): pdxf_timeout_count A count of instances where the input signal has timed out. The counter wraps modulo 16777216. Cannot be NULL. Range: [0, 16777216] timeouts

Note

pdxf_timeout_count is not supported on M5xx targets

Arg (data out): pdxf_timed_out Set if the input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is counted in pdxf_timeout_count. Cannot be NULL. Range: 0 or 1

Arg (data out): pdxf_pin_state Set if the input signal is high, clear if the input signal is low. Cannot be NULL.

Copyright 2019, Pi Innovo 184 Library interface

Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

• PDX_RC_INACTIVE - channel inactive

5.10.3.3.8. pdx_pwm_output()

Definition: PDX_RC_T pdx_pwm_output(PDX_LCHAN_T pdxf_lchan, F32 pdxf_freq, F32 pdxf_duty, F32 pdxf_offset, BOOL pdxf_init)

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or drive a PWM output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc.

On the M250 target, when driving the H-bridge arms independently, the driven signal may have dead-time inserted when changing from low-side to high-side or high-side to low-side for one task period to avoid shoot-through and damage to the ECU. This means that the actual duty cycle may be less than the requested duty cycle for one task cycle, especially at high base frequencies.

If the output pin can be configured for either a low-side or high-side output, the polarity of the output is generally controlled by calling pdx_digital_output() using the channel with a name of the form PIO_DOT_XXX_SELECT_HIGH_SIDE . See the technical reference for the targets for specific information. Can raise the following errors: PDX_PWM_OUT_CHANNEL_UNSUPPORTED + pdxf_lchan , or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a PWM output. Use the macros included by the pio.h file, of the form PIO_POT_[NAME].

Copyright 2019, Pi Innovo 185 Library interface

Arg (data in): pdxf_freq The desired frequency of the output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate. Range: [0.5, 10000] Hz

Arg (data in): pdxf_duty The desired duty cycle of the PWM output. This is the fraction of the period (1 / pdxf_freq) which the output will be active. For low-side outputs this is the period that the output is pulled to ground and for high-side outputs this is the time the output will be pulled to supply voltage. When the output is inactive, the output will be in a high-impedence state. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise. Range: [0, 1] unitless

Arg (data in): pdxf_offset The desired phase offset of the PWM output, relative to other PWM output channels that have been configured with the same frequency. This Range: [0, 2000] ms

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

• PDX_RC_FREQ_TOO_LOW - frequency to slow for target, frequency will be clipped to minimum allowed.

• PDX_RC_FREQ_TOO_HIGH - frequency to quick for target, frequency will be clipped to maximum allowed.

5.10.3.3.9. pdx_quad_freq_input()

Definition: PDX_RC_T pdx_quad_freq_input(PDX_LCHAN_T pdxf_pri_lchan, PDX_LCHAN_T pdxf_sec_lchan, U8 pdxf_count, U32 pdxf_last_edges, S32 *pdxf_delta_edges, U32 *pdxf_this_edges, F32 *pdxf_pchan_freq, F32 *pdxf_schan_freq, U32 pdxf_pchan_last_edges, U32 pdxf_schan_last_edges, U32 *pdxf_pchan_edges,

Copyright 2019, Pi Innovo 186 Library interface

U32 *pdxf_schan_edges, U32 pdxf_pchan_last_time, U32 pdxf_schan_last_time, U32 *pdxf_pchan_time, U32 *pdxf_schan_time, F32 pdxf_timeout, BOOL *pdxf_pchan_timed_out, BOOL *pdxf_schan_timed_out, BOOL pdxf_init)

Supported targets:

Required license: None (Main library).

Description: Function to initialise or read a quadrature and frequency input channel.

This function returns the latest measured edges seen as a quadrature input and the frequency of each input. The function relies on a hardware peripheral to decode the input and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc.. Can raise the following errors: PDX_TPU_QFI_CHANNEL_DEVICE_ERROR + pdxf_pri_lchan , or PDX_QDEC_FREQ_IN_CHANNEL_UNSUPPORTED + pdxf_pri_lchan , or PDX_CHANNEL_INVALID + pdxf_pri_lchan

Arg (data in): pdxf_pri_lchan The primary digital channel to use as a quadrature and frequency input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_sec_lchan The secondary digital channel to use as a quadrature and frequency input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME]. Cannot be the same as parameter pdxf_pri_lchan.

Arg (data in): pdxf_count The number of cycles the secondary frequency measurement is averaged over. If set to 1, the measurement is made from the latest cycle. The primary frequency measurement is taken from a single cycle. Range: [1, 255] cycles

Arg (data in): pdxf_last_edges This parameter should be populated with zero on the first call to this function, and subsequently with the value written last time to pdxf_this_edges Range: [-8388608, 8388607] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_delta_edges The signed difference in edges seen since the last call is written through this pointer. The sign determines the direction of travel of the quadrature input signal. Cannot be NULL. Range: [-8388608, 8388607] edges (for M250, M460 and M461 targets)

Copyright 2019, Pi Innovo 187 Library interface

Arg (data out): pdxf_this_edges This parameter is populated with a function-internal value which needs to be passed the next time the function is called in the pdxf_last_edges parameter. Cannot be NULL. Range: [N/A]

Arg (data out): pdxf_pchan_freq The measured frequency of the primary input channel is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written. The range of the frequency is limited in various ways.

• The range of the frequency that can be measured is limited by the filter circuitry of the input pin.

• The lowest measurable frequency is limited by the filter circuitry and the size of the corresponding processor timer for a channel. Any input frequency below the documented limit, is reported as timed-out.

• The highest measurable frequency is limited by the filter circuitry and the resolution of the corresponding processor timer for a channel. In general, the block reports the frequency of the filtered signal and the input filtering forms an upper limit. However, as the frequency increases, the resolution of measurement decreases. Details of the input pin's filtering and processor timing can be found in an ECU's technical specification. Cannot be NULL. Range: [0.5, ...] Hz (for M250, M460 and M461 targets)

Arg (data out): pdxf_schan_freq The measured frequency of the secondary input channel is written through this pointer. If the input signal has timed out, the last measured input frequency (or zero if none has been measured) is written. Cannot be NULL. Range: [0.5, ...] Hz (for M250, M460 and M461 targets)

Arg (data in): pdxf_pchan_last_edges A count of edges seen by the quadrature and frequency input function last time this function was called (or zero if this is the first time the function has been called). The counter is used to determine whether the primary signal has timed out or not. Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data in): pdxf_schan_last_edges A count of edges seen by the quadrature and frequency input function last time this function was called (or zero if this is the first time the function has been called). The counter is used to determine whether the secondary signal has timed out or not. Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_pchan_edges The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_pchan_last_edges next time the function is called.

Copyright 2019, Pi Innovo 188 Library interface

Cannot be NULL. Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data out): pdxf_schan_edges The count of edges seen by the frequency input function this time is written through this pointer. It is the value to be passed as pdxf_schan_last_edges next time the function is called. Cannot be NULL. Range: [0, 16777215] edges (for M250, M460 and M461 targets)

Arg (data in): pdxf_pchan_last_time The time of the last call to this quadrature and frequency input function (or zero if it is the first call). It is used to determine whether the primary signal has timed out or not. Range: [0, 4294967295] microseconds

Arg (data in): pdxf_schan_last_time The time of the last call to this quadrature and frequency input function (or zero if it is the first call). It is used to determine whether the secondary signal has timed out or not. Range: [0, 4294967295] microseconds

Arg (data out): pdxf_pchan_time The time of this call is written through this pointer. It is the value to be passed as pdxf_pchan_last_time next time the function is called. Cannot be NULL. Range: [0, 4294967295] microseconds

Arg (data out): pdxf_schan_time The time of this call is written through this pointer. It is the value to be passed as pdxf_schan_last_time next time the function is called. Cannot be NULL. Range: [0, 4294967295] microseconds

Arg (data in): pdxf_timeout The duration of the input signal timeout period. Range: [100, 2000000] microseconds (for M250, M460 and M461 targets)

Arg (data out): pdxf_pchan_timed_out Set if the primary input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered. Cannot be NULL. Range: 0 or 1

Arg (data out): pdxf_schan_timed_out Set if the secondary input signal has timed out at the point of calling. If between calls, the input signal timed out and then re-established itself, the time out event is not registered. Cannot be NULL. Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

Copyright 2019, Pi Innovo 189 Library interface

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - configuration error

5.10.3.3.10. pdx_quad_input()

Definition: PDX_RC_T pdx_quad_input(PDX_LCHAN_T pdxf_pri_lchan, PDX_LCHAN_T pdxf_sec_lchan, U32 pdxf_last_edges, S32 *pdxf_delta_edges, U32 *pdxf_this_edges, BOOL pdxf_init)

Supported targets:

Required license: None (Main library).

Description: Function to initialise or read a quadrature input channel.

This function returns the latest measured edges seen as a quadrature input. The function relies on a hardware peripheral to decode the input and present the information on request.

Note

Consider hardware effects such as inversion, filtering, etc.. Can raise the following errors: PDX_TPU_QI_CHANNEL_DEVICE_ERROR + pdxf_pri_lchan , or PDX_QDEC_IN_CHANNEL_UNSUPPORTED + pdxf_pri_lchan , or PDX_CHANNEL_INVALID + pdxf_pri_lchan

Arg (data in): pdxf_pri_lchan The primary digital channel to use as a quadrature input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_sec_lchan The secondary digital channel to use as a quadrature input. Use the macros included by the pio.h file, of the form PIO_QDIN_[NAME].

Arg (data in): pdxf_last_edges A sum of edges seen by the quadrature input function on the primary and secondary input channels last time this function was called (or zero if this is the first time the function has been called). Range: [-8388608, 8388607] edges

Arg (data out): pdxf_delta_edges The signed difference in edges seen since the last call is written through this pointer. The sign determines the direction of travel of the quadrature input signal. Cannot be NULL. Range: [-8388608, 8388607] edges

Arg (data out): pdxf_this_edges The count of edges seen this call is written through this pointer. It is the value to be passed as pdxf_last_edges next time the function is called.

Copyright 2019, Pi Innovo 190 Library interface

Cannot be NULL. Range: [-8388608, 8388607] edges

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - if successful action

• PDX_RC_SW_ERROR - if channel not supported

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - if configuration error

5.10.3.3.11. pdx_sent_input()

Definition: PDX_RC_T pdx_sent_input(PDX_LCHAN_T pdxf_lchan, F32 pdxf_tick_length_us, U8 pdxf_num_nibbles, PIO_PDX_SENT_CRC_T pdxf_crc_version, U8 *pdxf_num_decoded_frames, U8 *pdxf_num_desyncs, BOOL *pdxf_valid, U8 *pdxf_status, U32 *pdxf_data, U32 *pdxf_timestamp, BOOL *pdxf_pin_state, BOOL pdxf_init)

Supported targets:

Required license: None (Main library).

Description: Function to initialise and read a SENT input channel, fast channel signals.

The SENT input function decodes a sensor's transmission pulses based on SAE J2716 Jan 2010, making available the sensor's status and data information. SAE J2716 describes SENT as:

The Single Edge Nibble Transmission encoding scheme (SENT) is intended for use in applications where high resolution sensor data needs to be communicated from a sensor to an Engine Control Unit (ECU). It is intended as a replacement for the lower resolution methods of 10 bit A/D converters and PWM and as a simpler low cost alternative to CAN or LIN. The implementation assumes that the sensor is a smart sensor containing a microprocessor or dedicated logic device (ASIC) to create the signal.

SENT is a unidirectional communications scheme from sensor / transmitting device to controller / receiving device which does not include a coordination signal from the controller / receiving device. The sensor signal is transmitted as a series of pulses with data encoded as falling to falling edge periods.

This SENT input function:

• decodes a stream of SENT pulses into status and fast data nibbles;

Copyright 2019, Pi Innovo 191 Library interface

• retrieves the last received, decoded and verified status and data nibbles;

• allows for a transmitter clock tick variance of +- 25% for the calibration and synchronisation pulse;

• allows for a transmitter clock tick between [3, 90] microseconds;

• allows for an optional pause pulse between transmissions;

• uses the calibration and sychronisation pulse to ratiometrically adjust the status, data and CRC pulses;

• verifies the frame size (checks the expected number of nibbles, or message edges);

• verifies the frame CRC, either the 2008 or 2010 version;

• verifies that successive calibration pulses differ by less than +- 1.5625%.

See the pdx_sent_serial_input() function for reading short serial or extended serial data.

Can raise the following errors: PDX_SENT_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a SENT input. Use the macros included by the pio.h file, of the form PIO_SENTIN_[NAME].

Arg (data in): pdxf_tick_length_us The length of the SENT sensor's transmission clock tick. Range: [3, 90] microseconds Resolution: 0.1 microseconds

Arg (data in): pdxf_num_nibbles The number of data nibbles transmitted by the SENT sensor in each frame. Range: [1, 6] nibbles

Arg (data in): pdxf_crc_version Which CRC algorithm the SENT sensor applies to each SENT frame. Either PIO_PDX_SENT_CRC_2008 or PIO_PDX_SENT_CRC_2010.

Arg (data out): pdxf_num_decoded_frames A counter incremented for each frame that is successfully received, decoded and verified. Cannot be NULL. Range: [0, inf] frames, modulo 256

Arg (data out): pdxf_num_desyncs A counter incremented for each loss of synchronisation with the SENT sensor pulse stream. Loss of synchronisation occurs when the pulse decoder has not seen a valid pulse for more than 125% of a calibration pulse duration (where a calibration pulse is 56 SENT ticks, see pdxf_tick_length_us); or a calibration, status, nibble or CRC pulse is too short; or the frame CRC verification fails.

Copyright 2019, Pi Innovo 192 Library interface

Cannot be NULL. Range: [0, inf] frames, modulo 256

Arg (data out): pdxf_valid True if at least one SENT frame has been successfully received, decoded and verified, false otherwise. If true, then the pdxf_status and pdxf_data parameters provide the status and data received from the last frame, and the pdxf_timestamp parameter provides the time when the frame was received. Cannot be NULL. Range: 0 or 1

Arg (data out): pdxf_status The status nibble of the last SENT frame that was successfully received, decoded and verified. Set to zero when a SENT frame has not been successfully received. Cannot be NULL.

Arg (data out): pdxf_data The data nibbles of the last SENT frame that was successfully received, decoded and verified. Set to zero when a SENT frame has not been successfully received. The data nibbles are packed into the integer right aligned. Cannot be NULL.

Arg (data out): pdxf_timestamp A timestamp is taken when the the last SENT frame was fully received, decoded and verified. The timestamp increments in counts of 256, wrapping approximately every 4 seconds. The timestamp can be used by the application to determine whether the SENT sensor is transmitting data at the expected period. Cannot be NULL. Range: [0, inf] counts, modulo 4294967296

Arg (data out): pdxf_pin_state 1 if the channel pin voltage is above the detection threshold, 0 otherwise. Can be used by the application for electrical diagnostics. Range: 0 or 1

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_BAD_ARGS - configuration error

• PDX_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.10.3.3.12. pdx_sent_serial_input()

Definition: PDX_RC_T pdx_sent_serial_input(PDX_LCHAN_T pdxf_lchan, U8 *pdxf_num_messages, U8 *pdxf_num_failed_crcs, BOOL *pdxf_valid, PDX_SENT_SERIAL_FORMAT_T *pdxf_serial_format, U8 *pdxf_message_id, U32 *pdxf_data, U32 *pdxf_timestamp)

Copyright 2019, Pi Innovo 193 Library interface

Supported targets:

Required license: None (Main library).

Description: Function to read a SENT input channel, slow channel signals.

This SENT input function:

• decodes the status nibble from 16 or 18 consecutive SENT transmissions into message identification and data values;

• retrieves the last received, decoded and verified serial data;

• verifies the serial message CRC.

The application must initialise a SENT channel by calling pdx_sent_input() before calling pdx_sent_serial_input().

Can raise the following errors: PDX_SENT_IN_CHANNEL_UNSUPPORTED + pdxf_lchan, or PDX_CHANNEL_INVALID + pdxf_lchan

Arg (data in): pdxf_lchan The digital channel to use as a SENT input. Use the macros included by the pio.h file, of the form PIO_SENTIN_[NAME].

Arg (data out): pdxf_num_messages A counter incremented for each serial message that is successfully received, decoded and verified. Cannot be NULL. Range: [0, inf] messages, modulo 256

Arg (data out): pdxf_num_failed_crcs A counter incremented for each serial message that is received but that fails a CRC verification. Cannot be NULL. Range: [0, inf] messages, modulo 256

Arg (data out): pdxf_valid True if at least one serial message has been successfully received, decoded and verified, false otherwise. If true, then the pdxf_serial_format, pdxf_message_id and pdxf_data parameters provide information about the last successfully received, decoded and verified message, and the pdxf_timestamp parameter provides the time when the message was received. Cannot be NULL. Range: 0 or 1

Arg (data out): pdxf_serial_format The detected serial format of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not been received. Cannot be NULL.

Arg (data out): pdxf_message_id The value of the message identifier of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not yet been received.

Copyright 2019, Pi Innovo 194 Library interface

Range: [0, 15] for short serial and enhanced serial format 2 Range: [0, 255] for enhanced serial format 1

Arg (data out): pdxf_data The data nibbles of the last successfully received, decoded and verified slow serial message. Set to zero when a serial message has not yet been received. Cannot be NULL. Range: [0, 255] for short serial Range: [0, 8192] for enhanced serial format 1 Range: [0, 65535] for enhanced serial format 2

Arg (data out): pdxf_timestamp A timestamp is taken when the the last successfully received, decoded and verified slow serial message. The timestamp increments in counts of 256, wrapping approximately every 4 seconds. The timestamp can be used by the application to determine whether the SENT sensor is transmitting data at the expected period. Cannot be NULL. Range: [0, inf] counts, modulo 4294967296

Return:

• PDX_RC_OK - successful action

• PDX_RC_SW_ERROR - channel not supported

• PDX_RC_BAD_ARGS - configuration error 5.10.3.3.13. pdx_spwm_output()

Definition: PDX_RC_T pdx_spwm_output(PDX_LCHAN_T pdxf_master_lchan, PDX_LCHAN_T pdxf_slave_lchan, F32 pdxf_master_freq, F32 pdxf_master_duty, F32 pdxf_master_offset, F32 pdxf_slave_freq, F32 pdxf_slave_duty, U32 pdxf_slave_delay, BOOL pdxf_init)

Supported targets:

Required license: None (Main library).

Description: Function to initialise or drive a synchronised PWM output channel.

Note

Consider hardware effects such as inversion, low-side/high-side driven, filtering, etc.. Can raise the following errors: PDX_TPU_SPO_CHANNEL_DEVICE_ERROR + pdxf_master_lchan , or PDX_SYNC_PWM_OUT_CHANNEL_UNSUPPORTED + pdxf_master_lchan , or PDX_CHANNEL_INVALID + pdxf_master_lchan

Arg (data in): pdxf_master_lchan The master digital channel to use as a synchronised PWM output. Use the macros included by the pio.h file, of the form PIO_SPOT_[NAME].

Copyright 2019, Pi Innovo 195 Library interface

Arg (data in): pdxf_slave_lchan The slave digital channel to use as a PWM output. Use the macros included by the pio.h file, of the form PIO_SPOT_INT_SLAVE_[NAME].

Arg (data in): pdxf_master_freq The desired frequency of the master channel output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate. Range: [1, 10000] Hz (for the M250, M460 targets)

Arg (data in): pdxf_master_duty The desired duty cycle of the master channel PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise. Range: [0, 1] unitless

Arg (data in): pdxf_master_offset The desired phase offset of the master (and hence slave) channel, relative to other channels that have been configured with the same frequency. Range: [0, 2000] ms (for the M250, M460 targets)

Arg (data in): pdxf_slave_freq The desired frequency of the slave channel output. If the software cannot match the desired frequency, the frequency will be adjusted to as close a match as is possible. If the frequency is outside of the allowed range, then it will be clipped to the allowed range and and either PDX_RC_FREQ_TOO_LOW or PDX_RC_FREQ_TOO_HIGH returned as appropriate. Range: [1, 10000] Hz (for the M250, M460 targets)

Arg (data in): pdxf_slave_duty The desired duty cycle of the slave channel PWM output. If the software cannot match the desired duty cycle, the frequency will be adjusted to as close a match as is possible. Some channels cannot achieve very low or very high duty cycles accurately (although 0% and 100% is correctly handled) and will introduce jitter into the signal. It is up to the caller to ensure this condition does not arise. Range: [0, 1] unitless

Arg (data in): pdxf_slave_delay The desired delay of the slave channel. Range: [0, 1000000] microseconds.

Arg (data in): pdxf_init True if the channel is to be initialised, false otherwise.

Return:

• PDX_RC_OK - if successful action

• PDX_RC_SW_ERROR - if channel not supported

Copyright 2019, Pi Innovo 196 Library interface

• PDX_RC_HW_ERROR - if error initialising channel

• PDX_RC_BAD_ARGS - if configuration error

• PDX_RC_SDM_ALLOC_ERROR - if error allocating ram in SDM

• PDX_RC_FREQ_TOO_LOW - frequency to slow for target

• PDX_RC_FREQ_TOO_HIGH - frequency to quick for target 5.11. Digital data feature (PDD) 5.11.1. Overview

The library supports functions to access virtual data I/O. 5.11.1.1. Digital data input

The library supports reading the value of arbitrary data inputs which are not well grouped into other interfaces (see pdd_data_input()).

An example might be the fault counters for SPI message queues. SPI message queues are not exposed to the application but the application needs to know when SPI messaging fails so the application can take remedial actions if desired.

Injector circuits can provide timing signals to specify boost recharge times. These values can be read though the pdd_data_input function for the application to process in the desired way. 5.11.1.2. Digital data output

The library supports writing a value to arbitrary data outputs which are not well grouped into other interfaces (see pdd_data_output()).

An example may be a user specified payload to write to an ASIC via a SPI message. SPI message queues are not exposed to the application but the application needs to have the ability to tune specified data parameters to send the appropriate real-time settings to an ASIC.

A real-time clock integrated circuit can receive various values that will be interpreted to start the on-chip countdown timer at different rates and times. These values can be written though the pdd_data_output function for the application to have control over values sent to the supported variables in the platform. 5.11.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pdd.h Enumerations PDD_RC_T

An enumerated type which contains success and failure codes returned by some digital data feature (PDD) functions.

Copyright 2019, Pi Innovo 197 Library interface

Type Identifier PDD_ERROR_CODE_T

Error values for debugging when an error is found when calling the digital data feature (PDD), the API calls a function with an enumeration from this type. Data types PDD_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets. Functions PDD_RC_T pdd_data_input

Function to initialise or read a digital data channel. PDD_RC_T pdd_data_output

Function to initialise or write to a specified digital data output channel. 5.11.3. Interface detail 5.11.3.1. Enumerations

5.11.3.1.1. PDD_RC_T

Summary: An enumerated type which contains success and failure codes returned by some digital data feature (PDD) functions.

Enumerations:

PDD_RC_OK Return code if everything progressed as expected.

PDD_RC_SW_ERROR Return code if an internal error occurred which was the result of a software error.

PDD_RC_HW_ERROR Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PDD_RC_BAD_ARGS Return code if at least one of the arguments could not be used. 5.11.3.1.2. PDD_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the digital data feature (PDD), the API calls a function with an enumeration from this type.

Enumerations:

PDD_CHANNEL_INVALID Error raised if the digital channel 'n' is not supported.

Copyright 2019, Pi Innovo 198 Library interface

'n' is (error_code - PDD_CHANNEL_INVALID).

PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a digital data input.

'n' is (error_code - PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED).

PDD_DIG_DATA_OUT_CHANNEL_UNSUPPORTED Error raised if the channel 'n' cannot be used as a digital data input.

'n' is (error_code - PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED). 5.11.3.2. Data types

5.11.3.2.1. PDD_LCHAN_T

Definition: typedef U16 PDD_LCHAN_T

Description: This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target. 5.11.3.3. Functions

5.11.3.3.1. pdd_data_input()

Definition: PDD_RC_T pdd_data_input(PDD_LCHAN_T pddf_lchan, S32 *pddf_data, BOOL pddf_init)

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or read a digital data channel.

Can raise the following errors: PDD_DIG_DATA_IN_CHANNEL_UNSUPPORTED + pddf_lchan, or PDD_CHANNEL_INVALID + pddf_lchan

Arg (data in): pddf_lchan The digital channel to use as a digital data input. Use the macros included by the pio.h file, of the from PIO_DIN_DATA_[NAME].

Arg (data out): pddf_data The value of the digital data is written through this pointer. Cannot be NULL. Range: [-2147483648, 2147483647] (the actual range may vary depending on the value read)

Arg (data in): pddf_init TRUE if the channel is to be initialised, FALSE otherwise.

Copyright 2019, Pi Innovo 199 Library interface

Return:

• PDD_RC_OK - if successful action

• PDD_RC_SW_ERROR - if channel not supported

• PDD_RC_BAD_ARGS - if configuration error

5.11.3.3.2. pdd_data_output()

Definition: PDD_RC_T pdd_data_output(PDD_LCHAN_T pddf_lchan, S32 pddf_data, BOOL pddf_init)

Supported targets: All targets

Required license: None (Main library).

Description: Function to initialise or write to a specified digital data output channel.

Can raise the following errors: PDD_DIG_DATA_OUT_CHANNEL_UNSUPPORTED + pddf_lchan, or PDD_CHANNEL_INVALID + pddf_lchan

Arg (data in): pddf_lchan The digital channel to use as a digital data output. Use the macros included by the pio.h file, of the from PIO_DDOT_DATA_[NAME].

Arg (data in): pddf_data The value of the digital data. Cannot be NULL. Range: [-2147483648, 2147483647] (the actual range may vary depending on the value write)

Arg (data in): pddf_init TRUE if the channel is to be initialised, FALSE otherwise.

Return:

• PDD_RC_OK - if successful action

• PDD_RC_SW_ERROR - if channel not supported

• PDD_RC_BAD_ARGS - if configuration error 5.12. Output driver control feature (PSS) 5.12.1. Overview

The output driver control feature allows access to the overall output driver switch for each ECU (if an ECU supports such a switch). The overall output driver switch can enable or disable a subset of the ECU outputs in one go. The application could use the switch as a safety device if necessary. See the technical specification for the ECU for a description of how the output driver switch works for that ECU (Section A.1, “ECU hardware reference documentation”).

Copyright 2019, Pi Innovo 200 Library interface

5.12.2. M220 target

On the M220 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection). 5.12.2.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over- current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress. 5.12.3. M250 target

On the M250 ECU, the output control circuit turns on or off the high side switch from which individual actuators can be attached. The choice of actuators which are directly controlled by the circuit is under the control of the system designer.

VPWR

high side switch control from blockset (pss_OutputControl block) LOAD LOAD

switch control from blockset (e.g., from digital output block)

PWRGND

switch control from blockset (e.g., from digital output block)

PWRGND

Internal to ECU External to ECU

5.12.3.1. Initialisation

The application can call pss_set_safety_switch() to set the output control switch state during application initialisation and application run. During power up, boot, library pre-initialisation and application initialisation, the switch is forced off by the library (thus ensuring the outputs do not glitch during the power up and initialisation sequence of the ECU). During library post- initialisation the switch is set as required by the application. If the application has not set the switch state during application initialisation, then the library will force the switch off.

Copyright 2019, Pi Innovo 201 Library interface

5.12.3.2. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over- current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress. 5.12.4. M460 target

On the M460 ECU, the output control circuit turns on or off the high side switch from which individual actuators can be attached. The choice of actuators which are directly controlled by the circuit is under the control of the system designer.

VPWR

high side weak pull-up control from blockset (pss_OvercurTripReset_DiagnEnable block) high side switch control weak from blockset pull (pss_outputControl block) up LOAD LOAD

weak switch control from software pull (e.g., from digital output) down

PWRGND

weak switch control from software pull (e.g., from PWM output) down

PWRGND

Internal to ECU External to ECU

5.12.4.1. Initialisation

The application can call pss_set_safety_switch() to set the output control switch state during application initialisation and application run. During power up, boot, library pre-initialisation and application initialisation, the switch is forced off by the library (thus ensuring the outputs do not glitch during the power up and initialisation sequence of the ECU). During library post- initialisation the switch is set as required by the application. If the application has not set the switch state during application initialisation, then the library will force the switch off. 5.12.4.2. Diagnostics

The application can call pss_overcur_trip_reset_and_diagn_enable_state() during application run to enable or disable the high side weak pull-up resistor for diagnostic purposes. See Technical Specification — M460 for details.

Copyright 2019, Pi Innovo 202 Library interface

If the function is never called to change the state of the high side weak pull-up resistor, the resistor is left disabled after library initialisation. 5.12.4.3. Over-current trip latches

The application can call pss_overcur_trip_reset_and_diagn_enable_state() during application run to reset the over-current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress. 5.12.5. M461 target

On the M461 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection). 5.12.5.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over- current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress. 5.12.6. M670 target

On the M670 ECU there is no output control circuit but the ECU does provide over-current trip protection (as well as other forms of circuit protection). See the M670 technical specification for a complete list of protection and electical monitoring signals. 5.12.6.1. Over-current trip latches

The application can call pss_overcur_trip_reset() during application run to reset the over- current trip latches. The API enforces a minimum duration between resets to allow the ECU time to dissipate heat and to reduce component stress. 5.12.7. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pss.h Functions void pss_overcur_trip_reset

Request that the over-current trip latches are reset. void pss_overcur_trip_reset_and_diagn_enable_state

Request that the over-current trip latches are reset and to set the high-side switch diagnostic enable. void pss_set_safety_switch

Function to set the safety switch state. void pss_set_switch

Function to set the safety switch state (deprecated).

Copyright 2019, Pi Innovo 203 Library interface

5.12.8. Interface detail 5.12.8.1. Functions

5.12.8.1.1. pss_overcur_trip_reset()

Definition: void pss_overcur_trip_reset(BOOL pssf_request_trip_reset)

Supported targets:

Required license: None (Main library).

Description: Request that the over-current trip latches are reset.

Note

The OpenECU software limits requests for over-current trip reset to be at least 50ms apart. If a second request is issued within 50ms from the first one, it will be latched and delayed until the 50ms time lag has expired.

Arg (data in): pssf_request_trip_reset Need to cause a transition from false to true to generate an over- current trip reset.

5.12.8.1.2. pss_overcur_trip_reset_and_diagn_enable_state()

Definition: void pss_overcur_trip_reset_and_diagn_enable_state(BOOL pssf_enable_diagn, BOOL pssf_request_trip_reset)

Supported targets:

Required license: None (Main library).

Description: Request that the over-current trip latches are reset and to set the high- side switch diagnostic enable.

Note

The OpenECU software limits requests for over-current trip reset to be at least 50ms apart. If a second request is issued within 50ms from the first one, it will be latched and delayed until the 50ms time lag has expired.

Arg (data in): pssf_enable_diagn True if the Diagnostic Enable signal is asserted, false otherwise.

Arg (data in): pssf_request_trip_reset Need to cause a transition from false to true to generate an over- current trip reset.

Copyright 2019, Pi Innovo 204 Library interface

5.12.8.1.3. pss_set_safety_switch()

Definition: void pss_set_safety_switch(BOOL pssf_enable)

Supported targets:

Required license: None (Main library).

Description: Function to set the safety switch state.

If this function is called during application initialisation, the switch state is remembered, and set during library post initialisation. If this function is called during application run, the switch state is actioned immediately. The platform may force the safety switch to stay open in case the battery voltage is detected to be too low.

Arg (data in): pssf_enable True to enable the safety switch and enable the output drivers, false otherwise.

5.12.8.1.4. pss_set_switch()

Definition: void pss_set_switch(BOOL pssf_enable)

Supported targets:

Required license: None (Main library).

Description: Function to set the safety switch state (deprecated).

Identical in functionality to pss_set_safety_switch(). This function became deprecated in version 1.7.3 and will be removed in a future release. The function is currently retained to provide backwards compatibility to previous releases.

Arg (data in): pssf_enable True to enable the safety switch and enable the output drivers, false otherwise. 5.13. Serial peripheral feature (PSP) 5.13.1. Overview

The serial peripheral feature initiates and completes communication between serial devices within the ECU. The feature is largely within the library with only one function exposed to trigger the periodic functionality required. 5.13.2. Input and output processing

The application must call psp_spi_trigger() at the end of each application task. The call ensures that the library performs appropriate input and output processing for the task at the task's activation rate.

Copyright 2019, Pi Innovo 205 Library interface

5.13.3. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and psp.h Enumerations PSP_ERROR_CODE_T

Error values for debugging when an error is found when calling the serial peripheral interface feature (PSP), the API calls a function with an enumeration from this type. Functions void psp_spi_trigger

Force all SPI queues accessed by the current task set to be marked as ready for processing. S16 psp_get_fault_count

Gets the fault count for a SPI device. 5.13.4. Interface detail 5.13.4.1. Enumerations 5.13.4.1.1. PSP_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the serial peripheral interface feature (PSP), the API calls a function with an enumeration from this type.

Enumerations:

PSP_QUEUE_OUT_OF_RANGE Error raised if the number of transactions configured for SPI transmission is greater than the maximum allowed.

PSP_TJA1145_UNSUPPORTED_BAUD Error raised if CAN-wake with selective CAN frames is configured for a baud with a data rate not supported by the TJA1145.

PSP_TJA1145_SW_ERROR Error raised if a development error in TJA1145 SW is detected. 5.13.4.2. Functions 5.13.4.2.1. psp_spi_trigger()

Definition: void psp_spi_trigger(void)

Supported targets: All targets

Copyright 2019, Pi Innovo 206 Library interface

Required license: None (Main library).

Description: Force all SPI queues accessed by the current task set to be marked as ready for processing.

Trigger all SPI queues that are read from or written to in the caller's task. This completes the serial communication cycle for passing information to and from serial peripherals.

5.13.4.2.2. psp_get_fault_count()

Definition: S16 psp_get_fault_count(PIO_SPI_DEVICE_T pspf_device)

Supported targets: All targets

Required license: None (Main library).

Description: Gets the fault count for a SPI device.

Reads values of saturating fault counter for a given SPI device.

Arg (data in): pspf_device device for which to get fault count Range: See pio.h for list of fault- able SPI devices.

Return: fault count Number of faults that have been logged since that application began. Or -1 if the parameter is invalid. Range: [-1, 255] integer count or "invalid". 5.14. CJ125 device driver for UEGO measurement feature (PCJ125) 5.14.1. Overview

The CJ125 control feature allows access to the configuration of supported CJ125 devices. See the technical specification for the ECU for a description of how the CJ125 works for that ECU (Section A.1, “ECU hardware reference documentation”). 5.14.2. Initialisation

The application can call pcj125_control() to set the configuration of a specified CJ125 device. 5.14.3. Diagnostics

The library can use the PDX feature to read various diagnostic details about the CJ125 devices. 5.14.4. Interface index

An index of interface objects for this feature.

Copyright 2019, Pi Innovo 207 Library interface

Type Identifier Include file openecu.h and pcj125.h Enumerations PCJ125_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PCJ125) functions. Data types PCJ125_LCHAN_T

This declares a type with enough value range to represent all logical CJ125 channels for all targets. PCJ125_WORKSPACE_T

This structure acts as scratch area for the CJ125 driver to save the configuration. Functions PCJ125_RC_T pcj125_control

Interface to control behaviour of CJ125 device. 5.14.5. Interface detail 5.14.5.1. Enumerations

5.14.5.1.1. PCJ125_RC_T

Summary: An enumerated type which contains success and failure codes returned by some digital input feature (PCJ125) functions.

Enumerations:

PCJ125_RC_OK Return code if everything progressed as expected.

PCJ125_RC_SW_ERROR Return code if an internal error occurred which was the result of a software error.

PCJ125_RC_HW_ERROR Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PCJ125_RC_BAD_ARGS Return code if at least one of the arguments could not be used. 5.14.5.2. Data types

5.14.5.2.1. PCJ125_LCHAN_T

Definition: typedef U8 PCJ125_LCHAN_T

Copyright 2019, Pi Innovo 208 Library interface

Description: This declares a type with enough value range to represent all logical CJ125 channels for all targets.

See pio.h for a list of relevant channels for a specific target.

5.14.5.2.2. PCJ125_WORKSPACE_T

Definition: typedef struct PCJ125_WORKSPACE_T_ PCJ125_WORKSPACE_T

Description: This structure acts as scratch area for the CJ125 driver to save the configuration.

One structure should be allocated per CJ125 driven and passed to the corresponding pcj125_control call. 5.14.5.3. Functions

5.14.5.3.1. pcj125_control()

Definition: PCJ125_RC_T pcj125_control(PCJ125_LCHAN_T pcj125f_channel, PIO_CJ125_REF_CURRENT_T pcj125f_ref_current, PIO_CJ125_IP_AMP_T pcj125f_ip_amplification, BOOL pcj125f_calibration_mode, PCJ125_WORKSPACE_T *pcj125f_workspace, BOOL pcj125f_init)

Supported targets:

Required license: None (Main library).

Description: Interface to control behaviour of CJ125 device.

This function is called periodically during an application task to set the internal configuration of the specified CJ125 device. The function should be called in a task with the desired rate at which the device should be reconfigured.

Note

This function should only be called once per task for each CJ125 device controlled. If this assumption is violated, then the function call could be out of sync with the device communication which could cause unpredictable behaviour.

Arg (data in): pcj125f_channel The CJ125 channel to control. Use the macros included by the pio.h file, of the form PIO_CJ125_[NAME].

Arg (data in): pcj125f_ref_current Enumeration of the desired reference current used by the device.

Arg (data in): pcj125f_ip_amplification Enumeration of the desired amplification.

Copyright 2019, Pi Innovo 209 Library interface

Arg (data in): pcj125f_calibration_mode TRUE to configure the device for calibration mode. FALSE otherwise.

Arg (data in,out): pcj125f_workspace Reference to a memory structure used to store information between function Calls. There should be one such structure allocated and passed to this function for each CJ125 in use.

Arg (data in): pcj125f_init True if the channel is to be initialised, false otherwise.

Return:

• PCJ125_RC_OK - successful action

• PCJ125_RC_HW_ERROR - error communicating on channel

• PCJ125_RC_BAD_ARGS - configuration error 5.15. CAN messaging feature (PCX) 5.15.1. Overview

Reception and transmission of CAN messages, as defined by ISO 11989, is supported by the library. The library provides mechanisms to receive and transmit messages, pack and unpack data for messages, as well as handling error cases. 5.15.2. Initialisation

During application initialisation, the application must configure the CAN buses to be used by calling ??? and declare any receive or transmit messages by calling ???. During library post-initialisation, the library configures the ECU hardware to efficiently receive and transmit these messages.

The call to ??? configures the baud rate for the CAN bus. The range of baud rates selectable is controlled by the library, as is the sample point for each CAN bit (set at 75%).

Figure 5.15. CAN bit sample point

Bit time

Sync Prop Phase1 Phase2

Sample point for CAN bit at 75%

The call to ??? returns a handle which must be used when referencing the same message in any other call to this feature. 5.15.3. Receiving messages

The library buffers received CAN messages for the application, discarding messages which are not of interest (i.e., not declared during initialisation). The application can determine whether a message has been received since last time and extract the contents of the message by calling ???.

Copyright 2019, Pi Innovo 210 Library interface

Each receive message buffer stores one CAN message. If a CAN message with the same identifier is received more than once between calls from the application, then the message buffer is overwritten with the latest received message. This ensures the latest copy of a CAN message is available to the application, but is not suitable for CAN messages which contain state information (e.g., CAN messages containing protocol information, etc.).

Each receive message buffer stores a low accuracy time taken a short period of time after the message is received. That period of time is variable depending on the load of the processor and will therefore suffer jitter, thus the classification of low accuracy. The timer used for the time stamp is a free running timer, that wraps at its maximum to zero.

The return value from calling ??? gives an indication of CAN message status. It provides an indication of whether a message has been received since the last call, whether more than one message with the same CAN identifier has been received, and whether an error occurred on reception. See ???, ??? and ??? for more.

To help unpack data from the contents of a CAN message, the library provides two functions: pcx_unpack_msg() and pcx_vdb_unpack_msg().

Warning

The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

5.15.4. Transmitting messages

The library transmits buffered CAN messages for the application. The application tells the library to transmit a new CAN message by calling ???.

Each transmit message buffer stores one CAN message. If the application requests a transmit of a CAN message before the library has transmitted the last CAN message with the same identifier, then the message buffer is overwritten with the latest transmit message. This ensures the latest version of a CAN message is transmitted by the library, but is not suitable for CAN messages which contain state information (e.g., CAN messages containing protocol information, etc.).

The library buffers multiple transmit messages but as the CAN bus is serial in nature, only one message can be transmitted at a time. The library attempts to transmit the messages in the order they are presented when ??? is called, but the library will not always adhere to this ordering.

To lessen the load experienced by the CAN bus and the ECU, after the library has transmitted one message, it will wait for 2 milliseconds before determining the next message to transmit (except for J1939 and CCP messaging which can occur more quickly than this).

To help pack data into the contents of a CAN message, the library provides two functions: pcx_pack_msg() and pcx_vdb_pack_msg().

The library provides a set of counters which can be used to determine whether a message has been transmitted or not. The ??? function provides a count of the requests for transmission from the application, a count of the number of times the message was queued in software rather than being immediately passed to the CAN controller for immediate transmission, and a count of the number of times the message was successfully transmited on the bus. A difference in the count between the application request for transmission and successful transmission indicates a failure to successfully transmit.

Copyright 2019, Pi Innovo 211 Library interface

Note

If a message is queued waiting for transmission and the application requests the same message is transmitted (possibly with different message data) then the queued message is overwritten with the most recent requested message.

5.15.5. CAN status

The library provides the function ??? to provide the current state of the CAN bus, one of: error-active, error-passive and bus-off. This function replaces the ??? function, which is now deprecated and retained only for backwards compatibility (deprecated functions may be removed in future versions of the developer software). 5.15.6. CAN buses

The number of CAN buses available to each target ECU varies. It may be than one ECU has two buses, but another ECU has only one. The number available to the application is defined by ???. 5.15.7. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

5.15.8. Library tasks

The library implements a couple of tasks to support CAN messaging. See Section 4.6.4, “Application and library tasks” for details. 5.15.9. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pcx.h Functions void pcx_pack_msg

Pack a series of data items into an array of CAN message bytes. void pcx_unpack_msg

Unpack a series of data items from an array of CAN message bytes.

Copyright 2019, Pi Innovo 212 Library interface

Type Identifier void pcx_vdb_pack_msg

Pack a series of data items into an array of CAN message bytes. void pcx_vdb_unpack_msg

Unpack a series of data items from an array of CAN message bytes. 5.15.10. Interface detail 5.15.10.1. Functions 5.15.10.1.1. pcx_pack_msg()

Definition: void pcx_pack_msg(U8 *pcxf_msg_data, const void *const *pcxf_item_ptr, const U8 *pcxf_field_start, const U8 *pcxf_field_width, const U8 *pcxf_is_signed, const U8 *pcxf_type_code, const U8 pcxf_use_bool_type, const U8 pcxf_num_fields)

Supported targets: All targets

Required license: None (Main library).

Description: Pack a series of data items into an array of CAN message bytes.

Pack a series of data items (of various value types) into an array of CAN message data bytes (e.g., convert a floating point data item to a 3 bit integer, and then pack it into an arbitrary bit position in the array). The array can be passed to pcx_transmit() as CAN data to be transmitted.

The packing sequence works as follows:

• for each element in pcxf_item_ptr

1. read the data value from pcxf_item_ptr based on the type from pcxf_type_code and convert to an integer (clip to maximum of a 32-bit integer if converting from a float)

2. clip the integer to the field width as given by pcxf_field_width taking into account the sign given by pcxf_is_signed

3. write bits to pcxf_msg_data based with most significant byte ordering and the bit position given by pcxf_field_start

Can raise the following errors: PCX_ERR_PACK_MSG_INVALID_PARAM, or PCX_ERR_PACK_MSG_FIELD_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_vdb_pack_msg().

Copyright 2019, Pi Innovo 213 Library interface

Arg (data out): pcxf_msg_data Pointer to an array of data bytes to be set (the array must be 8 bytes in length, if it is too small, this function will write off the end of the array). Unspecified fields are set to zero. Cannot be NULL.

Arg (data in): pcxf_item_ptr Pointer to array of pointers to data to be packed, the type of the final pointed to data is defined by the array pcxf_type_code. Cannot be NULL.

Arg (data in): pcxf_field_start Pointer to array of field start bit numbers. For each item to pack into pcxf_msg_data, the function determines where to place the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. For items whose bit length entry exceeds 7, the bit length must be one of: 0, 8, 16, 24, 32, 40, 48, 56. For fields with lengths ranging from 1 to 15 bits, the start address defines where the message's least significant bit is stored. For fields with lengths more than or equal to 16 bits, the start address defines where the message's most significant bit is stored. Cannot be NULL.

Example: To pack or unpack the bit sequence:

10 9 8 23 22 21 20 19 18 17 16

MS bit LS bit The start position is specified as 16 and the bit length as 11.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

Note

If the fields overlap (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_field_width Pointer to array of field bit widths. For each item to pack into pcxf_msg_data, the function determines how many bits to place into the array using the corresponding element from this array. The following values are allowed: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24 and 32. Items of 8 bits or fewer may not be defined so as to straddle CAN byte boundaries.

Copyright 2019, Pi Innovo 214 Library interface

Cannot be NULL.

Arg (data in): pcxf_is_signed Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to pack into pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not. If the item is negative but specified in this array as unsigned, the item is clipped to zero. Cannot be NULL.

Arg (data in): pcxf_type_code Pointer to array of data type codes. Each element determines the data type of each element in pcxf_item_ptr. The type of each element is one of: PCX_TYPECODE_F32, PCX_TYPECODE_BOOL, PCX_TYPECODE_S8, PCX_TYPECODE_U8 , PCX_TYPECODE_S16 , PCX_TYPECODE_U16, PCX_TYPECODE_S32 , PCX_TYPECODE_U32. The data storage for a boolean type depends on the pcxf_use_bool_type argument. Cannot be NULL.

Arg (data in): pcxf_use_bool_type True if boolean types are stored as 8-bit integers, false clear if boolean types are stored as 32-bit floating point.

Arg (data in): pcxf_num_fields Number of fields in each of pcxf_item_ptr, pcxf_field_start , pcxf_field_width, pcxf_is_signed, and pcxf_type_code. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. Range: [1, 255] fields

5.15.10.1.2. pcx_unpack_msg()

Definition: void pcx_unpack_msg(void *const *pcxf_item_ptr, const U8 *pcxf_msg_data, const U8 *pcxf_field_start, const U8 *pcxf_field_width, const U8 *pcxf_is_signed, const U8 *pcxf_type_code, const U8 pcxf_use_bool_type, const U8 pcxf_num_fields)

Supported targets: All targets

Required license: None (Main library).

Description: Unpack a series of data items from an array of CAN message bytes.

Unpack a series of integer data items from an array of CAN message data bytes (e.g., unpack a 3 bit data value from an arbitrary bit position in the array). The array can be filled by calling pcx_receive().

The unpacking sequence works as follows:

• for each element in pcxf_item_ptr

1. read the data from the buffer pcxf_msg_data, based on the item's field start position pcxf_field_start, and bit width pcxf_field_width, most significant byte first

Copyright 2019, Pi Innovo 215 Library interface

2. if the item is signed as given by pcxf_is_signed, then perform sign extension

3. convert the value to the appropriate type as given by pcxf_type_code

4. write the converted value to the store given by pcxf_item_ptr

Note

An alternative of this function with differing functionality is available as pcx_vdb_unpack_msg(). Can raise the following errors: PCX_ERR_UNPACK_MSG_INVALID_PARAM, or PCX_ERR_UNPACK_MSG_FIELD_PARAM.

Arg (data in): pcxf_msg_data Pointer to an array of data bytes to be read from (the array must be large enough to bound the unpacking, if it is too small, this function will read off the end of the array). Cannot be NULL.

Arg (data in): pcxf_item_ptr Pointer to array of pointers to data to be unpacked, the type of the final pointed to data is defined by the array pcxf_type_code. Cannot be NULL.

Arg (data in): pcxf_field_start Pointer to array of field start bit numbers. For each item to unpack from pcxf_msg_data, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. For items whose bit length entry exceeds 7, the bit length must be one of: 0, 8, 16, 24, 32, 40, 48, 56. For fields with lengths ranging from 1 to 15 bits, the start address defines where the message's least significant bit is stored. For fields with lengths more than or equal to 16 bits, the start address defines where the message's most significant bit is stored. Cannot be NULL.

Example: To pack or unpack the bit sequence:

10 9 8 23 22 21 20 19 18 17 16

MS bit LS bit The start position is specified as 16 and the bit length as 11.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

Copyright 2019, Pi Innovo 216 Library interface

Arg (data in): pcxf_field_width Pointer to array of field bit widths. For each item to unpack from pcxf_msg_data, the function determines how many bits to retrieve from the array using the corresponding element from this array. The following values are allowed: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24 and 32. Items of 8 bits or fewer may not be defined so as to straddle CAN byte boundaries. Cannot be NULL.

Note

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack from pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not. If the item is negative but specified in this array as unsigned, the item is clipped to zero. Cannot be NULL.

Arg (data in): pcxf_type_code Pointer to array of data type codes. Each element determines the data type of each element in pcxf_item_ptr. The type of each element is one of: PCX_TYPECODE_F32, PCX_TYPECODE_BOOL, PCX_TYPECODE_S8, PCX_TYPECODE_U8 , PCX_TYPECODE_S16 , PCX_TYPECODE_U16, PCX_TYPECODE_S32 , PCX_TYPECODE_U32. The data storage for a boolean type depends on the pcxf_use_bool_type argument. Cannot be NULL.

Arg (data in): pcxf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

Arg (data in): pcxf_num_fields Number of fields in each of pcxf_item_ptr, pcxf_field_start , pcxf_field_width, pcxf_is_signed, and pcxf_type_code. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.

5.15.10.1.3. pcx_vdb_pack_msg()

Definition: void pcx_vdb_pack_msg(const F32 *const *pcxf_item_ptr, U8 *pcxf_msg_data, const U8 *pcxf_field_start, const U8 *pcxf_field_width, const U8 *pcxf_is_signed, const U8 *pcxf_valtype, const U8 *pcxf_order, const F32 *pcxf_eng_min, const F32 *pcxf_eng_max, const F32 *pcxf_scale, const F32 *pcxf_offset, const U8 pcxf_clip_scaled, const U8 pcxf_use_bool_type, const U8 pcxf_num_fields)

Supported targets: All targets

Copyright 2019, Pi Innovo 217 Library interface

Required license: None (Main library).

Description: Pack a series of data items into an array of CAN message bytes.

Pack a series of floating point data items into an array of CAN message data bytes (e.g., convert a floating point data item to a 32 bit integer, and then pack it into an arbitrary bit position in the array). The array can be passed to pcx_transmit() as CAN data to be transmitted.

The packing sequence works as follows:

• for each element in pcxf_item_ptr

1. clip to engineering min and max given by pcxf_eng_min and pcxf_eng_max, if pcxf_clip_scaled is true

2. convert to value type given by pcxf_valtype (if converting to integer value type, scale based on pcxf_scale and pcxf_offset)

3. clip to bit width of field in CAN message bytes based on pcxf_field_width

4. write bits to pcxf_msg_data based on the byte order given in pcxf_order and the bit position given by pcxf_field_start

Can raise the following errors: PCX_ERR_PACK_VDB_MSG_INVALID_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_pack_msg().

Arg (data in): pcxf_item_ptr Pointer to array of pointers to data to be packed. Each data item is stored as a 32-bit float. Cannot be NULL.

Arg (data out): pcxf_msg_data Pointer to an array of data bytes to be set (the array must be 8 bytes in length, if it is too small, this function will write off the end of the array). All unwritten fields are set to zero. Cannot be NULL.

Arg (data in): pcxf_field_start Pointer to array of field start bit numbers. For each item to pack into pcxf_msg_data, the function determines where to place the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. Cannot be NULL. The ordering of the bytes (see pcxf_order) determines how the start position is specified. If the ordering is specified as LSB then the start position is the least significant message bit of the least significant message byte.

Copyright 2019, Pi Innovo 218 Library interface

Example: To pack or unpack the CANdb LSB (Intel) bit sequence:

17 16 15 14 13 12

MS bit LS bit The start position is specified as 12 and the bit length as 6.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

If the ordering is specified as MSB then the start position is the most significant message bit of the most significant message byte.

Example: To pack or unpack the CANdb MSB (Motorola) bit sequence:

17 16 31 30 29 28

MS bit LS bit The start position is specified as 17 and the bit length as 6.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

Note

If the fields overlap (due to overlapping start and width parameters) then the functionality is undefined.

Arg (data in): pcxf_field_width Pointer to array of field bit widths. For each item to pack into pcxf_msg_data, the function determines how many bits to place into the array using the corresponding element from this array. Cannot be NULL. Element range: [1, 32] bits

Note

If the fields overlap (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Copyright 2019, Pi Innovo 219 Library interface

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed Unused. Set to NULL.

Arg (data in): pcxf_valtype Pointer to array of data type codes. Each element can be one of: PCX_VAL_INT, and PCX_VAL_FLOAT32. Cannot be NULL.

Arg (data in): pcxf_order Pointer to array of data type byte storage order. Each element can be one of: PCX_MSB_ORDER, and PCX_LSB_ORDER. Cannot be NULL.

Arg (data in): pcxf_use_bool_type Unused. Set to false.

Arg (data in): pcxf_eng_min Pointer to array of engineering minimum values. For each item to pack into pcxf_msg_data, the function clips the item to the corresponding minimum element from this array if pcxf_clip_scaled is true. Cannot be NULL.

Arg (data in): pcxf_eng_max Pointer to array of engineering maximum values. For each item to pack into pcxf_msg_data, the function clips the item to the corresponding maximum element from this array if pcxf_clip_scaled is true. Cannot be NULL.

Arg (data in): pcxf_scale Pointer to array of divisors. For each integer item to pack into pcxf_msg_data, the function subtracts an offset specified by pcxf_offset and scales the item by the corresponding divisor in this array. Cannot be NULL.

Note

If the divisor is zero, then the integer item is set to zero.

Arg (data in): pcxf_offset Pointer to array of adders. For each integer item to pack into pcxf_msg_data, the function subtracts the offset specified by this array and scales the item by the corresponding divisor in pcxf_scale. Cannot be NULL.

Arg (data in): pcxf_clip_scaled True if each data item should be clipped to the minimum and maximum specified by pcxf_eng_min and pcxf_eng_max, otherwise false if no clipping is to be performed.

Copyright 2019, Pi Innovo 220 Library interface

Note

If the representation of the data item value (from pcxf_item_ptr, after clipping (if clipping is applied)) is larger in bit width than the field to pack into, then the packed value is clipped to the bit width of the field to pack into.

Arg (data in): pcxf_num_fields Number of fields in each of pcxf_item_ptr, pcxf_field_start , pcxf_field_width, pcxf_is_signed , pcxf_valtype , pcxf_order , pcxf_eng_min, pcxf_eng_max, pcxf_scale and pcxf_offset. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument.

5.15.10.1.4. pcx_vdb_unpack_msg()

Definition: void pcx_vdb_unpack_msg(F32 *const *pcxf_item_ptr, U32 *const *pcxf_item_raw_ptr, const U8 *pcxf_msg_data, const U8 *pcxf_field_start, const U8 *pcxf_field_width, const U8 *pcxf_is_signed, const U8 *pcxf_valtype, const U8 *pcxf_order, const F32 *pcxf_eng_min, const F32 *pcxf_eng_max, const F32 *pcxf_scale, const F32 *pcxf_offset, const U8 pcxf_clip_scaled, const U8 pcxf_use_bool_type, const U8 pcxf_num_fields)

Supported targets: All targets

Required license: None (Main library).

Description: Unpack a series of data items from an array of CAN message bytes.

Unpack a series of data items of various types from an array of CAN message data bytes (e.g., unpack a 32 bit data value from an arbitrary bit position in the array). The array can be filled by calling pcx_receive().

The unpacking sequence works as follows:

• for each element in pcxf_item_ptr

1. read the data from the buffer pcxf_msg_data, based on the item's field start position pcxf_field_start, and bit width pcxf_field_width, where the byte order of the data is given by pcxf_order

2. convert to a floating point value, performing sign extension if necessary as specified by pcxf_is_signed

3. scale the value as given by pcxf_scale and pcxf_offset

4. if clipping is enabled pcxf_clip_scaled, then clip the value based on the engineering minimum and maximum (pcxf_eng_min and pcxf_eng_max)

5. write the resulting value to the store given by pcxf_item_ptr

Can raise the following errors:

Copyright 2019, Pi Innovo 221 Library interface

PCX_ERR_UNPACK_VDB_MSG_INVALID_PARAM.

Note

An alternative of this function with differing functionality is available as pcx_unpack_msg().

Arg (data in): pcxf_item_ptr Pointer to array of pointers to data to be unpacked. Each data item is stored as a 32-bit float. Cannot be NULL.

Arg (data in): pcxf_item_raw_ptr Pointer to array of pointers to data to be unpacked. Each data item is stored as a 32-bit integer, taken from the CAN message without clipping and scaling. If the pointer is NULL, raw data items are not written.

Arg (data out): pcxf_msg_data Pointer to an array of data bytes to be read (the array must be large enough to bound the unpacking, if it is too small, this function will read off the end of the array). Cannot be NULL.

Arg (data in): pcxf_field_start Pointer to array of field start bit numbers. For each item to unpack from pcxf_item_ptr, the function determines where to read the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message and 63 to the most significant bit of data byte 7 of the message, assuming these exist. Cannot be NULL. The ordering of the bytes (see pcxf_order) determines how the start position is specified. If the ordering is specified as LSB then the start position is the least significant message bit of the least significant message byte.

Example: To pack or unpack the CANdb LSB (Intel) bit sequence:

17 16 15 14 13 12

MS bit LS bit The start position is specified as 12 and the bit length as 6.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

If the ordering is specified as MSB then the start position is the most significant message bit of the least significant message byte.

Copyright 2019, Pi Innovo 222 Library interface

Example: To pack or unpack the CANdb MSB (Motorola) bit sequence:

17 16 31 30 29 28

MS bit LS bit The start position is specified as 17 and the bit length as 6.

CAN data byte: 0 7 6 5 4 3 2 1 0 1 15 14 13 12 11 10 9 8 2 23 22 21 20 19 18 17 16 3 31 30 29 28 27 26 25 24 4 39 38 37 36 35 34 33 32 5 47 46 45 44 43 42 41 40 6 55 54 53 52 51 50 49 48 7 63 62 61 60 59 58 57 56

Arg (data in): pcxf_field_width Pointer to array of field bit widths. For each item to unpack from pcxf_msg_data, the function determines how many bits to read into the array using the corresponding element from this array. Cannot be NULL. Element range: [1, 32] bits

Note

If a field extends beyond the length of the message data contents (as given by pcxf_field_start and pcxf_field_width) then the functionality is undefined.

Arg (data in): pcxf_is_signed Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack into pcxf_msg_data, the function determines whether to use the MSB of the packed data as a sign bit or not. Cannot be NULL.

Arg (data in): pcxf_valtype Pointer to array of data type codes. Each element can be one of: PCX_VAL_INT, and PCX_VAL_FLOAT32. Cannot be NULL.

Arg (data in): pcxf_order Pointer to array of data type byte storage order. Each element can be one of: PCX_MSB_ORDER, and PCX_LSB_ORDER. Cannot be NULL.

Arg (data in): pcxf_use_bool_type Unused. Set to false.

Arg (data in): pcxf_eng_min Pointer to array of engineering minimum values. For each item to unpack from pcxf_msg_data, the function clips the item to the corresponding minimum element from this array if pcxf_clip_scaled is true. Cannot be NULL.

Copyright 2019, Pi Innovo 223 Library interface

Arg (data in): pcxf_eng_max Pointer to array of engineering maximum values. For each item to unpack from pcxf_msg_data, the function clips the item to the corresponding maximum element from this array if pcxf_clip_scaled is true. Cannot be NULL.

Arg (data in): pcxf_scale Pointer to array of multipliers. For each integer item to unpack from pcxf_msg_data, the function scales the item by the corresponding multiplier in this array and adds an offset specified by pcxf_offset. Cannot be NULL.

Arg (data in): pcxf_offset Pointer to array of adders. For each integer item to unpack from pcxf_msg_data, the function scales the item by the corresponding multiplier in pcxf_scale and adds the offset specified by this array. Cannot be NULL.

Arg (data in): pcxf_clip_scaled True if each data item should be clipped to the minimum and maximum specified by pcxf_eng_min and pcxf_eng_max, otherwise false if no clipping is to be performed.

Arg (data in): pcxf_num_fields Number of fields in each of pcxf_item_ptr, pcxf_field_start , pcxf_field_width, pcxf_is_signed , pcxf_valtype , pcxf_order , pcxf_eng_min, pcxf_eng_max, pcxf_scale and pcxf_offset (and for pcxf_item_raw_ptr if it is not NULL). The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. 5.16. CAN Calibration Protocol (CCP) messaging feature (PCP) 5.16.1. Overview

The CAN Calibration Protocol (CCP — as defined by ASAM MCD-MC1) is a simple CAN based messaging system for communicating between a PC based tool and the ECU. The PC based tool could be used for reprogramming, or calibration, or servicing (see Appendix C, Supporting tools for an introduction to a few of these tools) through the use of an ASAP2 file (see Target ASAP2 file for more).

Copyright 2019, Pi Innovo 224 Library interface

Figure 5.16. ASAM MCD-MC1 interaction

PC

ASAP2 Tool file

ASAP2 defined by ASAM MCD-2MC gives description of ECU memories and ECU variables. CAN device

ASAM MCD-1MC (ASAP1) defines CCP communication between PC tool and ECU

CAN peripheral

CCP driver

ECU

The messaging used to implement CCP is defined by ASAM MCD-1MC (ASAP1), where ASAM MCD-1a covers the ECU and ASAM MCD-1b covers the PC tool. The implementation of CCP messages by OpenECU is detailed in Appendix F, CCP compliance. 5.16.1.1. Messaging

The CCP implementation uses a small number of CAN identifiers for transporting messages to and from the ECU.

Figure 5.17. CCP messaging

PC based tool

CRO message DTO message DAQ messages from tool from ECU from ECU to ECU to tool to tool

ECU

CRO — Command Return Object The CAN message used by the reprogramming or calibration tool when sending a request to the ECU.

DTO — Data Transmission Object The CAN message used by the ECU when replying to a CRO.

Copyright 2019, Pi Innovo 225 Library interface

DAQ — Data Acquisition Queue The CAN message used to transmit DAQ information from the ECU to the calibration tool.

Unlike CRO and DTO messages, which are response based, the DAQ messages are sent on a periodic basis (rather than on request from the calibration tool). DAQ messages are sent by the library in bursts.

The OpenECU implementation of CCP uses the same CAN identifier for DAQ messages as DTO messages.

The CAN identifiers to be used are defined by the application during build time.

Note

Certain targets, which are not on general release, support CCP parameters which can themselves be calibrated. Using this feature requires caution as the act of reprogramming them with altered values changes subsequent communications using the very interface just used for reprogramming.

On those targets pcpc_tx_id and pcpc_rx_id set the DTO and CRO CAN IDs used by the ECU respectively; pcpc_bus is the zero-based CAN bus index to use for CCP; pcpc_station_addr is the station address for the ECU; and pcpc_baud is the baud rate selected (in kbit/s) used in reprogramming mode, though this may be set differently by user initialisation of the CAN bus in application mode.

5.16.1.2. CCP during reprogramming mode

During reprogramming mode, CCP is used for reprogramming of the ECU. See Section 3.3.11, “Program the ECU” for details. 5.16.1.3. CCP during application mode

During application mode, CCP is used for a number of purposes:

To initiate reprogramming While in application mode, the ECU can accept or reject reprogramming requests. In some cases, it is convenient to accept reprogramming requests because it removes the need to put the ECU into reprogramming mode through a power reset. In some other cases, it is essential that an accidental reprogramming request does not cause application mode to stop when it is controlling the system (e.g., controlling a motor or set of injectors). For this reason, the application can tell the library when to accept and reject reprogramming requests through the pcp_inhibit_reprogramming() function.

To write application calibration variables If the ECU is a developer unit, then the library will accept requests to change calibration data while the application is running. Developer units have additional RAM which allows the calibration which is usually stored in ROM to be stored in RAM and modified while the application is running.

To read application variables The library's CCP implementation supports DAQ lists. A DAQ list is a list of addresses to read and transmit on a periodic basis. The PC based tool creates the DAQ lists and requests the ECU to transmit them periodically. The library supports 4 DAQ lists with 16 ODTs each (each ODT can have up to 7 addresses for reading). For further information about DAQ lists and ODTs, see the ASAM MCD-MC1 specification.

Extract manufacturer's information using EXCHANGE_ID command The extended EXCHANGE_ID message can be used to extract manufacturer's information. More information on how EXCHANGE_ID is set up on OpenECU see the Section F.1, “EXCHANGE_ID message handling” section.

Copyright 2019, Pi Innovo 226 Library interface

Whether CCP is enabled during application mode can be controlled by setting the pcp_ccpenabled variable at build time. 5.16.1.4. CCP seed/key security

To prevent third parties recalibrating or reprogramming modules, manufacturers typically enable CCP seed/key security for production modules. This requires a valid seed/key exchange to take place with the calibration tool, where the module generates a seed (usually at random) and the calibration tool must respond with the correct key value corresponding to that seed, calculated by a secret algorithm known to the module and the calibration tool. Brute-force attacks are deterred by applying a significant delay (usually 10s) after each incorrect key before a further attempt may be made.

The pcp_seed_key_config array (and the corresponding array size pcp_num_seed_key_configs) configures CCP seed/key security. Each element of this array specifies whether security is required for a CCP privilege level, and if so, what functions are used to generate the seed and to validate the key returned by the calibration tool. Note that seed generation functions are optional; if omitted, the platform will simply generate 32-bit random seeds for CCP seed/key exchanges for this privilege level.

To ensure that CCP seed/key security is also used during reprogramming mode, the functions used to generate the seed (if required) and validate the key are copied to non-volatile storage by the application. The reprogramming mode software retrieves the functions from non- volatile storage, and copies them to RAM for execution.

CCP privilege levels are defined as: calibration; data acquisition; and programming. From the calibration tool it is necessary to gain access to calibration before carrying out data acquisition; and likewise it is necessary to gain access to calibration before carrying out programming. Note however that data acquisition and programming privilege levels are independent: it is possible to read variables without being able to reprogram the module, and vice versa.

CCP seed/key security is a standard feature of the protocol; however configuring it on different calibration/programming tools requires some knowledge of that tool's operation. Support will currently only be given for CCP seed/key security on PiSnoop (see Section C.2, “PiSnoop”), Vector CANape (see Section C.5, “Vector CANape”), and ATI Vision (see Section C.3, “ATI Vision”) 5.16.1.4.1. Specifying functions for use with CCP seed/key security

5.16.1.4.1.1. Seed generator function

The seed generator function must be of the form:

void seed_generator(const U8 privilege_level, U8 *const seed)

privilege_level specifies the privilege level for which a seed is being requested. Values are fixed by the CCP standard as:

• 0x01 (1): Calibration

• 0x02 (2): Data acquisition

• 0x40 (64): Programming

seed is a four-byte array. This will initially contain values generated by a 32-bit random number algorithm within the OpenECU platform. The seed generator function may choose to leave these values intact, or may choose to set its own values in the seed array.

5.16.1.4.1.2. Key validator function

The key validator function must be of the form:

Copyright 2019, Pi Innovo 227 Library interface

BOOL key_validator(const U8 privilege_level, const U8 *const seed, const U8 *const key, const U8 key_size)

privilege_level specifies the privilege level for which a seed is being requested (see Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for details).

seed is a four-byte array containing the last seed value passed to the calibration tool.

key is an array of up to six bytes whose length is specified by key_size. This contains the key passed back by the calibration tool.

The CCP 2.1 specification for the CCP_UNLOCK command has a six-byte field for the key, although in practice most implementations only use four bytes. The contents of the remaining bytes are often undefined, so the key validator must take care to match the expected seed- key algorithm.

The function must return TRUE if the key is valid for the seed, or FALSE if it is not.

5.16.1.4.1.3. Implementing seed/key functions

Because the seed generator and key validator functions will be relocated and run during reprogramming mode, it is ESSENTIAL that these functions do NOT access any global or static storage OR call any functions. If this is not the case, relocating and invoking the function in reprogramming mode will have unexpected consequences, because the function will read/ write/execute memory at addresses which are not valid when in reprogramming mode. These consequences may include stuck outputs resulting in physical damage to hardware or electrical damage to the ECU, and/or complete permanent disablement of the ECU.

Diab implementation considerations If the application is built using the Diab compiler, then the file containing these functions should be specified for compilation as normal. It is frequently the case that seed/key functions are supplied only as object or library code for security reasons, in which case the file must have been compiled with PowerPC variable bit length (VLE) instructions.

GCC implementation considerations If the application is built using GCC, then the file containing these functions must also contain section attribute specifiers to place the code in sections that correspond to the names of the security functions. The attribute specifiers must be applied to the function prototypes in the form:

void seed_generator(const U8 privilege_level, U8 *const seed) __attribute__ ((section (".seed_generator")));

It is frequently the case that seed/key functions are supplied only as object or library code for security reasons, in which case the file must have been compiled without PowerPC variable bit length (VLE) instructions.

Note however that linkage of these functions requires special handling. Since compilers/ linkers do not provide information about the sizes of functions, and since relocation of a function requires the function size to be known, extra symbols must be generated to report the end of each of these functions. These must be linked according to specific rules. To implement this, a suitable linker definition file excerpt is generated automatically, and this must be inserted at the correct point in the main linker definition file. See --diab- ldfile=FILE and --gcc-ldfile=FILE for further details about generating the linker excerpt. See --output-linker-file=FILE and --ld-excerpt-file=FILE for details about inserting the excerpt into the main linker definition file. 5.16.1.5. Library tasks

The library implements a single task to support CCP messaging. See Section 4.6.4, “Application and library tasks” for details. Excessive delay of this task by application tasks

Copyright 2019, Pi Innovo 228 Library interface

can cause CCP messages to miss their timing deadlines and this may be reported by PC based support tools. 5.16.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pcp.h Macros PCP_PL_CAL

Mask value for CCP calibration privilege level. PCP_PL_DAQ

Mask value for CCP data acquisition privilege level. PCP_PL_PGM

Mask value for CCP reprogramming privilege level. PCP_PL_ALL

Mask value for all CCP privilege levels. Data types PCP_SEED_KEY_CONFIG_T

Structure configuring security for one or more CCP privilege levels. PCP_SEED_GENERATOR_T

Typedef for the callback function used to generate a seed for a CCP seed-key exchange. PCP_KEY_VALIDATOR_T

Typedef for the callback function used to validate a key for a CCP seed-key exchange. Variables const pcp_seed_key_config PCP_SEED_KEY_CONFIG_T CCP seed-key configuration for application. const U8 pcp_num_seed_key_configs

Number of array elements in pcp_seed_key_config. const U8 pcp_ccpenabled

True if CCP messaging is enabled during application run, false otherwise. Functions U32 pcp_get_rx_count

Return the number of CCP CRO messages received since the last reset.

Copyright 2019, Pi Innovo 229 Library interface

Type Identifier void pcp_inhibit_reprogramming

Enable or disable CCP reprogramming requests while running application mode. void pcp_client_task

The CAN calibration protocol (CCP) messaging task. 5.16.3. Interface detail 5.16.3.1. Macros 5.16.3.1.1. PCP_PL_CAL

Definition: #define PCP_PL_CAL 0x01

Description:

Mask value for CCP calibration privilege level. 5.16.3.1.2. PCP_PL_DAQ

Definition: #define PCP_PL_DAQ 0x02

Description:

Mask value for CCP data acquisition privilege level. 5.16.3.1.3. PCP_PL_PGM

Definition: #define PCP_PL_PGM 0x40

Description:

Mask value for CCP reprogramming privilege level. 5.16.3.1.4. PCP_PL_ALL

Definition: #define PCP_PL_ALL (PCP_PL_CAL | PCP_PL_DAQ | PCP_PL_PGM)

Description:

Mask value for all CCP privilege levels. 5.16.3.2. Data types 5.16.3.2.1. PCP_SEED_KEY_CONFIG_T

Summary: Structure configuring security for one or more CCP privilege levels.

Members:

U8 PCP_SEED_KEY_CONFIG_T::privilege_levels Bitwise mask specifying which privilege levels this applies to.

Copyright 2019, Pi Innovo 230 Library interface

This mask may be set using the literals PCP_PL_CAL (calibration), PCP_PL_DAQ (data acquisition), PCP_PL_PGM (reprogramming) or PCP_PL_ALL (all three).

BOOL PCP_SEED_KEY_CONFIG_T::security_required If security_required is set FALSE, no seed-key exchange is required for the specified privilege level(s).

They may be invoked by the calibration tool at any time. The callback structure elements are ignored.

If security_required is set TRUE, the callbacks provided are used to unlock the specified privilege levels. Activities for these privilege levels may not be invoked by the CCP master until they have been unlocked.

If security_required is set TRUE but either callback is NULL, it will not be possible to unlock these privilege levels and the calibration tool will be permanently prohibited from invoking activities for these privilege levels.

PCP_SEED_GENERATOR_T PCP_SEED_KEY_CONFIG_T::seed_request_callback Pointer to callback function which is called to request a seed value for the specified privilege level(s) when the calibration tool attempts to unlock the privilege level(s).

Set this value to NULL if security is not required.

U8* PCP_SEED_KEY_CONFIG_T::seed_request_callback_end_addr Address of location immediately after seed_request_callback function.

This allows the platform to calculate the size of the function.

PCP_KEY_VALIDATOR_T PCP_SEED_KEY_CONFIG_T::key_validation_callback Pointer to callback function which is called to validate a key value for the returned by the calibration tool, where the key is generated from the seed returned by the previously-called seed_request_callback function.

Set this value to NULL if security is not required.

U8* PCP_SEED_KEY_CONFIG_T::key_validation_callback_end_addr Address of location immediately after key_validation_callback function.

This allows the platform to calculate the size of the function. 5.16.3.2.2. PCP_SEED_GENERATOR_T

Definition: typedef void(* PCP_SEED_GENERATOR_T)(const U8 pcpf_privilege_level, U8 *const pcpf_seed)

Description: Typedef for the callback function used to generate a seed for a CCP seed-key exchange.

The function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute,

Copyright 2019, Pi Innovo 231 Library interface

and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

The platform software may copy the callback function to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg (data in): pcpf_privilege_level The privilege level for this request will be one of the bit-mask values PCP_PL_CAL, PCP_PL_DAQ or PCP_PL_PGM , representing a request for calibration, data acquisition or programming privilege levels respectively.

Return: The function must return a 32-bit seed value. Typically this will be generated through a random or pseudo-random process. This seed must be stored for later use by the corresponding key validation function when the calibration tool returns a key. 5.16.3.2.3. PCP_KEY_VALIDATOR_T

Definition: typedef BOOL(* PCP_KEY_VALIDATOR_T)(const U8 pcpf_privilege_level, const U8 *const pcpf_seed, const U8 *const pcpf_key, const U8 pcpf_key_size)

Description: Typedef for the callback function used to validate a key for a CCP seed- key exchange.

The function must generate the expected key from the last seed value returned by the corresponding seed request callback function and compare this to the key calculated by the calibration tool.

The function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

The platform software may copy the callback function to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg (data in): pcpf_privilege_level The privilege level for this request will be one of the bit-mask values PCP_PL_CAL, PCP_PL_DAQ or PCP_PL_PGM , representing a

Copyright 2019, Pi Innovo 232 Library interface

request for calibration, data acquisition or programming privilege levels respectively.

Arg (data in): pcpf_key The key is an array of bytes returned by the calibration tool, generated from the seed returned by the corresponding seed request callback function.

Arg (data in): pcpf_key_size Size of key array in bytes. The array may be between zero and 6 bytes long. Typically the key will be a 32-bit value (4 bytes), i.e. the same size as the seed, but there is no requirement for this to be the case. The size must be checked by the function to ensure that out- of-bounds array accesses do not take place.

Return: The function must return TRUE if the key is correct, or FALSE if not. 5.16.3.3. Variables

5.16.3.3.1. pcp_seed_key_config

Definition: const PCP_SEED_KEY_CONFIG_T pcp_seed_key_config[]

Description: CCP seed-key configuration for application.

Each array element specifies the CCP seed-key security to be applied to one or more CCP privilege levels.

The code tolerates multiple array entries existing which specify the same CCP privilege level. If this occurs, the code carries out processing only for the first array element with a matching CCP privilege level. Any or all subsequent array entries are ignored.

5.16.3.3.2. pcp_num_seed_key_configs

Definition: const U8 pcp_num_seed_key_configs

Description: Number of array elements in pcp_seed_key_config.

5.16.3.3.3. pcp_ccpenabled

Definition: const U8 pcp_ccpenabled

Description: True if CCP messaging is enabled during application run, false otherwise. 5.16.3.4. Functions

5.16.3.4.1. pcp_get_rx_count()

Definition: U32 pcp_get_rx_count(void)

Copyright 2019, Pi Innovo 233 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Return the number of CCP CRO messages received since the last reset.

Return: A count of CCP CRO messages received since the last reset. The counter wraps modulo 4294967295. Range: [0, 4294967295] messages

5.16.3.4.2. pcp_inhibit_reprogramming()

Definition: void pcp_inhibit_reprogramming(U8 pcpf_inhibit)

Supported targets: All targets

Required license: None (Main library).

Description: Enable or disable CCP reprogramming requests while running application mode.

The ECU uses the CAN calibration protocol for reprogramming. Reprogramming requests are always honoured while the ECU is in reprogramming mode. In application mode, reprogramming requests can be enabled or disabled. For instance, the application might enable reprogramming requests only while it is in an idle and safe state.

If uncalled by the application, reprogramming is allowed by default.

Arg (data in): pcpf_inhibit True if reprogramming should be inhibited, false otherwise.

5.16.3.4.3. pcp_client_task()

Definition: void pcp_client_task(void)

Supported targets: All targets

Required license: None (Main library).

Description: The CAN calibration protocol (CCP) messaging task.

This is the entry point for the CCP messaging task. The task handles enabling or disabling messaging based on pcp_ccpenabled. If messaging is enabled, then the task manages CCP CAN messages (reception and transmission) and scheduling of DAQ message processing (transmission).

Copyright 2019, Pi Innovo 234 Library interface

Note

The CCP messaging task must be scheduled every 5 milliseconds. 5.17. J1939 (SAE) messaging feature (PJ1939) 5.17.1. Overview

J1939 is a SAE communications protocol, based on CAN, largely defined by the following documents:

SAE J1939/21 Defines the data link layer, including how J1939 messages map to the CAN specification, definition of Parameter Groups (PG), and definition of the transport protocol (for sending J1939 messages with more than 8 data bytes).

The library directly supports the transport protocol and has facilities to handle PG messages: on request (from another node on the network); periodically (ECU periodically transmits a PG); and on event (ECU transmits PG when a condition becomes true).

SAE J1939/71 Defines the vehicle application layer, essentially a list of predetermined messages and their contents.

SAE J1939/73 Defines the application layer diagnostics, which includes (amongst other things) support for Diagnostic Trouble Codes (DTC).

The core library supports the following basic diagnostic messages (to deal with Diagnostic Trouble Codes):

DM1 All active Diagnostic Trouble Codes

DM2 All previously active Diagnostic Trouble Codes

SAE J1939/81 Defines the network management protocol, a mechanism for allocating addresses to nodes on the J1939 network dynamically.

For the moment, the library only provides support for fixed address J1939 networks. The library will participate in messaging required to claim an address for the ECU, but the library will not dynamically change address when it loses negotiation, nor will the library track the address of other nodes.

It is assumed throughout this document, that the reader is familiar with the SAE J1939 specifications. 5.17.2. Node addressing

All nodes on a J1939 network have a unique identifier and a preferred network address. This information can be specified by setting the name and node_addr variables.

The name array is populated from the J1939 name fields (see SAE J1939 for further details) as follows:

Copyright 2019, Pi Innovo 235 Library interface

Element Bit number

0 0 IG2 IG1 IG0 VSI3 VSI2 VSI1 VSI0

1 VS6 VS5 VS4 VS3 VS2 VS1 VS0 1

2 F7 F6 F5 F4 F3 F2 F1 F0

3 FI4 FI3 FI2 FI1 FI0 EI2 EI1 EI0

4 MC10 MC9 MC8 MC7 MC6 MC5 MC4 MC3

5 MC2 MC1 MC0 IN20 IN19 IN18 IN17 IN16

6 IN15 IN14 IN13 IN12 IN11 IN10 IN9 IN8

7 IN7 IN6 IN5 IN4 IN3 IN2 IN1 IN0

Where:

IG Industry Group

VSI Vehicle System Instance

VS Vehicle System

F Function

FI Function Instance

EI ECU Instance

MC Manufacturer code

IN Identity Number

For now, the library does not support dynamic addressing. Applications must use a fixed network address. If that address is claimed, then the ECU will claim the NULL address (254) and only process network messages (see J1939/81).

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications. When the ECU has a network address (has claimed a non-NULL address without conflict), then the ECU can participate in all communications. 5.17.3. Messaging

J1939 supports long messages. Long messages contain more than 8 data bytes (and hence require more than one CAN message to be transmitted) and can be up to 1785 bytes long. Not all J1939 networks will have messages this long, and as RAM memory is precious on most of the target ECUs, the application can specify the largest message to be received through the pj1939_size_j1939_rx_buf variable.

The application can also define the number of receive and transmit long messages through the pj1939_num_rx_tx_bufs variable, allowing some balance in RAM use against application responsiveness.

Copyright 2019, Pi Innovo 236 Library interface

Similarly, as RAM is precious, the number of receive and transmit messages to be buffered between processing by the J1939 stack is configurable by the application through the pj1939_num_trx and pj1939_num_ttx variables. As the CAN link baud rate will be known, and the time between processing by the application will be known, the worst case number of J1939 CAN messages could be derived by the application at build time, and an automatic number of buffers allocated. 5.17.4. Message bit and byte numbering

The library follows the bit and byte numbering convention laid out by the J1939 specifications.

Data byte Bit number LS MS LS 1 8 7 6 5 4 3 2 1 2 16 15 14 13 12 11 10 9 ...... 1785 14280 14279 14278 14277 14276 14275 14274 14273 MS MS LS

where byte 1 corresponds to the first received data byte in the first CAN message for the PG message. This numbering scheme, matches the J1939 specification but differs from the existing CAN feature (e.g., like ??? which refers to the first byte as byte 0). It is felt that although this may cause some confusion, it is better to present the bit ordering according to J1939.

A field which starts at bit 5 and has 10 bits of width is identified as follows:

Data byte Bit number 1 8 7 6 5 - - - - 2 - - 14 13 12 11 10 9

J1939 message fields are generally packed LSB first, so the bits would be interpreted as:

MS LS Data byte 2 Data byte 1 ------14 13 12 11 10 9 8 7 6 5 s s s s s s x x x x x x x x x x

where x is the corresponding bit taken from the J1939 message data bytes, and s is the sign extension of the data. In this case, bit 14 may be considered the sign bit, if the data in the J1939 message data is signed.

However, if the J1939 message field was packed MSB first, the bits would be interpreted as:

MS LS Data byte 1 Data byte 2 ------6 5 14 13 12 11 10 9 8 7 s s s s s s x x x x x x x x x x

where x is the corresponding bit taken from the J1939 message data bytes, and s is the sign extension of the data. In this case, bit 6 may be considered the sign bit, if the data in the J1939 message data is signed.

Copyright 2019, Pi Innovo 237 Library interface

5.17.5. PGNs

The library makes use of PGN values. A PGN is a 17 bit wide integer, having either PDU1 or PDU2 format (see SAE J1939/21 for more):

Bits 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 PDU1 format

DP0 PF7 PF6 PF5 PF4 PF3 PF2 PF1 PF0 DA7 DA6 DA5 DA4 DA3 DA2 DA1 DA0 PDU2 format

DP0 PF7 PF6 PF5 PF4 PF3 PF2 PF1 PF0 PS7 PS6 PS5 PS4 PS3 PS2 PS1 PS0

Where:

DP Data page

PF PDU format — the PGN has PDU1 format when the value of PDU format is less than 240, and has PDU2 format when greater than or equal to 240.

PS PDU specific

DA Destination address

A common action when using the J1939 protocol is responding to requests, and the library provides support for trapping specific PGs and filtering out others by populating the _pgn_table and pj1939_num_pgns variables. The library will automatically generate a NACK if a PG request message is received but does not match one of the PGNs in _pgn_table (unless of course, the request was sent to the global address, in which case, the library does not generate a NACK).

To determine if a PGN has been requested, the library provides the pj1939_was_pgn_requested() function. 5.17.6. Receive messages

The library buffers received J1939 messages for the application, discarding messages which are not of interest. The application can determine whether a message has been received since last time and extract the contents of the message by calling pj1939_pg_receive().

Each receive message buffer stores one J1939 message. If a J1939 message with the same PGN is received more than once between calls from the application, then the message buffer is overwritten with the latest received message. This ensures the latest copy of a J1939 message is available to the application, but is not suitable for J1939 messages which contain state information (e.g., J1939 messages containing protocol information, etc.).

The pj1939_pg_receive() function gives an indication of J1939 message status by writing to various status flags. The function provides an indication of whether a message has been received since the last call, whether more than one message with the same CAN identifier has been received, and whether an error occurred on reception. The function also provides a timestamp of the last valid message received.

To help unpack data from the contents of a J1939 message, the function takes data detailing the fields of the message contents, extracts the fields and writes them to application variables.

Copyright 2019, Pi Innovo 238 Library interface

Warning

The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

5.17.7. Transmit messages

The library transmits buffered J1939 messages for the application. The application tells the library to transmit a new J1939 message by calling pj1939_pg_transmit().

Each transmit message buffer stores one J1939 message. If the application requests a transmit of a J1939 message before the library has transmitted the last CAN message with the same identifier, then the message buffer is overwritten with the latest transmit message. This ensures the latest version of a J1939 message is transmitted by the library, but is not suitable for J1939 messages which contain state information (e.g., J1939 messages containing protocol information, etc.).

The library buffers multiple J1939 transmit messages but as the CAN bus is serial in nature, only one message can be transmitted at a time. The library attempts to transmit the messages in the order they are presented when pj1939_pg_transmit() is called, but the library will not always adhere to this ordering.

Unlike the CAN feature (PCX) which attempts to lessen the load experienced by the CAN bus and the ECU, after the library has transmitted one J1939 message, it will attempt to transmit the next as soon as possible to make it more likely that all protocol message deadlines will be met. However, this may not be possible depending on the current CAN bus loading and the ECU processor loading.

To help pack data into the contents of a J1939 message, the function takes data detailing the fields of the message contents and values of those fields, and writes them to J1939 message (setting all unspecified bits to one). 5.17.8. Core Diagnostic messages

The core library provides functions to help deal with basic diagnostic messaging, specifically DM1 and DM2 messages through the functions pj1939_dm1_transmit(), pj1939_dm1_receive(), pj1939_dm1_decode_dtc(), pj1939_dm2_transmit(), pj1939_dm2_receive() and pj1939_dm2_decode_dtc()

The J1939/73 specification, section 5.7.1, details the transmission rate of the DM1 message (both on request, and periodic transmission). The examples included in that section, show the frequency of transmission and the need to limit bandwidth. Two parameters are made available to filter out high-frequency activation or deactivation of DTCs, to reduce the frequency of DM1 message transmission.

The library schedules DM1 messages to be sent every second if the conditions are right, but will evaluate when to check DTCs for state changes when pj1939_dm1_receive() is called, thus giving the application some control over how frequently the DTC list is inspected to determine newly active DTCs. 5.17.9. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Copyright 2019, Pi Innovo 239 Library interface

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

5.17.10. Library tasks

The library implements a single task to support J1939 messaging. See Section 4.6.4, “Application and library tasks” for details. 5.17.11. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pj1939.h Enumerations PJ1939_ERROR_T

Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type. Data types J1939_TX_MESSAGE_T

This is the definition of a J1939 transmit message. J1939_RX_MESSAGE_T

This is the definition of a J1939 receive message. CAN_PACKET_T

This is the structure of a single CAN packet. PJ1939_RX_BUF_T

This is the structure for buffering received J1939 messages. PGN_T

This is a typedef for the PGN (parameter group number). Variables const U8 pj1939_enabled

Set true if J1939 functionality is enabled, set false otherwise. const U8 pj1939c_node_addr_0

This sets the desired J1939 node address and can be altered by calibration. U8 node_addr

Copyright 2019, Pi Innovo 240 Library interface

Type Identifier This is a list of preferred J1939 network addresses (all unique and not the null address (254) or the broadcast address (255)). const U8 pj1939_num_node_addr

This is the number of declared J1939 network addresses in the node_addr[] array. const U8 name

This is the J1939 network name of this unit. const PGN_T _pgn_table

This is an array of receive PGNs the library must filter. const U32 pj1939_num_pgns

This is the number of receive PGNs in _pgn_table[]. const PGN_T pj1939_pgn_requested_table

This is the list of expected PGN requests to filter. const U32 pj1939_num_requested_pgns

This is the number of expected PGN requests in the pj1939_pgn_requested_table[] array. U8 pj1939_pgn_requested_src_addr

This is the buffer of source addresses for each PGN request message. U8 pj1939_pgn_requested_dest_addr

This is the buffer of destination addresses for each PGN request message. U32 pj1939_pgn_requested_timestamp

This is the buffer of timestamps for each PGN request message. U8 pj1939_pgn_requested_bitmap

This is the buffer of priority for each PGN request message. U16 pj1939_rx_buf_data_size

This is the size of the data portion to each J1939 receive buffer. U8 *const pj1939_rx_buf_data

This is an array of pointers to each data buffer for each J1939 receive message. PJ1939_RX_BUF_T *const pj1939_rx_buf

This is an array of pointers to each J1939 receive message. const PCX_LCHAN_T pj1939_can_link

Copyright 2019, Pi Innovo 241 Library interface

Type Identifier This is the CAN link used for the J1939 network messaging. const U8 pj1939_num_ttx

This is the number of transport transmit buffers that can run in parallel. const U8 pj1939_num_trx

This is the number of transport receive buffers that can run in parallel. const U16 pj1939_size_j1939_rx_buf

This is the maximum data size of any J1939 message (both reception and transmission). const U8 pj1939_num_rx_tx_bufs

This is the number of receive and transmit CAN buffers allocated for J1939 message processing. J1939_TX_MESSAGE_T pj1939_ttx_buf

This is an array of J1939 transmit messages. U8 * pj1939_ttx_error_ptr

This is an array of pointers to counters for delayed transmit errors. U8 pj1939_ttx_buf_data

This is the buffer space allocated for all J1939 transmit messages. U8 pj1939_msg_buffer

This is the buffer space allocated for all J1939 receive messages. J1939_TRANSPORT_TX_INFO tx_state

This is the state of the transmission messages that require transport support (i.e., messages that have a data length greater than 8 bytes). J1939_MESSAGE rx_message

This is the state of the receive messages that require transport support (i.e., messages that have a data length greater than 8 bytes) CAN_PACKET_T in_queue

This is the queue of received messages. CAN_PACKET_T out_queue

This is the queue of transmit messages. const BOOL pj1939_use_common_mf_priority

Copyright 2019, Pi Innovo 242 Library interface

Type Identifier This is a flag to determine whether to use a common priority for all J1939 multi-frame diagnostic message transmissions. const U8 pj1939_common_multiframe_priority

This is the common priority used for all J1939 multi- frame diagnostic message transmissions. const U8 pj1939_dm1_source_addr

This is an array of J1939 node addresses corresponding to the list of addresses which are known to transmit DM1 messages. const U8 pj1939_dm1_source_addr_num

This is the number of declared J1939 DM1 transmitter addresses in the pj1939_dm1_source_addr[] array. U8 *const pj1939_dm1_rx_buf_data

This is the list of pointers to message data buffers for each DM1 message to be received. U32 pj1939_dm1_rx_counters

This is an array of counters for each DM1 message to be received. PJ1939_RX_BUF_T *const pj1939_dm1_rx_buf

This is an array of pointers to message buffers for each DM1 message to be received. const U8 pj1939_dm2_source_addr

This is an array of J1939 node addresses corresponding to the list of addresses which are known to transmit DM2 messages. const U8 pj1939_dm2_source_addr_num

This is the number of declared J1939 DM2 transmitter addresses in the pj1939_dm2_source_addr[] array. U8 *const pj1939_dm2_rx_buf_data

This is the list of pointers to message data buffers for each DM2 message to be received. PJ1939_RX_BUF_T *const pj1939_dm2_rx_buf

This is an array of pointers to message buffers for each DM2 message to be received. U32 pj1939_dm2_rx_counters

This is an array of counters for each DM2 message to be received. U8 pj1939_state

This is an array of states for each DTC.

Copyright 2019, Pi Innovo 243 Library interface

Type Identifier U8 pj1939_sent

This is an array of sent flags for each DTC. U8 pj1939_transient

This is an array of transient fault states for each DTC. U8 pj1939_transient_sent

This is an array of transient sent flags for each DTC. Functions U8 pj1939_dm1_receive

This function indicates if and when a J1939 DM1 message was received. void pj1939_dm1_decode_dtc

This function decodes part of a received J1939 DM1 message. U8 pj1939_dm2_receive

This function indicates if and when a J1939 DM2 message was received. void pj1939_dm2_decode_dtc

This function decodes part of a received J1939 DM2 message. void pj1939_dm1_transmit

This function attempts to transmit a J1939 DM1 message. void pj1939_dm2_transmit

This function attempts to transmit a J1939 DM2 message. void pj1939_inhibit_reprogramming

Enable or disable J1939 reprogramming 'Boot Load' requests while running application mode. void pj1939_was_pgn_requested

Determine whether a PGN has been requested from this node. void pj1939_pg_receive

Determine if a PGN has been received and extract its contents if required. void pj1939_pg_transmit

Construct a J1939 message and attempt to send it (deprecated). void pj1939_pdu1_transmit

Copyright 2019, Pi Innovo 244 Library interface

Type Identifier Construct a J1939 message and attempt to send it. void pj1939_pdu2_transmit

Construct a J1939 message and attempt to send it. 5.17.12. Interface detail 5.17.12.1. Enumerations

5.17.12.1.1. PJ1939_ERROR_T

Summary: Error values for debugging when an error is found in a call to the PCX API, the feature calls a function with an enumeration from this type.

Enumerations:

PJ1939_WAS_REQ_PGN_INVALID_ARG Error raised if the PGN requested function finds an invalid function argument.

PJ1939_PG_RECEIVE_INVALID_ARG Error raised if the PG receive function finds an invalid function argument.

PJ1939_PG_TRANSMIT_INVALID_ARG Error raised if the PG transmit function finds an invalid function argument.

PJ1939_DM1_DECODE_INVALID_ARG Error raised if the DM1 decode function finds an invalid function argument.

PJ1939_DM2_DECODE_INVALID_ARG Error raised if the DM2 decode function finds an invalid function argument.

PJ1939_DM1_TRANSMIT_INVALID_ARG Error raised if the DM1 transmit function finds an invalid function argument.

PJ1939_DM2_TRANSMIT_INVALID_ARG Error raised if the DM2 transmit function finds an invalid function argument.

PJ1939_DM4_TRANSMIT_INVALID_ARG Error raised if the DM4 transmit function finds an invalid function argument.

PJ1939_DM5_TRANSMIT_INVALID_ARG Error raised if the DM5 transmit function finds an invalid function argument.

PJ1939_DM6_TRANSMIT_INVALID_ARG Error raised if the DM6 transmit function finds an invalid function argument.

Copyright 2019, Pi Innovo 245 Library interface

PJ1939_DM7_COMMANDED_TEST_INVALID_ARG Error raised if the DM7 commanded test function finds an invalid function argument.

PJ1939_DM8_TRANSMIT_INVALID_ARG Error raised if the DM8 transmit function finds an invalid function argument.

PJ1939_DM10_TRANSMIT_INVALID_ARG Error raised if the DM10 transmit function finds an invalid function argument.

PJ1939_DM12_TRANSMIT_INVALID_ARG Error raised if the DM12 transmit function finds an invalid function argument.

PJ1939_DM14_DECODE_INVALID_ARG Error raised if the DM14 decode function finds an invalid function argument.

PJ1939_DM15_TRANSMIT_INVALID_ARG Error raised if the DM15 transmit function finds an invalid function argument.

PJ1939_DM16_DECODE_INVALID_ARG Error raised if the DM16 decode function finds an invalid function argument.

PJ1939_DM16_TRANSMIT_INVALID_ARG Error raised if the DM16 transmit function finds an invalid function argument.

PJ1939_DM20_TRANSMIT_INVALID_ARG Error raised if the DM20 transmit function finds an invalid function argument.

PJ1939_DM21_TRANSMIT_INVALID_ARG Error raised if the DM21 transmit function finds an invalid function argument.

PJ1939_DM23_TRANSMIT_INVALID_ARG Error raised if the DM23 transmit function finds an invalid function argument.

PJ1939_DM24_TRANSMIT_INVALID_ARG Error raised if the DM24 transmit function finds an invalid function argument.

PJ1939_DM25_TRANSMIT_INVALID_ARG Error raised if the DM25 transmit function finds an invalid function argument.

PJ1939_DM26_TRANSMIT_INVALID_ARG Error raised if the DM26 transmit function finds an invalid function argument.

PJ1939_DM27_TRANSMIT_INVALID_ARG Error raised if the DM27 transmit function finds an invalid function argument.

Copyright 2019, Pi Innovo 246 Library interface

PJ1939_DM28_TRANSMIT_INVALID_ARG Error raised if the DM28 transmit function finds an invalid function argument.

PJ1939_DM29_TRANSMIT_INVALID_ARG Error raised if the DM29 transmit function finds an invalid function argument.

PJ1939_DM30_TRANSMIT_INVALID_ARG Error raised if the DM30 transmit function finds an invalid function argument.

PJ1939_DM31_TRANSMIT_INVALID_ARG Error raised if the DM31 transmit function finds an invalid function argument.

PJ1939_DM32_TRANSMIT_INVALID_ARG Error raised if the DM32 transmit function finds an invalid function argument.

PJ1939_DM33_TRANSMIT_INVALID_ARG Error raised if the DM33 transmit function finds an invalid function argument.

PJ1939_DM34_TRANSMIT_INVALID_ARG Error raised if the DM34 transmit function finds an invalid function argument.

PJ1939_DM35_TRANSMIT_INVALID_ARG Error raised if the DM35 transmit function finds an invalid function argument.

PJ1939_DM36_TRANSMIT_INVALID_ARG Error raised if the DM36 transmit function finds an invalid function argument.

PJ1939_DM37_TRANSMIT_INVALID_ARG Error raised if the DM37 transmit function finds an invalid function argument.

PJ1939_DM38_TRANSMIT_INVALID_ARG Error raised if the DM38 transmit function finds an invalid function argument.

PJ1939_DM39_TRANSMIT_INVALID_ARG Error raised if the DM39 transmit function finds an invalid function argument.

PJ1939_DM40_TRANSMIT_INVALID_ARG Error raised if the DM40 transmit function finds an invalid function argument.

PJ1939_DM41_TRANSMIT_INVALID_ARG Error raised if the DM41 transmit function finds an invalid function argument.

PJ1939_DM42_TRANSMIT_INVALID_ARG Error raised if the DM42 transmit function finds an invalid function argument.

Copyright 2019, Pi Innovo 247 Library interface

PJ1939_DM43_TRANSMIT_INVALID_ARG Error raised if the DM43 transmit function finds an invalid function argument.

PJ1939_DM44_TRANSMIT_INVALID_ARG Error raised if the DM44 transmit function finds an invalid function argument.

PJ1939_DM45_TRANSMIT_INVALID_ARG Error raised if the DM45 transmit function finds an invalid function argument.

PJ1939_DM46_TRANSMIT_INVALID_ARG Error raised if the DM46 transmit function finds an invalid function argument.

PJ1939_DM47_TRANSMIT_INVALID_ARG Error raised if the DM47 transmit function finds an invalid function argument.

PJ1939_DM48_TRANSMIT_INVALID_ARG Error raised if the DM48 transmit function finds an invalid function argument.

PJ1939_DM49_TRANSMIT_INVALID_ARG Error raised if the DM49 transmit function finds an invalid function argument.

PJ1939_DM50_TRANSMIT_INVALID_ARG Error raised if the DM50 transmit function finds an invalid function argument.

PJ1939_DM51_TRANSMIT_INVALID_ARG Error raised if the DM51 transmit function finds an invalid function argument.

PJ1939_DM52_TRANSMIT_INVALID_ARG Error raised if the DM52 transmit function finds an invalid function argument.

PJ1939_PGN_TRANSMIT_INVALID_ARG Error raised if the PGN transmit function finds an invalid function argument.

PJ1939_DM1_RECEIVE_INVALID_ARG Error raised if the DM1 receive function finds an invalid function argument.

PJ1939_DM2_RECEIVE_INVALID_ARG Error raised if the DM2 receive function finds an invalid function argument. 5.17.12.2. Data types

5.17.12.2.1. J1939_TX_MESSAGE_T

Summary: This is the definition of a J1939 transmit message.

Copyright 2019, Pi Innovo 248 Library interface

Members:

PGN_T J1939_TX_MESSAGE_T::PGN This is the message Parameter Group Number.

U8* J1939_TX_MESSAGE_T::data_ptr This is a pointer to the data bytes contained in the J1939 message.

If the data pointer is NULL, the message should be considered invalid.

U16 J1939_TX_MESSAGE_T::byte_count This is the number of data bytes in the J1939 message.

Range: [0, 1785] bytes

U8 J1939_TX_MESSAGE_T::priority This is the J1939 message priority (0 is the highest priority, 7 the lowest).

Priorities requested outside this range will be clipped to 7. Range: [0, 7]

U8 J1939_TX_MESSAGE_T::dest_addr This is the network address of the intended destination node.

This field is ignored for PDU2 format messages with eight or fewer data bytes since they are always broadcast globally. PDU2 format messages with more than eight bytes of data can be broadcast globally or sent to a specific destination. A destination address (global or specific) is required for all PDU1 formats.

S8 J1939_TX_MESSAGE_T::status This is used to define transport layer error and acknowledgment.

Description:

This is the definition of a J1939 transmit message.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.2. J1939_RX_MESSAGE_T

Summary: This is the definition of a J1939 receive message.

Members:

PGN_T J1939_RX_MESSAGE_T::PGN This is the message Parameter Group Number.

U8* J1939_RX_MESSAGE_T::data_ptr This is a pointer to the data bytes contained in the J1939 message.

If the data pointer is NULL, the message should be considered invalid.

U16 J1939_RX_MESSAGE_T::byte_count This is the number of data bytes in the J1939 message.

Copyright 2019, Pi Innovo 249 Library interface

Range: [0, 1785] bytes

U8 J1939_RX_MESSAGE_T::source_addr This is the network address of the node that transmitted the message.

U8 J1939_RX_MESSAGE_T::dest_addr This is the network address of the node to which the message was sent.

Always set to the global address (255) for PDU2 format messages.

Description:

This is the definition of a J1939 receive message.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.3. CAN_PACKET_T

Summary: This is the structure of a single CAN packet.

Members:

U32 CAN_PACKET_T::identifier This is the 29-bit CAN identifier contained in an extended format packet.

The identifier is right justified within the 32-bit field so that the upper three bits are always zero.

U8 CAN_PACKET_T::data[CAN_MAX_BYTE_COUNT] This is the data bytes contained in the CAN packet.

The value of unused data bytes is undefined.

U8 CAN_PACKET_T::byte_count This is the number of valid data bytes in the CAN packet.

Range: [0, 8] bytes

Description:

This is the structure of a single CAN packet.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.4. PJ1939_RX_BUF_T

Summary: This is the structure for buffering received J1939 messages.

Members:

U32 PJ1939_RX_BUF_T::timestamp This timestamp records when the J1939 message was received.

Range: [0, 4294967295] microseconds

Copyright 2019, Pi Innovo 250 Library interface

U8 PJ1939_RX_BUF_T::source_addr This is the source address of a received J1939 message.

Range: [0, 255]

U8 PJ1939_RX_BUF_T::dest_addr This is the destination address of the received J1939 message.

Range: [0, 255]

U16 PJ1939_RX_BUF_T::byte_count This is the number of data bytes in the received J1939 message.

Range: [0, 1785] bytes

U8 PJ1939_RX_BUF_T::flags This is a bitfield of status information.

If bit 0 is set, the message has been received at least once since the bit was last cleared. If bit 1 is set, the message has been received more than once since the bit was last cleared. If bit 2 is set, an error was trapped on the last receive.

Description:

This is the structure for buffering received J1939 messages.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

5.17.12.2.5. PGN_T

Definition: typedef U32 PGN_T

Description: This is a typedef for the PGN (parameter group number).

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code. 5.17.12.3. Variables

5.17.12.3.1. pj1939_enabled

Definition: const U8 pj1939_enabled

Description: Set true if J1939 functionality is enabled, set false otherwise.

5.17.12.3.2. pj1939c_node_addr_0

Definition: volatile const U8 pj1939c_node_addr_0

Description: This sets the desired J1939 node address and can be altered by calibration.

Copyright 2019, Pi Innovo 251 Library interface

However, it is used only during ECU initialisation, so any calibration change must be programmed into flash to take effect on the next power- up.

Note

The _0 suffix is to allow for the future possibility of multiple nodes being implemented in one ECU. Range: [0, 253]

5.17.12.3.3. node_addr

Definition: U8 node_addr[]

Description: This is a list of preferred J1939 network addresses (all unique and not the null address (254) or the broadcast address (255)).

The first element contains the preferred node address. The last element must contain the global address (255).

Range: [0, 253] or 255

5.17.12.3.4. pj1939_num_node_addr

Definition: const U8 pj1939_num_node_addr

Description: This is the number of declared J1939 network addresses in the node_addr[] array.

Range: [2, 255]

5.17.12.3.5. name

Definition: const U8 name[]

Description: This is the J1939 network name of this unit.

See J1939 specification for details.

5.17.12.3.6. _pgn_table

Definition: const PGN_T _pgn_table[]

Description: This is an array of receive PGNs the library must filter.

Must be declared in ascending order and each element must have a unique value. If the application must respond to DM1, DM2, DM3 or DM11 messages, then the PGNs for these must be added to this array.

Copyright 2019, Pi Innovo 252 Library interface

5.17.12.3.7. pj1939_num_pgns

Definition: const U32 pj1939_num_pgns

Description: This is the number of receive PGNs in _pgn_table[].

Values outside of the defined range will result in undefined behaviour.

Range: [1, 2147483647]

5.17.12.3.8. pj1939_pgn_requested_table

Definition: const PGN_T pj1939_pgn_requested_table[]

Description: This is the list of expected PGN requests to filter.

Must be declared in ascending order and be unique.

5.17.12.3.9. pj1939_num_requested_pgns

Definition: const U32 pj1939_num_requested_pgns

Description: This is the number of expected PGN requests in the pj1939_pgn_requested_table[] array.

5.17.12.3.10. pj1939_pgn_requested_src_addr

Definition: U8 pj1939_pgn_requested_src_addr[]

Description: This is the buffer of source addresses for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.11. pj1939_pgn_requested_dest_addr

Definition: U8 pj1939_pgn_requested_dest_addr[]

Description: This is the buffer of destination addresses for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the

Copyright 2019, Pi Innovo 253 Library interface

array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code. 5.17.12.3.12. pj1939_pgn_requested_timestamp

Definition: U32 pj1939_pgn_requested_timestamp[]

Description: This is the buffer of timestamps for each PGN request message.

Indexes are the same as the pj1939_pgn_requested_table[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_requested_pgns (or one if there are no requested PGNs). The array is not to be accessed by application code. 5.17.12.3.13. pj1939_pgn_requested_bitmap

Definition: U8 pj1939_pgn_requested_bitmap[]

Description: This is the buffer of priority for each PGN request message.

Indexes are the same as pj1939_pgn_requested_table[], but applied per bit, rather than per byte.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal { (pj1939_num_requested_pgns + 7) / 8 } (or one if there are no requested PGNs). The array is not to be accessed by application code. 5.17.12.3.14. pj1939_rx_buf_data_size

Definition: U16 pj1939_rx_buf_data_size[]

Description: This is the size of the data portion to each J1939 receive buffer.

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is the number of data bytes for the corresponding PGN message.

Range: [0, 1785] bytes 5.17.12.3.15. pj1939_rx_buf_data

Definition: U8* const pj1939_rx_buf_data[]

Description: This is an array of pointers to each data buffer for each J1939 receive message.

Copyright 2019, Pi Innovo 254 Library interface

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is a pointer to an area of memory large enough to store the data bytes for the corresponding PGN message. 5.17.12.3.16. pj1939_rx_buf

Definition: PJ1939_RX_BUF_T* const pj1939_rx_buf[]

Description: This is an array of pointers to each J1939 receive message.

The array must be declared and sized by the application. The size of the array must equal pj1939_num_pgns (or one if there are no received PGNs).

Each element corresponds to the same element in the array _pgn_table[], and is a pointer to a variable of type PJ1939_RX_BUF_T. 5.17.12.3.17. pj1939_can_link

Definition: const PCX_LCHAN_T pj1939_can_link

Description: This is the CAN link used for the J1939 network messaging.

Use the macros included by the pio.h file, of the form PIO_CAN_[NAME]. 5.17.12.3.18. pj1939_num_ttx

Definition: const U8 pj1939_num_ttx

Description: This is the number of transport transmit buffers that can run in parallel.

The more transmit buffers there are, the larger the number of destination nodes can be communicated with at the same time. At the same time, the more transmit buffers there are, the larger the amount of RAM required to accommodate the parallel information. Values outside of the defined range will result in undefined behaviour.

Range: [1, 127] buffers. 5.17.12.3.19. pj1939_num_trx

Definition: const U8 pj1939_num_trx

Description: This is the number of transport receive buffers that can run in parallel.

The more receive buffers there are, the larger the number of destination nodes can be communicated with at the same time. At the same time, the more receive buffers there are, the larger the amount of RAM required to accommodate the parallel information.

Copyright 2019, Pi Innovo 255 Library interface

Range: [1, 255] buffers.

5.17.12.3.20. pj1939_size_j1939_rx_buf

Definition: const U16 pj1939_size_j1939_rx_buf

Description: This is the maximum data size of any J1939 message (both reception and transmission).

Any J1939 message with data larger than this variable is rejected by the library.

Range: [8, 1785] bytes.

5.17.12.3.21. pj1939_num_rx_tx_bufs

Definition: const U8 pj1939_num_rx_tx_bufs

Description: This is the number of receive and transmit CAN buffers allocated for J1939 message processing.

Range: [1, 255]

5.17.12.3.22. pj1939_ttx_buf

Definition: J1939_TX_MESSAGE_T pj1939_ttx_buf[]

Description: This is an array of J1939 transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx (or one if there are no requested PGNs). The array is not to be accessed by application code.

5.17.12.3.23. pj1939_ttx_error_ptr

Definition: U8* pj1939_ttx_error_ptr[]

Description: This is an array of pointers to counters for delayed transmit errors.

The index is the same as for the pj1939_ttx_buf[] array.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx. The array is not to be accessed by application code.

5.17.12.3.24. pj1939_ttx_buf_data

Definition: U8 pj1939_ttx_buf_data[]

Copyright 2019, Pi Innovo 256 Library interface

Description: This is the buffer space allocated for all J1939 transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal {pj1939_num_ttx * pj1939_size_j1939_rx_buf}. The array is not to be accessed by application code.

5.17.12.3.25. pj1939_msg_buffer

Definition: U8 pj1939_msg_buffer[]

Description: This is the buffer space allocated for all J1939 receive messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal {pj1939_num_trx * pj1939_size_j1939_rx_buf}. The array is not to be accessed by application code.

5.17.12.3.26. tx_state

Definition: J1939_TRANSPORT_TX_INFO tx_state[]

Description: This is the state of the transmission messages that require transport support (i.e., messages that have a data length greater than 8 bytes).

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_ttx. The array is not to be accessed by application code.

5.17.12.3.27. rx_message

Definition: J1939_MESSAGE rx_message[]

Description: This is the state of the receive messages that require transport support (i.e., messages that have a data length greater than 8 bytes)

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_trx. The array is not to be accessed by application code.

5.17.12.3.28. in_queue

Definition: CAN_PACKET_T in_queue[]

Description: This is the queue of received messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of

Copyright 2019, Pi Innovo 257 Library interface

the array must equal pj1939_num_rx_tx_bufs. The array is not to be accessed by application code.

5.17.12.3.29. out_queue

Definition: CAN_PACKET_T out_queue[]

Description: This is the queue of transmit messages.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_rx_tx_bufs. The array is not to be accessed by application code.

5.17.12.3.30. pj1939_use_common_mf_priority

Definition: const BOOL pj1939_use_common_mf_priority

Description: This is a flag to determine whether to use a common priority for all J1939 multi-frame diagnostic message transmissions.

If true then the priority for such messages is taken from pj1939_common_multiframe_priority. If false, the priority is as defined in the argument to the appropriate message transmit function. Note that that function argument always determines priority for single-frame messages.

5.17.12.3.31. pj1939_common_multiframe_priority

Definition: const U8 pj1939_common_multiframe_priority

Description: This is the common priority used for all J1939 multi-frame diagnostic message transmissions.

It is only used when the pj1939_use_common_mf_priority flag is true.

Range: [0, 7]

5.17.12.3.32. pj1939_dm1_source_addr

Definition: const U8 pj1939_dm1_source_addr[]

Description: This is an array of J1939 node addresses corresponding to the list of addresses which are known to transmit DM1 messages.

Addresses must be declared in ascending order with each address being unique. DM1 messages sent from other addresses are ignored by the library.

If the ECU is to process received DM1 messages, then the PGN 65226 must be added to the array _pgn_table[].

Copyright 2019, Pi Innovo 258 Library interface

Range: [0, 253]

5.17.12.3.33. pj1939_dm1_source_addr_num

Definition: const U8 pj1939_dm1_source_addr_num

Description: This is the number of declared J1939 DM1 transmitter addresses in the pj1939_dm1_source_addr[] array.

Range: [0, 255]

5.17.12.3.34. pj1939_dm1_rx_buf_data

Definition: U8* const pj1939_dm1_rx_buf_data[]

Description: This is the list of pointers to message data buffers for each DM1 message to be received.

Each message buffer pointed to must be an array of bytes of size pj1939_size_j1939_rx_buf. The size of the array must equal pj1939_dm1_source_addr_num.

5.17.12.3.35. pj1939_dm1_rx_counters

Definition: U32 pj1939_dm1_rx_counters[]

Description: This is an array of counters for each DM1 message to be received.

Each counter is incremented by pj1939_dm1_receive when a new message is received. The size of the array must equal to pj1939_dm1_source_addr_num.

5.17.12.3.36. pj1939_dm1_rx_buf

Definition: PJ1939_RX_BUF_T* const pj1939_dm1_rx_buf[]

Description: This is an array of pointers to message buffers for each DM1 message to be received.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_dm1_source_addr_num. The array is not to be accessed by application code.

5.17.12.3.37. pj1939_dm2_source_addr

Definition: const U8 pj1939_dm2_source_addr[]

Description: This is an array of J1939 node addresses corresponding to the list of addresses which are known to transmit DM2 messages.

Copyright 2019, Pi Innovo 259 Library interface

Addresses must be declared in ascending order with each address being unique. DM2 messages sent from other addresses are ignored by the library.

Range: [0, 253]

5.17.12.3.38. pj1939_dm2_source_addr_num

Definition: const U8 pj1939_dm2_source_addr_num

Description: This is the number of declared J1939 DM2 transmitter addresses in the pj1939_dm2_source_addr[] array.

If the ECU is to process received DM2 messages, then the PGN 65227 must be added to the array _pgn_table[].

Range: [0, 255]

5.17.12.3.39. pj1939_dm2_rx_buf_data

Definition: U8* const pj1939_dm2_rx_buf_data[]

Description: This is the list of pointers to message data buffers for each DM2 message to be received.

Each message buffer pointed to must be an array of bytes of size pj1939_size_j1939_rx_buf. The size of the array must equal pj1939_dm2_source_addr_num.

5.17.12.3.40. pj1939_dm2_rx_buf

Definition: PJ1939_RX_BUF_T* const pj1939_dm2_rx_buf[]

Description: This is an array of pointers to message buffers for each DM2 message to be received.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_dm2_source_addr_num. The array is not to be accessed by application code.

5.17.12.3.41. pj1939_dm2_rx_counters

Definition: U32 pj1939_dm2_rx_counters[]

Description: This is an array of counters for each DM2 message to be received.

Each counter is incremented by pj1939_dm2_receive when a new message is received. The size of the array must equal to pj1939_dm2_source_addr_num.

Copyright 2019, Pi Innovo 260 Library interface

5.17.12.3.42. pj1939_state

Definition: U8 pj1939_state[]

Description: This is an array of states for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM1 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.43. pj1939_sent

Definition: U8 pj1939_sent[]

Description: This is an array of sent flags for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM1 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.44. pj1939_transient

Definition: U8 pj1939_transient[]

Description: This is an array of transient fault states for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM35 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.3.45. pj1939_transient_sent

Definition: U8 pj1939_transient_sent[]

Copyright 2019, Pi Innovo 261 Library interface

Description: This is an array of transient sent flags for each DTC.

The array is sized by total number of DTCs in the system, as reported by pdtc_table_all. It is used by the J1939 feature to maintain information required for DM35 messages.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time to minimise the library memory footprint.

5.17.12.4. Functions

5.17.12.4.1. pj1939_dm1_receive()

Definition: U8 pj1939_dm1_receive(U8 pj1939f_dm1_idx, U8 *pj1939f_lamp_malfunction, U8 *pj1939f_lamp_red, U8 *pj1939f_lamp_amber, U8 *pj1939f_lamp_protect, U32 *pj1939f_timestamp)

Supported targets: All targets

Required license: None (Main library).

Description: This function indicates if and when a J1939 DM1 message was received.

Examines a received J1939 DM1 message and decodes lamp information and provides a receive timestamp and counter per power cycle. Can be used in conjunction with pj1939_dm1_decode_dtc to determine when a certain diagnostic trouble code becomes active.

WARNING: The PCX feature takes precedence over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors: PJ1939_DM1_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_dm1_idx Index into pj1939_dm1_rx_buf, pj1939_dm1_rx_buf_data and pj1939_dm1_rx_counters, thus identifying the DM1 message to work with (i.e., a DM1 message from a specific address). Range: [0, pj1939_dm1_source_addr_num - 1]

Arg (data out): pj1939f_lamp_malfunction Pointer to location to write the 'lamp malfunction' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3]

Copyright 2019, Pi Innovo 262 Library interface

One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_red Pointer to location to write the 'lamp red' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_amber Pointer to location to write the 'lamp amber' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_protect Pointer to location to write the 'lamp protect' status for the source transmitting DM1. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_timestamp A pointer to the location to write with the timestamp of the received message. Cannot be NULL. Range: [0, 4294967295] us

Return: One or more flags may be set in the return value to indicate:

• whether a fresh message was received since the last poll (PJ1939_RX_DATA);

• whether more than one message was received since the last poll (PJ1939_RX_OVERRUN);

• whether a receive error occurred for this message (PJ1939_RX_ERROR). 5.17.12.4.2. pj1939_dm1_decode_dtc()

Definition: void pj1939_dm1_decode_dtc(U8 pj1939f_dm1_idx, U32 pj1939f_spn, U8 pj1939f_fmi, U8 pj1939f_cm, U8 *pj1939f_active, U8 *pj1939f_oc)

Supported targets: All targets

Copyright 2019, Pi Innovo 263 Library interface

Required license: None (Main library).

Description: This function decodes part of a received J1939 DM1 message.

Examine a received J1939 DM1 message for a specific diagnostic trouble code (given by a combination of pj1939f_spn, pj1939f_fmi and pj1939f_cm) and report what is found.

Can be used in conjunction with pj1939_dm1_receive to determine when a certain diagnostic trouble code becomes active.

Can raise the following errors: PJ1939_DM1_DECODE_INVALID_ARG.

Arg (data in): pj1939f_dm1_idx Index into pj1939_dm1_rx_buf and pj1939_dm1_rx_buf_data, thus identifying the DM1 message to work with (i.e., a DM1 message from a specific address). Range: [0, pj1939_dm1_source_addr_num - 1]

Arg (data in): pj1939f_spn The 'suspect parameter number' value to search for. Range: [0, 524287]

Arg (data in): pj1939f_fmi The SPN 'failure mode indicator' value to search for. Range: [0, 31]

Arg (data in): pj1939f_cm The SPN 'conversion method' value to search for. Range: [0, 1]

Arg (data out): pj1939f_active Pointer to location to write the status of the SPN/FMI/CM diagnostic trouble code. Written TRUE if the diagnostic trouble code is reported in the message (i.e. Active, for DM1), or written FALSE otherwise. Cannot be NULL.

Arg (data out): pj1939f_oc Pointer to the location to write the occurrence count of the diagnostic trouble code. Cannot be NULL. Range: [0, 127]

5.17.12.4.3. pj1939_dm2_receive()

Definition: U8 pj1939_dm2_receive(U8 pj1939f_dm2_idx, U8 *pj1939f_lamp_malfunction, U8 *pj1939f_lamp_red, U8 *pj1939f_lamp_amber, U8 *pj1939f_lamp_protect, U32 *pj1939f_timestamp)

Supported targets: All targets

Required license: None (Main library).

Copyright 2019, Pi Innovo 264 Library interface

Description: This function indicates if and when a J1939 DM2 message was received.

Examines a received J1939 DM2 message and decodes lamp information and provides a receive timestamp and counter per power cycle. Can be used in conjunction with pj1939_dm2_decode_dtc to determine when a certain diagnostic trouble code becomes inactive (or previously active).

WARNING: The PCX feature takes precedence over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors: PJ1939_DM2_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_dm2_idx Index into pj1939_dm2_rx_buf, pj1939_dm2_rx_buf_data and pj1939_dm2_rx_counters, thus identifying the DM2 message to work with (i.e., a DM2 message from a specific address). Range: [0, pj1939_dm2_source_addr_num - 1]

Arg (data out): pj1939f_lamp_malfunction Pointer to location to write the 'lamp malfunction' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_red Pointer to location to write the 'lamp red' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_amber Pointer to location to write the 'lamp amber' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3] One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_lamp_protect Pointer to location to write the 'lamp protect' status for the source transmitting DM2. Once a valid message has been received, only updated if a new message is received or an error occurs. Cannot be NULL. Range: [0, 3]

Copyright 2019, Pi Innovo 265 Library interface

One of PIO_DTC_LAMP_SLOW_FLASH, PIO_DTC_LAMP_FAST_FLASH, PIO_DTC_LAMP_ON or PIO_DTC_LAMP_OFF (default if no valid reception).

Arg (data out): pj1939f_timestamp A pointer to the location to write with the timestamp of the received message. Cannot be NULL. Range: [0, 4294967295] us

Return: One or more flags may be set in the return value to indicate:

• whether a fresh message was received since the last poll (PJ1939_RX_DATA);

• whether more than one message was received since the last poll (PJ1939_RX_OVERRUN);

• whether a receive error occurred for this message (PJ1939_RX_ERROR). 5.17.12.4.4. pj1939_dm2_decode_dtc()

Definition: void pj1939_dm2_decode_dtc(U8 pj1939f_dm2_idx, U32 pj1939f_spn, U8 pj1939f_fmi, U8 pj1939f_cm, U8 *pj1939f_previously_active, U8 *pj1939f_oc)

Supported targets: All targets

Required license: None (Main library).

Description: This function decodes part of a received J1939 DM2 message.

Examine a received J1939 DM2 message for a specific diagnostic trouble code (given by a combination of pj1939f_spn, pj1939f_fmi and pj1939f_cm) and report what is found.

Can be used in conjunction with pj1939_dm2_receive to determine when a certain diagnostic trouble code becomes inactive (previously active).

Can raise the following errors: PJ1939_DM2_DECODE_INVALID_ARG.

Arg (data in): pj1939f_dm2_idx Index into pj1939_dm2_rx_buf and pj1939_dm2_rx_buf_data, thus identifying the DM2 message to work with (i.e., a DM2 message from a specific address). Range: [0, pj1939_dm2_source_addr_num - 1]

Arg (data in): pj1939f_spn The 'suspect parameter number' value to search for. Range: [0, 524287]

Arg (data in): pj1939f_fmi The SPN 'failure mode indicator' value to search for.

Copyright 2019, Pi Innovo 266 Library interface

Range: [0, 31]

Arg (data in): pj1939f_cm The SPN 'conversion method' value to search for. Range: [0, 1]

Arg (data out): pj1939f_previously_active Pointer to location to write the status of the SPN/FMI/CM diagnostic trouble code. Written TRUE if the diagnostic trouble code is reported in the message (i.e. Previously Active, for DM2), or written FALSE otherwise. Cannot be NULL.

Arg (data out): pj1939f_oc Pointer to the location to write the occurrence count of the diagnostic trouble code. Cannot be NULL. Range: [0, 127]

5.17.12.4.5. pj1939_dm1_transmit()

Definition: void pj1939_dm1_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_force_transmission, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: None (Main library).

Description: This function attempts to transmit a J1939 DM1 message.

Request that a J1939 DM1 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM1 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

The transmission of a DM1 message can involve many CAN packets and to avoid overloading the CAN bus, the J1939 specification provides some guidance for transmission rates. This can be overridden if necessary.

• forced transmission - causes the function to attempt to transmit a DM1 message regardless of the changing state of the DTCs.

• unforced transmission - causes the function to attempt to transmit a DM1 message:

• since the last transmission, a duration of one second has past and either, there is at least one active DTC, or despite no active DTCs a DTC becoming inactive has not been transmitted yet;

• since the last transmission, a DTC changes state for the first time (subsequent state changes do not cause a DM1 message to be transmitted).

Copyright 2019, Pi Innovo 267 Library interface

Can raise the following errors: PJ1939_DM1_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM1 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_force_transmission Set true if the DM1 message should be transmitted regardless of DTC state changes, set false if the DM1 message should be transmitted according to the general guidelines laid out in SAE J1939-73.

Arg (data in): pj1939f_priority The priority of the DM1 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM1 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors 5.17.12.4.6. pj1939_dm2_transmit()

Definition: void pj1939_dm2_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: None (Main library).

Description: This function attempts to transmit a J1939 DM2 message.

Request that a J1939 DM2 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM2 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

Unlike DM1 messages, DM2 messages are transmitted on request.

Can raise the following errors:

Copyright 2019, Pi Innovo 268 Library interface

PJ1939_DM2_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM2 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM2 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM2 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM2 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

5.17.12.4.7. pj1939_inhibit_reprogramming()

Definition: void pj1939_inhibit_reprogramming(U8 pj1939f_inhibit, PJ1939_INHIBIT_REPR_REASONS_T pj1939f_reason)

Supported targets: All targets

Required license: None (Main library).

Description: Enable or disable J1939 reprogramming 'Boot Load' requests while running application mode.

The ECU uses the J1939 protocol for reprogramming. Reprogramming requests are always honoured while the ECU is in reprogramming mode. In application mode, reprogramming requests can be enabled or disabled. For instance, the application might enable reprogramming requests only while it is in an idle and safe state. The application needs to supply a reason for inhibitting reprogramming. This reason will be passed on to an reprogramming -requesting Service Tools.

Arg (data in): pj1939f_inhibit True if reprogramming should be inhibited, false otherwise.

Arg (data in): pj1939f_reason Gives the reason for inhibiting reprogramming.

Copyright 2019, Pi Innovo 269 Library interface

5.17.12.4.8. pj1939_was_pgn_requested()

Definition: void pj1939_was_pgn_requested(const U32 pj1939f_pgn_idx, U32 *pj1939f_timestamp, U8 *pj1939f_requested, U8 *pj1939f_source_addr, U8 *pj1939f_dest_addr)

Supported targets: All targets

Required license: None (Main library).

Description: Determine whether a PGN has been requested from this node.

Search through the list of PGN requests which have been made either to this node's address or to the broadcast address. If a request has been made then clear the PGN request from the list and return details relating to the request.

Can raise the following errors: PJ1939_WAS_REQ_PGN_INVALID_ARG.

Note

If a PG request message is received, but the requested PG does not match any requested PGN, then the library shall respond with a NACK to the sender of the PG request message, unless the request for PG was sent to the global address, in which case, the NACK is not transmitted.

Arg (data in): pj1939f_pgn_idx The index into the pj1939_pgn_requested_table [] array, thus identifying the requested PGN to work with. Use the macros included by the header file generated from the interface tool, of the form PJ1939_PGN_TABLE_IDX_[PGN- NUMBER]. Range: [0, pj1939_num_requested_pgns - 1]

Arg (data out): pj1939f_timestamp A pointer to the location to write the timestamp of the received message. Cannot be NULL. Range: [0, 4294967295] us

Arg (data out): pj1939f_requested A pointer to the location to write the result of searching for the PGN. Written true if the PGN has been requested, written false otherwise. The request status is cleared after the search. Cannot be NULL.

Arg (data out): pj1939f_source_addr A pointer to the location to write the source address of the J1939 message requesting the PGN. Cannot be NULL. Range of source address: [0, 253]

Copyright 2019, Pi Innovo 270 Library interface

Arg (data out): pj1939f_dest_addr A pointer to the location to write the destination address of the J1939 message requesting the PGN. Cannot be NULL. Range of destination address: [0, 253 or 255] 5.17.12.4.9. pj1939_pg_receive()

Definition: void pj1939_pg_receive(const U32 pj1939f_pgn_idx, U32 *pj1939f_timestamp, U8 *pj1939f_error_flag, U8 *pj1939f_rx_trig_flag, U8 *pj1939f_overrun_flag, U8 *pj1939f_source_addr, U8 *pj1939f_dest_addr, const U16 pj1939f_message_len, const U16 pj1939f_num_fields, void *const *pj1939f_item_ptr, const U16 *pj1939f_field_start_pos, const U8 *pj1939f_field_width, const U8 *pj1939f_field_sign, const U8 *pj1939f_field_packing)

Supported targets: All targets

Required license: None (Main library).

Description: Determine if a PGN has been received and extract its contents if required.

If a PGN has been received, then unpack the contents of the received message. If a PGN has not been received, then unpack the contents of the received message as if all message data was zero.

The unpacking sequence works as follows:

• for each element in pj1939f_item_ptr

1. read the data from the PGN receive message buffer given by pj1939f_pgn_idx , based on the item's field start position pj1939f_field_start, and bit width pj1939f_field_width, based on the byte ordering of the item given by pj1939f_field_packing

2. if the item is signed as given by pj1939f_field_sign, then perform sign extension

3. write the converted value to the store given by pj1939f_item_ptr

In addition, the function sets various flags to indicate the state of message reception (received since last call, received more than once since last call, received in error).

WARNING: The PCX feature takes precendece over the PJ1939 feature. If you configure the PCX feature to receive a J1939 frame, the PJ1939 feature will not see the frame, and it will not be processed by the platform. This especially causes problems when receiving J1939 DM14 'Boot Load' commands.

Can raise the following errors: PJ1939_PG_RECEIVE_INVALID_ARG.

Arg (data in): pj1939f_pgn_idx The index into the _pgn_table[] and pj1939_rx_buf[] arrays, thus identifying the received PGN message to work with.

Copyright 2019, Pi Innovo 271 Library interface

Use the macros included by the header file generated from the interface tool, of the form PJ1939_PGN_TABLE_IDX_[PGN- NUMBER]. Range: [0, pj1939_num_pgns - 1]

Arg (data out): pj1939f_timestamp A pointer to the location to write the timestamp of the received message. Cannot be NULL. Range: [0, 4294967295] us

Arg (data out): pj1939f_error_flag A pointer to the location to write the error status of receiving the J1939 message. Written true if there was an error when receiving the message last time, written false otherwise. An error occurs if the length of the J1939 message data contents does not match pj1939f_message_len, or if this node has lost its address claim, or if this node is currently bus-off. Cannot be NULL.

Arg (data out): pj1939f_rx_trig_flag A pointer to the location to write the status of receiving the J1939 message. Written true if the message was received since the last call, written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_overrun_flag A pointer to the location to write the status of receiving the J1939 message. Written true if the message was received more than once since the last call, written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_source_addr A pointer to the location to write the source address of the received J1939 message. Range of source address: [0, 253] Cannot be NULL.

Arg (data out): pj1939f_dest_addr A pointer to the location to write the destination address of the received J1939 message. Can be NULL (in which case, it is not written). Range of destination address: [0, 253 or 255]

Arg (data in): pj1939f_message_len The expected length of the data contents of the received J1939 message. Range: [0, 1785] bytes

Arg (data in): pj1939f_num_fields Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width , pj1939f_field_sign, and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. Range: [0, 65535] fields

Arg (data in): pj1939f_item_ptr Pointer to array of pointers to data to be unpacked from the receive buffer. Each item in this array should point to 32-bit signed or unsigned integer.

Copyright 2019, Pi Innovo 272 Library interface

Cannot be NULL.

Arg (data in): pj1939f_field_start_pos Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 0 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist. Cannot be NULL.

Arg (data in): pj1939f_field_width Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array. Cannot be NULL. Range: [1, 32]

Note

If a field extends beyond the length of the data contents of the received message (given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_sign Pointer to array of sign flags (flag set true if signed, false otherwise). For each item to unpack from the J1939 message, the function determines whether to use the MSB of the packed data as a sign bit or not. Cannot be NULL.

Arg (data in): pj1939f_field_packing Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB. Cannot be NULL. 5.17.12.4.10. pj1939_pg_transmit()

Definition: void pj1939_pg_transmit(const U32 pj1939f_pgn, U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error, const U16 pj1939f_message_len, const U16 pj1939f_num_fields, void *const *pj1939f_item_ptr, const U16 *pj1939f_field_start_pos, const U8 *pj1939f_field_width, const U8 *pj1939f_field_packing)

Supported targets: All targets

Required license: None (Main library).

Description: Construct a J1939 message and attempt to send it (deprecated).

Became deprecated in version 2.2.0. This function will be removed in a future release. This function is no longer necessary, please remove from use in application code.

Copyright 2019, Pi Innovo 273 Library interface

Pack a set of data fields into a J1939 message and attempt to send it.

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications.

If the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off, then the software shall set the output pj1939f_error_flag parameter true and not attempt to buffer the message for transmission.

When the ECU has a network address (has claimed a non- NULL address without conflict), then the ECU can participate in all communications.

The library transmits the buffered message when possible. If the message has a data length greater than 8 bytes, then the message is transmitted using the transport protocol. The protocol includes various timeouts and abort conditions, and these are accumulated by the function and presented to the application on the next call to this function via pj1939f_transport_error.

When the application completes initialisation, the library sets the PG message's transport error count to zero.

If an error occurs while transmitting the message using the transport protocol, then the library increments the message's transport error count (saturating at 255).

The packing sequence works as follows:

• set the data contents of the PGN transmit message buffer given by pj1939f_pgn to all bits set

• for each element in pj1939f_item_ptr

1. read the integer data value from pj1939f_item_ptr

2. clip the integer to the field width as given by pj1939f_field_width

3. write bits to PGN transmit buffer identified by pj1939f_msg_data based with the byte ordering given by pj1939f_field_packing and the bit position given by pj1939f_field_start

Can raise the following errors: PJ1939_PG_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_pgn The PGN value of the J1939 transmit message including the PS field. The PS field of the PGN must represent the destination address for PDU1 format. If the PS field is zero, the message will be broadcasted globally (PDU2 format). Range: [0, 131071]

Arg (data in): pj1939f_priority The priority of the J1939 message to transmit. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the error status of transmitting the J1939 message. Written true if there was an error when transmitting the message this time, written false otherwise. An error

Copyright 2019, Pi Innovo 274 Library interface

occurs if there are no free buffers to store the transmit message, or if the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off. Cannot be NULL.

Arg (data out): pj1939f_transport_error A saturated count of the transport transmit errors encountered while transmitting a J1939 message. The transport layer is only involved if the message must be broken into more than one CAN message (i.e., the data content of the message exceeds 8 data bytes). Cannot be NULL. Range: [0, 255] errors

Arg (data in): pj1939f_message_len The length of the data contents of the J1939 transmit message. Range: [0, 1785] bytes

Arg (data in): pj1939f_item_ptr Pointer to array of pointers to data to be packed into the transmit buffer. Cannot be NULL.

Arg (data in): pj1939f_num_fields Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. Range: [0, 65535] fields

Arg (data in): pj1939f_field_start_pos Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 1 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist. Cannot be NULL.

Arg (data in): pj1939f_field_width Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array. Cannot be NULL. Range: [1, 32]

Note

If a field overlaps (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

If a field extends beyond the length of the transmit data contents (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_packing Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes

Copyright 2019, Pi Innovo 275 Library interface

are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB. Cannot be NULL.

5.17.12.4.11. pj1939_pdu1_transmit()

Definition: void pj1939_pdu1_transmit(const U32 pj1939f_pgn, const U8 pj1939f_dest_addr, U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error, const U16 pj1939f_message_len, const U16 pj1939f_num_fields, void *const *pj1939f_item_ptr, const U16 *pj1939f_field_start_pos, const U8 *pj1939f_field_width, const U8 *pj1939f_field_packing)

Supported targets: All targets

Required license: None (Main library).

Description: Construct a J1939 message and attempt to send it.

Pack a set of data fields into a J1939 message and attempt to send it using PDU1 format.

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications.

If the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off, then the software shall set the output pj1939f_error_flag parameter true and not attempt to buffer the message for transmission.

When the ECU has a network address (has claimed a non- NULL address without conflict), then the ECU can participate in all communications.

The library transmits the buffered message when possible. If the message has a data length greater than 8 bytes, then the message is transmitted using the transport protocol. The protocol includes various timeouts and abort conditions, and these are accumulated by the function and presented to the application on the next call to this function via pj1939f_transport_error.

When the application completes initialisation, the library sets the PG message's transport error count to zero.

If an error occurs while transmitting the message using the transport protocol, then the library increments the message's transport error count (saturating at 255).

The packing sequence works as follows:

• set the data contents of the PGN transmit message buffer given by pj1939f_pgn to all bits set

• for each element in pj1939f_item_ptr

Copyright 2019, Pi Innovo 276 Library interface

1. read the integer data value from pj1939f_item_ptr

2. clip the integer to the field width as given by pj1939f_field_width

3. write bits to PGN transmit buffer identified by pj1939f_msg_data based with the byte ordering given by pj1939f_field_packing and the bit position given by pj1939f_field_start

Can raise the following errors: PJ1939_PG_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_pgn The PGN value of the J1939 transmit message. Range: [0, 130816]

Arg (data in): pj1939f_dest_addr The destination address for the J1939 transmit message. Range: [0, 255]

Arg (data in): pj1939f_priority The priority of the J1939 message to transmit. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the error status of transmitting the J1939 message. Written true if there was an error when transmitting the message this time, written false otherwise. An error occurs if there are no free buffers to store the transmit message, or if the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off. Cannot be NULL.

Arg (data out): pj1939f_transport_error A saturated count of the transport transmit errors encountered while transmitting a J1939 message. The transport layer is only involved if the message must be broken into more than one CAN message (i.e., the data content of the message exceeds 8 data bytes). Cannot be NULL. Range: [0, 255] errors

Arg (data in): pj1939f_message_len The length of the data contents of the J1939 transmit message. Range: [0, 1785] bytes

Arg (data in): pj1939f_item_ptr Pointer to array of pointers to data to be packed into the transmit buffer. Cannot be NULL.

Arg (data in): pj1939f_num_fields Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. Range: [0, 65535] fields

Arg (data in): pj1939f_field_start_pos Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to

Copyright 2019, Pi Innovo 277 Library interface

retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 1 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist. Cannot be NULL.

Arg (data in): pj1939f_field_width Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array. Cannot be NULL. Range: [1, 32]

Note

If a field overlaps (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

If a field extends beyond the length of the transmit data contents (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_packing Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB. Cannot be NULL.

5.17.12.4.12. pj1939_pdu2_transmit()

Definition: void pj1939_pdu2_transmit(const U32 pj1939f_pgn, U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error, const U16 pj1939f_message_len, const U16 pj1939f_num_fields, void *const *pj1939f_item_ptr, const U16 *pj1939f_field_start_pos, const U8 *pj1939f_field_width, const U8 *pj1939f_field_packing)

Supported targets: All targets

Required license: None (Main library).

Description: Construct a J1939 message and attempt to send it.

Pack a set of data fields into a J1939 message and attempt to broadcast it using PDU2 format.

When the ECU has no network address (has claimed the NULL address), it can only participate in network communications.

If the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off, then the software shall set the output pj1939f_error_flag parameter true and not attempt to buffer the message for transmission.

Copyright 2019, Pi Innovo 278 Library interface

When the ECU has a network address (has claimed a non- NULL address without conflict), then the ECU can participate in all communications.

The library transmits the buffered message when possible. If the message has a data length greater than 8 bytes, then the message is transmitted using the transport protocol. The protocol includes various timeouts and abort conditions, and these are accumulated by the function and presented to the application on the next call to this function via pj1939f_transport_error.

When the application completes initialisation, the library sets the PG message's transport error count to zero.

If an error occurs while transmitting the message using the transport protocol, then the library increments the message's transport error count (saturating at 255).

The packing sequence works as follows:

• set the data contents of the PGN transmit message buffer given by pj1939f_pgn to all bits set

• for each element in pj1939f_item_ptr

1. read the integer data value from pj1939f_item_ptr

2. clip the integer to the field width as given by pj1939f_field_width

3. write bits to PGN transmit buffer identified by pj1939f_msg_data based with the byte ordering given by pj1939f_field_packing and the bit position given by pj1939f_field_start

Can raise the following errors: PJ1939_PG_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_pgn The PGN value of the J1939 transmit message. Range: [0, 130816]

Arg (data in): pj1939f_priority The priority of the J1939 message to transmit. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the error status of transmitting the J1939 message. Written true if there was an error when transmitting the message this time, written false otherwise. An error occurs if there are no free buffers to store the transmit message, or if the node address for the ECU cannot be claimed, or the CAN link for J1939 is bus-off. Cannot be NULL.

Arg (data out): pj1939f_transport_error A saturated count of the transport transmit errors encountered while transmitting a J1939 message. The transport layer is only involved if the message must be broken into more than one CAN message (i.e., the data content of the message exceeds 8 data bytes). Cannot be NULL. Range: [0, 255] errors

Copyright 2019, Pi Innovo 279 Library interface

Arg (data in): pj1939f_message_len The length of the data contents of the J1939 transmit message. Range: [0, 1785] bytes

Arg (data in): pj1939f_item_ptr Pointer to array of pointers to data to be packed into the transmit buffer. Cannot be NULL.

Arg (data in): pj1939f_num_fields Number of fields in each of pj1939f_item_ptr, pj1939f_field_start_pos, pj1939f_field_width and pj1939f_field_packing. The function does not check that all arrays have the same length. The results of the function are undefined if the length of each differs from this function argument. Range: [0, 65535] fields

Arg (data in): pj1939f_field_start_pos Pointer to array of field start bit numbers. For each item to unpack from the J1939 message, the function determines where to retrieve the data using the corresponding element from this array. 0 corresponds to the least significant bit of data byte 1 of the message, 15 to the most significant bit of data byte 2 of the message, and so on, assuming these exist. Cannot be NULL.

Arg (data in): pj1939f_field_width Pointer to array of field bit widths. For each item to unpack from the J1939 message, the function determines how many bits to retrieve from the array using the corresponding element from this array. Cannot be NULL. Range: [1, 32]

Note

If a field overlaps (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

If a field extends beyond the length of the transmit data contents (as given by pj1939f_field_start_pos and pj1939f_field_width) then the functionality is undefined.

Arg (data in): pj1939f_field_packing Pointer to array of byte ordering flags (flag set true if field's data bytes are ordered most significant byte first, false if field's data bytes are ordered least significant byte first (as is typical for J1939 data)). For each item to unpack from the J1939 message, the function determines whether to unpack MSB or LSB. Cannot be NULL. 5.18. Diagnostic Trouble Code (DTC) feature (PDTC) 5.18.1. Overview

The library's diagnostic trouble code feature provides a mechanism to declare basic DTCs, manipulate them and store them persistently across power cycles. It is not suitable for

Copyright 2019, Pi Innovo 280 Library interface

emissions related DTCs which need to meet specific legislated requirements. In that case see the Extended Diagnostic Functions section.

The library groups DTCs into tables. Each table can contain one or more DTC, and a DTC can exist in one table only. DTC tables allow the application to act on a group of DTCs as one action (and though not currently supported by the library, allows the application emulate more than one node on the same J1939 network).

This library concentrates on J1939 DTCs. However, a DTC may be reported over ISO 15765-2 based protocols, or J1939, or both. The emissions related functions of ISO 15765-2 and J1939 are available in the Extended Diagnostic Functions. 5.18.2. Diagnostic trouble codes — generic

The application declares the DTCs of interest during build time by defining the feature variables, including pdtc_num_dtc_tables and pdtc_table_list. Individual DTCs are declared in the interface file (see Section 7.1.4.28, “Compound statement: dtc-data”).

The information for DTCs is recalled from non-volatile store after application initialisation occurs. If DTC data cannot be recalled from non-volatile store, then all DTCs are reset to Clear state.

None of the target ECUs have the capability to time-stamp information. For this reason, DTCs do not have an associated time-stamp stored with them. 5.18.3. Diagnostic trouble codes — J1939

The library maintains an internal state for a J1939 DTC based on the pdtcf_active_in parameter to the function pdtc_update_j1939_dtc() as given in the following state diagram:

Figure 5.18. J1939 activation state machine

if ‘pdtcf_active_in’ = FALSE if ‘pdtcf_active_in’ = TRUE

if ‘pdtcf_active_in’ = TRUE

clear active

1 2

if ‘pdtcf_active_in’ = FALSE if ‘pdtcf_active_in’ = TRUE

inactive

3

if ‘pdtcf_active_in’ = FALSE

Note: DTCs can also adopt a pending state, used for reporting over ISO diagnostic protocols but not J1939.

Copyright 2019, Pi Innovo 281 Library interface

When the DTC's internal state changes from clear to active, or from inactive to active, the library increases the DTC's internal count (saturating at 126).

Not shown in Figure 5.18, “J1939 activation state machine”, is that the DTC state can be forcefully set to clear through the use of the pdtc_clear_all(), pdtc_clear_all_if_active() or pdtc_clear_all_if_inactive() functions. 5.18.4. Storage of data across power cycles

On start-up, the library attempts to retrieve the DTC table data prior to running the application. While the application is running, changes to DTC states are written to non-volatile storage when function pdtc_commit_to_store() is called by the application. This will typically be carried out by the application on shutdown and at periodic intervals during execution. Note that the application has full responsibility for invoking writes to non-volatile storage; the platform will never initiate this itself.

If DTCs have not changed since the last write to non-volatile storage, calls to function pdtc_commit_to_store() will not result in additional writes to non-volatile storage. This maximises the lifespan of the non-volatile storage device and may reduce the time taken to shut down the ECU.

The DTC table data is check-summed using a 16-bit CRC. Failure to match the check-sum against the table data during library initialisation means that the data cannot be recovered. In this case, DTC table data is reverted to default start-up conditions. These are:

Table 5.4. DTC initialisation values

DTC information Initial value State Clear Lamp States All off

There are two types of non-volatile memory dedicated to DTCs:

Battery backed RAM Storage that requires an external power source when the ECU is powered down (not available on all target ECUs).

Flash Storage that requires no external power supply when the ECU is powered down (not available on all target ECUs).

See Section A.1, “ECU hardware reference documentation” for details of what non-volatile memory stores are available for each target ECU. 5.18.5. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

Copyright 2019, Pi Innovo 282 Library interface

5.18.6. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pdtc.h Macros PDTC_STORE_IN_BBRAM

This macro defines the value for pdtc_store when DTCs are to be stored in battery backed RAM across power cycles. PDTC_STORE_IN_FLASH

This macro defines the value for pdtc_store when DTCs are to be stored in Flash across power cycles. Enumerations PDTC_STATE_T

This enumeration declares the different types of DTCs available. PDTC_ERROR_CODE_T

Error values when an error is found by the diagnostic trouble code feature (PDTC), the feature calls a system error log function with an enumeration from this type. Data types PDTC_DTC_NV_T

This structure declares the run-time data to be stored with each DTC. PDTC_DTC_T

This structure declares the constant data to be stored with each DTC type. PDTC_TABLE_VAR_T

This structure declares all per-DTC-table variable data. PDTC_TABLE_T

This structure declares a table of DTCs. Variables U16 pdtc_nv_chksum

This is the CRC checksum of the DTC store in non- volatile memory. const U8 pdtc_store

This defines which memory type will be used to store non-volatile DTCs.

Copyright 2019, Pi Innovo 283 Library interface

Type Identifier const U16 pdtc_num_dtc_tables

This is the total number of DTC tables the library will maintain. const PDTC_TABLE_T *const pdtc_table_list

This is a list of the DTC tables the library will maintain. Functions void pdtc_commit_to_store

Commit DTC data, and freeze frame data if supported, to non-volatile store. BOOL pdtc_is_store_intact

Test whether there are DTC changes not yet committed to NV store. void pdtc_clear_all

Clear the state of each DTC of matching type in a DTC table. void pdtc_clear_all_if_active

Clear the state of each DTC of matching type in a DTC table, if the DTC state is active. void pdtc_clear_all_if_inactive

Clear the state of each DTC of matching type in a DTC table, if the DTC state is inactive. void pdtc_enable_periodic_lamp_updates

Allows an application to enable or disable periodic processing of the pdtc lamp status. void pdtc_update_j1939_dtc

Update the status and data of a J1939 DTC. 5.18.7. Interface detail 5.18.7.1. Macros

5.18.7.1.1. PDTC_STORE_IN_BBRAM

Definition: #define PDTC_STORE_IN_BBRAM 0

Description:

This macro defines the value for pdtc_store when DTCs are to be stored in battery backed RAM across power cycles. 5.18.7.1.2. PDTC_STORE_IN_FLASH

Definition: #define PDTC_STORE_IN_FLASH 1

Copyright 2019, Pi Innovo 284 Library interface

Description:

This macro defines the value for pdtc_store when DTCs are to be stored in Flash across power cycles. 5.18.7.2. Enumerations

5.18.7.2.1. PDTC_STATE_T

Summary: This enumeration declares the different types of DTCs available.

Enumerations:

PDTC_STATE_CLEAR The clear state for a DTC.

PDTC_STATE_ACTIVE The active state for a DTC.

PDTC_STATE_PREVIOUSLY_ACTIVE

PDTC_STATE_INACTIVE The inactive (or CARB "previously active") state for a DTC.

PDTC_STATE_PENDING The pending state for a DTC.

5.18.7.2.2. PDTC_ERROR_CODE_T

Summary: Error values when an error is found by the diagnostic trouble code feature (PDTC), the feature calls a system error log function with an enumeration from this type.

Enumerations:

PDTC_OK No error.

PDTC_UPDATE_INVALID_ARG Error raised if the DTC update function finds an invalid argument.

PDTC_CLEAR_ALL_INVALID_ARG Error raised if the DTC clear all function finds an invalid argument.

PDTC_CLEAR_ALL_IF_ACT_INVALID_ARG Error raised if the DTC clear all if active function finds an invalid argument.

PDTC_CLEAR_ALL_IF_INACT_INVALID_ARG Error raised if the DTC clear all if inactive function finds an invalid argument.

PDTC_GET_DTC_STATUS_INVALID_ARG Error raised if the DTC clear all if inactive function finds an invalid argument.

PDTC_MATCH_EXISTS_INVALID_ARG Error raised if the match exists function finds an invalid argument.

Copyright 2019, Pi Innovo 285 Library interface

PDTC_CLEAR_DTCS_INVALID_ARG Error raised if the DTC clear function finds an invalid argument.

PDTC_BAD_LICENSE Error raised if function call not licensed. 5.18.7.3. Data types

5.18.7.3.1. PDTC_DTC_NV_T

Summary: This structure declares the run-time data to be stored with each DTC.

Members:

PDTC_STATE_T PDTC_DTC_NV_T::state This is the current state of the DTC.

One of PDTC_STATE_CLEAR, PDTC_STATE_ACTIVE , PDTC_STATE_INACTIVE or PDTC_STATE_PENDING.

U8 PDTC_DTC_NV_T::count This is the (saturated) number of times the DTC has changed to the PDTC_STATE_ACTIVE state.

Range: [0, 127] counts - 0 to 126 (The value 127 is reserved for indicating not available)

U8 PDTC_DTC_NV_T::lamp_states This is a bit pattern of states for 4 lamps.

Bits 7:6 correspond to the malfunction lamp, bits 5:4 correspond to the red lamp, bits 3:2 correspond to the amber lamp and bits 1:0 correspond to the protect lamp. The bit pattern for each lamp state is determined by the J1939 specification.

Note that this is only used by the legacy (deprecated) interface for J1939 DTCs, to allow backwards compatibility for existing applications, and may be removed in a future version of the API.

Description:

This structure declares the run-time data to be stored with each DTC.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.3.2. PDTC_DTC_T

Summary: This structure declares the constant data to be stored with each DTC type.

Members:

PIO_DTC_TYPE_T PDTC_DTC_T::type This is the enumeration for a diagnostic trouble code.

Copyright 2019, Pi Innovo 286 Library interface

Range: [1, 2]

U32 PDTC_DTC_T::spn This is the suspect parameter number associated with a J1939 DTC.

Range: [0, 524287]

U8 PDTC_DTC_T::fmi This is the failure mode indicator associated with a J1939 DTC.

Range: [0, 31]

U8 PDTC_DTC_T::cm This is the conversion method associated with a J1939 DTC.

Range: [0, 1]

PDTC_DTC_NV_T* PDTC_DTC_T::nv_data This points to the non-volatile storage structure for this DTC.

May not be NULL.

PDTC_DTC_VAR_T* PDTC_DTC_T::var_data This points to the volatile (RAM) storage structure for this DTC.

May not be NULL.

Description:

This structure declares the constant data to be stored with each DTC type.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.3.3. PDTC_TABLE_VAR_T

Summary: This structure declares all per-DTC-table variable data.

Members:

PDTC_COMBINED_LAMP_STATE_T PDTC_TABLE_VAR_T::lamp_states[4] This is an array of lamp states (sized by PDTC_NUM_LAMPS) for all lamps whose status is set by DTCs in this table.

Description:

This structure declares all per-DTC-table variable data.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

Copyright 2019, Pi Innovo 287 Library interface

5.18.7.3.4. PDTC_TABLE_T

Summary: This structure declares a table of DTCs.

Members:

U16 PDTC_TABLE_T::num_dtcs This is the number of DTCs referenced by the table.

Range: [0, 65535] dtcs

U16 PDTC_TABLE_T::dtc_offset This is the bit offset into pj1939_state[] and pj1939_sent[], used to track the state of a DTC for DM1 message transmit rules.

The DTCs are allocated to these arrays in a contiguous fashion per table. Range: [0, 65535]

const PDTC_DTC_T* const* PDTC_TABLE_T::dtcs This is a pointer to an array of const pointers (sized by num_dtcs) to DTCs referenced by this table.

PDTC_TABLE_VAR_T* PDTC_TABLE_T::per_table_data This is a pointer to per-DTC-table variable data.

Description:

This structure declares a table of DTCs.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

5.18.7.4. Variables 5.18.7.4.1. pdtc_nv_chksum

Definition: U16 pdtc_nv_chksum

Description: This is the CRC checksum of the DTC store in non-volatile memory.

The CRC checksum of the DTC store is updated prior to storing DTC data in non-volatile memory when calling pdtc_commit_to_store().

Range: [0, 65535] unitless 5.18.7.4.2. pdtc_store

Definition: const U8 pdtc_store

Description: This defines which memory type will be used to store non-volatile DTCs.

If set to PDTC_STORE_IN_BBRAM then DTCs are stored in battery backed RAM, and if set to PDTC_STORE_IN_FLASH then the DTCs are stored in Flash.

Copyright 2019, Pi Innovo 288 Library interface

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

5.18.7.4.3. pdtc_num_dtc_tables

Definition: const U16 pdtc_num_dtc_tables

Description: This is the total number of DTC tables the library will maintain.

5.18.7.4.4. pdtc_table_list

Definition: const PDTC_TABLE_T* const pdtc_table_list[]

Description: This is a list of the DTC tables the library will maintain. 5.18.7.5. Functions

5.18.7.5.1. pdtc_commit_to_store()

Definition: void pdtc_commit_to_store(void)

Supported targets: All targets

Required license: None (Main library).

Description: Commit DTC data, and freeze frame data if supported, to non-volatile store.

Warning

On this function merely queues the saving of data and returns, so application execution is unaffected. If the data must be committed to memory as part of a power-down sequence, follow this by a call to pfs_flush_all to ensure the data write is complete before powering off.

Note

Old DTC data is reused so long as it has the expected total data size and was written by an application with the same user- specified version number. Otherwise the values revert to defaults. If the usage of DTCs has changed in a new software version, increase the application sub-minor version number to ensure that any old values are not used, as they may not map appropriately to

Copyright 2019, Pi Innovo 289 Library interface

the DTCs in the new application even if the total data size happens to match.

5.18.7.5.2. pdtc_is_store_intact()

Definition: BOOL pdtc_is_store_intact(void)

Supported targets: All targets

Required license: None (Main library).

Description: Test whether there are DTC changes not yet committed to NV store.

Return: True if there are no DTC changes since last commit to non-volatile store (from calling pdtc_commit_to_store()), false otherwise 5.18.7.5.3. pdtc_clear_all()

Definition: void pdtc_clear_all(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type)

Supported targets: All targets

Required license: None (Main library).

Description: Clear the state of each DTC of matching type in a DTC table.

For the DTC table (pdtcf_table) the function to clear all DTCs is called.

Freeze frame data associated with the cleared DTCs is also cleared. Monitor (DME and DTE) data is also cleared other than persistent data which is never cleared (e.g. numerators and denominators). As the platform does not know which DME/DTE objects are associated with which DTCs in an application, it is assumed that the table being cleared applies to all emissions-relevant monitors.

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details. 5.18.7.5.4. pdtc_clear_all_if_active()

Definition: void pdtc_clear_all_if_active(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type)

Supported targets: All targets

Copyright 2019, Pi Innovo 290 Library interface

Required license: None (Main library).

Description: Clear the state of each DTC of matching type in a DTC table, if the DTC state is active.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type, and the DTC state is PDTC_STATE_ACTIVE, then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Any freeze frame data associated with cleared DTCs is also erased, but not monitor data. See also pdtc_clear_all.

Can raise the following errors: PDTC_CLEAR_ALL_IF_ACT_INVALID_ARG

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details. 5.18.7.5.5. pdtc_clear_all_if_inactive()

Definition: void pdtc_clear_all_if_inactive(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type)

Supported targets: All targets

Required license: None (Main library).

Description: Clear the state of each DTC of matching type in a DTC table, if the DTC state is inactive.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type, and the DTC state is PDTC_STATE_INACTIVE, then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Any freeze frame data associated with cleared DTCs is also erased, but not monitor data. See also pdtc_clear_all.

This function would normally be called only in response to a J1939 DM3 request (not intended for emissions-related systems).

Can raise the following errors: PDTC_CLEAR_ALL_IF_INACT_INVALID_ARG

Copyright 2019, Pi Innovo 291 Library interface

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details. 5.18.7.5.6. pdtc_enable_periodic_lamp_updates()

Definition: void pdtc_enable_periodic_lamp_updates(BOOL pdtcf_en)

Supported targets: All targets

Required license: None (Main library).

Description: Allows an application to enable or disable periodic processing of the pdtc lamp status.

Note

Periodic processing is enabled by default so this function is not required to enable processing.

Arg (data in): pdtcf_en Flag indicating if periodic updates should be enabled (TRUE) or disabled (FALSE). 5.18.7.5.7. pdtc_update_j1939_dtc()

Definition: void pdtc_update_j1939_dtc(const PDTC_DTC_T *const pdtcf_dtc, U8 pdtcf_active_in, U8 pdtcf_lamp_bitmap, U8 *pdtcf_active_out, U8 *pdtcf_state, U8 *pdtcf_count)

Supported targets: All targets

Required license: None (Main library).

Description: Update the status and data of a J1939 DTC.

Updates the status and data of a J1939 DTC. When the DTC's internal state changes from clear to active, or from inactive to active, the function increases the DTC's internal activation count (saturating at 127).

Can raise the following errors: PDTC_UPDATE_INVALID_ARG.

Arg (data in,out): pdtcf_dtc Pointer to DTC to update. Cannot be NULL.

Arg (data in): pdtcf_active_in True if the DTC should become active, false otherwise.

Copyright 2019, Pi Innovo 292 Library interface

Arg (data in): pdtcf_lamp_bitmap Bitmap of lamp information (for J1939 DTCs). For future software, this must always be set to PDTC_LAMPS_OFF, which selects lamp state as calibrated for the DTC. For legacy software this may be set to a bitmap where bits 7:6 correspond to the malfunction lamp, bits 5:4 correspond to the red lamp, bits 3:2 correspond to the amber lamp and bits 1:0 correspond to the protect lamp. The bit pattern for each lamp state is determined by the J1939 specification.

Arg (data out): pdtcf_active_out Pointer to where the boolean result of whether the DTC is active or not is to be stored. Cannot be NULL.

Arg (data out): pdtcf_state Pointer to where the current DTC state will be written. Cannot be NULL. Range: 1 = Clear, 2 = Active, 3 = Inactive

Arg (data out): pdtcf_count Pointer to where the current DTC activation count will be written. Cannot be NULL. Range: [0, 127] counts 5.19. Adaptive non-volatile memory feature (PNV) 5.19.1. Overview

The library's non-volatile memory feature provides a mechanism to declare non-volatile data, manipulate the data and store the data persistently across power cycles.

The library supports the following data types:

Non-volatile array The library provides access to an array of non-volatile data through the pnv_array() function. The data can be modified, reset and stored to memory to be recalled during the next library initialisation. The entire array can be output using the pnv_array_dump() function

Adaptive scalar The library provides access to a single non-volatile variable through the pnv_adap_scalar_f32() function. The scalar can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Adaptive 1-d look-up map The library provides access to a non-volatile adaptive 1-d look-up map through the pnv_adap_map_1d_f32() function. The map can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Prior to looking up the map and performing interpolation to determine the output value (as done by put_cal_map_1d_f32()), the application can request that the map is modified: either reset to its default, or adjusted by an increment.

The library adjusts the map's Z-data as follows:

Copyright 2019, Pi Innovo 293 Library interface

zb

za

xa xb

xa and xb bound pnvf_adapt_xx (see exceptions below), while za and zb are the corresponding elements pnvf_pz, both parameters to function pnv_adap_map_1d_f32().

There are some exceptions, see the function documentation for more.

Adaptive 2-d look-up map The library provides access to a non-volatile adaptive 2-d look-up map through the pnv_adap_map_2d_f32() function. The map can be adjusted by a relative amount, reset and stored to memory to be recalled during the next library initialisation.

Prior to looking up the map and performing interpolation to determine the output value (as done by put_cal_map_2d_f32()), the application can request that the map is modified: either reset to its default, or adjusted by an increment.

The library adjusts the map's Z-data as follows:

yb zab zbb

ya zaa zba

xa xb

xa and xb bound pnvf_adapt_xx, ya and yb bound pnvf_adapt_yy, zaa, zab, zba and zbb are the corresponding elements in pnvf_pz, all parameters to function pnv_adap_map_1d_f32().

Copyright 2019, Pi Innovo 294 Library interface

There are some exceptions, see the function documentation for more.

pnv_is_ram_adap_csum_valid() The library provides access to the status of the adaptive RAM checksum through the pnv_is_ram_adap_csum_valid() function. The function returns true if the checksum is valid and false otherwise.

pnv_is_flash_adap_csum_valid() The library provides access to the status of the adaptive RAM checksum through the pnv_is_flash_adap_csum_valid() function. The function returns true if the checksum is valid and false otherwise. 5.19.2. Storage of data across power cycles

On start-up, the library attempts to retrieve adaptive data prior to running the application. While the application is running, the time at which the adaptive data is stored back to non- volatile memory is determined by the application itself.

The adaptive data is check-summed using a 16-bit CRC. Failure to match the check-sum against the adaptive data during library initialisation means that the data cannot be recovered. In this case, adaptive data is reverted to the default for each adaptive element (the defaults can be specified by the application).

There are two types of non-volatile memory dedicated to adaptive data:

Battery backed RAM Storage that requires an external power source when the ECU is powered down (not available on all target ECUs),

Flash Storage that requires no external power supply when the ECU is powered down (not available on all target ECUs).

See Section A.1, “ECU hardware reference documentation” for details of what non-volatile memory stores are available for each target ECU.

Copyright 2019, Pi Innovo 295 Library interface

The application starts a commit of adaptive data to non-volatile store by calling pnv_commit_to_store().

Note

If the non-volatile memory store is Flash, then the library will halt the application while committing adaptive data to non-volatile memory. This is to prevent any higher-rate tasks interrupting and attempting to access the Flash device (which will generally be unavailable at that time).

The worst case scenario is for the application to be stopped for about 1.8 seconds. It is the responsibility of the application to ensure that there will be no detrimental side effects to stopping the application for this length of time, e.g., the application should ensure all coil and injector outputs are turned off if applicable for that ECU.

It should also be noted that, once started, it is not possible to interrupt the Flash commit process. So if, for example, a user of the ECU requests that the ECU start-up before the process has completed, the ECU will not try to start until control is passed back to the application.

The application can determine if the adaptive data requires a commit to non-volatile memory through the pnv_is_store_intact() function. When the ECU decides to power down, if this function returns true, there will be no need to store the data to non-volatile memory again; this is important for a Flash-based solution as this means there is no need to write the data to Flash, thus minimising shutdown time and reducing the number of Flash write cycles. 5.19.3. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pnv.h Macros PNV_STORE_IN_BBRAM

This macro defines the value for pnv_store when non- volatile data is to be stored in battery backed RAM across power cycles. PNV_STORE_IN_FLASH

This macro defines the value for pnv_store when non- volatile data is to be stored in Flash across power cycles. PNV_FILE_ACCESS_MAX_NUM_FILES

This macro defines the maximum number of filesystem files that can be managed by pnv_file functions. Enumerations PNV_ERROR_CODE_T

Error values for debugging when an error is found when calling the PNV API, the API calls a function with an enumeration from this type. PNV_RC_T

Copyright 2019, Pi Innovo 296 Library interface

Type Identifier An enumerated type which contains success and failure codes returned by the adaptive map lookup and interpolation functions. Data types PNV_ADAP_T

This typedef defines a structure which is used to locate all of the adaptive parameters. Variables const U8 pnv_store

This defines which memory type will be used to store non-volatile adaptive data. U8 pnv_adap_csum

This is a checksum of the non-volatile memory objects stored in RAM. Functions void pnv_commit_to_store

Commit RAM data to non-volatile store. BOOL pnv_is_store_intact

Test whether there are adaptive data changes not yet committed to NV store. PNV_RC_T pnv_adap_map_1d_f32

1D table adaption, lookup and interpolation. PNV_RC_T pnv_adap_map_2d_f32

2D table adaption, lookup and interpolation. void pnv_adap_scalar_f32

Adaptive scalar update. BOOL pnv_is_ram_adap_csum_valid

Return the state of RAM adaptive checksum. BOOL pnv_is_flash_adap_csum_valid

Return the state of Flash adaptive checksum. void pnv_array

Non-volatile array read and write functionality. void pnv_array_dump

Non-volatile array output facility.

Copyright 2019, Pi Innovo 297 Library interface

5.19.4. Interface detail 5.19.4.1. Macros 5.19.4.1.1. PNV_STORE_IN_BBRAM

Definition: #define PNV_STORE_IN_BBRAM 0

Description:

This macro defines the value for pnv_store when non-volatile data is to be stored in battery backed RAM across power cycles. 5.19.4.1.2. PNV_STORE_IN_FLASH

Definition: #define PNV_STORE_IN_FLASH 1

Description:

This macro defines the value for pnv_store when non-volatile data is to be stored in Flash across power cycles. 5.19.4.1.3. PNV_FILE_ACCESS_MAX_NUM_FILES

Definition: #define PNV_FILE_ACCESS_MAX_NUM_FILES (32)

Description:

This macro defines the maximum number of filesystem files that can be managed by pnv_file functions. 5.19.4.2. Enumerations 5.19.4.2.1. PNV_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the PNV API, the API calls a function with an enumeration from this type.

Enumerations:

PNV_ADAPMAP_INVALID_ARG Error raised if one of the adaptive table lookup and interpolation functions finds an invalid argument.

PNV_ADAPSCALAR_INVALID_ARG Error raised if the adaptive scalar function find an invalid argument.

PNV_ARRAY_INVALID_ARG Error raised if the array function finds an invalid argument.

PNV_ARRAY_DUMP_INVALID_ARG Error raised if the array dump function finds an invalid argument. 5.19.4.2.2. PNV_RC_T

Summary: An enumerated type which contains success and failure codes returned by the adaptive map lookup and interpolation functions.

Copyright 2019, Pi Innovo 298 Library interface

Enumerations:

PNV_RC_OK Return code if everything progressed as expected.

PNV_RC_BAD_ARGS Return code if at least one of the arguments points to null.

PNV_RC_INSUFFICIENT_ELEMENTS Return code if there are insufficient elements to use the function.

PNV_RC_ERROR Return code if the operation could not be completed. 5.19.4.3. Data types 5.19.4.3.1. PNV_ADAP_T

Summary: This typedef defines a structure which is used to locate all of the adaptive parameters.

Members:

void* PNV_ADAP_T::adap_ptr A pointer to the RAM version of the object.

Used during run-time for read and write purposes, it is initialised from the non-volatile copy of the same object (or the constant copy if non- volatile memory fails). The RAM version is copied to non-volatile memory (if possible) when pnv_commit_to_store() is called. Cannot point to NULL.

const void* PNV_ADAP_T::def_ptr A pointer to a constant version of the object, used to restore a default value if the non-volatile copy of the same object could not be recovered from non-volatile memory during initialisation.

Cannot point to NULL.

U32 PNV_ADAP_T::size The size of the object pointed to by adap_ptr and def_ptr in bytes.

Cannot be zero.

Description:

This typedef defines a structure which is used to locate all of the adaptive parameters.

During initialisation, if the adaptive data cannot be recalled, the default adaptive data is used instead. 5.19.4.4. Variables 5.19.4.4.1. pnv_store

Definition: const U8 pnv_store

Description: This defines which memory type will be used to store non-volatile adaptive data.

Copyright 2019, Pi Innovo 299 Library interface

If set to PNV_STORE_IN_BBRAM then non-volatile adaptive data is stored in battery backed RAM, and if set to PNV_STORE_IN_FLASH then the non-volatile adaptive data is stored in Flash.

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

5.19.4.4.2. pnv_adap_csum

Definition: U8 pnv_adap_csum[]

Description: This is a checksum of the non-volatile memory objects stored in RAM.

The checksum is the CCITT CRC. The checksum must be the first linked variable in the RAM memory area dedicated to non-volatile memory. It is allocated by the linker. 5.19.4.5. Functions

5.19.4.5.1. pnv_commit_to_store()

Definition: void pnv_commit_to_store(void)

Supported targets: All targets

Required license: None (Main library).

Description: Commit RAM data to non-volatile store.

Update the checksum for the non-volatile data, and if the data is stored in Flash, then write the data to Flash.

Warning

This function merely queues the saving of data and returns, so application execution is unaffected. If the data must be committed to memory as part of a power-down sequence, follow this by a call to pfs_flush_all to ensure the data write is complete before powering off.

Note

Old adaptive data is reused so long as it has the expected total data size and was written by an application with the same user-specified version number. Otherwise the values revert to defaults. If the usage of adaptive parameters has changed in a new software version, increase the application sub-minor version

Copyright 2019, Pi Innovo 300 Library interface

number to ensure that any old values are not used, as they may not map appropriately to the parameters in the new application even if the total data size happens to match.

5.19.4.5.2. pnv_is_store_intact()

Definition: BOOL pnv_is_store_intact(void)

Supported targets: All targets

Required license: None (Main library).

Description: Test whether there are adaptive data changes not yet committed to NV store.

Return: True if there are no adaptive data changes since the last commit to the non-volatile store (from calling pnv_commit_to_store()), false otherwise 5.19.4.5.3. pnv_adap_map_1d_f32()

Definition: PNV_RC_T pnv_adap_map_1d_f32(F32 pnvf_adapt_xx, F32 pnvf_adapt_increment, BOOL pnvf_adapt, BOOL pnvf_reset, S32 pnvf_n, volatile const F32 *pnvf_px, volatile const F32 *pnvf_pz_default, F32 *pnvf_pzz)

Supported targets: All targets

Required license: None (Main library).

Description: 1D table adaption, lookup and interpolation.

Linearly interpolates between map elements when input is within the map's range (possibly adapting or resetting the table data before the lookup and interpolation). Clips to the x-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors: PNV_ADAPMAP_INVALID_ARG.

Note

The 1d lookup is of function z(x). The use of z as the function name, rather than y, is chosen to be consistent with the 2d lookup function.

See pnv_adapmap_2d_f32() for 2d table adaptive lookup.

See put_calmap_1d_f32() and put_calmap_2d_f32() for table lookups without adaption.

Copyright 2019, Pi Innovo 301 Library interface

Arg (data in): pnvf_adapt_xx The argument to z(x), a point on the x-axis for interpolation.

Arg (data in): pnvf_adapt_increment The adaption increment, applied proportionately over interpolated values.

Arg (data in): pnvf_adapt Set true to adapt the adaptive table based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset Set true to reset the adaptive table to its default (pnvf_pz_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_n The number of elements in the x-axis and z-data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_scalar_f32() for a scalar function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_px Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing. Cannot be NULL.

Arg (data in): pnvf_pz_default Pointer to array of the map's default z-data. The default z-data is used to overwrite the adaptive map's z-data if the pnvf_reset parameter is true. The map which this pointer references must be declared with the OE_ADAP macro. Cannot be NULL.

Arg (data out): pnvf_pzz Pointer to interpolated output (possibly adapted or reset). Cannot be NULL.

Return:

• PNV_RC_BAD_ARGS - if the input parameters are invalid

• PNV_RC_INSUFFICIENT_ELEMENTS - if there are insufficient elements to use the function

• PNV_RC_OK - if operation is successful 5.19.4.5.4. pnv_adap_map_2d_f32()

Definition: PNV_RC_T pnv_adap_map_2d_f32(F32 pnvf_adapt_xx, F32 pnvf_adapt_yy, F32 pnvf_adapt_increment, BOOL pnvf_adapt, BOOL pnvf_reset, S32 pnvf_nx, S32 pnvf_ny, volatile const F32 *pnvf_px, volatile const F32 *pnvf_py, volatile const F32 *pnvf_pz_default, F32 *pnvf_pzz)

Supported targets: All targets

Copyright 2019, Pi Innovo 302 Library interface

Required license: None (Main library).

Description: 2D table adaption, lookup and interpolation.

Bilinearly interpolates between map elements when input is within the map's range (possibly adapting or resetting the table data before the lookup and interpolation). Clips to the x-axis and y-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors: PNV_ADAPMAP_INVALID_ARG.

Note

See put_adapmap_1d_f32() for 1d table lookup with adaption.

See pnv_calmap_1d_f32() and pnv_calmap_2d_f32() for table lookups without adaption.

Arg (data in): pnvf_adapt_xx The argument to z(x,y), a point on the x-axis for interpolation.

Arg (data in): pnvf_adapt_yy The argument to z(x,y), a point on the y-axis for interpolation.

Arg (data in): pnvf_adapt_increment The adaption increment, applied proportionately over interpolated values.

Arg (data in): pnvf_adapt Set true to adapt the adaptive table based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset Set true to reset the adaptive table to its default (pnvf_pz_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_nx The number of elements in the x-axis and z(x,) data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_map_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_ny The number of elements in the y-axis and z(,y) data. If the number of elements is less than two (2), the output is set to zero and an error is returned (instead call pnv_adap_map_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the y-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): pnvf_px Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing.

Copyright 2019, Pi Innovo 303 Library interface

Cannot be NULL.

Arg (data in): pnvf_py Pointer to array of the map's y-axis. The values stored in the y-axis array must be monotonically increasing or decreasing. Cannot be NULL.

Arg (data in): pnvf_pz_default Pointer to array of the map's default z-data. The default z-data is used to overwrite the adaptive map's z-data if the pnvf_reset parameter is true. The map which this pointer references must be declared with the OE_ADAP macro. Cannot be NULL.

Arg (data out): pnvf_pzz Pointer to interpolated output (possibly adapted or reset). Cannot be NULL.

Return:

• PNV_RC_BAD_ARGS - if the input parameters are invalid

• PNV_RC_INSUFFICIENT_ELEMENTS - if there are insufficient elements to use the function

• PNV_RC_OK - if operation is successful 5.19.4.5.5. pnv_adap_scalar_f32()

Definition: void pnv_adap_scalar_f32(F32 pnvf_adapt_increment, BOOL pnvf_adapt, BOOL pnvf_reset, volatile const F32 *pnvf_adapt_default, F32 *pnvf_adapted)

Supported targets: All targets

Required license: None (Main library).

Description: Adaptive scalar update.

Returns a scalar held in non-volatile memory after possibly adapting its value.

Can raise the following errors: PNV_ADAPSCALAR_INVALID_ARG.

Arg (data in): pnvf_adapt_increment The adaption increment to be applied to the scalar value.

Arg (data in): pnvf_adapt Set true to adapt the adaptive scalar based on the adaption increase (pnvf_adapt_increment), set false for no adaption. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Arg (data in): pnvf_reset Set true to reset the adaptive scalar to its default (pnvf_adapt_default), set false for no reset. If both pnvf_adapt and pnvf_reset are set true, then no adaption occurs.

Copyright 2019, Pi Innovo 304 Library interface

Arg (data in): pnvf_adapt_default Pointer to scalar's default value. The default value is used to overwrite the adaptive scalar's value if the pnvf_reset parameter is true. The calibration which this pointer represents must be declared with the OE_ADAP macro. Cannot be NULL.

Arg (data out): pnvf_adapted Pointer to adapted output. Cannot be NULL.

5.19.4.5.6. pnv_is_ram_adap_csum_valid()

Definition: BOOL pnv_is_ram_adap_csum_valid(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return the state of RAM adaptive checksum.

Return: True if RAM checksum intact, false otherwise.

5.19.4.5.7. pnv_is_flash_adap_csum_valid()

Definition: BOOL pnv_is_flash_adap_csum_valid(void)

Supported targets: All targets

Required license: None (Main library).

Description: Return the state of Flash adaptive checksum.

Return: True if Flash checksum intact, false otherwise.

5.19.4.5.8. pnv_array()

Definition: void pnv_array(U32 pnvf_index, volatile const void *pnvf_new_value, BOOL pnvf_change, BOOL pnvf_reset, U32 pnvf_elem_size, S32 pnvf_n, volatile const void *pnvf_array_default, BOOL *pnvf_valid_index, void *pnvf_value)

Supported targets: All targets

Required license: None (Main library).

Copyright 2019, Pi Innovo 305 Library interface

Description: Non-volatile array read and write functionality.

Detailed description of functionality: This block is similar to the pnv_adaptive_map1d block. It can store an array of values in non-volatile memory, change individual elements of the array and read individual elements out of the array (but does not interpolate entries as the pnv_adaptive_map1d block does). The DDE type for arrays use the v character in the DDE naming scheme (similar to the use of the c character when declaring scalar calibrations).

Can raise the following errors: PNV_ARRAY_INVALID_ARG.

Arg (data in): pnvf_index The index to the array element to access. Range: [0, { pnvf_n - 1 }]

Arg (data in): pnvf_new_value A pointer to the new value to write to the array index. Written only if pnvf_change is true and pnvf_reset is false. As the parameter is a void pointer, the size in bytes of the new value to write is given by pnvf_elem_size. Cannot be NULL.

Arg (data in): pnvf_change Set true to change the adaptive based on the new value (pnvf_new_value), set false for no change. If both pnvf_change and pnvf_reset are set true, then no change occurs.

Arg (data in): pnvf_reset Set true to reset the adaptive to its default (pnvf_array_default), set false for no reset. If both pnvf_change and pnvf_reset are set true, then no change occurs.

Arg (data in): pnvf_elem_size The size of each array element in bytes. Must be greater than zero.

Arg (data in): pnvf_n The number of elements in the adaptive array. Must be greater than zero.

Arg (data in): pnvf_array_default Pointer to array's default contents. The contents are used to overwrite the adaptive array's contents if the pnvf_reset parameter is true. The array which this pointer represents must be declared with the OE_ADAP macro. Cannot be NULL.

Arg (data out): pnvf_valid_index Pointer to boolean to be written with the result of whether the array index (pnvf_index) is valid or not. Cannot be NULL.

Arg (data out): pnvf_value Pointer to memory to be written with the array element referenced by pnvf_index. If the array index (pnvf_index) is invalid, then the first element of the array is written to the memory pointed to by pnvf_value. Cannot be NULL.

Copyright 2019, Pi Innovo 306 Library interface

5.19.4.5.9. pnv_array_dump()

Definition: void pnv_array_dump(U32 pnvf_elem_size, S32 pnvf_num_elems, volatile const void *pnvf_array_default, void *pnvf_output)

Supported targets: All targets

Required license: None (Main library).

Description: Non-volatile array output facility.

Detailed description of functionality: This function will dump the entire contents of the adaptive array specified by the third argument to a memory location specified by the fourth argument. The size of the array in bytes is inferred from the first two arguments here, namely the number of bytes per element in the array, and the total number of elements in the array. Note that the DDE type for calibratable arrays uses the v character in the DDE naming scheme (similar to the use of the c character when declaring scalar calibrations).

Can raise the following errors: PNV_ARRAY_DUMP_INVALID_ARG

Arg (data in): pnvf_elem_size The size of each array element in bytes.

Arg (data in): pnvf_num_elems The number of elements in the adaptive array.

Arg (data in): pnvf_array_default Pointer to array's default contents. This is just used to identify the true adaptive array. Cannot be NULL.

Arg (data out): pnvf_output Pointer to memory to be written with the entire contents of the adaptive array. Cannot be NULL. 5.20. Non-volatile Filesystem feature (PFS) 5.20.1. Overview

The library's nonvolatile filesystem feature manages the storage of data persistently across power cycles. It is used by the library to store data such as DTCs and adaptive parameters, but can also be used by application code. To achieve this it emulates the operations of a simple disk drive, with operations to read, write and delete files at run time.

The filesystem feature is only available on the targets: All targets.

On these targets it uses particular features of the microcontroller's flash memory to allow "background" operations, so writing of data can continue while the application executes as normal. This means that operations such as file writing or deletion do not occur immediately when requested, but are queued to take place in parallel with other application processing.

Copyright 2019, Pi Innovo 307 Library interface

Facilities are provided to allow the application to determine when a queued operation is complete. 5.20.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pfs.h Macros PFS_FTYPE_PLATFORM

File IDs with this bit set are reserved for platform use. PFS_FTYPE_RESERVED

The use of this bit in file IDs is reserved for future use. PFS_FTYPE_READONLY

The use of this bit in file IDs indicates a file which must not be deleted in any future 'delete all' operation. PFS_ORIGIN_YEAR

Build timestamps as returned by pfs_fstat() are stored in a compressed format. PFS_DATESTAMP_SEC_PER_BIT

Build timestamps as returned by pfs_fstat() are stored in a compressed format. Enumerations PFS_ERROR_T

Error values for debugging when an error is found in a call to the PFS API, the feature calls a function with an enumeration from this type. Data types PFS_FILESYS_STATS_T

Structure which conveys statistical information about the current status of the non-volatile filesystem. PFS_FILE_STATS_T

Structure which conveys statistical information about the current status of one file in the filesystem. PFS_REVISION_T

The type used to store file revision (version) number. PFS_FILE_ID_T

The type used to represent a file ID (equivalent to a filename, but simply a compact numerical type). Variables

Copyright 2019, Pi Innovo 308 Library interface

Type Identifier const U16 pfs_max_num_user_files

Maximum number of simultaneous application-specific files supported. Functions PFS_RC_T pfs_fread

Reads all or part of a file and places data at client- provided location. BOOL pfs_is_newer

Determines if one revision number is newer than another, taking account of integer wraparound. PFS_RC_T pfs_fwrite_queue

Queues a file for writing, where the source data is provided as a contiguous region of memory identified by a start pointer and length. PFS_RC_T pfs_get_filesystem_stats

Obtains statistical information on the current state of the filesystem. PFS_RC_T pfs_get_file_id_by_idx

Obtains the file ID of the file currently at the provided index position in the sorted directory listing of files maintained by the filesystem. PFS_RC_T pfs_fstat

Obtains statistical information on a file. PFS_RC_T pfs_fdelete_queue

Queues a request to mark a file as deleted. U32 pfs_encode_time

Converts a calendar time and date into the compact form used in files. void pfs_flush_all

Ensures all file write and delete operations are complete before returning. void pfs_lock_filesystem

Suspends filesystem operations including the copying of client data during file writes. void pfs_unlock_filesystem

Resumes filesystem operations including the copying of client data during file writes.

Copyright 2019, Pi Innovo 309 Library interface

5.20.3. Interface detail 5.20.3.1. Macros 5.20.3.1.1. PFS_FTYPE_PLATFORM

Definition: #define PFS_FTYPE_PLATFORM 0x8000

Description:

File IDs with this bit set are reserved for platform use.

User applications may not write or delete such files. 5.20.3.1.2. PFS_FTYPE_RESERVED

Definition: #define PFS_FTYPE_RESERVED 0x4000

Description:

The use of this bit in file IDs is reserved for future use.

User applications may not write or delete files with this bit set in the file ID. 5.20.3.1.3. PFS_FTYPE_READONLY

Definition: #define PFS_FTYPE_READONLY 0x2000

Description:

The use of this bit in file IDs indicates a file which must not be deleted in any future 'delete all' operation.

User applications may create files with this ID set. A specific request to delete such a file will succeed however. 5.20.3.1.4. PFS_ORIGIN_YEAR

Definition: #define PFS_ORIGIN_YEAR 2010

Description:

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

A zero value corresponds to 00:00 on 1 January of this year. 5.20.3.1.5. PFS_DATESTAMP_SEC_PER_BIT

Definition: #define PFS_DATESTAMP_SEC_PER_BIT 180

Description:

Build timestamps as returned by pfs_fstat() are stored in a compressed format.

This constant defines the resolution of the timestamp values.

Copyright 2019, Pi Innovo 310 Library interface

5.20.3.2. Enumerations 5.20.3.2.1. PFS_ERROR_T

Summary: Error values for debugging when an error is found in a call to the PFS API, the feature calls a function with an enumeration from this type.

Enumerations:

PFS_ECC_ERROR_DURING_FLASH_OP Error raised if the PGN requested function finds an invalid function argument.

PFS_RUNTIME_CORRUPT_FILE_FOUND Error raised if the PG receive function finds an invalid function argument. 5.20.3.3. Data types 5.20.3.3.1. PFS_FILESYS_STATS_T

Summary: Structure which conveys statistical information about the current status of the non-volatile filesystem.

Members:

S32 PFS_FILESYS_STATS_T::byte_capacity The total raw space available for file storage.

This includes the overhead of storing metadata and padding, but does not include the duplication of space in different flash memory blocks.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_used The total raw space currently used by files, metadata and padding.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_total_size The total raw space allocated to the non-volatile filesystem, summing all the space in the flash memory blocks allocated to it.

Range: [0, 262143] bytes

S32 PFS_FILESYS_STATS_T::bytes_bad The total space which has been found to contain invalid data or for which flash programming operations failed.

This is reset to zero on power-up, and then any invalid data found already present in the system contributes to this total before any file writes are attempted.

Range: [0, 262143] bytes

U32 PFS_FILESYS_STATS_T::lifetime_erases The total number of times that a flash erase operation has been started on any block allocated to the filesystem.

Range: [0, 16777215] erases

Copyright 2019, Pi Innovo 311 Library interface

PFS_REVISION_T PFS_FILESYS_STATS_T::head_revision The revision number of the most recent event (file write, delete, erase etc) that has been attempted in the filesystem.

Range: [0, 65535]

S16 PFS_FILESYS_STATS_T::user_files The number of valid, completely written files currently present in the filesystem belonging to the application.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::platform_files The number of valid, completely written files currently present in the filesystem with platform-reserved IDs.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::total_files The total number of valid, completely written files currently present in the filesystem.

Range: [0, max_files]

S16 PFS_FILESYS_STATS_T::failed_writes The number of times since the most recent power-on that the system failed to successfully write a file.

Range: [0, 32767]

S16 PFS_FILESYS_STATS_T::discarded_files The number of times since the most recent power-on that the system ignored a file it found on disk because its directory space was already full.

As different versions of the file may be found on disk, this may be larger than the number of unique files which were discarded.

Range: [0, 32767]

S16 PFS_FILESYS_STATS_T::runtime_corrupt_files The number of files that have been detected by runtime processing to be corrupt since power-on.

Range: [0, 32767]

S8 PFS_FILESYS_STATS_T::blocks The number of separate flash memory blocks used by the filesystem to achieve redundant storage.

Range: [2, 7]

S8 PFS_FILESYS_STATS_T::active_block_idx The zero-based index of the flash memory block to which file writes are currently being made.

Range: [0, 7]

Description:

Structure which conveys statistical information about the current status of the non-volatile filesystem.

See also pfs_get_filesystem_stats().

Copyright 2019, Pi Innovo 312 Library interface

5.20.3.3.2. PFS_FILE_STATS_T

Summary: Structure which conveys statistical information about the current status of one file in the filesystem.

Members:

S32 PFS_FILE_STATS_T::size_bytes The size of the actual useful data contained in the file, excluding any overhead or padding.

Range: [0, 262143] bytes

S32 PFS_FILE_STATS_T::disk_bytes The size of flash memory consumed by this file in the filesystem, including metadata overhead and any padding.

Range: [0, 262143] bytes

U32 PFS_FILE_STATS_T::encoded_build_time The timestamp of the application software build responsible for the last write of this file.

See also PFS_DATESTAMP_SEC_PER_BIT and PFS_ORIGIN_YEAR.

Range: [0, 16777215]

PFS_REVISION_T PFS_FILE_STATS_T::revision The revision number of the file stored in the system.

Range: [0, 65535]

U16 PFS_FILE_STATS_T::user_data Data provided by the client when the file was written.

This can be used for example to define a use-specific layout version, such that the client can interpret old files correctly if the format has changed. This is kept separate from the actual file data to allow that to consist of equal-sized records (see pfs_fwrite_simple_queue()).

Range: [0, 65535]

U8 PFS_FILE_STATS_T::app_ver_major The major version number of the application software build responsible for the last write of this file, e.g.

"2" in version "2.7.13".

Range: [0, 255]

U8 PFS_FILE_STATS_T::app_ver_minor The minor version number of the application software build responsible for the last write of this file, e.g.

"7" in version "2.7.13".

Range: [0, 255]

U8 PFS_FILE_STATS_T::app_ver_subminor The sub-minor version number of the application software build responsible for the last write of this file, e.g.

Copyright 2019, Pi Innovo 313 Library interface

"13" in version "2.7.13".

Range: [0, 255]

BOOL PFS_FILE_STATS_T::on_disk Whether this file is already safely stored in the filesystem.

For a new file, this becomes TRUE when the write process has completed.

BOOL PFS_FILE_STATS_T::write_queued Whether this file has a write or delete operation queued or in progress.

BOOL PFS_FILE_STATS_T::this_build_wrote Whether this file was written by software matching the build timestamp of the currently executing application software.

BOOL PFS_FILE_STATS_T::this_ver_wrote Whether this file was written by software matching the build version (e.g.

"2.3.17") of the currently executing application software.

Description:

Structure which conveys statistical information about the current status of one file in the filesystem.

Except where stated otherwise, each statistic refers to the file already stored on disk, and not to any new version for which a write operation is in progress.

See also pfs_fstat(). 5.20.3.3.3. PFS_REVISION_T

Definition: typedef U16 PFS_REVISION_T

Description: The type used to store file revision (version) number.

Revision numbers eventually wrap around to zero and start counting up again from there. The revision number applies to the whole filesystem (similar to the use in the Subversion system). See also pfs_is_newer(). 5.20.3.3.4. PFS_FILE_ID_T

Definition: typedef U16 PFS_FILE_ID_T

Description: The type used to represent a file ID (equivalent to a filename, but simply a compact numerical type). 5.20.3.4. Variables 5.20.3.4.1. pfs_max_num_user_files

Definition: const U16 pfs_max_num_user_files

Copyright 2019, Pi Innovo 314 Library interface

Description: Maximum number of simultaneous application-specific files supported.

This is currently fixed, but could in future be a C-API specified item to support applications that need to write a large number of different files. 5.20.3.5. Functions

5.20.3.5.1. pfs_fread()

Definition: PFS_RC_T pfs_fread(PFS_FILE_ID_T pfsf_file_id, U32 pfsf_byte_offset, U8 *pfsf_dest_ptr, U32 pfsf_max_bytes, U32 *pfsf_actual_bytes)

Supported targets: All targets

Required license: None (Main library).

Description: Reads all or part of a file and places data at client-provided location.

Arg (data in): pfsf_file_id ID of file to read (numeric equivalent of filename) Range: [0, 65535]

Arg (data in): pfsf_byte_offset Byte offset from start of file at which to start reading; zero to start from beginning of file Range: [0, 16777215]

Arg (data in,out): pfsf_dest_ptr Location to write the file data to; cannot be NULL

Arg (data in): pfsf_max_bytes Maximum size of data to read from file, or zero to read whole file Range: [0, 16777215]

Arg (data in,out): pfsf_actual_bytes Pointer to location in which to place the number of bytes that were read from the file; can be NULL Range: [0, 16777215]

Return: PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred

5.20.3.5.2. pfs_is_newer()

Definition: BOOL pfs_is_newer(PFS_REVISION_T pfsf_old_revision, PFS_REVISION_T pfsf_new_revision)

Supported targets: All targets

Required license: None (Main library).

Copyright 2019, Pi Innovo 315 Library interface

Description: Determines if one revision number is newer than another, taking account of integer wraparound.

Arg (data in): pfsf_new_revision The revision number which is expected to be older. Range: [0, 65535]

Arg (data in): pfsf_old_revision The revision number which is expected to be newer. Range: [0, 65535]

Return: TRUE if the expected newer revision was indeed newer than the expected older revision, otherwise FALSE. 5.20.3.5.3. pfs_fwrite_queue()

Definition: PFS_RC_T pfs_fwrite_queue(PFS_FILE_ID_T pfsf_file_id, const U8 *pfsf_src_ptr, S32 pfsf_byte_len, U16 pfsf_user_data, S16 pfsf_coherent_copy_size)

Supported targets: All targets

Required license: None (Main library).

Description: Queues a file for writing, where the source data is provided as a contiguous region of memory identified by a start pointer and length.

This function returns immediately and the file write continues in the background. Use pfs_fstat to determine when the file write has completed successfully.

Arg (data in): pfsf_file_id ID of file to write (numeric equivalent of filename) Range: [0, 65535]

Arg (data in): pfsf_src_ptr First byte location containing data to be written to file

Arg (data in): pfsf_byte_len Number of bytes to write Range: [0, 16777215]

Arg (data in): pfsf_user_data User-specific data to store as part of file metadata; for example, this might convey format information relating to the content of the file. It can be retrieved using pfs_fstat(). This is separate from the actual file content, so that the latter can consist of equal-sized records (where appropriate) for coherent writing. Range: [0, 65535]

Arg (data in): pfsf_coherent_copy_size The filesystem will copy the provided data in multiples of this size, and prevent execution of the client task during the copy operation. For example, if the data to be saved consists of an array of structures each of 6 bytes in size, set this to 6 to ensure the filesystem always reads a whole struct at a time. A value of zero means "don't care".

Copyright 2019, Pi Innovo 316 Library interface

If a write is in progress, the client can temporarily suspend it by using pfs_lock_filesystem while updating its data.

Together these facilities mean it is possible to ensure that the data saved to a file never consists of an incoherent copy containing both 'old' and 'new' data, as updated by the client, so long as the data is organised in equal-sized records like this. Range: [0, 16]

Return: PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred 5.20.3.5.4. pfs_get_filesystem_stats()

Definition: PFS_RC_T pfs_get_filesystem_stats(PFS_FILESYS_STATS_T *pfsf_stats)

Supported targets: All targets

Required license: None (Main library).

Description: Obtains statistical information on the current state of the filesystem.

See also documentation for PFS_FILESYS_STATS_T.

Arg (data in,out): pfsf_stats Pointer to structure provided by caller into which the statistics should be placed. Cannot be NULL.

Return: PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred 5.20.3.5.5. pfs_get_file_id_by_idx()

Definition: PFS_RC_T pfs_get_file_id_by_idx(U16 pfsf_file_idx, PFS_FILE_ID_T *pfsf_file_id_ptr)

Supported targets: All targets

Required license: None (Main library).

Description: Obtains the file ID of the file currently at the provided index position in the sorted directory listing of files maintained by the filesystem.

Client code can use this function to discover what files are available in the filesystem for reading.

Return: PFS_RC_OK if successful, PFS_RC_OUT_OF_RANGE if no file exists at that index in the list, or another PFS_RC_T value for other error conditions.

Copyright 2019, Pi Innovo 317 Library interface

5.20.3.5.6. pfs_fstat()

Definition: PFS_RC_T pfs_fstat(PFS_FILE_ID_T pfsf_file_id, PFS_FILE_STATS_T *pfsf_file_stats)

Supported targets: All targets

Required license: None (Main library).

Description: Obtains statistical information on a file.

See also documentation for PFS_FILE_STATS_T.

Arg (data in): pfsf_file_id ID of file of interest (numeric equivalent of filename) Range: [0, 65535]

Arg (data in,out): pfsf_file_stats Pointer to structure provided by caller into which the statistics should be placed. Cannot be NULL.

Return: PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred 5.20.3.5.7. pfs_fdelete_queue()

Definition: PFS_RC_T pfs_fdelete_queue(PFS_FILE_ID_T pfsf_file_id)

Supported targets: All targets

Required license: None (Main library).

Description: Queues a request to mark a file as deleted.

This function returns immediately and the file delete process continues in the background. Use pfs_fstat to determine when the file deletion has completed successfully.

Arg (data in): pfsf_file_id ID of file to delete (numeric equivalent of filename) Range: [0, 65535]

Return: PFS_RC_OK if successful, otherwise one of PFS_RC_T constants indicating an error occurred 5.20.3.5.8. pfs_encode_time()

Definition: U32 pfs_encode_time(U16 pfsf_sec, U16 pfsf_min, U16 pfsf_hour, U16 pfsf_day, U16 pfsf_month, U16 pfsf_year)

Copyright 2019, Pi Innovo 318 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Converts a calendar time and date into the compact form used in files.

See also documentation for PFS_FILE_STATS_T.

Arg (data in): pfsf_sec Seconds value of time to encode Range: [0, 59]

Arg (data in): pfsf_min Minutes value of time to encode Range: [0, 59]

Arg (data in): pfsf_hour Hour value (in 24 hour system) of time to encode Range: [0, 23]

Arg (data in): pfsf_day Day of month of date to encode Range: [1, 31]

Arg (data in): pfsf_month Month of date to encode Range: [1, 12]

Arg (data in): pfsf_year Year value of date to encode Range: [2010, 2099]

Return: Encoded compact timestamp. Always succeeds, as all input values are forced to comply with their allowed range. 5.20.3.5.9. pfs_flush_all()

Definition: void pfs_flush_all(void)

Supported targets: All targets

Required license: None (Main library).

Description: Ensures all file write and delete operations are complete before returning.

Warning

This function suspends normal application execution until it returns. It is suitable only for calling as part of a managed power-down operation, or in applications with no hard real-time constraints.

Copyright 2019, Pi Innovo 319 Library interface

5.20.3.5.10. pfs_lock_filesystem()

Definition: void pfs_lock_filesystem(void)

Supported targets: All targets

Required license: None (Main library).

Description: Suspends filesystem operations including the copying of client data during file writes.

This can be used together with the coherent copy size parameter of pfs_fwrite_queue to ensure that the filesystem does not write a file containing an incoherent mixture of old and new data in one record, should the client need to update a record during a file write.

Warning

Do not use this function unnecessarily, because it will suspend the execution of all other application tasks until pfs_unlock_filesystem is called.

Note

This is also used internally by the filesystem feature to ensure integrity of the data structures during operations that modify the queue of write operations or the directory list of files.

5.20.3.5.11. pfs_unlock_filesystem()

Definition: void pfs_unlock_filesystem(void)

Supported targets: All targets

Required license: None (Main library).

Description: Resumes filesystem operations including the copying of client data during file writes.

See pfs_lock_filesystem() for further details.

5.21. On-board external flash (PEF) 5.21.1. Overview

The library's on-board external (serial) flash feature manages the storage of data persistently across power cycles. It can be used by application code for the storage and retrieval of data. The flash memory can be bulk erased or sector erased when required by the application.

Copyright 2019, Pi Innovo 320 Library interface

The PEF feature is not currently supported. 5.21.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pef.h Functions BOOL pef_get_lock

Get the access lock, but only if already free (unlocked). void pef_release_lock

Releases the access lock, regardless if already locked. BOOL pef_is_available

Gets the flash device availability status. void pef_get_identification

Gets the flash device identification information. PEF_RC_T pef_read_status

Read the status register from the external serial flash device. BOOL pef_busy

Determines if the device is busy, should be used primarily to confirm the completion of an erase or write operation. PEF_RC_T pef_read

Read data from the external serial flash device. PEF_RC_T pef_write

Write data to the external serial flash device. PEF_RC_T pef_erase_sector

Erase a sector of external serial flash memory. PEF_RC_T pef_erase_all

Erase all the external serial flash memory. 5.21.3. Interface detail 5.21.3.1. Functions

5.21.3.1.1. pef_get_lock()

Definition: BOOL pef_get_lock(void)

Copyright 2019, Pi Innovo 321 Library interface

Supported targets: None at the moment

Required license: None (Main library).

Description: Get the access lock, but only if already free (unlocked).

If the lock is not available the caller MUST not access any pef functions, they should wait and try again later!

Return: TRUE if lock was available, FALSE otherwise 5.21.3.1.2. pef_release_lock()

Definition: void pef_release_lock(void)

Supported targets: None at the moment

Required license: None (Main library).

Description: Releases the access lock, regardless if already locked.

Therefore this should only be done if the caller has the lock!

5.21.3.1.3. pef_is_available()

Definition: BOOL pef_is_available(void)

Supported targets: None at the moment

Required license: None (Main library).

Description: Gets the flash device availability status.

Return: TRUE if the expected flash device is detected 5.21.3.1.4. pef_get_identification()

Definition: void pef_get_identification(PEF_IDENTIFICATION_T *peff_identification)

Supported targets: None at the moment

Required license: None (Main library).

Description: Gets the flash device identification information.

Copyright 2019, Pi Innovo 322 Library interface

Arg (data out): peff_identification Identification information read from the flash device, 0xFFs returned if not present 5.21.3.1.5. pef_read_status()

Definition: PEF_RC_T pef_read_status(U8 *peff_status)

Supported targets: None at the moment

Required license: None (Main library).

Description: Read the status register from the external serial flash device.

Arg (data out): peff_status Set to the status byte read from the device, use the PEF_STATUS_xxx macros to mask the required bits

Return: PEF_RC_OK - if status read ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected

Note

The access lock should be obtained prior to calling this function and then released.

5.21.3.1.6. pef_busy()

Definition: BOOL pef_busy(void)

Supported targets: None at the moment

Required license: None (Main library).

Description: Determines if the device is busy, should be used primarily to confirm the completion of an erase or write operation.

Return: TRUE if the device is busy, ie a write or erase operation is in progress. FALSE otherwise, or no device is present!

Note

The access lock should be obtained prior to calling this function and then released.

5.21.3.1.7. pef_read()

Definition: PEF_RC_T pef_read(U32 peff_addr, U16 peff_size, U8 *peff_data)

Copyright 2019, Pi Innovo 323 Library interface

Supported targets: None at the moment

Required license: None (Main library).

Description: Read data from the external serial flash device.

Arg (data in): peff_addr Address in the device for data to be read from Range: [0, 2097150]

Arg (data in): peff_size Size of data to read, in bytes Range: [2, 2097152]

Arg (data in): peff_data Pointer to data structure to populate

Return: PEF_RC_OK - if data read ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/ erase operation is already in progress PEF_RC_ERR - peff_data is a NULL pointer PEF_RC_ERR_SIZE - if the size is not a multiple of 2 bytes PEF_RC_ERR_ALIGNMENT - if the address is not word aligned PEF_RC_ERR_ADDR_RANGE - if address is or would go out of range

Note

The access lock should be obtained prior to calling this function and then released.

Can only read in multiples of 2, therefore the size must be an even number and the address must be word aligned!

This function blocks the client until all the data has been read. This operation will potentially be slow for large data transfers.

5.21.3.1.8. pef_write()

Definition: PEF_RC_T pef_write(U32 peff_addr, U16 peff_size, const U8 *peff_data)

Supported targets: None at the moment

Required license: None (Main library).

Description: Write data to the external serial flash device.

Arg (data in): peff_addr Address in the device to write data to Range: [0, 2097150]

Arg (data in): peff_size Size of data to write, in bytes Range: [2, 2097152]

Arg (data out): peff_data Pointer to data to copy to flash memory

Copyright 2019, Pi Innovo 324 Library interface

Return: PEF_RC_OK - if data written ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress PEF_RC_ERR - peff_data is a NULL pointer, or a timeout occurred when writing PEF_RC_ERR_SIZE - if the size is not a multiple of 2 bytes PEF_RC_ERR_ALIGNMENT - if the address is not word aligned PEF_RC_ERR_ADDR_RANGE - if address is or would go out of range

Note

The access lock should be obtained prior to calling this function and then released.

Can only write in multiples of 2, therefore the size must be an even number and the address must be word aligned!

This function blocks the client until all the data has been written. This operation will potentially be slow for large data transfers.

5.21.3.1.9. pef_erase_sector()

Definition: PEF_RC_T pef_erase_sector(U32 peff_addr)

Supported targets: None at the moment

Required license: None (Main library).

Description: Erase a sector of external serial flash memory.

Arg (data in): peff_addr Address in the sector of the device to erase Range: [0, 2097151]

Return: PEF_RC_OK - if sector erase request sent ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress PEF_RC_ERR_ADDR_RANGE - if address is out of range

Note

The access lock should be obtained prior to calling this function and then released.

The given address can be anywhere within the sector to be erased.

5.21.3.1.10. pef_erase_all()

Definition: PEF_RC_T pef_erase_all(void)

Copyright 2019, Pi Innovo 325 Library interface

Supported targets: None at the moment

Required license: None (Main library).

Description: Erase all the external serial flash memory.

Return: PEF_RC_OK - if bulk erase request sent ok PEF_RC_ERR_NOT_AVAILABLE - if no device detected PEF_RC_ERR_BUSY - if some previous write/erase operation is already in progress

Note

The access lock should be obtained prior to calling this function and then released. 5.22. General utilities feature (PUT) 5.22.1. Overview 5.22.1.1. CRC calculation

The library provides a function to efficiently calculate a CRC on a section of memory, put_calc_crc(). The implemented CRC matches the CCITT 16-bit polynomial: x16 + x12 + x5 + 1. Broken sections of memory can be check-summed by chaining together calls to put_calc_crc(). 5.22.1.2. Table look-up and interpolation

The library provides two basic map look-up and interpolation functions. The 1-D version is accessed by calling put_cal_map_1d_f32(). The function works by interpreting the data its given as a simple 1-D map.

Figure 5.19. Map look-up

Z-data

z4

Output: z3 interpolated value

z2

z1

z0

x0 x1 x2 x3 x4 X-axis

There is a direct correspondence between the X-axis data points and the Z-data points (for instance, between x1 and z1). The function searches through the X-axis data points to find a bounding pair for the look-up value, then calculates the output value by linearly interpolating between the corresponding Z-data bounding pair.

Copyright 2019, Pi Innovo 326 Library interface

Figure 5.20. Map look-up with interpolation

Z-data

z4

Output: z3 interpolated value (bound by z2 and z3)

z2

z1

z0

x0 x1 x2 x3 x4 X-axis

Input: lookup point in X-axis (bound by x2 and x3)

The 2-D version is accessed by calling put_cal_map_2d_f32(). It works in a similar fashion to the 1-D version, but performs bi-linear interpolation instead. 5.22.1.3. Range checking

The library provides a set of range checking functions: put_range_check_f32(), put_range_check_s8(), put_range_check_s16() , put_range_check_s32() , put_range_check_u8(), put_range_check_u16() and put_range_check_u32(). 5.22.1.4. Signal debounce

The library provides two functions to debounce a logical signal: put_debounce_by_cycles() and put_debounce_by_time(). The debounce functions work by checking to see if the raw input signal is steady over a number of cycles (function calls) or over a duration of time. If the signal is steady, then the debounce function passes through the steady signal state. If the signal is unsteady, then the debounce functions passes through the last steady state.

The debounce functions might be used for removing glitches on external switches. 5.22.1.5. Slew rate checking

The library provides the put_slew_rate_check() function to detect a change in signal value over time, greater than might be expected.

The slew rate check function might be used for detecting a failed temperature sensor, where the rate of change of temperature is greater than possible. 5.22.1.6. Leaky bucket fault detection

The library provides two fault integration functions: put_leaky_bucket_u8() and put_leaky_bucket_f32(). The functions are modelled on the idea of a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly. When the bucket fills, the integration is complete and the fault is considered confirmed.

The leaky bucket fault detection function might be used to filter out sporadic transient fault conditions, in effect, ensuring that a fault has been present for long enough to be considered real.

Copyright 2019, Pi Innovo 327 Library interface

5.22.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and put.h Enumerations PUT_ERROR_CODE_T

Error values for debugging when an error is found when calling the utility API (PUT), the API calls a function with an enumeration from this type. PUT_LIST_OPTIONS_T

Enumeration for specifying the monotonicity of an ordered array when searching for a closest match. Data types PUT_DEBOUNCE_CYCLE_T

This type provides storage for persistent information across calls to the debounce-by-cycles function. PUT_DEBOUNCE_TIME_T

This type provides storage for persistent information across calls to the debounce-by-time function. PUT_LEAKY_BUCKET_T

This type provides storage for persistent information across calls to the leaky bucket function. PUT_SLEW_RATE_CHECK_T

This type provides storage for persistent information across calls to the slew rate check function. PUT_ANALOGUE_WORKSPACE_T

Structure to hold values for the analogue input processing function that requires persistence. PUT_ENH_ANALOGUE_WORKSPACE_T

Structure to hold values for the analogue input processing function that requires persistence. PUT_ANALOGUE_CAL_DATA_T

Structure to hold all items that are calibratable when calling the analogue input processing function. Functions void put_array_search_f32

Given an F32 value and an ordered array of F32 values, return the index of the array value closest to the requested value.

Copyright 2019, Pi Innovo 328 Library interface

Type Identifier void put_cal_map_1d_f32

1D table lookup and interpolation. void put_cal_map_2d_f32

2D table lookup and interpolation. U16 put_calc_crc

Calculate a 16-bit CRC value for a given memory block. U8 put_calc_crc_j1850

Calculate an 8-bit SAE-J1850 CRC value for a given memory block. void put_debounce_by_cycles_init

Initialisation routine for logical signal debounce (by cycles). U8 put_debounce_by_cycles

Logical signal debounce (by cycles). void put_debounce_by_time_init

Initialisation routine for logical signal debounce (by time). void put_debounce_by_time

Logical signal debounce (over time). void put_dutycycle_processing

Duty cycle scaling and inversion. void put_enh_process_analog_input_init

Enhanced Analogue input fault filter initialisation. void put_enh_process_analog_input

Enhanced Analogue input fault filter processing. U16 put_calc_ipv4_checksum

Calculate a 16-bit checksum value using the IPv4 header checksum algorithm. void put_leaky_bucket_f32

Fault filtering using a leaky bucket analogy. void put_leaky_bucket_f64

Fault filtering using a leaky bucket analogy. void put_leaky_bucket_init

Initialisation of leaky bucket fault filtering. void put_leaky_bucket_u8

Fault filtering using a leaky bucket analogy.

Copyright 2019, Pi Innovo 329 Library interface

Type Identifier PUT_POOL_RC_T put_pool_write PUT_POOL_RC_T put_pool_iterate_init BOOL put_pool_iterate_next BOOL put_pool_iterate_next_w_clear BOOL put_pool_iterate_clear PUT_POOL_RC_T put_pool_clear void put_process_analog_input_init

Analogue input fault filter initialisation. void put_process_analog_input

Analogue input fault filter processing. void put_range_check_f32

Vector range check (min and max) function for F32 types. void put_range_check_s16

Vector range check (min and max) function for S16 types. void put_range_check_s32

Vector range check (min and max) function for S32 types. void put_range_check_s8

Vector range check (min and max) function for S8 types. void put_range_check_u16

Vector range check (min and max) function for U16 types. void put_range_check_u32

Vector range check (min and max) function for U32 types. void put_range_check_u8

Vector range check (min and max) function for U8 types. void put_slew_rate_check_init

Initialisation routine for slew rate checking. BOOL put_slew_rate_check

Slew rate checking. void put_state_processing

State fault processing and inversion.

Copyright 2019, Pi Innovo 330 Library interface

5.22.3. Interface detail 5.22.3.1. Enumerations 5.22.3.1.1. PUT_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the utility API (PUT), the API calls a function with an enumeration from this type.

Enumerations:

PUT_CALMAP_INVALID_ARG Error raised if the one of the table lookup and interpolation functions find an invalid argument.

PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG Error raised if the debounce-by-cycles functions find an invalid argument.

PUT_LEAKY_BUCKET_INVALID_ARG Error raised if one of the leaky bucket functions find an invalid argument.

PUT_SLEW_RATE_CHECK_INVALID_ARG Error raised if one of the slew rate check functions find an invalid argument.

PUT_RANGE_CHECK_INVALID_ARG Error raised if one of the range check functions find an invalid argument.

PUT_DEBOUNCE_BY_TIME_INVALID_ARG Error raised if the debounce-by-time functions find an invalid argument.

PUT_DUTYCYCLE_PROCESSING_INVALID_ARG Error raised if the duty cycle processing function finds an invalid argument.

PUT_STATE_PROCESSING_INVALID_ARG Error raised if the state processing function finds an invalid argument.

PUT_ANALOG_INPUT_FILTER_INVALID_ARG Error raised if the analogue input filter function finds an invalid argument.

PUT_ARRAY_SEARCH_INVALID_ARG Error raised if the array search function finds an invalid argument. 5.22.3.1.2. PUT_LIST_OPTIONS_T

Summary: Enumeration for specifying the monotonicity of an ordered array when searching for a closest match.

Enumerations:

PUT_LIST_ASCENDING Search an array of values in ascending order.

Copyright 2019, Pi Innovo 331 Library interface

PUT_LIST_DESCENDING Search an array of values in descending order.

PUT_NUM_LIST_OPTIONS 5.22.3.2. Data types

5.22.3.2.1. PUT_DEBOUNCE_CYCLE_T

Summary: This type provides storage for persistent information across calls to the debounce-by-cycles function.

Members:

U8 PUT_DEBOUNCE_CYCLE_T::last_state The state of the input last time the debounce function was invoked.

Range: 0 or 1

U8 PUT_DEBOUNCE_CYCLE_T::steady_state The debounced steady state of the input.

Range: 0 or 1

U16 PUT_DEBOUNCE_CYCLE_T::cycle The number of cycles the input has been steady for.

Range: [0, 65535] cycles

5.22.3.2.2. PUT_DEBOUNCE_TIME_T

Summary: This type provides storage for persistent information across calls to the debounce-by-time function.

Members:

F32 PUT_DEBOUNCE_TIME_T::set_sum Persistent accumulator used to set the debounced output state.

F32 PUT_DEBOUNCE_TIME_T::reset_sum Persistent accumulator used to reset the debounced output state.

U8 PUT_DEBOUNCE_TIME_T::steady_state Debounced output signal.

Range: 0 or 1

5.22.3.2.3. PUT_LEAKY_BUCKET_T

Summary: This type provides storage for persistent information across calls to the leaky bucket function.

Members:

F32 PUT_LEAKY_BUCKET_T::bucket_level This is the level of the bucket for a given fault last time the leaky bucket function was called for that fault.

Copyright 2019, Pi Innovo 332 Library interface

BOOL PUT_LEAKY_BUCKET_T::last_cff True if the fault was confirmed last time the leaky bucket function was called for that fault.

5.22.3.2.4. PUT_SLEW_RATE_CHECK_T

Summary: This type provides storage for persistent information across calls to the slew rate check function.

Members:

F32 PUT_SLEW_RATE_CHECK_T::last_input This is the value of the input last time the slew check function was invoked.

U8 PUT_SLEW_RATE_CHECK_T::first_call True if the slew check function has not been called previously, false otherwise.

5.22.3.2.5. PUT_ANALOGUE_WORKSPACE_T

Summary: Structure to hold values for the analogue input processing function that requires persistence.

Members:

F32 PUT_ANALOGUE_WORKSPACE_T::last_raw_value Last raw value read in by the analogue channel.

This is used to establish if there is a slew rate fault on the input. It is initialised to 0.0.

F32 PUT_ANALOGUE_WORKSPACE_T::latched_engineering_value Latched engineering value for transient faults.

This is the last good engineering value output by the analogue input before a transient fault is detected. This value is output until the transient fault is no longer present. It is initialised to 0.0.

U8 PUT_ANALOGUE_WORKSPACE_T::confirmed_fault_present Flag to indicate if a confirmed fault has been detected.

This flag indicates if one or more transient faults have persisted long enough to be registered as a confirmed fault in the analogue input. A value of zero indicates that no fault is present whilst a value of one indicates that a fault has been detected. Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_max_raw_range_tff Flag to indicate the latched value of a transient fault flag for the raw value being greater than allowed.

If a confirmed fault is detected, this flag indicates if the raw input value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero. Range: [0, 1] unitless flag

Copyright 2019, Pi Innovo 333 Library interface

U8 PUT_ANALOGUE_WORKSPACE_T::latched_min_raw_range_tff Flag to indicate the latched value of a transient fault flag for the raw value being less than allowed.

If a confirmed fault is detected, this flag indicates if the raw input value was currently less than the minimum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero. Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_slew_rate_tff Flag to indicate the latched value of a transient fault flag for the slew rate being greater than allowed.

If a confirmed fault is detected, this flag indicates if the slew rate of the raw input value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero. Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_max_eng_range_tff Flag to indicate the latched value of a transient fault flag for the engineering value being greater than allowed.

If a confirmed fault is detected, this flag indicates if the engineering value was currently greater than the maximum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero. Range: [0, 1] unitless flag

U8 PUT_ANALOGUE_WORKSPACE_T::latched_min_eng_range_tff Flag to indicate the latched value of a transient fault flag for the engineering value being less than allowed.

If a confirmed fault is detected, this flag indicates if the engineering value was currently less than the minimum allowed value at the time the confirmed fault was detected. A value of 1 indicates the transient fault was present at that time and 0 otherwise. It is initialised to zero. Range: [0, 1] unitless flag

PUT_SLEW_RATE_CHECK_T PUT_ANALOGUE_WORKSPACE_T::slew_rate_data Structure to handle slew rate input check.

This structure contains the variable data required by the slew rate check.

PUT_LEAKY_BUCKET_T PUT_ANALOGUE_WORKSPACE_T::leaky_bucket_data Structure to handle leaky bucket fault filtering.

This structure contains the variable data required by the leaky bucket filtering. 5.22.3.2.6. PUT_ENH_ANALOGUE_WORKSPACE_T

Summary: Structure to hold values for the analogue input processing function that requires persistence.

Copyright 2019, Pi Innovo 334 Library interface

Members:

F32 PUT_ENH_ANALOGUE_WORKSPACE_T::last_raw_value Last raw value read in by the analogue channel.

This is used to establish if there is a slew rate fault on the input. It is initialised to 0.0.

F32 PUT_ENH_ANALOGUE_WORKSPACE_T::latched_engineering_value Latched engineering value for transient faults.

This is the last good engineering value output by the analogue input before a transient fault is detected. This value is output until the transient fault is no longer present. It is initialised to 0.0.

F32 PUT_ENH_ANALOGUE_WORKSPACE_T::leaky_bucket_levels[PUT_EPAI_NUM_LEAKY_BUCKETS] Arrays to handle leaky bucket fault filtering.

Note, memory is at a premium so we havent created an array of PUT_LEAKY_BUCKET_T here as there is excessive packing.

PUT_SLEW_RATE_CHECK_T PUT_ENH_ANALOGUE_WORKSPACE_T::slew_rate_data Structure to handle slew rate input check.

This structure contains the variable data required by the slew rate check. 5.22.3.2.7. PUT_ANALOGUE_CAL_DATA_T

Summary: Structure to hold all items that are calibratable when calling the analogue input processing function.

Members:

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::min_raw_value Minimum allowable raw value for the channel.

Pointer to the minimum allowable value of the raw measurement.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_raw_value Maximum allowable raw value for the channel.

Pointer to the maximum allowable value of the raw measurement.

volatile const S32* PUT_ANALOGUE_CAL_DATA_T::num_eng_lookup_elements Number of elements in the engineering map table.

Pointer to the number of elements in the lookup map that converts the raw measurement into an engineering value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::eng_lookup_x_axis Engineering lookup table X Axis array.

Pointer to the array that holds the x axis lookup values for converting the raw measurement into an engineering value. These correspond to a monotonically increasing or decreasing array of raw input values.

Copyright 2019, Pi Innovo 335 Library interface

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::eng_lookup_z_axis Engineering lookup table Z Axis array.

Pointer to the array that holds the z axis lookup values for converting the raw measurement into an engineering value. These correspond to a monotonically increasing or decreasing array of engineering output values.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::min_eng_value Minimum allowable engineering value for the channel.

Pointer to the minimum allowable value of the engineering value that has been derived from the raw value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_eng_value Maximum allowable engineering value for the channel.

Pointer to the maximum allowable value of the engineering value that has been derived from the raw value.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_rise_rate Leaky bucket rise rate for the channel.

Pointer to the rise rate for the leaky bucket used for fault filtering. This amount, multiplied by the sample rate for the channel, is added to the leaky bucket contents each time a transient fault is present. The bucket is clipped to a maximum value of 1.0.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_fall_rate Leaky bucket fall rate for the channel.

Pointer to the fall rate for the leaky bucket used for fault filtering. This amount, multiplied by the sample rate for the channel, is subtracted from the leaky bucket contents at each iteration of the function. The bucket is clipped to a minimum value of 0.0.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::leaky_bucket_fault_clear_level Leaky bucket value at which a confirmed fault is cleared.

Pointer to the clear fault level for the leaky bucket fault filter. Once a confirmed fault has been detected on the channel, the content of the leaky bucket must fall to less than this value in order to clear the fault. Range: [0.0, 1.0] unitless

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::default_output_value The value output by the channel if a confirmed fault is present.

Pointer to the engineering value that is output by the filter logic as long as a confirmed fault is present. This can be outside the range of the minimum and maximum engineering values used to determine if a transient fault is present.

volatile const F32* PUT_ANALOGUE_CAL_DATA_T::max_slew_rate The maximum slew rate allowed for the raw value.

Copyright 2019, Pi Innovo 336 Library interface

Pointer to the maximum allowed slew rate of the raw value. 5.22.3.3. Functions

5.22.3.3.1. put_array_search_f32()

Definition: void put_array_search_f32(const F32 *putf_array, const S32 putf_array_size, const F32 putf_input_value, S32 *putf_index_return, PUT_LIST_OPTIONS_T putf_search_order)

Supported targets: All targets

Required license: None (Main library).

Description: Given an F32 value and an ordered array of F32 values, return the index of the array value closest to the requested value.

Can raise the following errors: PUT_ARRAY_SEARCH_INVALID_ARG.

Arg (data in): putf_array Pointer to array of 32-bit floating point variables. Cannot be NULL.

Arg (data in): putf_array_size Number of elements in the putf_array array. Range: [1, 2147483647] elements

Arg (data in): putf_input_value The value for which the closest match is to be identified. Cannot be NULL.

Arg (data out): putf_index_return Pointer through which the index of the closest match is returned. Cannot be NULL.

Arg (data in): putf_search_order Indicates whether the array is a list of values that are increasing with index number or decreasing with index number. PUT_LIST_ASCENDING - values increase with index number PUT_LIST_DESCENDING - values decrease with index number

5.22.3.3.2. put_cal_map_1d_f32()

Definition: void put_cal_map_1d_f32(F32 putf_x, S32 putf_n, volatile const F32 *const putf_px, volatile const F32 *const putf_pz, F32 *putf_pzz)

Supported targets: All targets

Required license: None (Main library).

Description: 1D table lookup and interpolation.

Copyright 2019, Pi Innovo 337 Library interface

Linearly interpolates between map elements when input is within the map's range. Clips to the x-axis extremes that would otherwise result in extrapolation outside the map bounds.

Can raise the following errors: PUT_CALMAP_INVALID_ARG.

Note

The 1d lookup is of function z(x). The use of z as the function name, rather than y, is chosen to be consistent with the 2d lookup function.

See put_calmap_2d_f32() for 2d table lookup.

See pnv_adapmap_1d_f32() and pnv_adapmap_2d_f32() for table lookups with adaption.

Arg (data in): putf_x The argument to z(x), a point on the x-axis for interpolation.

Arg (data in): putf_n The number of elements in the x-axis and z-data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1, the output it set to the only z-data value. If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_px Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing. Cannot be NULL.

Arg (data in): putf_pz Pointer to array of the map's z-data. Cannot be NULL.

Arg (data out): putf_pzz Pointer to interpolated output. Cannot be NULL. 5.22.3.3.3. put_cal_map_2d_f32()

Definition: void put_cal_map_2d_f32(F32 putf_x, F32 putf_y, S32 putf_nx, S32 putf_ny, volatile const F32 *putf_px, volatile const F32 *putf_py, volatile const F32 *putf_pz, F32 *putf_pzz)

Supported targets: All targets

Required license: None (Main library).

Description: 2D table lookup and interpolation.

Bilinearly interpolates between map elements when input is within the map's range. Clips to the x-axis and y-axis extremes that would otherwise result in extrapolation outside the map bounds.

Copyright 2019, Pi Innovo 338 Library interface

Can raise the following errors: PUT_CALMAP_INVALID_ARG.

Note

See put_calmap_1d_f32() for 1d table lookup.

See pnv_adapmap_1d_f32() and pnv_adapmap_2d_f32() for table lookups with adaption.

Arg (data in): putf_x The argument to z(x,y), a point on the x-axis for interpolation.

Arg (data in): putf_y The argument to z(x,y), a point on the y-axis for interpolation.

Arg (data in): putf_nx The number of elements in the x-axis and z(x,) data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1 (i.e., a 1d lookup if putf_ny is greater than one), the output it set to the first z-data value (call put_calmap_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the x-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_ny The number of elements in the y-axis and z(,y) data. If the number of elements is less than 1, the output is set to zero. If the number of elements is 1 (i.e., a 1d lookup if putf_nx is greater than one), the output it set to the first z-data value (call put_calmap_1d_f32() for a 1d table lookup and interpolate function). If the number of elements is greater than 1, then the y-axis is searched for bounding breakpoints to perform the interpolation.

Arg (data in): putf_px Pointer to array of the map's x-axis data. The values stored in the x-axis array must be monotonically increasing or decreasing. Cannot be NULL.

Arg (data in): putf_py Pointer to array of the map's y-axis. The values stored in the y-axis array must be monotonically increasing or decreasing. Cannot be NULL.

Arg (data in): putf_pz Pointer to array of the map's z-data. The array lookup is performed as { putf_pz[(x-index * putf_ny) + y-index] } and the data definition must correspond. Cannot be NULL.

Arg (data out): putf_pzz Pointer to interpolated output. Cannot be NULL. 5.22.3.3.4. put_calc_crc()

Definition: U16 put_calc_crc(U16 putf_shift_reg, const U8 *putf_addr, U32 putf_len)

Copyright 2019, Pi Innovo 339 Library interface

Supported targets: All targets

Required license: None (Main library).

Description: Calculate a 16-bit CRC value for a given memory block.

The CRC polynomial is taken from the CCITT standard (x^16 + x^12 + x^5 + x^0), assumes that the initial value for the CRC register is 0xFFFF and that the bit-stream is reflected.

Note

Can be used to calculate a single CRC for multiple memory blocks - first call to put_calc_crc() should set the shift register to 0xFFFFu; subsequent calls should set the shift register to the return value of the previous call.

Arg (data in): putf_shift_reg The initial value of the CRC. Range: [0, 65535] unitless

Arg (data in): putf_addr Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len Length of memory block in bytes. Range: [0, 4294967295] bytes

Return: The calculated CRC. Range: [0, 65535] unitless

5.22.3.3.5. put_calc_crc_j1850()

Definition: U8 put_calc_crc_j1850(U8 putf_shift_reg, BOOL putf_start, BOOL putf_finish, const U8 *putf_addr, U32 putf_len)

Supported targets: All targets

Required license: None (Main library).

Description: Calculate an 8-bit SAE-J1850 CRC value for a given memory block.

The CRC polynomial is taken from the J1850 standard (x^8 + x^4 + x^3 + x^2 + x^0), with an intial value of 0xFF and a final one's complement.

Note

This can be used to calculate a single CRC for multiple memory blocks. To do this, in the first call to put_calc_crc_j1850() set

Copyright 2019, Pi Innovo 340 Library interface

putf_start=TRUE and putf_finish=FALSE; in intermediate calls, set both FALSE, passing the previous return value in through putf_shift_reg; and in the final call set setputf_start=FALSE and putf_finish=TRUE.

Arg (data in): putf_shift_reg The initial value of the CRC. Ignored if putf_start=TRUE. Range: [0, 255] unitless

Arg (data in): putf_start Whether to intialise the CRC to the standard value before starting, in which case the input value putf_shift_reg is ignored. Usually TRUE, but use FALSE if the function is being called again to continue an existing checksum over a further region of memory.

Arg (data in): putf_finish Whether to apply the final J1850-required one's complement operation to the computed CRC. Usually TRUE, but use FALSE if the function is to be called again to checksum an additional region of memory to include in the same overall calculation.

Arg (data in): putf_addr Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len Length of memory block in bytes. Range: [0, 4294967295] bytes

Return: The calculated CRC. Range: [0, 255] unitless

5.22.3.3.6. put_debounce_by_cycles_init()

Definition: void put_debounce_by_cycles_init(PUT_DEBOUNCE_CYCLE_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Initialisation routine for logical signal debounce (by cycles).

Initialise the debounce state information that persists between calls to put_debounce_by_cycles().

Can raise the following errors: PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG.

Arg (data in,out): putf_store A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_debounce_by_cycles_init(). Cannot be NULL.

Copyright 2019, Pi Innovo 341 Library interface

5.22.3.3.7. put_debounce_by_cycles()

Definition: U8 put_debounce_by_cycles(U8 putf_input, U16 putf_cycle_threshold, PUT_DEBOUNCE_CYCLE_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Logical signal debounce (by cycles).

Debounce the state of a logical input signal over a number of cycles (calls to this function). When the logical input signal is unchanged for the cycle threshold the signal is deemed steady and the debounced output state changes to the steady logical input state.

On the first call, the debounced output state is set to the logical input state.

Can raise the following errors: PUT_DEBOUNCE_BY_CYCLES_INVALID_ARG.

Arg (data in): putf_input The current state. Range: [0, 1] unitless

Arg (data in): putf_cycle_threshold The number of cycles of unchanging input required before the input state (putf_input) is deemed steady. Set to zero or one for no debounce. Range: [0, 65535] cycles

Arg (data in,out): putf_store A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_debounce_by_cycles_init(). Cannot be NULL.

Return: The debounced state. Range: [0, 1] unitless

5.22.3.3.8. put_debounce_by_time_init()

Definition: void put_debounce_by_time_init(PUT_DEBOUNCE_TIME_T *putf_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Initialisation routine for logical signal debounce (by time).

Copyright 2019, Pi Innovo 342 Library interface

This function initialises any persistent data for a logical signal prior to it first being called.

Can raise the following errors: PUT_DEBOUNCE_BY_TIME_INVALID_ARG.

Arg (data out): putf_channel_wrk_data Pointer to logical input signal workspace data structure. This provides persistence for data in between calls to the filter function.

5.22.3.3.9. put_debounce_by_time()

Definition: void put_debounce_by_time(U8 putf_raw_state, F32 putf_sample_rate, U8 putf_invert, F32 putf_set_dead_time, F32 putf_reset_dead_time, U8 *putf_debounced_state, PUT_DEBOUNCE_TIME_T *putf_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Logical signal debounce (over time).

Debounce the state of a logical input signal over time. When the logical input signal is unchanged for the time threshold the signal is deemed steady and the debounced output state changes to the steady logical input state.

The time for becoming steady set (value 1) and for becoming steady reset (value 0) are parameters to the function.

On the first call, the debounced output state is set to the logical input state.

Can raise the following errors: PUT_DEBOUNCE_BY_TIME_INVALID_ARG.

Arg (data in): putf_raw_state The value of the logical input signal (e.g., as obtained from a call to the pdx_digital_input() function). Range: 0 or 1.

Arg (data in): putf_sample_rate The rate at which this function is called for debounce computation (effectively the amount of time since the last call). Ideally this function should be called at the same rate as the input state sampling but the function can be called less frequently if necessary. As an example, if an input state must be checked 5 times within a debounce period of 1 second (for both set and reset steady states) then the function could be called every 200 milliseconds. Range: [0.001, 3600] seconds

Arg (data in): putf_invert Channel inversion. If inversion is set, then a logical NOT operation is applied to the input value before further processing.

Copyright 2019, Pi Innovo 343 Library interface

Arg (data in): putf_set_dead_time Set dead time. The time in seconds the input will have to be high, before the function switches its output from 0 to 1. A zero or negative value causes the debounced state to be set to the input state without delay.

Arg (data in): putf_reset_dead_time Reset dead time. The time in seconds the input will have to be low, before the function switches its output from 1 to 0. A zero or negative value causes the debounced state to be set to the input state without delay.

Arg (data out): putf_debounced_state Pointer to the value that will represent the output of the logical input debounced state. Cannot be NULL.

Arg (data in,out): putf_channel_wrk_data Pointer to logical signal channel workspace data structure. This provides persistence for data in between calls to the filter function. Cannot be NULL. 5.22.3.3.10. put_dutycycle_processing()

Definition: void put_dutycycle_processing(F32 putf_inp_duty_cycle, U8 putf_invert, U8 putf_fault, F32 putf_default, F32 putf_min, F32 putf_max, F32 *putf_out_duty_cycle)

Supported targets: All targets

Required license: None (Main library).

Description: Duty cycle scaling and inversion.

This function provides a scaling of the input duty cycle as follows: scaled_duty_cycle = (input_duty_cycle * (max - min)) + min

If inversion is set the scaled duty cycle is converted as follows: scaled_duty_cycle = 1.0 - scaled_duty_cycle

If fault is set the output duty cycle is set to the default value.

Can raise the following errors: PUT_DUTYCYCLE_PROCESSING_INVALID_ARG.

Arg (data in): putf_inp_duty_cycle The input duty cycle value. Range: [0, 1] unitless

Arg (data in): putf_invert If inversion is set the scaled duty cycle is converted as follows: scaled_duty_cycle = 1.0 - scaled_duty_cycle Range: [0, 1] unitless flag

Arg (data in): putf_fault If true it forces the output value to be equal to putf_default, no effect otherwise.

Copyright 2019, Pi Innovo 344 Library interface

Range: [0, 1] unitless flag

Arg (data in): putf_default Used to set the output value when putf_fault is true, no effect otherwise. Range: [0, 1] unitless

Arg (data in): putf_min Lower threshold value in scaling the input duty cycle. Range: [0, 1] unitless

Arg (data in): putf_max Upper threshold value in scaling the input duty cycle. Range: [0, 1] unitless

Arg (data out): putf_out_duty_cycle Pointer to the value that will represent the output duty cycle. Cannot be NULL. Range: [0, 1] unitless

5.22.3.3.11. put_enh_process_analog_input_init()

Definition: void put_enh_process_analog_input_init(PUT_ENH_ANALOGUE_WORKSPACE_T *const putf_adc_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Enhanced Analogue input fault filter initialisation.

This function initialises any persistent data for an analogue channel prior to it first being called.

Can raise the following errors: PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_adc_channel_wrk_data Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function. Cannot be NULL.

5.22.3.3.12. put_enh_process_analog_input()

Definition: void put_enh_process_analog_input(F32 putf_raw_adc_value, F32 putf_adc_sample_rate, F32 *const putf_analogue_value, U8 *const putf_confirmed_min_raw_range_fault, U8 *const putf_confirmed_max_raw_range_fault, U8 *const putf_confirmed_slew_rate_fault, U8 *const putf_confirmed_min_eng_range_fault, U8 *const putf_confirmed_max_eng_range_fault, U8 *const putf_transient_fault_flag, const PUT_ANALOGUE_CAL_DATA_T *const putf_adc_channel_cal_data,

Copyright 2019, Pi Innovo 345 Library interface

PUT_ENH_ANALOGUE_WORKSPACE_T *const putf_adc_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Enhanced Analogue input fault filter processing.

This function is an enhanced version of put_process_analog_input(). Like that function, it is provided with a raw A/D value, details about the fault filtering that should be applied to it and pointers to an output value and a series of fault flags. The raw value is converted into an engineering value for output. This function differs in its processing of transient faults. The put_process_analog_input() function has the concept of a confirmed fault status, which is based on the status of all transient fault. This function monitors each transient fault individually and can provide more accurate information as to which faults are currently confirmed or not. Both the transient and any confirmed fault flags are made available to the calling function.

Can raise the following errors: PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_raw_adc_value The raw A/D value as obtained from a call to the basic analogue input code. Range: [-4096, 4096] A/D counts

Arg (data in): putf_adc_sample_rate The rate at which this function is called for fault filtering on the given A/D channel raw values. Range: [0.001, 3600] seconds

Arg (data out): putf_analogue_value Pointer to the value that will represent the output of the A/D conversion to an engineering value once the fault filtering has taken place. Cannot be NULL.

Arg (data out): putf_confirmed_min_raw_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being below the minimum allowed value. Cannot be NULL.

Arg (data out): putf_confirmed_max_raw_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being above the maximum allowed value. Cannot be NULL.

Arg (data out): putf_confirmed_slew_rate_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value changing faster than the maximum allowed slew rate value. Cannot be NULL.

Copyright 2019, Pi Innovo 346 Library interface

Arg (data out): putf_confirmed_min_eng_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being below the minimum allowed value. Cannot be NULL.

Arg (data out): putf_confirmed_max_eng_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being above the maximum allowed value. Cannot be NULL.

Arg (data out): putf_transient_fault_flag Pointer to the flag that will indicate if a transient fault has been detected. This will cause the output analogue value to be latched at the last valid engineering value or zero if the fault is present on the first iteration. Cannot be NULL.

Arg (data in): putf_adc_channel_cal_data Pointer to A/D channel calibration data structure. Cannot be NULL.

Arg (data in): putf_adc_channel_wrk_data Pointer to enhanced A/D channel workspace data structure. This provides persistence for data in between calls to the filter function. Cannot be NULL. 5.22.3.3.13. put_calc_ipv4_checksum()

Definition: U16 put_calc_ipv4_checksum(U16 putf_sum_reg, BOOL putf_start, BOOL putf_finish, const U8 *putf_addr, U32 putf_len)

Supported targets: All targets

Required license: None (Main library).

Description: Calculate a 16-bit checksum value using the IPv4 header checksum algorithm.

The IPv4 checksum is fast to compute, as it is based on simple 16-bit addition. However, it wraps overflowing bits back into the low-order bits of the sum, making it much stronger against undetected errors in the high bit than a simple sum.

Note

This can be used to calculate a single checksum for multiple memory blocks. To do this, in the first call set putf_start=TRUE and putf_finish=FALSE; in intermediate calls, set both FALSE, passing the previous return value in through putf_sum_reg; and in the final call set putf_start=FALSE and putf_finish=TRUE.

Arg (data in): putf_sum_reg The initial value of the checksum. Ignored if putf_start=TRUE.

Copyright 2019, Pi Innovo 347 Library interface

Range: [0, 65535] unitless

Arg (data in): putf_start Whether to initialise the checksum to the standard value before starting, in which case the input value putf_sum_reg is ignored. Usually TRUE, but use FALSE if the function is being called again to continue an existing checksum over a further region of memory.

Arg (data in): putf_finish Whether to apply the final one's complement operation to the computed checksum. Usually TRUE, but use FALSE if the function is to be called again to checksum an additional region of memory to include in the same overall calculation.

Arg (data in): putf_addr Pointer to the start of the memory block to be checksummed. Cannot be NULL.

Arg (data in): putf_len Length of memory block in bytes. Range: [0, 4294967295] bytes

Return: The calculated checksum. Range: [0, 65535] unitless 5.22.3.3.14. put_leaky_bucket_f32()

Definition: void put_leaky_bucket_f32(F32 putf_fall_rate, F32 putf_rise_rate, F32 putf_hyst, F32 putf_delta_time, U32 putf_n, volatile const F32 *const putf_tff, F32 *const putf_cff, PUT_LEAKY_BUCKET_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state

Value

level

0

Copyright 2019, Pi Innovo 348 Library interface

confirmed-fault-condition

false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Transient fault condition

Change in level

true

level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)

false

level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level

Confirmed fault condition

>= 1

true

< hysteresis

false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate The leak rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Arg (data in): putf_rise_rate The fill rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Arg (data in): putf_hyst The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent. Range: [-1, 1] unitless

Arg (data in): putf_delta_time The difference in time since the last call to this function for all faults in this call. Units: seconds

Copyright 2019, Pi Innovo 349 Library interface

Arg (data in): putf_n Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Arg (data out): putf_cff Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_u8()

5.22.3.3.15. put_leaky_bucket_f64()

Definition: void put_leaky_bucket_f64(F32 putf_fall_rate, F32 putf_rise_rate, F32 putf_hyst, F32 putf_delta_time, U32 putf_n, volatile const F64 *putf_tff, F64 *putf_cff, PUT_LEAKY_BUCKET_T *putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state

Value

level

0

confirmed-fault-condition

false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Copyright 2019, Pi Innovo 350 Library interface

Transient fault condition

Change in level

true

level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)

false

level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level

Confirmed fault condition

>= 1

true

< hysteresis

false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate The leak rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Arg (data in): putf_rise_rate The fill rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Arg (data in): putf_hyst The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent. Range: [-1, 1] unitless

Arg (data in): putf_delta_time The difference in time since the last call to this function for all faults in this call. Units: seconds

Arg (data in): putf_n Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Copyright 2019, Pi Innovo 351 Library interface

Arg (data out): putf_cff Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_u8(), put_leaky_bucket_f32()

5.22.3.3.16. put_leaky_bucket_init()

Definition: void put_leaky_bucket_init(U32 putf_n, PUT_LEAKY_BUCKET_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Initialisation of leaky bucket fault filtering.

Initialise the leaky bucket to empty.

Arg (data in): putf_n Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data out): putf_store A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. This function initialises the stores.

5.22.3.3.17. put_leaky_bucket_u8()

Definition: void put_leaky_bucket_u8(F32 putf_fall_rate, F32 putf_rise_rate, F32 putf_hyst, F32 putf_delta_time, U32 putf_n, volatile const U8 *putf_tff, U8 *putf_cff, PUT_LEAKY_BUCKET_T *putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Fault filtering using a leaky bucket analogy.

The function provides a simple integrator to determine if a fault has been present for long enough to declare the fault confirmed (i.e., the function filters out intermittent transient fault detection).

The function is modeled on a leaky bucket. The bucket has a hole in the bottom. When water is poured into the bucket, the relative rates of

Copyright 2019, Pi Innovo 352 Library interface

filling and leaking determine whether the bucket fills or empties, and how quickly.

Initially, the leaky bucket is empty and no fault has been confirmed:

Initial state

Value

level

0

confirmed-fault-condition

false

At each function call, the level is adjusted and clipped depending on whether a transient fault is present or not:

Transient fault condition

Change in level

true

level = MIN(MAX(level - delta-fall + delta-rise, 0), 1)

false

level = MAX(level - delta-fall, 0)

The delta-rise and delta-fall values are scaled based on how much time has passed since the last function call. For instance, if the leaky bucket were scheduled to run every 0.5 seconds, then delta-rise and delta-fall would be set to the user supplied rise and fall values multiplied by 0.5.

The level is then checked to determine if the bucket is full or empty:

level

Confirmed fault condition

>= 1

true

< hysteresis

false

For example, if the bucket had a leak rate of 1 unit per second, and took in 2 units per second, the bucket would fill up at a rate of 1 unit per second. When the bucket is full or overflowing, the fault is confirmed as active. When the bucket empties below a hysteresis level, the fault is confirmed as absent.

Arg (data in): putf_fall_rate The leak rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Arg (data in): putf_rise_rate The fill rate of the buckets applied to all faults in this call. Range: [0, 1000] units per second

Copyright 2019, Pi Innovo 353 Library interface

Arg (data in): putf_hyst The level below which the fault is confirmed absent. If the hysteresis is negative, then the fault will be confirmed present and never become confirmed absent. Range: [-1, 1] unitless

Arg (data in): putf_delta_time The difference in time since the last call to this function for all faults in this call. Units: seconds

Arg (data in): putf_n Number of elements in arrays putf_tff, putf_cff and putf_store.

Arg (data in): putf_tff Pointer to array of transient fault indicators. A fault is present if the corresponding array element is true (non-zero), a fault is absent otherwise.

Arg (data out): putf_cff Pointer to array of confirmed fault indicators. A fault is confirmed present if the corresponding array element is true (non-zero), a fault is confirmed absent otherwise.

Arg (data in,out): putf_store A pointer to a store of information relating to a leaky bucket for each fault in putf_tff. Not to be accessed by the application. Call put_leaky_bucket_init() to initialise the store.

put_leaky_bucket_init(), put_leaky_bucket_f32() 5.22.3.3.18. put_pool_write()

Definition: PUT_POOL_RC_T put_pool_write(PUT_POOL_T *putf_pool, U16 putf_id, const U8 *putf_array, U16 putf_num_bytes, PUT_POOL_ITERATOR_T *putf_iterator)

Description:

Arg (data out): putf_pool Handle of the memory pool.

Arg (data out): putf_id Identifier of the data entry to write.

Arg (data in): putf_array Pointer to the start of the data to write.

Arg (data in): putf_num_bytes Number of bytes to write.

Arg (data in): putf_iterator If not NULL, iterator to keep up to date with pool change. 5.22.3.3.19. put_pool_iterate_init()

Definition: PUT_POOL_RC_T put_pool_iterate_init(PUT_POOL_ITERATOR_T *putf_iterator, PUT_POOL_T *putf_pool, PUT_POOL_COMPARATOR_T putf_comparator, U16 putf_id)

Copyright 2019, Pi Innovo 354 Library interface

Description:

Arg (data out): putf_iterator Keeps track of fetched blocks

Arg (data out): putf_pool Handle of the memory pool

Arg (data in): putf_comparator Type of comparison

Arg (data in): putf_id Value to compare against 5.22.3.3.20. put_pool_iterate_next()

Definition: BOOL put_pool_iterate_next(PUT_POOL_ITERATOR_T *putf_iterator)

Description:

Arg (data out): putf_iterator A pointer to a structure, keeps track of fetched blocks.

Return:

• TRUE- antoher match is found in the memory pool 5.22.3.3.21. put_pool_iterate_next_w_clear()

Definition: BOOL put_pool_iterate_next_w_clear(PUT_POOL_ITERATOR_T *putf_iterator, BOOL putf_already_advanced)

Description:

Arg (data out): putf_iterator A pointer to a structure, keeps track of fetched blocks.

Arg (data in): putf_already_advanced Indicates whether the loop managed by put_pool_iterate_next() has incremented.

Return:

• TRUE- another match is found in the memory pool 5.22.3.3.22. put_pool_iterate_clear()

Definition: BOOL put_pool_iterate_clear(PUT_POOL_ITERATOR_T *putf_iterator)

Description:

Arg (data out): putf_iterator A pointer to a structure, keeps track of fetched blocks.

Return:

• TRUE- the iterator has been advanced.

• FALSE- the iterator has not been advanced.

Copyright 2019, Pi Innovo 355 Library interface

5.22.3.3.23. put_pool_clear()

Definition: PUT_POOL_RC_T put_pool_clear(PUT_POOL_T *putf_pool, U16 putf_id)

Description:

Arg (data out): putf_pool Handle of the memory pool

Arg (data in): putf_id Identifier of the data entry to clear

Return:

• PUT_POOL_OK- successfuly deleted data

• PUT_POOL_ID_NOT_FOUND- data could not be properly deleted

5.22.3.3.24. put_process_analog_input_init()

Definition: void put_process_analog_input_init(PUT_ANALOGUE_WORKSPACE_T *const putf_adc_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Analogue input fault filter initialisation.

This function initialises any persistent data for an analogue channel prior to it first being called.

Can raise the following errors: PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_adc_channel_wrk_data Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function. Cannot be NULL.

5.22.3.3.25. put_process_analog_input()

Definition: void put_process_analog_input(F32 putf_raw_adc_value, F32 putf_adc_sample_rate, F32 *const putf_analogue_value, U8 *const putf_confirmed_min_raw_range_fault, U8 *const putf_confirmed_max_raw_range_fault, U8 *const putf_confirmed_slew_rate_fault, U8 *const putf_confirmed_min_eng_range_fault, U8 *const putf_confirmed_max_eng_range_fault, U8 *const putf_transient_fault_flag, const PUT_ANALOGUE_CAL_DATA_T *const putf_adc_channel_cal_data,

Copyright 2019, Pi Innovo 356 Library interface

PUT_ANALOGUE_WORKSPACE_T *const putf_adc_channel_wrk_data)

Supported targets: All targets

Required license: None (Main library).

Description: Analogue input fault filter processing.

This function is provided with a raw A/D value, details about the fault filtering that should be applied to it and pointers to an output value and a series of fault flags. The raw value is converted into an engineering value for output. If transient faults persist for long enough, a confirmed fault is generated. Both the transient and any confirmed fault flags are made available to the calling function.

Can raise the following errors: PUT_ANALOG_INPUT_FILTER_INVALID_ARG.

Arg (data in): putf_raw_adc_value The raw A/D value as obtained from a call to the basic analogue input code. Range: [-4096, 4096] A/D counts, [-5, 5] volts

Arg (data in): putf_adc_sample_rate The rate at which this function is called for fault filtering on the given A/D channel raw values. Range: [0.001, 3600] seconds

Arg (data out): putf_analogue_value Pointer to the value that will represent the output of the A/D conversion to an engineering value once the fault filtering has taken place. Cannot be NULL.

Arg (data out): putf_confirmed_min_raw_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being below the minimum allowed value. Cannot be NULL.

Arg (data out): putf_confirmed_max_raw_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value being above the maximum allowed value. Cannot be NULL.

Arg (data out): putf_confirmed_slew_rate_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the raw A/D value changing faster than the maximum allowed slew rate value. Cannot be NULL.

Arg (data out): putf_confirmed_min_eng_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being below the minimum allowed value.

Copyright 2019, Pi Innovo 357 Library interface

Cannot be NULL.

Arg (data out): putf_confirmed_max_eng_range_fault Pointer to the flag that will indicate if a confirmed fault has been recorded due to the engineering A/D value being above the maximum allowed value. Cannot be NULL.

Arg (data out): putf_transient_fault_flag Pointer to the flag that will indicate if a transient fault has been detected. This will cause the output analogue value to be latched at the last valid engineering value or zero if the fault is present on the first iteration. Cannot be NULL.

Arg (data in): putf_adc_channel_cal_data Pointer to A/D channel calibration data structure. Cannot be NULL.

Arg (data in): putf_adc_channel_wrk_data Pointer to A/D channel workspace data structure. This provides persistence for data in between calls to the filter function. Cannot be NULL.

5.22.3.3.26. put_range_check_f32()

Definition: void put_range_check_f32(U32 putf_n, volatile const F32 *putf_value, volatile const F32 *putf_max, volatile const F32 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for F32 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Copyright 2019, Pi Innovo 358 Library interface

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point. 5.22.3.3.27. put_range_check_s16()

Definition: void put_range_check_s16(U32 putf_n, volatile const S16 *putf_value, volatile const S16 *putf_max, volatile const S16 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for S16 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Copyright 2019, Pi Innovo 359 Library interface

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point. 5.22.3.3.28. put_range_check_s32()

Definition: void put_range_check_s32(U32 putf_n, volatile const S32 *putf_value, volatile const S32 *putf_max, volatile const S32 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for S32 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type.

Copyright 2019, Pi Innovo 360 Library interface

Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.29. put_range_check_s8()

Definition: void put_range_check_s8(U32 putf_n, volatile const S8 *putf_value, volatile const S8 *putf_max, volatile const S8 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for S8 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Copyright 2019, Pi Innovo 361 Library interface

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point. 5.22.3.3.30. put_range_check_u16()

Definition: void put_range_check_u16(U32 putf_n, volatile const U16 *putf_value, volatile const U16 *putf_max, volatile const U16 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for U16 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type.

Copyright 2019, Pi Innovo 362 Library interface

Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

5.22.3.3.31. put_range_check_u32()

Definition: void put_range_check_u32(U32 putf_n, volatile const U32 *putf_value, volatile const U32 *putf_max, volatile const U32 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for U32 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Copyright 2019, Pi Innovo 363 Library interface

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point. 5.22.3.3.32. put_range_check_u8()

Definition: void put_range_check_u8(U32 putf_n, volatile const U8 *putf_value, volatile const U8 *putf_max, volatile const U8 *putf_min, void *putf_gt, void *putf_lt, U8 putf_use_bool_type)

Supported targets: All targets

Required license: None (Main library).

Description: Vector range check (min and max) function for U8 types.

For each element in the vectors, i, the function sets the output vectors as: putf_gt[i] = putf_value[i] > putf_max[i] putf_lt[i] = putf_value[i] < putf_min[i]

Can raise the following errors: PUT_RANGE_CHECK_INVALID_ARG.

Arg (data in): putf_n Number of elements in vectors putf_value, putf_max , putf_min, putf_gt and putf_lt. Range: [1, 4294967295] elements

Arg (data in): putf_value Pointer to array of values. Cannot be NULL.

Arg (data in): putf_max Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_min Pointer to array of values. Each value is compared against the corresponding element in putf_value. Cannot be NULL.

Arg (data in): putf_gt Pointer to array of flags. Each flag is the result of: putf_value[i] > putf_max [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_lt Pointer to array of flags. Each flag is the result of: putf_value[i] < putf_min [i]. The type of each flag is determined by putf_use_bool_type. Cannot be NULL.

Arg (data in): putf_use_bool_type True if boolean types are stored as 8-bit integers, false if boolean types are stored as 32-bit floating point.

Copyright 2019, Pi Innovo 364 Library interface

5.22.3.3.33. put_slew_rate_check_init()

Definition: void put_slew_rate_check_init(PUT_SLEW_RATE_CHECK_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Initialisation routine for slew rate checking.

Initialise the slew rate check information that persists between calls to put_slew_rate_check().

Can raise the following errors: PUT_SLEW_RATE_CHECK_INVALID_ARG.

Arg (data in,out): putf_store A pointer to a store of information relating to the input signal. Not to be accessed by the application. Cannot be NULL. 5.22.3.3.34. put_slew_rate_check()

Definition: BOOL put_slew_rate_check(F32 putf_input, F32 putf_slew_rate_limit, F32 putf_delta_time, PUT_SLEW_RATE_CHECK_T *const putf_store)

Supported targets: All targets

Required license: None (Main library).

Description: Slew rate checking.

Return whether the rate of change of the input variable (putf_input) exceeds the slew rate limit or not. On the first call to this function, there is not enough information to determine if the rate of change has exceeded the limit or not, and the function returns false.

Can raise the following errors: PUT_SLEW_RATE_CHECK_INVALID_ARG.

Arg (data in): putf_input The current value of the input. Units: none

Arg (data in): putf_slew_rate_limit The rate of change limit. Negative values are clipped to zero. Units: /second

Arg (data in): putf_delta_time The difference in time since the last call to this function. On the first call to this function, this parameter is ignored. Units: seconds

Copyright 2019, Pi Innovo 365 Library interface

Arg (data in,out): putf_store A pointer to a store of information relating to the input signal. Not to be accessed by the application. Initialise the store by calling put_slew_rate_check_init(). Cannot be NULL.

Return: True if the input rate of change exceeds the limit, false otherwise. 5.22.3.3.35. put_state_processing()

Definition: void put_state_processing(U8 putf_inp_state, U8 putf_invert, U8 putf_fault, U8 putf_default, U8 *putf_out_state)

Supported targets: All targets

Required license: None (Main library).

Description: State fault processing and inversion.

If putf_fault is true, the output the putf_default value. Otherwise, output the putf_state value (with inversion if putf_invert is true).

Can raise the following errors: PUT_STATE_PROCESSING_INVALID_ARG.

Arg (data in): putf_inp_state The input state. Range: 0 or 1, unitless

Arg (data in): putf_invert If inversion is set the input state is converted as follows: output_state = 1 - input_state Range: 0 or 1, unitless

Arg (data in): putf_fault If true the function forces the output value to be equal to putf_default, no effect otherwise. Range: 0 or 1, unitless

Arg (data in): putf_default Used to set the output value when putf_fault is true, no effect otherwise. Range: [0, 1] unitless

Arg (data out): putf_out_state Pointer to the value that will represent the output state. Cannot be NULL. Range: [0, 1] unitless 5.23. Angular function feature (PAN) 5.23.1. Overview

The library supports port injected (gasoline) and direct injected (gasoline and diesel) engine types. The library supports decoding crank and cam sensor inputs into an overall engine position/angle which can be used to trigger application tasks and A/D input sampling, and

Copyright 2019, Pi Innovo 366 Library interface

used to generation injection and spark pulses at specific points in each engine cycle. Independent of the aforementioned engine types the library also supports decoding a toothed crankshaft wheel, for rotational speed etc. 5.23.1.1. Configuration

The configuration functions allow the application to specify fundamental engine parameters that the ECU uses to keep track of the engine position, schedule tasks and schedule capture of analogue input channels on an angular basis, irrespective of engine type.

Crank and cam input configuration The configuration of the crank and cam trigger wheel patterns through pan_config_crank_wheel_mtg(), pan_config_cam_wheel_st() and pan_config_cam_wheel_app() specifies how the ECU will keep track of the overall engine position. Whether synchronisation has been gained with the crank or cam trigger wheels, and various other measurements, are provided by various functions, see Section 5.23.1.2, “Crank and cam signal decoding”.

A detailed description of the crank decode functionality is provided in Appendix H, Crank wheel signal decoding.

Engine and TDC-firing angle configuration The configuration of each cylinder's TDC-firing angle through pan_config_engine() provides a reference for scheduling events for each cylinder. The TDC-firing positions are given relative to an absolute crank wheel position.

Figure 5.21. Definition of 0° crank (VR sensor input)

Missing tooth region

Crank wheel teeth

VR sensor signal

0° crank

Figure 5.22. Definition of 0° crank (Hall-effect sensor input)

Missing tooth region

Crank wheel teeth

Hall-effect signal

0° crank

In order to update injection and spark events, the task for each cylinder is executed at an angular offset from its TDC-firing position. As an

Copyright 2019, Pi Innovo 367 Library interface

example, consider a common 4 cylinder engine, with a firing order of [1, 3, 4, 2] and TDC-firing angles at angles [90, 630, 270, 450] for cylinder 1 through 4 respectively:

Figure 5.23. TDC-firing events relative to 0° crank

90° 270° 450° 630°

crank angle 0° 360° 720°

Mid point of first tooth TDC firing TDC firing TDC firing TDC firing after "missing tooth" for cylinder 1 for cylinder 3 for cylinder 4 for cylinder 2 region

The angular offset is specified by the panf_task_calc_angle parameter to function pan_config_engine() (negative offsets occur before TDC-firing). When the appropriate calculation point is reached, a task execution occurs. So for instance, with a calculation angle of -120°, the task for cylinder 3 would start 120° before the third cylinder's TDC- firing position.

Figure 5.24. Task execution relative to cylinder's TDC-firing event

Start to run model iteration for cylinder 3 (panf_calculation_angle)

crank angle 0° 360° 720°

TDC firing for cylinder 3

negative angles before TDC positive angles after TDC

The current engine position and speed, and various other measurements, are provided by various functions, see Section 5.23.1.3, “Engine measurements”.

Angular A/D input sampling configuration The configuration of the angular analogue inputs through pan_config_angular_ad_var(), specifies when the ECU will sample up to PIO_ANG_MAX_AD_SAMPLES analogue inputs for each cylinder relative to the engine position.

Figure 5.25. Analogue inputs sampled relative to angular model iteration

Angular sample points must be before the panf_calculation_angle

crank angle 0° 360° 720°

Model iteration TDC firing for cylinder 3 for cylinder 3

Copyright 2019, Pi Innovo 368 Library interface

The information from the sampling can be retrieved and used in the task for a cylinder as described by Section 5.23.1.4, “Angular A/D measurements”.

Injector configuration The configuration of the injector driver through pan_config_injectors() or pan_config_injector(), specifies the associations between injector output channels and cylinders. These functions also specifiy the type of injector drive signal (for instance, saturating or peak-and-hold) and injection profile (port-injection versus direct-injection). The library then drives those channels in response to injection requests from the application (see Section 5.23.1.6, “Injection pulse scheduling (direct injection injectors)” or Section 5.23.1.7, “Injection pulse scheduling (port injected engines)” for more).

Spark configuration The configuration of the injector driver through pan_config_sparks(), specifies the spark output channels to be used for each cylinder and the type of drive signal (for instance, wasted-spark or coil-on-plug). The library then drives those channels in response to spark requests from the application (see Section 5.23.1.8, “Spark control” for more).

Angular output configuration The configuration of the generic angular output driver through pan_config_angular_output(), specifies the output mode (angle-angle or angle-time), and the output stall action for an output channel. The library then drives those channels in response to output requests from the application (see ??? for more). 5.23.1.2. Crank and cam signal decoding

The library provides a set of functions which can be split into a number of functional areas:

Movement and synchronisation The library can detect movement of the crank or cam trigger wheel by looking for a number of teeth within a period of time, and provide that information through functions pan_get_crank_wheel_movement() and pan_get_cam_wheel_movement().

This differs from synchronisation which the library determines by decoding the teeth signals looking for the patterns declared during configuration. Whether the library has gained or lost synchronisation with the trigger wheel signals can be retrieved by calling pan_get_crank_wheel_sync() or pan_get_cam_wheel_sync().

Rather than a physical cam trigger wheel, the application can declare the use of a virtual cam trigger wheel where the application determines synchronisation and signals this to the library by calling pan_declare_cam_wheel_sync().

Speed The library can provide speed information about each trigger wheel input signal once synchronisation has been gained. There are different speed measurements made over different angle ranges: an instantaneous measurement can be retrieved by calling pan_get_crank_speed_per_tooth(); an averaged measurement can be retrieved by calling pan_get_crank_speed_per_rev() or pan_get_cam_speed_per_rev().

Copyright 2019, Pi Innovo 369 Library interface

Position The library can provide position information about the crank trigger wheel once synchronisation has been gained. Some position information is an estimate based on at least the last two measured teeth signals and should be treated appropriately. The position information can be retrieved by calling pan_get_crank_wheel_angle() or pan_get_crank_wheel_tooth(). 5.23.1.3. Engine measurements

The library provides a set of functions which can be split into a number of functional areas:

Synchronisation The library can provide synchronisation information about the overall engine position (as determined from the crank and/or cam trigger wheel signals). This can be retieved by calling pan_get_engine_sync().

Speed The library can provide speed information about the overall engine state (as determined from the crank and/or cam trigger wheel signals). There are different speed measurements made over different angle ranges: an instantaneous measurement can be retrieved by calling pan_get_engine_speed_per_tooth() ; an averaged measurement between each TDC-firing event by calling pan_get_engine_speed_per_cyl(); an averaged measurement between each engine revolution by calling pan_get_engine_speed_per_rev(); and an averaged measurement between specific crank teeth by calling pan_get_engine_speed_tr_abs() or pan_get_engine_speed_tr_rel().

Position The library can provide position information about the overall engine position (as determined from the crank and/or cam trigger wheel signals). The position information is an estimate based on at least the last two measured teeth signals and should be treated appropriately. The position information can be retrieved by calling pan_get_engine_angle().

When the engine position reaches the TDC-firing calculation angle for each cylinder the library determines which cylinder is being processed before triggering the corresponding application task to do per cylinder calculations. The cylinder to be processed can be retrieved by calling pan_get_engine_cyl(). 5.23.1.4. Angular A/D measurements

The library will take measurements of multiple A/D input channels at specific engine positions and make them available to the application through the various functions. Samples taken at engine angles (relative to TDC-firing) defined during run time can be retrieved using the pan_get_angular_ad_avg_var() and pan_get_angular_ad_samples_var() functions. Samples taken at engine angles (relative to zero degrees crank) defined during run time can be retrieved using the pan_get_angular_ad_avg_abs() and pan_get_angular_ad_samples_abs() functions. 5.23.1.5. Scheduling modes

The various angular functions of the library can operate in 360 degree and/or 720 degree mode depending on the synchronisation state with the crank and cam trigger signals. For instance, the port injection function can operate in 360 degree mode when there is

Copyright 2019, Pi Innovo 370 Library interface

only synchronisation with the crank trigger wheel and in 720 degree mode when there is synchronisation with both the crank and cam trigger wheels. 5.23.1.6. Injection pulse scheduling (direct injection injectors)

For direct injection type injectors, the library supports the generation of up to six injection pulses per injector per cycle. The pulses for each injector are configured with the pan_set_injection_di() function.

The library will schedule the requested number (panf_pulses) of pulses, using an array of on angles (panf_rel_on_angle) and requested amounts (either explicit time or volume). The on angles are relative to the TDC-firing angle of the cylinder associated with the injector, with a negative value indicating an angle before TDC.

Figure 5.26. Multiple injection pulses

start of injection event (panf_rel_on_angle) Multiple pulses (panf_pulses = 4) injection event crank angle 0° 90°

injection event duration (panf_fuel_volume)

TDC firing Drop Dead Angle for Cylinder n (panf_drop_dead_angle)

negative angles before TDC positive angles after TDC

An injector can be scheduled to convert a requested volume of fuel into a pulse duration by setting panf_duration_mode to PIO_INJDI_DURATION_MODE_VOLUME and setting the elements of the panf_fuel_amount array to desired volume in mm3.

Note: the platform has an internal volume resolution of 1/8 (0.125) mm3.

In this mode, the library samples fuel rail pressure shortly before the injection on angle and uses a map lookup to derive the required injection duration. This mechanism compensates for very rapid fluctuations in fuel rail pressure that cannot be compensated for by the application, as the application cannot be scheduled to run just prior to each injection pulse without increasing the load on the CPU significantly.

The application specifies the analogue input (panf_frp_chan) the library should use for the injector lookup, the injector characteristic map, and other data with the pan_config_injectors_comp_di() function.

If required, the fuel-rail pressure measurement can be specified by the application with the pan_set_injection_comp_frp_di() function. This allows the application to control the injector lookup explicitly or use a default if the specified analogue input is deemed to be unusable by the application.

An injector can alternatively be scheduled to actuate for an explicit amount of time requested by the application by choosing PIO_INJDI_DURATION_MODE_TIME and setting the elements of the panf_fuel_amount array to desired duration in milliseconds.

Note: the best resolution of injection duration is 0.25 microseconds for M2xx targets and 0.2424 microseconds for M670. Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request. In the current implementation, granularity doubles every power of two times the maximum timer duration. The maximum timer duration is 16.384 ms for M2xx targets, and 15.887 ms for M670. For example, the M2xx resolution

Copyright 2019, Pi Innovo 371 Library interface

is 0.25 us if the maximum pulse duration is less than 16.384 ms, and the resolution will go to 0.50 us if the maximum pulse duration is between 16.384 us and 32.7675 us, etc.

Injection pulses are generated for each injector according to the requested pulse schedule. If two pulses on the same injector overlap, the latter pulse will be delayed. (Note that its duration will not be modified.) If this delay then means that the next two pulses overlap, then the next pulse will be delayed, and so on for the remaining pulses.

The pan_config_injections_di() function is used to define constraints that apply to all injections.

Figure 5.27. Injection constraints

Actual Injection Requested Injection Requested Injection Event Requested Injection Event Actual Injection Event Event Event Actual Injection Event

injection event crank angle 0° 90°

Minimum inter-injection Minimum pulse duration delay (panf_min_inj_time) (panf_min_off_time) TDC firing Drop Dead Angle for Cylinder n (panf_drop_dead_angle)

• A minimum injection duration that is applied to all pulses can be defined using the panf_min_inj_time parameter. All scheduled injections will have at least this duration unless clipped by the drop-dead angle.

Note The actual minimum attainable pulse width may be larger than this value. For very short pulse widths, system latency may cause the pulse to be on for longer than this minimum value.

• A minimum inter-injection delay applied to the durations between all pulses can be defined using the panf_min_off_time parameter.

• The drop-dead angle for each cylinder is defined with the panf_drop_dead_angle parameter. This is an angle relative to TDC where a negative value indicates an angle before TDC. The drop-dead angle is the injection cut-off point for a cylinder on a particular cycle, i.e., any injection in progress at this angle will be terminated and any subsequent injections for the in-progress sequence will not be scheduled. New pulses from the next cycle will be scheduled automatically.

• The on-angles in the pulse sequence for pulses that have non-zero requested volumes must be strictly increasing.

If OpenECU loses synchronization with the crank or cam wheel, it forces all injectors off. On regaining synchronisation with the cam, no injections occur until a new pulse schedule is requested with pan_set_injection_di(), i.e., the previously active schedule will not resume.

See pan_set_injection_di() , pan_config_injectors_comp_di() , pan_set_injection_comp_frp_di() and pan_config_injections_di() for additional information. 5.23.1.7. Injection pulse scheduling (port injected engines)

For port injected engines, the pan_set_initial_injection_gpi() function programs the duration of the fuel priming pulse which occurs when the engine is first seen to be turning (before synchronisation has been achieved). If the engine stops and then starts again without the

Copyright 2019, Pi Innovo 372 Library interface

ECU losing power, an initial fuel pulse will occur again if there was at least 1.5 seconds between the ECU detecting the engine stop condition and the engine start condition.

The function pan_set_injection_gpi() is used to set up the injection on each cylinder. A first main injection pulse starts at a requested angle (panf_rel_on_angle), and lasts for a requested duration.

Figure 5.28. Main injection event

start of injection event (panf_rel_on_angle)

injection event crank angle 0° 360° 720°

injection event duration (panf_dead_time + panf_flow_time) TDC firing Injection event stop for Cylinder n (panf_end_of_intake_angle)

negative angles before TDC positive angles after TDC

The injector pulse is constructed from a dead time (panf_dead_time) and a flow time (panf_flow_time). The dead time represents the time it takes the injector needle to lift and allow fuel to flow. The flow time represents the time the injector allows fuel to pass the injector tip.

Note: all times have a resolution of 0.25 us for M2xx targets, and 0.2424 us for M670.

Figure 5.29. Injector pulse duration is composed of “dead time” and “flow time”

panf_flow_time

injection pulse crank angle

panf_dead_time

If the duration of the injection event extends beyond the end of intake angle (panf_end_of_intake_angle) then the injection pulse is stopped. Usually panf_end_of_intake_angle is configured to occur before the inlet valve closes so that fuel is not left to pool behind the intake valve to be ingested in the next engine cycle.

Figure 5.30. Clipped injection event

requested injection event actual injection event crank angle 0° 360° 720°

TDC firing Injection event stop for cylinder n (panf_end_of_intake_angle)

A second main injection pulse may be generated by OpenECU when unsynchronised with the cam wheel. In this mode, OpenECU generates an injection pulse with half the flow time (plus the full dead time) at the requested start on angle and a second injection pulse with half the flow time (plus the full dead time) at the requested start on angle plus 360°.

Copyright 2019, Pi Innovo 373 Library interface

Figure 5.31. Injection events in 360° mode

Secondary pulse 360° on from start of main pulse Main pulse

injection event crank angle 0° 360° 720°

injection event duration injection event duration (panf_dead_time + (panf_dead_time + ½ panf_flow_time) ½ panf_flow_time)) Secondary injection event stop Main injection event stop (panf_end_of_intake_angle + 360°) (panf_end_of_intake_angle)

TDC firing for cylinder n

Generating two pulses in this manner provides a full charge for the intake phase.

When OpenECU is unsynchronised with the crank wheel, it forces all injectors off (the exception to this rule is the initial fuel pulse which may occur if movement in the crank wheel has been detected but crank synchronisation has not yet been achieved).

The pan_set_injection_gpi() function schedules a main pulse (and possibly a second main pulse if synchronisation with the CAM wheel has not been achieved). Once scheduled, the start angle and duration of the pulse can be modified in response to transient conditions.

The pan_update_injection_gpi() function can change the start of the main injection pulse if the main pulse has not started. It can also change the duration of the main injection pulse if the main pulse has not started or if the pulse has not completed. This may result in a contracted or extended pulse.

The pan_update_injection_gpi() function can generate a post injection pulse if the main pulse has completed and the requested duration is larger than the already delivered pulse. The block may generate more than one post pulse if invoked more than once during the engine cycle.

Figure 5.32. Post injection events

Main pulse Post pulse

injection event crank angle 0° 360° 720°

TDC firing Additional request from Injection event stop for cylinder n pan_update_injector() (panf_end_of_intake_angle) happens immediately

When OpenECU is unsynchronised with the crank wheel, it forces all injectors off.

See pan_set_injection_gpi() and pan_update_injection_gpi(). 5.23.1.8. Spark control

The pan_set_spark() function schedules the angles at which the ignition coil for the cylinder is turned on and off.

These angles are specified in degrees by the value of the panf_rel_on_angle and panf_rel_off_angle arguments respectively. These angles are relative to the cylinder's TDC-firing angle:

Copyright 2019, Pi Innovo 374 Library interface

Figure 5.33. Spark event relative to cylinder's TDC-firing angle

start of end of coil event coil event (panf_rel_on_angle) (panf_rel_off_angle)

coil event crank angle 0° 360° 720°

TDC firing for cylinder n

positive angles before TDC negative angles after TDC

Warning

The angle sense differs from the injection blocks: a positive value denotes an angle before TDC, and a negative value denotes an angle after TDC.

Refer to the technical specification for each module for a description of the feedback signals available for the coil output drivers.

See pan_set_spark(), pan_config_sparks() and pan_spark_config_successful(). 5.23.1.9. Angular output

The pan_set_angular_output() function schedules a sequence of events for an output in the angular domain in a fairly generic way specifying start and end actions on a digital output pin state.

The start actions are always specified to occur at a start angle with the panf_ang_out_start_angle argument, while the end actions are specified to occur at some duration after the start angle with the panf_ang_out_duration argument. The duration can be either an angle or a time depending on the output mode selected, with the panf_ang_out_mode argument. Note that the output mode is a fixed property of the output that is specified by the corresponding pan_config_angular_output() function. Possible actions are setting the pin state to active or inactive, toggling the state, or leaving the state unchanged.

In addition to controlling the output in the angular domain, this function allows an immediate action to be specified, by the panf_ang_out_action_now argument. This allows a relatively crude level of purely time-based control to occur at the resolution of the task time in which this function resides. An application thus might control an output using this immediate action prior to achieving crank synchronization, and then use the angular control once crank sync has been attained.

Some illustrations of this function in action are given below.

Copyright 2019, Pi Innovo 375 Library interface

Figure 5.34. Output pulse - Angle-Time Duration (turn-on/turn-off)

start_angle start_action = ‘turn-on’ end_action = ‘turn-off’

Output pin state

crank angle 0° 360° 720°

duration = X ms

Block is called immediate_action = ‘turn-off’

Figure 5.35. Output pulse - Angle-Time Duration (turn-on/no-action)

start_angle & start_action = ‘turn-on’ end_action = ‘no-action’

Output pin state

crank angle 0° 360° 720°

duration = X ms

Block is called immediate_action = ‘turn-off’

Figure 5.36. Output pulse - Angle-Angle Duration (turn-off/toggle)

start_angle & start_action = ‘turn-off’ end_action = ‘toggle’

don’t care Output pin state

crank angle 0° 360° 720°

Duration = Y degrees

Block is called immediate_action = ‘turn-on’

Figure 5.37. Output pulse - Angle-Angle Duration (turn-on/turn-off)

start_angle & start_action = ‘turn-on’ (output stays on) end_action = ‘turn-off’

don’t care Output pin state

crank angle 0° 360° 720°

duration = Y degrees

Block is called immediate_action = ‘turn-on’

The start angle is interpreted either relative to crank-zero, or relative to the top-dead centre (TDC) angle of a specified cylinder number. The specified start event will then

Copyright 2019, Pi Innovo 376 Library interface

occur at the next such start angle to occur. For a two-stroke engine (as specified in the pan_config_engine() function), the start angle is interpreted modulo 360 degrees. For a four- stroke engine, it is interpreted modulo 360 degrees before full engine synchronisation, and modulo 720 degrees after full engine synchronisation.

When OpenECU is unsynchronised with the crank wheel, the outputs can be scheduled but will not be driven as the crank position will be unknown. If crank synchronisation is lost, then the pin state is set to the value specified in the panf_ang_out_stall_action argument of the corresponding pan_config_angular_output() function. This also determines the initial output state before the first time the function is called.

The sequence of events can be repeated automatically every engine cycle by setting the panf_ang_out_allow_cycle_repeat argument to TRUE (non-zero). If the panf_ang_out_allow_cycle_repeat argument is set to FALSE (zero), then a single sequence of events will be scheduled, and a further function call is required to generate further events. If the function is called before the next scheduled event has started, and the start angle of the new data is still in the future, then the new data will supersede the previous data. If the start angle of the new data is in the past, and the previous data is in the future, then the previous data will be used for only the next event instead of scheduling the event for the next engine cycle. The preference being that it is better to keep the previously scheduled event, than to skip the event for the current engine cycle.

Each index in the array of values is treated as a seperate event. If the function is called while an event is underway and the data for the the current event in the array of values is modified, then the behaviour is determined by the panf_ang_out_allow_end_mod argument value. If this is FALSE (0), then the data will be buffered and take effect on the next instance of that event. On the other hand, if the panf_ang_out_allow_end_mod argument value is TRUE (non-zero), then the end of the event will be updated according to the newly provided duration and end action values (and the start action and start angle values are ignored). If the newly provided duration has already elapsed, then the end action is applied immediately. (Note that in this case it will be applied immediately after any immediate action that has been specified.)

Figure 5.38. Output data updated during an event, end modification allowed

Block is called again with allow_end_modification TRUE start_angle & start_action = ‘turn-on’ Angle duration is modified for the current Output pin state pulse

crank angle 0° 720° 1440°

Initial duration, end_action = ‘turn-off’

Block is called

Copyright 2019, Pi Innovo 377 Library interface

Figure 5.39. Output data updated during an event, end modification not allowed

Block is called again with allow_end_modification FALSE New pulse is scheduled for start_angle & the next available start angle start_action = ‘turn-on’

Output pin state

crank angle 0° 720° 1440° angle_duration & end_action = ‘turn-off’

Block is called

If the duration for an event is zero, then that event will be skipped for the schedule of events. If the duration for all events in the schedule are set to zero, then at the start angle of the event in the first index of the schedule, a single action will be performed corresponding to the result of applying the start action followed by the end action. For example, if both actions specify that the output pin state should be toggled, then no change to the pin state will occur. If an update occurs when an event is underway with duration of zero and panf_ang_out_allow_end_mod argument is set to TRUE, then the newly specified end action is applied immediately.

If two events in a schedule overlap, the first pulse will be terminated at the start angle of the next pulse with a single action corresponding to the result of applying the end action of the first event followed by the start action of the next event. The schedule will then continue normally with the duration of the next event, resulting in the correct timing of the next event from that event's start angle.

Figure 5.40. Output event with overlap between two events

1st event start_angle, 2nd event start_angle, start_action = ‘turn-on’, & start_action = ‘turn-on’, & end_action = ‘turn-off’ end_action = ‘turn-off’

1st event

2nd event

Output pin state

crank angle 0° 720° 1440° 1st and 2nd events combined

Block is called

If an event start action occurs within the last panf_ang_out_min_off_time argument after the end action of a previous event, the second event will be delayed to ensure the minimum off time is maintained between the two events. The minimum off time can be set to zero to prevent the subsequent pulse from being delayed.

Copyright 2019, Pi Innovo 378 Library interface

Figure 5.41. Output event starting within minimum off time

1st event start_angle, 2nd event start_angle, start_action = ‘turn-on’, & start_action = ‘turn-on’, & end_action = ‘turn-off’ end_action = ‘turn-off’

1st event

2nd event

nd Output pin state 2 event delayed

crank angle 0° 720° 1440°

minimum off time Block is called

The possible values for the arguments panf_ang_out_action_now, panf_ang_out_start_action, and panf_ang_out_end_action are enumerated as: Table 5.5. Pin actions. Value Description 0 Turn-off - the output pin will be modified to the non-driven state. 1 Turn-on - the output pin will be modified to the driven state. 2 Toggle - the output pin will be toggled. 3 No-action - the output pin will not change driven state.

See pan_set_angular_output() and pan_config_angular_output(). 5.23.1.10. Crankshaft Wheel Decoding Independent of Engine Type

Applications where the ECU is not controlling an internal combustion engine may not need to schedule tasks on an angular basis. Disabling the angle clock used to schedule tasks on an angular basis removes the overhead for such applications but still allows the speed of a crank wheel to be decoded. See pan_config_crank_wheel_mtg(). 5.23.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pan.h Enumerations PAN_RC_T

An enumerated type which contains success and failure codes returned by some angular feature (PAN) functions. Data types PAN_DEVICE_KNOCK_T

This declares a type with enough value range to represent all logical knock devices for all targets.

Copyright 2019, Pi Innovo 379 Library interface

Type Identifier PAN_LCHAN_KNOCK_T

This declares a type with enough value range to represent all logical knock devices for all targets. Functions PAN_RC_T pan_config_angular_ad_var

Function to configure the angular analogue input channel relative to the TDC firing for each cylinder. PAN_RC_T pan_get_angular_ad_avg_var

Function to read the average of sampling an analogue input channel relative to the TDC firing angle for the current cylinder. PAN_RC_T pan_get_angular_ad_samples_var

Function to read the individual samples taken from an analogue input channel relative to the TDC firing angle for the given cylinder. PAN_RC_T pan_get_angular_ad_avg_abs

Function to read the average of sampling an analogue input channel relative to the start of an engine cycle. PAN_RC_T pan_get_angular_ad_samples_abs

Function to read the individual samples taken from an analogue input channel relative to the start of an engine cycle. PAN_RC_T pan_config_angular_output

Function to configure a generic angular output. PAN_RC_T pan_set_angular_output

Function to control a generic angular output. PAN_RC_T pan_config_crank_wheel_mtg

Function to configure a missing tooth grouped type of crank wheel. PAN_RC_T pan_config_crank_wheel_mtg_ext

Function to configure additional parameters involved in crank synchronisation. PAN_RC_T pan_get_crank_wheel_angle

Function to determine the current angle of the crank wheel. PAN_RC_T pan_get_crank_wheel_movement

Function to determine if the crank wheel is moving. PAN_RC_T pan_get_crank_speed_per_rev

Copyright 2019, Pi Innovo 380 Library interface

Type Identifier Function to determine the speed of the crank wheel on a per revolution basis. PAN_RC_T pan_get_crank_speed_per_tooth

Function to determine the speed of the crank wheel on a per tooth basis. PAN_RC_T pan_get_crank_wheel_sync

Function to determine whether the ECU has synchronised to the crank wheel or not. PAN_RC_T pan_get_crank_wheel_tooth

Function to determine the current tooth of the crank wheel. PAN_RC_T pan_get_crank_secondary_phase

Function to determine the current phase angle of a secondary crank wheel relative to the primary crank wheel. PAN_RC_T pan_get_crank_pin_state

Function to read the crank pin state. PAN_RC_T pan_config_cam_wheel_st

Function to configure a single tooth cam wheel. PAN_RC_T pan_config_cam_wheel_mt

Function to configure a single or multi-toothed cam wheel. PAN_RC_T pan_config_cam_wheel_app

Function to configure a cam wheel where synchronisation is determined by the application. PAN_RC_T pan_get_cam_wheel_movement

Function to determine if the cam wheel is moving. PAN_RC_T pan_get_cam_speed_per_rev

Function to determine the speed of the cam wheel on a per revolution basis. PAN_RC_T pan_get_cam_wheel_sync

Function to determine whether the ECU has synchronised to the cam wheel or not. PAN_RC_T pan_declare_cam_wheel_sync

Function to allow the application to declare synchronisation to cam. PAN_RC_T pan_get_cam_wheel_teeth_angles

Function to retrieve captured angle information about cam wheel teeth.

Copyright 2019, Pi Innovo 381 Library interface

Type Identifier PAN_RC_T pan_config_engine

Function to configure the fundamental engine parameters that the ECU uses to keep track of the engine position and schedule tasks on an angular rate. PAN_RC_T pan_get_engine_cyl

Function to determine the current cylinder of the engine. PAN_RC_T pan_get_engine_angle

Function to determine the current angle of the engine. PAN_RC_T pan_get_engine_speed_per_cyl

Function to determine the speed of the engine on a per cylinder basis. PAN_RC_T pan_get_engine_speed_per_rev

Function to determine the speed of the engine on a per revolution basis. PAN_RC_T pan_get_engine_speed_per_tooth

Function to read the speed of the engine on a per tooth basis. PAN_RC_T pan_get_engine_speed_tr_abs

Function to determine the speed of the engine between crank teeth relative to the first crank tooth (for the engine cycle). PAN_RC_T pan_get_engine_speed_tr_rel

Function to determine the speed of the engine between crank teeth relative to a cylinder's TDC firing angle. PAN_RC_T pan_get_engine_sync

Function to read whether the ECU has synchronised to the crank and (where applicable) cam wheel(s) or not. PAN_RC_T pan_config_injectors

Function to configure injector channels and drive type. PAN_RC_T pan_config_injector

Function to configure a single injector. BOOL pan_injection_config_successful

Function to discover if injection configuration was successful. PAN_RC_T pan_config_injectors_comp_di

Function to configure the maps and channels used for direct-injection fuel injector characteristic lookup to determine pulse width from a volume request and current fuel rail pressure for any DI injector

Copyright 2019, Pi Innovo 382 Library interface

Type Identifier that has pulses scheduled with a duration mode PIO_INJDI_DURATION_MODE_VOLUME. PAN_RC_T pan_set_injection_comp_frp_di

Function to override the fuel rail pressure input. PAN_RC_T pan_config_injections_di

Function to configure various injection parameters. PAN_RC_T pan_set_injection_di

Function to request injections for a given injector. PAN_RC_T pan_get_injection_di_setpoint

Function to read back injection parameters for a given injector. PAN_RC_T pan_set_initial_injection_gpi

Function to convert and store the duration for the initial (priming) fuel pulse. PAN_RC_T pan_enable_initial_injection_gpi

Function to enable an initial (priming) fuel pulse. PAN_RC_T pan_set_injection_gpi

Function to set the injector pulse schedule for a cylinder (angle-duration). PAN_RC_T pan_update_injection_gpi

Function to update a cylinder's injector pulse schedule (angle-duration). PAN_RC_T pan_get_injection_gpi_setpoint

Function to read back injection parameters for a given injector. PAN_RC_T pan_config_knock

Function to configure the knock sensing feature, and set the earliest starting angle of any knock detection window relative to any cyclinder's TDC firing angle (positive angles before TDC). PAN_RC_T pan_get_knock_feedback

Function to retrieve the last processed knock signal result for a given cylinder. PAN_RC_T pan_set_knock_window

Function to schedule a knock window relative to a cylinder's TDC. PAN_RC_T pan_set_knock_filter_hip901x

Function to set the filtering parameters to be applied to the knock transducer signal when it is sampled.

Copyright 2019, Pi Innovo 383 Library interface

Type Identifier PAN_RC_T pan_convert_knock_filter_hip901x_values

Convert real values for HIP901x filter values into enumeration values. PAN_RC_T pan_config_sparks

Function to configure spark output channels and type. PAN_RC_T pan_set_spark

Function to request a spark pulse for a given cylinder. BOOL pan_spark_config_successful

Function to discover if spark configuration was successful. 5.23.3. Interface detail 5.23.3.1. Enumerations

5.23.3.1.1. PAN_RC_T

Summary: An enumerated type which contains success and failure codes returned by some angular feature (PAN) functions.

Enumerations:

PAN_RC_OK Return code if everything progressed as expected.

PAN_RC_SW_ERROR Return code if an internal error occurred which was the result of a software error.

PAN_RC_HW_ERROR Return code if a hardware error occurred which stopped a channel being sampled or actuated.

PAN_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PAN_RC_CLIPPED_ARGS Return code if at least one of the arguments was clipped to its valid range.

PAN_RC_SDM_ALLOC_ERROR Return code if could not allocate eTPU SDM for function (internal error).

PAN_RC_BAD_IO_CHAN Return code if a given I/O channel cannot be used.

PAN_RC_ENGINE_NOT_CONFIGURED Return code if basic engine configuration hasn't happened yet.

PAN_RC_CRANK_NOT_CONFIGURED Return code if basic crank configuration hasn't happened yet.

Copyright 2019, Pi Innovo 384 Library interface

PAN_RC_CAM_NOT_CONFIGURED Return code if basic cam configuration hasn't happened yet.

PAN_RC_INJ_NOT_CONFIGURED Return code if basic injection output configuration hasn't happened yet.

PAN_RC_SPARK_NOT_CONFIGURED Return code if basic spark output configuration hasn't happened yet.

PAN_RC_ANGULAR_AD_NOT_CONFIGURED Return code if basic angular analogue input configuration hasn't happened yet.

PAN_RC_ENGINE_NOT_SYNCED Return code if engine sync hasn't happened yet.

PAN_RC_CRANK_NOT_SYNCED Return code if crank sync hasn't happened yet.

PAN_RC_CAM_NOT_SYNCED Return code if cam sync hasn't happened yet.

PAN_RC_CAM_DATA_UNAVAILABLE Return code if cam data is unavailable.

PAN_RC_CAM_WINDOW_CONFIG_INVALID Return code if the cam window is defined across an engine gap.

PAN_RC_CAM_WINDOW_TOO_WIDE Return code if the cam window too large.

PAN_RC_CONFIGURATION_INCOMPLETE Return code if basic engine configuration hasn't happened yet.

PAN_RC_CONFIG_MISMATCH Return code if there is a configuration mismatch, e.g., the number of injectors != the number of cylinders configured or the primary crank wheel required by the injection functionality has not been configured.

PAN_RC_BAD_AXIS Return code if an axis is not monotonically incrementing as expected.

PAN_RC_ANGULAR_SAMPLE_TOO_FAR Return code if one of the angular A/D sample angles is too far from the TDC calculation point.

PAN_RC_ANGULAR_CLOCK_NOT_CONFIGURED Return code where the angular clock (generated using a toothed crank wheel) has not been configured.

PAN_RC_ENGINE_SPEED_DATA_INCOMPLETE Return code if the data used to calculate engine speed is incomplete.

PAN_RC_INVALID An invalid value, used to when indicated that a valid value has not yet been set.

PAN_RC_KNOCK_NOT_CONFIGURED Return code if knock configuration hasn't happened yet or has not been successful.

Copyright 2019, Pi Innovo 385 Library interface

5.23.3.2. Data types 5.23.3.2.1. PAN_DEVICE_KNOCK_T

Definition: typedef U16 PAN_DEVICE_KNOCK_T

Description: This declares a type with enough value range to represent all logical knock devices for all targets.

See pio.h for a list of relevant devices for a specific target. 5.23.3.2.2. PAN_LCHAN_KNOCK_T

Definition: typedef U16 PAN_LCHAN_KNOCK_T

Description: This declares a type with enough value range to represent all logical knock devices for all targets.

See pio.h for a list of relevant devices for a specific target. 5.23.3.3. Functions 5.23.3.3.1. pan_config_angular_ad_var()

Definition: PAN_RC_T pan_config_angular_ad_var(PAX_LCHAN_T panf_lchan, PIO_AD_GROUP_T panf_group)

Supported targets:

Required license: None (Main library).

Description: Function to configure the angular analogue input channel relative to the TDC firing for each cylinder.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling either pan_get_angular_ad_avg_var() or pan_get_angular_ad_samples_var()

Arg (data in): panf_lchan The channel number of the analogue input channel to be read at an angular rate. The channel will be sampled across the engine cycle, so that values for arbitary angles can be retrieved using the pan_get_angular_ad_avg_var() and pan_get_angular_ad_samples_var() functions. Use the macros included by the pio.h file, of the form PIO_AIN_[NAME].

Copyright 2019, Pi Innovo 386 Library interface

Arg (data in): panf_group The group number to configure for the angular input channel. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_IO_CHAN - channel not supported

• PAN_RC_BAD_ARGS - one or more incorrect function parameter 5.23.3.3.2. pan_get_angular_ad_avg_var()

Definition: PAN_RC_T pan_get_angular_ad_avg_var(U8 panf_cyl, PIO_AD_GROUP_T panf_group, S16 *panf_adc, U8 panf_num_sample, volatile const F32 *panf_sample_angles)

Supported targets:

Required license: None (Main library).

Description: Function to read the average of sampling an analogue input channel relative to the TDC firing angle for the current cylinder.

Arg (data in): panf_cyl The cylinder to retrieve the samples for.

Arg (data in): panf_group The group number to read the angular input value for the given cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc Pointer to the averaged conversion result for the angular analogue input. Cannot be NULL Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample The number of elements in panf_sample_angles Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles An array of angle offsets relative to TDC firing angle per cylinder. Note that a positive value indicates a sample after TDC. Cannot be NULL The sample angles are resolved to the closest actual sample, (samples occur every 6 degrees throughout the engine cycle). Range: (-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - one or more incorrect function parameter

Copyright 2019, Pi Innovo 387 Library interface

• PAN_RC_ANGULAR_AD_NOT_CONFIGURED - angular A/D feature has not been configured 5.23.3.3.3. pan_get_angular_ad_samples_var()

Definition: PAN_RC_T pan_get_angular_ad_samples_var(U8 panf_cyl, PIO_AD_GROUP_T panf_group, S16 *panf_adc, U8 panf_num_sample, volatile const F32 *panf_sample_angles)

Supported targets:

Required license: None (Main library).

Description: Function to read the individual samples taken from an analogue input channel relative to the TDC firing angle for the given cylinder.

Arg (data in): panf_cyl The cylinder to retrieve the samples for.

Arg (data in): panf_group The group number to read the angular input value for the current cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc Pointer to an array where this function stores the conversion results for the angular analogue input channel.The array must have size panf_num_sample or larger. Cannot be NULL Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample The number of elements in panf_sample_angles Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles An array of angle offsets relative to TDC firing angle per cylinder. Note that a positive value indicates a sample after TDC. Cannot be NULL The sample angles are resolved to the closest actual sample (samples occur every 6 degrees throughout the engine cycle). Range: (-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - one or more incorrect function parameter

• PAN_RC_ANGULAR_AD_NOT_CONFIGURED - angular A/D feature has not been configured 5.23.3.3.4. pan_get_angular_ad_avg_abs()

Definition: PAN_RC_T pan_get_angular_ad_avg_abs(PIO_AD_GROUP_T panf_group, S16 *panf_adc, U8 panf_num_sample, volatile const F32 *panf_sample_angles)

Copyright 2019, Pi Innovo 388 Library interface

Supported targets:

Required license: None (Main library).

Description: Function to read the average of sampling an analogue input channel relative to the start of an engine cycle.

Arg (data in): panf_group The group number to read the angular input value for the given angles. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Arg (data out): panf_adc Pointer to the averaged conversion result for the angular analogue input. Cannot be NULL Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample The number of elements in panf_sample_angles Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles An array of angle offsets relative to TDC firing angle per cylinder. Note that a positive value indicates a sample after TDC. Cannot be NULL The sample angles are resolved to the closest actual sample (samples occur every 6 degrees throughout the engine cycle). Range: (-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - one or more incorrect function parameter

• PAN_RC_ANGULAR_AD_NOT_CONFIGURED - angular A/D feature has not been configured 5.23.3.3.5. pan_get_angular_ad_samples_abs()

Definition: PAN_RC_T pan_get_angular_ad_samples_abs(PIO_AD_GROUP_T panf_group, S16 *panf_adc, U8 panf_num_sample, volatile const F32 *panf_sample_angles)

Supported targets:

Required license: None (Main library).

Description: Function to read the individual samples taken from an analogue input channel relative to the start of an engine cycle.

Arg (data in): panf_group The group number to read the angular input value for the current cylinder. Use the enum included by the pio.h file, of the form PIO_AD_GROUP[NUMBER].

Copyright 2019, Pi Innovo 389 Library interface

Arg (data out): panf_adc Pointer to an array where this function stores the conversion results for the angular analogue input channel. The array must have size panf_num_sample or larger. Cannot be NULL Range: [-1, 1] @ 1/4096 A/D counts per LSB.

Arg (data in): panf_num_sample The number of elements in panf_sample_angles Range: [PIO_ANG_MIN_AD_SAMPLES, PIO_ANG_MAX_AD_SAMPLES] elements

Arg (data in): panf_sample_angles An array of angle offsets relative to TDC firing angle per cylinder. Note that a positive value indicates a sample after TDC. Cannot be NULL The sample angles are resolved to the closest actual sample (samples occur every 6 degrees throughout the engine cycle). Range: (-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - one or more incorrect function parameter

• PAN_RC_ANGULAR_AD_NOT_CONFIGURED - angular A/D feature has not been configured 5.23.3.3.6. pan_config_angular_output()

Definition: PAN_RC_T pan_config_angular_output(PDX_LCHAN_T panf_ang_out_channel, PIO_ANG_OUTPUT_MODE_T panf_ang_out_mode, PIO_ANG_OUTPUT_STALL_ACTION_T panf_ang_out_stall_action)

Supported targets:

Required license: None (Main library).

Description: Function to configure a generic angular output.

This function is used to configure a channel to be a generic angular output.

Warning

The function must be called during application initialisation and never during application run-time.

Arg (data in): panf_ang_out_channel The output channel. Use the macros included by the pio.h file, of the form PIO_ANGOT_[NAME].

Arg (data in): panf_ang_out_mode The angular output mode, angle-angle or angle-time. Use the PIO_ANG_OUTPUT_MODE_T macros included by the pio.h file.

Copyright 2019, Pi Innovo 390 Library interface

Arg (data in): panf_ang_out_stall_action The action to take on a stall. This also specifies the initial output state. Use the PIO_ANG_STALL_ACTION_T macros included by the pio.h file.

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - out of range value passed

• PAN_RC_SDM_ALLOC_ERROR - error allocating eTPU RAM

5.23.3.3.7. pan_set_angular_output()

Definition: PAN_RC_T pan_set_angular_output(PDX_LCHAN_T panf_ang_out_channel, U32 panf_ang_out_cyl_id, PIO_ANG_OUTPUT_ACTION_T panf_ang_out_action_now, U8 panf_ang_out_num_pulses, volatile const PIO_ANG_OUTPUT_ACTION_T *panf_ang_out_start_action, volatile const PIO_ANG_OUTPUT_ACTION_T *panf_ang_out_end_action, volatile const F32 *panf_ang_out_start_angle, volatile const F32 *panf_ang_out_duration, BOOL panf_ang_out_allow_end_mod, BOOL panf_ang_out_allow_cycle_repeat, F32 panf_ang_out_min_off_time)

Supported targets:

Required license: None (Main library).

Description: Function to control a generic angular output.

This function is used to control a generic angular output.

Note

pan_config_angular_output() must be called during application initialisation in order to use this functionality.

Arg (data in): panf_ang_out_channel The output channel. Use the macros included by the pio.h file, of the form PIO_ANGOT_[NAME].

Arg (data in): panf_ang_out_cyl_id This parameter specifies how to interpret the start angle. If the value passed here is zero then the value passed in panf_ang_out_start_angle is interpreted as an angle relative to crank zero. If the value passed is a valid cylinder number (starting from 1) then the start angle is intepreted relative to that cylinder's TDC angle. Range: 0 or [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_ang_out_action_now The action to be taken with immediate effect. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file. It is expected that this will usually be set to "no change", which makes it effectively invisible. However, this allows an application to

Copyright 2019, Pi Innovo 391 Library interface

drive an output at an approximate periodic rate (e.g. called from a periodic task) when crank sync has not be attained.

Arg (data in): panf_ang_out_num_pulses The number of elements in the arrays containing the pulse start angles, durations, start actions, and end actions. Each array must be of the same length. on angles. Range: [1, PIO_NUM_ANG_OUTPUT_MAX_PULSES]

Arg (data in): panf_ang_out_start_action An array of panf_ang_out_num_pulses actions to be taken at the start of each pulse event. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file.

Arg (data in): panf_ang_out_end_action An array of panf_ang_out_num_pulses actions to be taken at the end of each pulse event. Use one of the PIO_ANG_OUTPUT_ACTION_T macros included by the pio.h file.

Arg (data in): panf_ang_out_start_angle An array of panf_ang_out_num_pulses angles at which each pulse event starts. This can be crank-relative or TDC-relative depending on the value of panf_ang_out_cyl_id. Positive angles are interpreted as after TDC. The angle is folded to the range [0 720] degrees or [0 360] degrees as appropriate, and an event is then scheduled for the next such angle to occur. For a 4-stroke engine, the range [0 360] degrees is used until full engine sync (i.e. synchronisation with the cam input) has been attained. Range: [-720, 720] degrees

Arg (data in): panf_ang_out_duration An array of panf_ang_out_num_pulses durations of each event which can be either an angle or a time, depending on the mode of operation, as specified by the panf_ang_out_mode parameter in prerequisite call to pan_config_angular_output(). A duration of zero is allowed, in which case the pulse is skipped, and the next non- zero pulse is used. Range: [0, 360000] degrees or [0, 2000] ms

Arg (data in): panf_ang_out_allow_end_mod A flag used to specify whether or not the event currently underway at the same index in the array of events should be adjusted according to the new input data. If this function is called after an event has started and before it has finished, then if this flag is set the end of the event will be adjusted to reflect the new duration and end action. If the duration would place the end point in the past, then the event is terminated immediately. Note that in this case, if any immediate action has been requested, the immediate action will be closely followed by the end action. On the other hand, if this function is called while an event is underway and this flag is clear, then the current event is not affected, and the data is used to schedule a subsequent event once the current event is over. Any immediate action is still honoured, however. Range: FALSE or TRUE

Arg (data in): panf_ang_out_allow_cycle_repeat A flag used to specify whether or not the schedule of pulses should be repeated automatically in the next engine cycle using the same values.

Copyright 2019, Pi Innovo 392 Library interface

Range: FALSE or TRUE

Arg (data in): panf_ang_out_min_off_time This parameter can be used to mandate a minimum time between pulse events after the end action of one event and the start action of the next event. Note a value out of range will be clipped at the endpoints. Range: [PIO_TIME_ANG_OUTPUT_MIN_OFF_TIME_MIN, PIO_TIME_ANG_OUTPUT_MIN_OFF_TIME_MAX] ms

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - input data out of range

• PAN_RC_SDM_ALLOC_ERROR - error allocating eTPU RAM

5.23.3.3.8. pan_config_crank_wheel_mtg()

Definition: PAN_RC_T pan_config_crank_wheel_mtg(PDX_LCHAN_T panf_lchan, PIO_CRANK_WHEEL_T panf_wheel, PIO_CRANK_WHEEL_SYNC_T panf_wheel_sync_scheme, U16 panf_physical_teeth, U16 panf_missing_teeth, BOOL panf_generate_angle_clk, PIO_CRANK_TOOTH_EDGE_T panf_tooth_edge)

Supported targets:

Required license: None (Main library).

Description: Function to configure a missing tooth grouped type of crank wheel.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any crank related functions

Arg (data in): panf_lchan The channel number of the digital input channel to be used for the crank input. Use the macros included by the pio.h file, of the form PIO_DIN[NAME].

Arg (data in): panf_wheel The wheel to configure for the crank input channel. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Copyright 2019, Pi Innovo 393 Library interface

Arg (data in): panf_wheel_sync_scheme The synchronisation scheme to use when syncing to the crank wheel. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL_SYNC[NAME].

Arg (data in): panf_physical_teeth The number of actual teeth and missing teeth on the crank wheel. Range: [PIO_CRANK_TEETH_MIN, PIO_CRANK_TEETH_MAX] teeth

Arg (data in): panf_missing_teeth The number of missing teeth on the crank wheel. Range: [PIO_CRANK_MISSING_MIN, PIO_CRANK_MISSING_MAX] teeth

Arg (data in): panf_generate_angle_clk Specifies whether or not the configured crank wheel generates an angular clock.

• TRUE if a crank wheel generates an angular clock;

• FALSE otherwise.

Arg (data in): panf_tooth_edge Specifies which edge to detect for transitions on the crank wheel. For VRS inputs, the differential signal will be processed in hardware first, and then the edge will be detected on this post processed digital signal. For hall effect, the digital signal is detected directly on the input pin. Use the enum included by the pio.h file, of the form PIO_CRANK_TOOTH_EDGE[NAME].

• DEFAULT uses the default edge for the ECU

• RISING sets the edge to rising edge detection

• FALLING sets the edge to falling edge detection

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_IO_CHAN - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SW_ERROR - internal software error 5.23.3.3.9. pan_config_crank_wheel_mtg_ext()

Definition: PAN_RC_T pan_config_crank_wheel_mtg_ext(PIO_CRANK_WHEEL_T panf_wheel, U8 panf_skip_crank_teeth, F32 panf_first_tooth_timeout, F32 panf_ratio_gap_short_long, F32 panf_ratio_gap_long_short, F32 panf_ratio_across_gap_nr_window, F32 panf_ratio_across_gap_sd_window, F32 panf_ratio_after_gap_nr_window, F32 panf_ratio_after_gap_sd_window, F32 panf_ratio_normal_nr_window,

Copyright 2019, Pi Innovo 394 Library interface

F32 panf_ratio_normal_sd_window, F32 panf_ratio_timeout_nr_window, F32 panf_ratio_timeout_sd_window)

Supported targets:

Required license: None (Main library).

Description: Function to configure additional parameters involved in crank synchronisation.

Warning

The function must be called during application initialisation and never during application run.

Arg (data in): panf_wheel The wheel to configure for the crank input channel. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data in): panf_skip_crank_teeth The number of processed teeth edges to ignore when the ECU initialises. Used to ignore noise when the ECU electronics power up. A value of zero disables this functionality. Range: [0, 255] teeth

Arg (data in): panf_first_tooth_timeout When crank synchronisation has not been achieved or is lost, this parameter defines the maximum length of time between teeth used to start looking for crank synchronisation. In effect, this defines the minimum speed the crankshaft must be turning before the library starts to look for crank synchronisation. Range: [0, 1000] milliseconds

Arg (data in): panf_ratio_gap_short_long The ratio between the tooth before the missing region and the missing region itself, used by the library determine crank synchronisation. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_gap_long_short The ratio between the tooth after the missing region and the missing region itself, used by the library determine crank synchronisation. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_across_gap_nr_window The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies only to the last tooth before the missing tooth region. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_across_gap_sd_window The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies only to the last tooth before the missing tooth region. See the user guide for further details.

Copyright 2019, Pi Innovo 395 Library interface

Range: [0, 4) unitless

Arg (data in): panf_ratio_after_gap_nr_window The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies only to the first tooth after the missing tooth region. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_after_gap_sd_window The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies only to the first tooth after the missing tooth region. See the user guide for further details. Range: [0, 4) unitless

Arg (data in): panf_ratio_normal_nr_window The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies to teeth that do no occur immediately before or after the missing tooth region. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_normal_sd_window The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies to teeth that do no occur immediately before or after the missing tooth region (normal teeth). See the user guide for further details. Range: [0, 4) unitless

Arg (data in): panf_ratio_timeout_nr_window The ratio of the last tooth-to-tooth time, used by the library to reject noise from the processed crank signal. Applies to the situation where the previous normal tooth did not arrive in time and crank stall is being considered. See the user guide for further details. Range: [0, 1) unitless

Arg (data in): panf_ratio_timeout_sd_window The ratio of the last tooth-to-tooth time, used by the library to detect crank stall. Applies to the situation where the previous normal tooth did not arrive in time and crank stall is being considered. See the user guide for further details. Range: [0, 4) unitless

Return:

• PAN_RC_OK if successful

• one of the other enumerations otherwise 5.23.3.3.10. pan_get_crank_wheel_angle()

Definition: PAN_RC_T pan_get_crank_wheel_angle(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_valid, F32 *panf_crank_angle)

Supported targets:

Required license: None (Main library).

Description: Function to determine the current angle of the crank wheel.

Copyright 2019, Pi Innovo 396 Library interface

Arg (data in): panf_wheel The configured crank wheel to read. Currently only PIO_CRANK_WHEEL_PRIMARY is supported.

Arg (data out): panf_valid Pointer to the boolean result of whether the value returned in panf_crank_angle is valid. Cannot be NULL

Arg (data out): panf_crank_angle Pointer to where the current crank angle will be written. Cannot be NULL Range: [0, 360) degrees Resolution: at least 0.1 degrees (for M250 targets)

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SW_ERROR - internal software error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been

• PAN_RC_CRANK_NOT_SYNCED - sync has not been gained with the crank wheel

• PAN_RC_ANGULAR_CLOCK_NOT_CONFIGURED - crank wheel is not configured to generate an angle clock

5.23.3.3.11. pan_get_crank_wheel_movement()

Definition: PAN_RC_T pan_get_crank_wheel_movement(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_crank_movement)

Supported targets:

Required license: None (Main library).

Description: Function to determine if the crank wheel is moving.

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_movement Pointer to the boolean result of whether the crank is moving. Cannot be NULL

Return:

• PAN_RC_OK - successful action

Copyright 2019, Pi Innovo 397 Library interface

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured 5.23.3.3.12. pan_get_crank_speed_per_rev()

Definition: PAN_RC_T pan_get_crank_speed_per_rev(PIO_CRANK_WHEEL_T panf_wheel, F32 *panf_crank_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the crank wheel on a per revolution basis.

The speed is calculated every 360 degrees.

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_speed Pointer to where the current crank speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_CRANK_NOT_SYNCED - sync has not been gained with the crank wheel 5.23.3.3.13. pan_get_crank_speed_per_tooth()

Definition: PAN_RC_T pan_get_crank_speed_per_tooth(PIO_CRANK_WHEEL_T panf_wheel, F32 *panf_crank_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the crank wheel on a per tooth basis.

The speed is calculated on request.

Arg (data in): panf_wheel The configured crank wheel to read.

Copyright 2019, Pi Innovo 398 Library interface

Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_speed Pointer to where the current crank speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured 5.23.3.3.14. pan_get_crank_wheel_sync()

Definition: PAN_RC_T pan_get_crank_wheel_sync(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_crank_sync)

Supported targets:

Required license: None (Main library).

Description: Function to determine whether the ECU has synchronised to the crank wheel or not.

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_crank_sync Pointer to the boolean result of whether the crank is synced. Cannot be NULL

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured 5.23.3.3.15. pan_get_crank_wheel_tooth()

Definition: PAN_RC_T pan_get_crank_wheel_tooth(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_valid, U16 *panf_crank_tooth)

Supported targets:

Required license: None (Main library).

Description: Function to determine the current tooth of the crank wheel.

Copyright 2019, Pi Innovo 399 Library interface

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME].

Arg (data out): panf_valid Pointer to the boolean result of whether the value returned in panf_crank_tooth is valid. Cannot be NULL

Arg (data out): panf_crank_tooth Pointer to where the current tooth will be written. The written tooth is not adjusted for the missing teeth (i.e., only physical teeth are represented). Cannot be NULL. Range: [1, PIO_CRANK_TEETH_MAX] teeth

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured 5.23.3.3.16. pan_get_crank_secondary_phase()

Definition: PAN_RC_T pan_get_crank_secondary_phase(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_valid, F32 *panf_phase)

Supported targets:

Required license: None (Main library).

Description: Function to determine the current phase angle of a secondary crank wheel relative to the primary crank wheel.

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL_SECONDARY_[NAME].

Arg (data out): panf_valid Pointer to the boolean result of whether the value returned in panf_phase is valid. Cannot be NULL

Arg (data out): panf_phase Pointer to where the current phase angle, between the primary crank wheel and the wheel selected in the panf_wheel parameter, is written. The phase angle is the secondary angle minus the primary angle, so if the secondary wheel were 10 degrees ahead of the primary, the phase would be 10 degrees, and if the primary wheel were 10 degrees ahead of the secondary, the phase would be 350 degrees. Cannot be NULL

Copyright 2019, Pi Innovo 400 Library interface

Range: [0, 360) degrees Resolution: 0.05 degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ANGULAR_CLOCK_NOT_CONFIGURED - crank wheel is not configured to generate an angle clock

• PAN_RC_SDM_ALLOC_ERROR - not enough space to accommodate all the eTPU functions allocated 5.23.3.3.17. pan_get_crank_pin_state()

Definition: PAN_RC_T pan_get_crank_pin_state(PIO_CRANK_WHEEL_T panf_wheel, BOOL *panf_crk_pin_state)

Supported targets:

Required license: None (Main library).

Description: Function to read the crank pin state.

Arg (data in): panf_wheel The configured crank wheel to read. Use the enum included by the pio.h file, of the form PIO_CRANK_WHEEL[NAME]. Range: [0, PIO_CRANK_WHEEL_LAST - 1]

Arg (data out): panf_crk_pin_state The state of the crank pin is written through this pointer. Cannot be NULL. Range: 0 or 1

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured 5.23.3.3.18. pan_config_cam_wheel_st()

Definition: PAN_RC_T pan_config_cam_wheel_st(PDX_LCHAN_T panf_lchan, PIO_CAM_WHEEL_T panf_wheel, F32 panf_start_window_angle, F32 panf_end_window_angle)

Supported targets:

Required license: None (Main library).

Copyright 2019, Pi Innovo 401 Library interface

Description: Function to configure a single tooth cam wheel.

If the cam wheel has a single tooth or lobe, or has a toothed pattern where one of the teeth is uniquely identifiable across both halves of the engine cycle, then the platform can decode the signal from the cam trigger wheel sensor and a related crank trigger wheel sensor to determine the overall engine position.

See the pan_config_cam_wheel_app() interface for instances where there is no cam trigger wheel and the application must determine engine position through other means.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any cam related functions

Arg (data in): panf_lchan The channel number of the digital input channel to be used for the cam input. Use the macros included by the pio.h file, of the form PIO_DIN[NAME].

Arg (data in): panf_wheel The wheel to configure for the cam input channel. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME]. Only the PRIMARY wheel will be used for engine cycle synchronisation.

Arg (data in): panf_start_window_angle The start angle of the cam window (the window within which a pulse on the cam signal will be accepted as a valid synchronisation pulse) after cylinder 1 firing TDC (a positive value denotes an angle after TDC). The cam window must not start, end or straddle the missing tooth region of the crank wheel. The cam window must enclose a uniquely identifiable edge across both halves of the engine cycle. Range: [-720, 720) degrees

Arg (data in): panf_end_window_angle The end angle of the cam window (the window within which a pulse on the cam signal will be accepted as a valid synchronisation pulse) after cylinder 1 firing TDC (a positive value denotes an angle after TDC). The cam window must not start, end or straddle the missing tooth region of the crank wheel. The cam window must enclose a uniquely identifiable edge across both halves of the engine cycle.

Copyright 2019, Pi Innovo 402 Library interface

Range: [-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_IO_CHAN - channel not supported

• PAN_RC_BAD_ARGS - configuration error 5.23.3.3.19. pan_config_cam_wheel_mt()

Definition: PAN_RC_T pan_config_cam_wheel_mt(PDX_LCHAN_T panf_lchan, PIO_CAM_WHEEL_T panf_wheel, U8 panf_num_teeth, PIO_CAM_CAP_EDGE_T panf_tooth_edge_capture, F32 panf_start_window_angle, F32 panf_end_window_angle)

Supported targets:

Required license: None (Main library).

Description: Function to configure a single or multi-toothed cam wheel.

If the cam wheel has a toothed pattern where one of the teeth is uniquely identifiable across both halves of the engine cycle, then the platform can decode the signal from the cam trigger wheel sensor and a related crank trigger wheel sensor to determine the overall engine position.

See the pan_config_cam_wheel_st() interface for a single toothed version of this function.

See the pan_config_cam_wheel_app() interface for instances where there is no cam trigger wheel and the application must determine engine position through other means.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any cam related functions

Arg (data in): panf_lchan The channel number of the digital input channel to be used for the cam input. Use the macros included by the pio.h file, of the form PIO_DIN[NAME].

Arg (data in): panf_wheel The wheel to configure for the cam input channel. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Copyright 2019, Pi Innovo 403 Library interface

Only the PRIMARY wheel will be used for engine cycle synchronisation.

Arg (data in): panf_num_teeth The number of physical teeth on the cam wheel. Range: [PIO_CAM_TEETH_MIN, PIO_CAM_TEETH_MAX] teeth

Arg (data in): panf_tooth_edge_capture The processed tooth edges to capture, either rising, falling or both.

Arg (data in): panf_start_window_angle The start angle of the cam window (the window within which a pulse on the cam signal will be accepted as a valid synchronisation pulse) after cylinder 1 firing TDC (a positive value denotes an angle after TDC). The cam window must not start, end or straddle the missing tooth region of the crank wheel. The cam window must enclose a uniquely identifiable edge across both halves of the engine cycle. Range: [-720, 720) degrees

Arg (data in): panf_end_window_angle The end angle of the cam window (the window within which a pulse on the cam signal will be accepted as a valid synchronisation pulse) after cylinder 1 firing TDC (a positive value denotes an angle after TDC). The cam window must not start, end or straddle the missing tooth region of the crank wheel. The cam window must enclose a uniquely identifiable edge across both halves of the engine cycle. Range: [-720, 720) degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_IO_CHAN - channel not supported

• PAN_RC_BAD_ARGS - configuration error 5.23.3.3.20. pan_config_cam_wheel_app()

Definition: PAN_RC_T pan_config_cam_wheel_app(PIO_CAM_WHEEL_T panf_wheel)

Supported targets:

Required license: None (Main library).

Description: Function to configure a cam wheel where synchronisation is determined by the application.

If there is a crank trigger wheel but no cam trigger wheel, and if the application can determine which half of the engine cycle is active (perhaps by looking at engine acceleration relative to cylinder combustion) then the application can tell the platform which half of the engine cycle is active to allow the platform to determine an overall engine position.

Copyright 2019, Pi Innovo 404 Library interface

See the pan_declare_cam_wheel_sync() interface to understand how to tell the platform about engine position.

See the pan_config_cam_wheel_st() interface for instances where there is a cam trigger wheel that the platform can decode independently from the application.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any cam related functions

Arg (data in): panf_wheel The cam wheel to configure for application declared synchronisation. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME]. Only the PRIMARY wheel can be used for engine cycle synchronisation and so that must be passed here, if more than one wheel is available for your target.

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_IO_CHAN - channel not supported

• PAN_RC_BAD_ARGS - configuration error

5.23.3.3.21. pan_get_cam_wheel_movement()

Definition: PAN_RC_T pan_get_cam_wheel_movement(PIO_CAM_WHEEL_T panf_wheel, BOOL *panf_cam_movement)

Supported targets:

Required license: None (Main library).

Description: Function to determine if the cam wheel is moving.

For use only with physical (non-virtual) cam wheels.

Arg (data in): panf_wheel The configured cam wheel to read. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_cam_movement Pointer to the boolean result of whether the cam is moving.

Copyright 2019, Pi Innovo 405 Library interface

Cannot be NULL

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured 5.23.3.3.22. pan_get_cam_speed_per_rev()

Definition: PAN_RC_T pan_get_cam_speed_per_rev(PIO_CAM_WHEEL_T panf_wheel, F32 *panf_cam_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the cam wheel on a per revolution basis.

The speed is calculated every 720 degrees. For use only with physical (non-virtual) cam wheels.

Arg (data in): panf_wheel The configured cam wheel to read. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_cam_speed Pointer to where the current cam speed will be written. Cannot be NULL Range: [0, 5000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured 5.23.3.3.23. pan_get_cam_wheel_sync()

Definition: PAN_RC_T pan_get_cam_wheel_sync(PIO_CAM_WHEEL_T panf_wheel, BOOL *panf_cam_sync)

Supported targets:

Required license: None (Main library).

Description: Function to determine whether the ECU has synchronised to the cam wheel or not.

Copyright 2019, Pi Innovo 406 Library interface

Arg (data in): panf_wheel The configured cam wheel to read. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_cam_sync Pointer to the boolean result of whether the cam is synced. Cannot be NULL

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured

5.23.3.3.24. pan_declare_cam_wheel_sync()

Definition: PAN_RC_T pan_declare_cam_wheel_sync(PIO_CAM_WHEEL_T panf_wheel, BOOL panf_cam_synced, BOOL panf_offset_engine_position)

Supported targets:

Required license: None (Main library).

Description: Function to allow the application to declare synchronisation to cam.

If a cam wheel has been declared using the pan_config_cam_wheel_app() interface, then the platform will not try to decode the signal from a cam trigger wheel sensor. Instead, the application can declare synchronisation when it determines which half of the engine cycle has occurred (for instance, by looking for engine acceleration immediately after combustion) using the panf_cam_synced parameter.

The application may detect synchronisation and determine that the current engine position reflects the current engine cycle, or that the engine position is half an engine cycle out. If the engine position is half an engine cycle out, the application must tell the platform using the panf_offset_engine_position parameter.

Arg (data in): panf_wheel The configured cam wheel to declare sync against. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME]. Only the PRIMARY wheel can be used for engine cycle synchronisation and so that must be passed here, if more than one wheel is available for your target.

Arg (data in): panf_cam_synced Set TRUE if synchronised, FALSE otherwise. This parameter is only actioned if it changes the cam wheel sync state. For instance, if sync had previously been declared as found (TRUE), then the function only performs an action if sync is declared as lost (FALSE).

Copyright 2019, Pi Innovo 407 Library interface

Arg (data in): panf_offset_engine_position Set TRUE if the engine position should be offset by 360 crank degrees, FALSE otherwise. This parameter is only used when panf_cam_synced is actioned.

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured 5.23.3.3.25. pan_get_cam_wheel_teeth_angles()

Definition: PAN_RC_T pan_get_cam_wheel_teeth_angles(PIO_CAM_WHEEL_T panf_wheel, F32 *panf_angles, BOOL *panf_timeout, U32 *panf_count_timeout, U32 *panf_count_missing, U32 *panf_count_extra)

Supported targets:

Required license: None (Main library).

Description: Function to retrieve captured angle information about cam wheel teeth.

For use only with physical (non-virtual) cam wheels.

Arg (data in): panf_wheel The configured cam wheel to read. Use the enum included by the pio.h file, of the form PIO_CAM_WHEEL[NAME].

Arg (data out): panf_angles A pointer to an array written with the engine angle of each cam trigger wheel edge, relative to TDC-firing of cylinder 1. The order of recorded angles differs depending on the synchronisation state of the cam trigger wheel. Unsynchronised: the array is treated as a circular buffer. Each time a processed cam tooth edge is detected, the next element in the array is used to record the angle. When all elements in the array are filled, the first array element is used to record the next edge angle. Synchronised: the first array element is set to the angle of the synchronisation edge and all remaining elements are set to zero. Subsequent cam tooth edge detections are recorded in subsequent array elements. Once the array is full, edges unrelated to synchronisation detection are not recorded (unrecorded edges can be determined by reading the missing and extra edge counters). Lost synchronisation: if more than one edge is detected in the synchronisation window then the last detected edge is used to set the first array element. If the detected edge is valid then at the end of the cam wheel revolution the missing edge error count is incremented. If the detected edge is invalid (spurious) then this condition will only be detectable if additional spurious events outside the synchronisation window occur (as extra edge counts) or if the application can determine that the recorded angle is incorrect. Cannot be NULL.

Copyright 2019, Pi Innovo 408 Library interface

Range: [0, 720) degrees

Arg (data out): panf_timeout A pointer to a store written with a boolean representing whether the input signal from the cam trigger wheel has timed out (TRUE) or not (FALSE). Cannot be NULL.

Arg (data out): panf_count_timeout A pointer to a store written with the number of timeout events. A timeout is declared if there is no cam trigger wheel edge for approx. 2.1 seconds (roughly 30 RPM for a single tooth cam trigger wheel). The count accumulates events modulo 16777216 (i.e., the counter will wrap). Cannot be NULL. Range: [0, 16777216) events

Arg (data out): panf_count_missing A pointer to a store written with the number of missing edge events. A missing edge event occurs when fewer edges than expected are detected for a single cam trigger wheel revolution. Note that synchronisation with the cam trigger wheel can occur, even with missing edge events, so long as a processed cam tooth edge is seen within the synchronisation window defined by the pan_config_cam_wheel_st() or pan_config_cam_wheel_mt() functions. The count accumulates events modulo 16777216 (i.e., the counter will wrap). Cannot be NULL. Range: [0, 16777216) events

Arg (data out): panf_count_extra A pointer to a store written with the number of extra edge events. An extra edge event occurs when more edges than expected are detected for a single cam trigger wheel revolution. Note that, as with the missing edge error logic, synchronisation can occur, even with extra edge events, so long as a processed cam tooth edge is seen within the synchronisation window defined by the pan_config_cam_wheel_st() or pan_config_cam_wheel_mt() functions. For instance, if a cam wheel is setup for two teeth through pan_config_cam_wheel_mt() but the sensor has three teeth, then the block will increase the extra edge count once per cam wheel revolution. Note that when synchronisation with the cam trigger wheel is lost because a processed cam tooth edge no longer occurs in the synchronisation window then the extra edge error indicator will increase. The count accumulates events modulo 16777216 (i.e., the counter will wrap). Cannot be NULL. Range: [0, 16777216) events

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured

Copyright 2019, Pi Innovo 409 Library interface

5.23.3.3.26. pan_config_engine()

Definition: PAN_RC_T pan_config_engine(PIO_ENGINE_TYPE_T panf_engine_type, PIO_ENGINE_CYCLE_TYPE_T panf_engine_cycle_type, U8 panf_num_cyl, volatile const F32 *panf_cyl_tdc_firing_angle, F32 panf_task_calc_angle)

Supported targets:

Required license: None (Main library).

Description: Function to configure the fundamental engine parameters that the ECU uses to keep track of the engine position and schedule tasks on an angular rate.

Warning

The function must be called during application initialisation and never during application run.

Note

This function must be called before calling any engine related functions

Arg (data in): panf_engine_type The expected type of engine to configure for the application. Use the enum included by the pio.h file, of the form PIO_ENGINE_TYPE[NAME].

Arg (data in): panf_engine_cycle_type The cycle type of the engine, i.e. 2-stroke or 4-stroke. Use the enum included by the pio.h file, of the form PIO_ENGINE_CYCLE_TYPE_[NAME].

Arg (data in): panf_num_cyl The number of elements in panf_cyl_tdc_firing_angle Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinders

Arg (data in): panf_cyl_tdc_firing_angle An array of values defining the angle of each cylinder's firing TDC in degrees from the mid point of the first tooth after the "missing tooth" gap. The array is specified in cylinder order (and hence the firing order can be derived). Cannot be NULL Range: [0, 720) degrees

Arg (data in): panf_task_calc_angle The angle in degrees relative to firing TDC when the angular task for each cylinder should be executed (a positive value denotes an angle after TDC, a negative value before TDC). It is a single value and applies to all cylinders. Range: [-360, 360] teeth

Copyright 2019, Pi Innovo 410 Library interface

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error 5.23.3.3.27. pan_get_engine_cyl()

Definition: PAN_RC_T pan_get_engine_cyl(BOOL *panf_valid, U8 *panf_cyl)

Supported targets:

Required license: None (Main library).

Description: Function to determine the current cylinder of the engine.

Arg (data out): panf_valid Pointer to the boolean result of whether the value returned in panf_cyl is valid. This will be set to a nonzero value if the engine is synchronized sufficiently to positively identify the cylinder (e.g., both cam and crank for a 4-stroke engine, or crank only for a 2-stroke). Cannot be NULL

Arg (data out): panf_cyl Pointer to where the current cylinder will be written. Cannot be NULL Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinder

Note

If *panf_valid is set to zero, the value of the cylinder outport may change, but may not represent the actual engine position. Use pan_get_engine_angle to determine crank position if the cylinder index is not valid.

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine 5.23.3.3.28. pan_get_engine_angle()

Definition: PAN_RC_T pan_get_engine_angle(BOOL *panf_valid, F32 *panf_engine_angle)

Supported targets:

Copyright 2019, Pi Innovo 411 Library interface

Required license: None (Main library).

Description: Function to determine the current angle of the engine.

Arg (data out): panf_valid Pointer to the boolean result of whether the value returned in panf_engine_angle is valid. Cannot be NULL

Arg (data out): panf_engine_angle Pointer to where the current engine angle will be written. When the ECU detects a tooth then the estimate is set to the known encoder angle. On some targets, between teeth, the estimate is updated at a rate equal to the previous tooth duration. When synchronisation with the cam trigger wheel is achieved, the reported angle may be adjusted by 360 degrees to account for the active half of the engine cycle. Cannot be NULL Range: [0, 720) degrees Resolution: at least 0.1 degrees (for M250 targets)

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_CAM_NOT_CONFIGURED - cam wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine 5.23.3.3.29. pan_get_engine_speed_per_cyl()

Definition: PAN_RC_T pan_get_engine_speed_per_cyl(F32 *panf_engine_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the engine on a per cylinder basis.

The speed is calculated before the angular task is called.

Arg (data out): panf_engine_speed Pointer to where the current engine speed will be written. Cannot be NULL Range: [0, 10000] RPM

Copyright 2019, Pi Innovo 412 Library interface

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine 5.23.3.3.30. pan_get_engine_speed_per_rev()

Definition: PAN_RC_T pan_get_engine_speed_per_rev(F32 *panf_engine_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the engine on a per revolution basis.

The speed is calculated every 360 degrees as the average of the last two revolutions of the crank wheel.

Arg (data out): panf_engine_speed Pointer to where the current engine speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine 5.23.3.3.31. pan_get_engine_speed_per_tooth()

Definition: PAN_RC_T pan_get_engine_speed_per_tooth(F32 *panf_engine_speed)

Supported targets:

Required license: None (Main library).

Copyright 2019, Pi Innovo 413 Library interface

Description: Function to read the speed of the engine on a per tooth basis.

The speed is updated on every tooth of the crank wheel.

Arg (data out): panf_engine_speed Pointer to where the current engine speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured 5.23.3.3.32. pan_get_engine_speed_tr_abs()

Definition: PAN_RC_T pan_get_engine_speed_tr_abs(S16 panf_tooth, S16 panf_tooth_num, F32 *panf_engine_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the engine between crank teeth relative to the first crank tooth (for the engine cycle).

The first crank tooth occurs immediately after the missing tooth region. (see user guide section for the angular feature for further details).

The time that the missing teeth would have occurred is not estimated and is treated the same as the last physical tooth prior to the missing region. If requesting the engine speed based on missing teeth only, the function will return a zero engine speed.

When crank synchronisation (and cam synchronisation if the application supports) has not been achieved then the function returns zero engine speed.

Arg (data in): panf_tooth The first crank tooth to be used in the engine speed calculation. The first crank tooth on the crank wheel occurs immediately after the missing tooth region. If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated. Range: [1, n*2] where n is the number of crank teeth + missing teeth

Arg (data in): panf_tooth_num The number of crank teeth after panf_tooth to be included as part of the engine speed calculation. The engine speed calculation is based on the time difference between the detection of these teeth.

Copyright 2019, Pi Innovo 414 Library interface

If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated. Range: [1, n*2) where n is the number of crank teeth + missing teeth

Arg (data out): panf_engine_speed Pointer to where the current engine speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine

• PAN_RC_CONFIGURATION_INCOMPLETE - tooth range has not been configured 5.23.3.3.33. pan_get_engine_speed_tr_rel()

Definition: PAN_RC_T pan_get_engine_speed_tr_rel(U8 panf_cyl, S16 panf_tooth, S16 panf_tooth_num, F32 *panf_engine_speed)

Supported targets:

Required license: None (Main library).

Description: Function to determine the speed of the engine between crank teeth relative to a cylinder's TDC firing angle.

The time that the missing teeth would have occurred is not estimated and is treated the same as the last physical tooth prior to the missing region. If requesting the engine speed based on missing teeth only, the function will return a zero engine speed.

When crank synchronisation (and cam synchronisation if the application supports) has not been achieved then the function returns zero engine speed.

Arg (data in): panf_cyl The cylinder number to use to read engine speed. Range: [PIO_ANG_MIN_CYLINDERS, PIO_ANG_MAX_CYLINDERS] cylinder

Arg (data in): panf_tooth A crank tooth relative to the cylinder's TDC firing angle (tooth), where 0 is the TDC firing tooth, -1 the proceeding tooth, and so on. If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated.

Copyright 2019, Pi Innovo 415 Library interface

Range: (-n*2, 0] where n is the number of crank teeth + missing teeth

Arg (data in): panf_tooth_num The number of crank teeth after panf_tooth to be included as part of the engine speed calculation. The engine speed calculation is based on the time difference between the detection of these teeth. If the given tooth is out of range, the tooth value will be clipped to the range before engine speed is calculated. Range: [1, n*2) where n is the number of crank teeth + missing teeth

Arg (data out): panf_engine_speed Pointer to where the current engine speed will be written. Cannot be NULL Range: [0, 10000] RPM

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_CRANK_NOT_CONFIGURED - crank wheel has not been configured

• PAN_RC_ENGINE_NOT_CONFIGURED - engine has not been configured

• PAN_RC_ENGINE_NOT_SYNCED - sync has not been gained with the engine

• PAN_RC_CONFIGURATION_INCOMPLETE - tooth range has not been configured 5.23.3.3.34. pan_get_engine_sync()

Definition: PAN_RC_T pan_get_engine_sync(BOOL *panf_engine_sync)

Supported targets:

Required license: None (Main library).

Description: Function to read whether the ECU has synchronised to the crank and (where applicable) cam wheel(s) or not.

For a two-stroke engine, the engine is considered fully synchronised one full crank cycle (360 crankshaft degrees) after the missing tooth gap has first been verified. For a four-stroke engine, the engine is considered synchronised once both crank synchronisation and cam synchronisation have been achieved, and then remains synchronised as long as the ECU remains synchronised to the crank, even if cam synchronisation is lost, i.e. as long as the engine position can still be determined.

Arg (data out): panf_engine_sync Pointer to the boolean result of whether the engine is synced. Cannot be NULL

Return:

• PAN_RC_OK - successful action

Copyright 2019, Pi Innovo 416 Library interface

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_ENGINE_NOT_CONFIGURED - crank wheel has not been configured

5.23.3.3.35. pan_config_injectors()

Definition: PAN_RC_T pan_config_injectors(volatile const PDX_LCHAN_T *panf_lchans, U32 panf_chans, PIO_INJECTOR_DRIVE_T panf_drive, BOOL panf_invert)

Supported targets:

Required license: None (Main library).

Description: Function to configure injector channels and drive type.

This function is used to configure outputs for use as injector channels. All injectors will be configured for the type of engine specified by the call to pan_config_engine.

Note

If both this function and pan_config_injector are used by your application, only the most recent call will take precedence.

This function must be called from your application's initialisation function.

Arg (data in): panf_lchans This is an array of output channels that will be configured as injector outputs. The first element will be applied to cylinder 1, the second to cylinder 2 and so on. Must not be NULL Use the macros included by the pio.h file, of the form PIO_INJOT_[NAME].

Arg (data in): panf_chans The number of injector channels to configure, i.e, the number of elements in panf_lchans. This must be the same as the number of cylinders in the engine. Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_drive The injector drive type, i.e., saturating or peak-hold. Use the macros included by the pio.h file, of the form PIO_INJECTOR_DRIVE_[NAME].

Arg (data in): panf_invert This parameter is used to invert the polarity of the injector output signal, (for saturing injector drive types). Set false for active low (default), true for active high.

Return:

• PAN_RC_OK - successful action

Copyright 2019, Pi Innovo 417 Library interface

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.23.3.3.36. pan_config_injector()

Definition: PAN_RC_T pan_config_injector(U32 panf_inj_id, PDX_LCHAN_T panf_lchan, U32 panf_cyl, PIO_INJECTOR_DRIVE_T panf_drive_type, PIO_INJECTOR_PULSE_TYPE_T panf_pulse_type, BOOL panf_invert)

Supported targets:

Required license: None (Main library).

Description: Function to configure a single injector.

This function is used to configure an injector output channel to have a specific output drive and pulse type, and associate it with a specific cylinder.

Note

If both this function and pan_config_injectors are used by your application, only the most recent call will take precedence. The first call of this function after a call to pan_config_injectors will reset the injector configuration for all injectors.

This function must be called from your application's initialisation function.

Arg (data in): panf_inj_id This is the injector ID to configure. This is a value in the range [1, PIO_ANG_MAX_INJECTORS] and identifies a logical injector.

Arg (data in): panf_lchan This the output channels to associate with the specified injector ID. Use the macros included by the pio.h file, of the form PIO_INJOT_[NAME]. This channel associates the logical injector with a specific hardware channel.

Arg (data in): panf_cyl The cylinder with which to associate this injector. This is the cylinder relative to which the injector events will be scheduled. Note that more than one injector can be associated with the same cylinder. Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_pulse_type The pulse type for the injector defined in pio.h: port- injection style or direct-injection style. Of the form PIO_INJECTOR_PULSE_TYPE_[NAME]

Arg (data in): panf_drive_type The injector drive type, i.e., saturating or peak-hold.

Copyright 2019, Pi Innovo 418 Library interface

Use the macros included by the pio.h file, of the form PIO_INJECTOR_DRIVE_[NAME].

Arg (data in): panf_invert This parameter is used to invert the polarity of the injector output signal, (for saturing injector drive types). Set false for active low (default), true for active high.

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.23.3.3.37. pan_injection_config_successful()

Definition: BOOL pan_injection_config_successful(PAN_RC_T *panf_config_result)

Supported targets:

Required license: None (Main library).

Description: Function to discover if injection configuration was successful.

Some aspects of the injection configuration have to occur after the initialisation functions are called. This is because the ordering of calls to the various initialisation functions cannot be guaranteed. This function reports whether or not injection configuration post-initialisation was successful.

Arg (data in): panf_config_result If non-NULL, a return code will be written here to allow a higher level of detail in the case of an error occuring during configuration. If configuration has yet to take place, a value of PAN_RC_INVALID will be written here. Range: [NULL or valid address]

Return:

• TRUE - configuration was successful

• FALSE - configuration failed

5.23.3.3.38. pan_config_injectors_comp_di()

Definition: PAN_RC_T pan_config_injectors_comp_di(PAX_LCHAN_T panf_frp_chan, volatile const F32 *panf_injcomp_map_x, U8 panf_injcomp_map_x_sz, volatile const F32 *panf_injcomp_map_y, U8 panf_injcomp_map_y_sz, volatile const F32 *panf_injcomp_map_z, volatile const F32 *panf_frp_tf_x_volts, volatile const F32 *panf_frp_tf_z_MPa, S32 panf_frp_tf_sz, F32 panf_frp_tf_max_volts)

Copyright 2019, Pi Innovo 419 Library interface

Supported targets:

Required license: None (Main library).

Description: Function to configure the maps and channels used for direct- injection fuel injector characteristic lookup to determine pulse width from a volume request and current fuel rail pressure for any DI injector that has pulses scheduled with a duration mode PIO_INJDI_DURATION_MODE_VOLUME.

Before each injection pulse is made, the fuel rail pressure (FRP) is sampled so that the appropriate injection duration can be accurately determined to deliver the requested fuel volume. The injection duration is looked up in the map panf_injcomp_map_z, using requested pulse volume and the FRP as inputs. The FRP is sampled at the pulse on angle.

Note

This function must be called before scheduling any injections requiring volume-based injections.

Arg (data in): panf_frp_chan The analogue input channel that the Fuel Rail Pressure input is to be read from. Use the macros included by the pio.h file, of the form PIO_AIN_INJ_FBK_[NAME].

Arg (data in): panf_injcomp_map_x This is the x axis of the fuel rail pressure compensation map and contains pulse volume values. Cannot be NULL. The axis values must be strictly increasing. Out- of-range values result in error and leave the characteristic map unconfigured. Range: [0, 512) mm3

Arg (data in): panf_injcomp_map_x_sz The number of elements in panf_injcomp_map_x. Range: [1, 10] elements

Arg (data in): panf_injcomp_map_y This is the y axis of the fuel rail pressure compensation map and contains fuel rail pressure values. Cannot be NULL. The axis values must be strictly increasing. Out- of-range values result in error and leave the characteristic map unconfigured. Range: [0, 500] MPa

Arg (data in): panf_injcomp_map_y_sz The number of elements in panf_injcomp_map_y. Range: [1, 10] elements

Arg (data in): panf_injcomp_map_z This is the z axis (data) of the fuel rail pressure compensation map and contains injection pulse duration values. This data must be stored in colum major order.

Copyright 2019, Pi Innovo 420 Library interface

The values in this map will be clipped to the range [0, 1000] ms.

Note

Actual resolution of the duration is a function of the maximum duration in the entire map. The resolution is (floor(max_duration/16.38375ms)+1)*0.25us (for MPC5534 based targets) and (floor(max_duration/15.88727ms)+1)*0.2424 us (for MPC5674F based targets) Cannot be NULL. Range: [0, 1000] ms

Arg (data in): panf_frp_tf_x_volts This is the x axis of the transfer function that converts a voltage (i.e., of a FRP sensor) into a fuel rail pressure quantity. Cannot be NULL. Range: [0, panf_frp_tf_max_volts] volts

Arg (data in): panf_frp_tf_z_MPa This is the z axis of the transfer function that converts a voltage (i.e., of a FRP sensor) into a fuel rail pressure quantity. Cannot be NULL. Range: [0, 500] MPa

Arg (data in): panf_frp_tf_sz The number of elements in panf_frp_tf_x_volts and panf_frp_tf_z_MPa. Range: [1, 10] elements

Arg (data in): panf_frp_tf_max_volts The upper voltage limit of panf_frp_chan. I.e., on a 0-5v input, this would be 5v. Range: [0, 24] volts

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - inconsistent initialization or other software error

• PAN_RC_BAD_IO_CHAN - the channel specified for the FRP measurement is not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

• PAN_RC_BAD_AXIS - At least one axis is incorrect (NULL or not strictly increasing).

5.23.3.3.39. pan_set_injection_comp_frp_di()

Definition: PAN_RC_T pan_set_injection_comp_frp_di(BOOL panf_override, F32 panf_frp)

Supported targets:

Copyright 2019, Pi Innovo 421 Library interface

Required license: None (Main library).

Description: Function to override the fuel rail pressure input.

This function provides the means to override the fuel rail pressure input.

Arg (data in): panf_override Set to true to override the fuel rail pressure input, false otherwise.

Arg (data in): panf_frp The value to override the fuel rail pressure with. Range: [0, 500] MPa

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.23.3.3.40. pan_config_injections_di()

Definition: PAN_RC_T pan_config_injections_di(F32 panf_min_inj_time, F32 panf_min_off_time, F32 panf_drop_dead_angle)

Supported targets:

Required license: None (Main library).

Description: Function to configure various injection parameters.

This function configures various parameters that the injection functionality uses when scheduling injections.

Arg (data in): panf_min_inj_time This parameter can be used to apply a minimum duration to all pulses. Set to zero if a minimum pulse duration is not required. If a requested pulse duration is greater than zero but smaller than this minimum time, the platform will generate a pulse equal to this minimum time. The actual delivered pulse may be shorter than this, however, if clipped by the drop dead angle. Range: [0, 1000] ms

Arg (data in): panf_min_off_time This parameter can be used to mandate a minimum time between pulses on a single injector, delaying subsequent pulses if necessary. Range: [0, 5] ms

Arg (data in): panf_drop_dead_angle The drop dead angle applied to all cylinders, relative to TDC. The platform will stop injections at this point on a given cylinder. Range: [0, 720] degrees

Copyright 2019, Pi Innovo 422 Library interface

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM 5.23.3.3.41. pan_set_injection_di()

Definition: PAN_RC_T pan_set_injection_di(U8 panf_inj, U8 panf_pulses, volatile const F32 *panf_rel_on_angle, volatile const F32 *panf_fuel_amount, F32 panf_duration_offset, PIO_INJDI_DURATION_MODE_T panf_duration_mode)

Supported targets:

Required license: None (Main library).

Description: Function to request injections for a given injector.

This function is used to update the injection schedule for a given injector. If injections are already in progress for this engine cycle then the schedule will be buffered and used in the next cycle, starting after the next drop dead angle for the cylinder with which the injector is associated is reached. If the requested schedule is invalid, the platform will use the most recent previously successful schedule instead.

The requested schedule, if valid, will be applied to the next engine cycle where no injection pulses have been generated and the first on-angle in the pulse sequence has not yet been reached.

Arg (data in): panf_inj ID of the injector to update. Range: [1, PIO_ANG_MAX_INJECTORS]

Note

If pan_config_injectors() was used, the injector ID corresponds to the cylinder with which the injector is associated.

Arg (data in): panf_pulses The number of elements in the arrays containing the pulse durations and on angles. Range: [0, PIO_ANG_INJECTOR_MAX_PULSES]

Arg (data in): panf_rel_on_angle An array of panf_pulses pulse on angles, relative to TDC. Note that a positive value indicates a pulse after TDC. On angles for which the corresponding panf_fuel_amount is non-zero must be strictly increasing. Range: [-720, 720] degrees

Arg (data in): panf_fuel_amount An array of panf_pulses pulse amounts, ordered to match panf_rel_on_angle.

Copyright 2019, Pi Innovo 423 Library interface

If this value is zero, no pulse will be generated at the corresponding angle. Fuel amounts will be clipped to the range limits. Range: [0, 512) mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME. Range: [0, 1000] ms if panf_duration_mode is PIO_INJDI_DURATION_MODE_TIME.

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data in): panf_duration_offset An offset applied to this injector's injection durations, used to compensate for slight differences in injectors. This offset will be applied to the automatically computed pulse duration for both volume and duration modes. Range: [-8.191, 8.192] ms (1/4096)

Arg (data in): panf_duration_mode Specifies if the fuel amount is specified in volume or time. If the fuel amount is specified in volume, the platform will compute the pulse duration at the start angle based on the characteristics provided by pan_config_injectors_comp_di. Range: PIO_INJDI_DURATION_MODE_[NAME]

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error. This can result from out-of-range start angles, too many pulses in the request, or start angles that are not strictly increasing.

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.23.3.3.42. pan_get_injection_di_setpoint()

Definition: PAN_RC_T pan_get_injection_di_setpoint(U8 panf_inj, U8 *panf_pulses, F32 *panf_rel_on_angle, F32 *panf_fuel_amount, F32 *panf_duration_offset, F32 *panf_drop_dead_angle, PIO_INJDI_DURATION_MODE_T *panf_duration_mode)

Supported targets:

Required license: None (Main library).

Description: Function to read back injection parameters for a given injector.

This function is used to read the injection schedule for a given injector. This function can be used to verify that the data stored in eTPU memory match that which the application intended to write, allowing for checks of eTPU memory faults.

Copyright 2019, Pi Innovo 424 Library interface

If this function is called while the eTPU is updating internal schedule parameters, it will wait until the eTPU is complete guaranteeing that all the parameters read are from a single schedule.

Arg (data in): panf_inj ID of the injector to read back. Range: [1, PIO_ANG_MAX_INJECTORS]

Note

If pan_config_injectors() was used, the injector ID corresponds to the cylinder with which the injector is associated.

Arg (data out): panf_pulses The number of elements in the arrays containing the pulse durations and on angles. Range: [0, PIO_ANG_INJECTOR_MAX_PULSES]

Arg (data out): panf_rel_on_angle An array of PTPU_DI_MAX_PULSES pulse on angles, relative to TDC to match the values passed passed to pan_set_injection_di(). Range: [-720, 720] degrees

Note

The value passed to the platform is transformed to be kept with in a valid angle range. This transform cannot be reversed, so the angle is reported with the following transform applied: on_angle = ((on_angle + 1080) mod 720) - 360

Arg (data out): panf_fuel_amount An array of PTPU_DI_MAX_PULSES pulse amounts to match the values passed to pan_set_injection_di(). Range: [0, 512) mm3 if panf_duration_mode is PIO_INJDI_DURATION_MODE_VOLUME. Range: [0, 1000] ms if panf_duration_mode is PIO_INJDI_DURATION_MODE_TIME.

Note

Actual resolution of the duration is a function of the maximum duration of all pulses in this schedule request.

Arg (data out): panf_duration_offset An offset applied to this injector's injection durations to match the value passed to pan_set_injection_di(). Range: [-8.191, 8.192] ms (1/4096)

Arg (data out): panf_drop_dead_angle The drop-dead angle configured for this injector to match the value passed to pan_config_injections_di().

Arg (data out): panf_duration_mode Specifies if the fuel amount is specified in volume or time to match the value passed to pan_set_injection_di().

Copyright 2019, Pi Innovo 425 Library interface

Range: PIO_INJDI_DURATION_MODE_[NAME]

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error. This can result from passing NULL parameters or an unsupported injector number.

• PAN_RC_INJ_NOT_CONFIGURED - Function called without first initialising DI injectors.

5.23.3.3.43. pan_set_initial_injection_gpi()

Definition: PAN_RC_T pan_set_initial_injection_gpi(F32 panf_flow_time, F32 panf_dead_time)

Supported targets:

Required license: None (Main library).

Description: Function to convert and store the duration for the initial (priming) fuel pulse.

An initial, or priming, fuel pulse is generated when the engine starts to turn. The purpose of the initial fuel pulse is to ensure there is sufficient fuel in the engine cylinders when the first sparks occur to match the environmental conditions and engine size, making the engine more likely to start.

The duration of the initial fuel pulse is calculated as MIN(panf_dead_time + panf_flow_time , 500) milliseconds and is unaffected by the end of intake angle specified by calling pan_set_injection_gpi().

Due to the relative timing between sensing the engine starting to turn and the software synchronising with the crank trigger wheel which in turn causes scheduled spark events to occur, unburnt fuel can pass through a cylinder into the exhaust. Because unburnt fuel can pass into the exhaust, the initial fuel pulse method is not generally used for emissions related programmes. The initial fuel pulse can be turned off by not calling this function, or calling this function with a total injection time of zero milliseconds.

Call during application initialisation or during application run.

Note

Function pan_config_engine() must be called prior to calling this function.

Function pan_enable_initial_injection_gpi() must be called independently of this function to actually enable a pulse.

Arg (data in): panf_flow_time The length of the initial fuel pulse in milliseconds. Range: [0, 500.0] ms

Copyright 2019, Pi Innovo 426 Library interface

Arg (data in): panf_dead_time The duration of injection dead time. Range: [0, 500.0] ms When the dead time is updated for injector 'n', it is updated for all injectors, as it is a shared parameter. 5.23.3.3.44. pan_enable_initial_injection_gpi()

Definition: PAN_RC_T pan_enable_initial_injection_gpi(void)

Supported targets:

Required license: None (Main library).

Description: Function to enable an initial (priming) fuel pulse.

An initial, or priming, fuel pulse is generated when the engine starts to turn, if enabled. This is the function to call to enabled such a pulse. Once enabled, the request to generate the priming pulse is latched internally until the pulse starts. The request cannot be rescinded, except indirectly by setting the initial pulse flow time to zero before the pulse starts. Once the pulse does start, the latched request is cleared. A second priming pulse will not occur when the engine restarts after a stall, unless it has been re-enabled, by calling this function, any time after the previous priming pulse began.

Call during application initialisation or during application run.

Note

Function ptpu_set_initial_injection_gpi() must be called independently to specify the duration of the priming pulse.

5.23.3.3.45. pan_set_injection_gpi()

Definition: PAN_RC_T pan_set_injection_gpi(U8 panf_cyl, F32 panf_rel_on_angle, F32 panf_flow_time, F32 panf_dead_time, F32 panf_end_of_intake_angle, F32 panf_split_fuel_factor)

Supported targets:

Required license: None (Main library).

Description: Function to set the injector pulse schedule for a cylinder (angle- duration).

This function schedules a main pulse for the specified cylinder. The main pulse occurs at a start angle relative to the cylinder's TDC firing angle and lasts for:

panf_dead_time + panf_flow_time milliseconds

or until the end of intake angle specified by panf_end_of_intake_angle, whichever comes first.

Copyright 2019, Pi Innovo 427 Library interface

Before cam sync is attained (for a four-stroke engine), each cylinder injects twice per engine cycle, 360 degrees apart. In this case the injection duration is:

panf_dead_time + (panf_split_fuel_factor x panf_flow_time ) milliseconds

Positive angles are after TDC firing. This differs from pan_set_coil().

Call at most once per cylinder per TDC firing event. To update the schedule subsequently, call pan_update_injector().

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_cyl The cylinder that is being set up. Range: [1, PAN_MAX_CYLINDERS]

Arg (data in): panf_rel_on_angle The angle at which to start injection pulse from TDC firing of cylinder. Range: [-360, 360] degrees

Arg (data in): panf_flow_time The duration of injection flow time. Range: [0, 349.5] ms

Arg (data in): panf_dead_time The duration of injection dead time, (added to the flow time to make pulse). Range: [0, 349.5] ms

Arg (data in): panf_end_of_intake_angle The angle at which to turn injector off. Range: [0, 720] degrees

Note

If crank sync has not been achieved, then this value will be that of negative the TDC firing angle.

Arg (data in): panf_split_fuel_factor The fraction of the flow time used when in split-fuel mode, i.e. when injections are scheduled modulo 360 degrees before cam sync has been attained. For example, if this is set to 0.6, and the flow-time and dead-time are 1 ms and 0.2 ms respectively, and the on-angle is set to 40 degrees, then after crank sync has been achieved and before cam sync has been achieved, there will be two injections per engine cycle, scheduled at 40 and 400 degrees respectively (after that cylinder's TDC), each of duration: 0.6 x 1 ms + 0.2 ms = 0.8 ms.

Range: [0, 1) absolute

Copyright 2019, Pi Innovo 428 Library interface

5.23.3.3.46. pan_update_injection_gpi()

Definition: PAN_RC_T pan_update_injection_gpi(U8 panf_enable, U8 panf_enable_post_pulses, U8 panf_cyl, F32 panf_rel_on_angle, F32 panf_flow_time, F32 panf_dead_time, F32 panf_split_fuel_factor)

Supported targets:

Required license: None (Main library).

Description: Function to update a cylinder's injector pulse schedule (angle-duration).

This function schedules an update to the main pulse for the specified cylinder. If the main pulse has not started, the start angle may be adjusted. In all cases, the pulse duration is adjusted. This may result in: - the pulse stopping immediately; - the pulse contracting; - the pulse expanding; - the generation of a post pulse.

Call after calling pan_set_injector() to update the injection schedule.

Any pulse that is in progress at the end of intake angle specified by parameter panf_end_of_intake_angle when calling pan_set_injection_gpi() is terminated immediately.

Otherwise, a main pulse lasts for the duration panf_dead_time + panf_flow_time. A post pulse lasts for the duration panf_dead_time

• remaining flow-time, where the remaining flow-time is the flow-time passed by the panf_flow_time parameter, minus the flow-time already accumulated on this cycle. A post-pulse is only generated if this function is called with the panf_enable_post_pulses flag set to TRUE. Otherwise, if this function is called after a pulse has completed on the current cycle, then the newly updated data will be held over and used on the next cycle.

Positive angles are after TDC firing. This differs from pan_set_coil().

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_enable

• TRUE if an update should occur;

• FALSE otherwise.

Arg (data in): panf_enable_post_pulses

• TRUE if a post pulse should occur;

• FALSE otherwise.

Arg (data in): panf_cyl The cylinder whose schedule is being updated. Range: [1, PAN_MAX_CYLINDERS]

Copyright 2019, Pi Innovo 429 Library interface

Arg (data in): panf_rel_on_angle The angle at which to start injection pulse from TDC firing of cylinder. Range: [-360, 360] degrees

Arg (data in): panf_flow_time The duration of injection flow time. Range: [0, 349.5] ms

Arg (data in): panf_dead_time The duration of injection dead time. Range: [0, 349.5] ms When the dead time is updated for injector 'n', it is updated for all injectors, as it is a shared parameter.

Arg (data in): panf_split_fuel_factor The fraction of the flow time used when in split-fuel mode. See the corresponding parameter in pan_set_injection_gpi() for details. Range [0, 1) absolute 5.23.3.3.47. pan_get_injection_gpi_setpoint()

Definition: PAN_RC_T pan_get_injection_gpi_setpoint(U8 panf_cyl, U8 *panf_enable_post_pulses, F32 *panf_rel_on_angle, F32 *panf_flow_time, F32 *panf_dead_time, F32 *panf_end_of_intake_angle, F32 *panf_split_fuel_factor)

Supported targets:

Required license: None (Main library).

Description: Function to read back injection parameters for a given injector.

Note

Function pan_config_engine() must be called prior to calling this function. Call during application run, not during application initialisation.

Arg (data in): panf_cyl The cylinder that is being read back up. Range: [1, PAN_MAX_CYLINDERS]

Arg (data out): panf_enable_post_pulses TRUE if a post pulse should occur or FALSE otherwise to match the value passed to pan_set_injection_gpi().

Arg (data out): panf_rel_on_angle The angle at which to start injection pulse from TDC firing of cylinder to match the value passed to pan_set_injection_gpi(). Range: [-360, 360] degrees

Note

The value passed to the platform is transformed to be kept with in a valid angle range. This transform cannot be reserved, so the angle is reported with the following transform applied:

Copyright 2019, Pi Innovo 430 Library interface

on_angle = on_angle mod 720

Arg (data out): panf_flow_time The duration of injection flow time to match the value passed to pan_set_injection_gpi(). Range: [0, 349.5] ms

Arg (data out): panf_dead_time The duration of injection dead time to match the value passed to pan_set_injection_gpi(). Range: [0, 349.5] ms

Arg (data out): panf_end_of_intake_angle The angle at which to turn injector off to match the value passed to pan_set_injection_gpi(). Range: [0, 720] degrees

Arg (data out): panf_split_fuel_factor The fraction of the flow time used when in split-fuel mode to match the value passed to pan_set_injection_gpi(). Range [0, 1) absolute

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error. This can result from passing NULL parameters or an unsupported cylinder number

• PAN_RC_ENGINE_NOT_CONFIGURED - Function called without first initialising DI injectors. 5.23.3.3.48. pan_config_knock()

Definition: PAN_RC_T pan_config_knock(PAN_DEVICE_KNOCK_T panf_knock_device, F32 panf_region_start_angle)

Supported targets:

Required license: None (Main library).

Description: Function to configure the knock sensing feature, and set the earliest starting angle of any knock detection window relative to any cyclinder's TDC firing angle (positive angles before TDC).

Arg (data in): panf_knock_device The HIP901x device, as identified by the input pins associated with it. Use the macros included by the pio.h file, of the form PIO_KDEV_[4_PINS]_KNOCK.

Arg (data in): panf_region_start_angle The earliest starting angle of any knock detection window relative to any cylinder's TDC firing angle (positive angles before TDC). Range: [-360, 360] deg

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

Copyright 2019, Pi Innovo 431 Library interface

• PAN_RC_KNOCK_NOT_CONFIGURED - start angle outside of -360 to 360 5.23.3.3.49. pan_get_knock_feedback()

Definition: PAN_RC_T pan_get_knock_feedback(U8 panf_cyl, PAN_LCHAN_KNOCK_T panf_lchan, PIO_KNOCK_WINDOW_T panf_knock_window, S16 *panf_adc, BOOL *panf_valid)

Supported targets:

Required license: None (Main library).

Description: Function to retrieve the last processed knock signal result for a given cylinder.

Arg (data in): panf_cyl The cylinder to retrieve the processed knock result. Range: [1, 8]

Arg (data in): panf_lchan The knock channel to use as the knock input. Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME]. Note that this parameter is currently unused, and is only provided for future expandability. The knock window channel is selected when the pan_set_knock_filter_hip901x() function is called.

Arg (data in): panf_knock_window The knock window type to use. Must be set to:

• PIO_KNOCK_WINDOW_ACTIVE - Use active knock window. Note that this parameter is unused, and is only provided for future expandability.

Arg (data out): panf_adc Pointer to the conversion result for the last processed knock signal. Range: [0, 4096] A/D counts

Arg (data out): panf_valid Pointer to Boolean giving the validity of panf_adc. This parameter can be false if: lack of engine sync, knock is not configured in the application, the requested cylinder is outside of the number of cylinders configured for your engine, or if you requested a knock start window too close to the knock window region in your knock configuration (where "too close" is within 223 microseconds at the current engine RPM). Range: [0, 1] Boolean

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_KNOCK_NOT_CONFIGURED - knock configuration hasn't happened yet or was not successful

Copyright 2019, Pi Innovo 432 Library interface

5.23.3.3.50. pan_set_knock_window()

Definition: PAN_RC_T pan_set_knock_window(U8 panf_cyl, PAN_LCHAN_KNOCK_T panf_lchan, PIO_KNOCK_WINDOW_T panf_knock_window, F32 panf_rel_on_angle, F32 panf_rel_off_angle)

Supported targets:

Required license: None (Main library).

Description: Function to schedule a knock window relative to a cylinder's TDC.

Arg (data in): panf_cyl The cylinder for setting the knock window. Range: [1, 8]

Arg (data in): panf_lchan The knock channel to use as the knock input. Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME]. Note that this parameter is currently unused, and is only provided for future expandability. The knock window channel is selected when the pan_set_knock_filter_hip901x() function is called.

Arg (data in): panf_knock_window The knock window type to use. Must be set to:

• PIO_KNOCK_WINDOW_ACTIVE - Use active knock window Note that this parameter is unused, and is only provided for future expandability.

Arg (data in): panf_rel_on_angle Start angle of the knock detection window relative to the cylinder's TDC firing angle (positive angles before TDC). This function folds the angle into the range [0, 720) deg.

Arg (data in): panf_rel_off_angle End angle of the knock detection window relative to the cylinder's TDC firing angle (positive angles before TDC). This function folds the angle into the range [0, 720) deg.

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

5.23.3.3.51. pan_set_knock_filter_hip901x()

Definition: PAN_RC_T pan_set_knock_filter_hip901x(U8 panf_cyl, PAN_LCHAN_KNOCK_T panf_lchan, PIO_KNOCK_WINDOW_T panf_knock_window, PIO_KNOCK_GAIN_T panf_gain, PIO_KNOCK_BANDPASS_FREQ_T panf_bandpass, PIO_KNOCK_TIME_CONST_T panf_int_time_const)

Copyright 2019, Pi Innovo 433 Library interface

Supported targets:

Required license: None (Main library).

Description: Function to set the filtering parameters to be applied to the knock transducer signal when it is sampled.

Arg (data in): panf_cyl The cylinder for setting the knock window. Range: [1, 8]

Arg (data in): panf_lchan The knock channel to use as the knock input. Use the macros included by the pio.h file, of the form PIO_KIN_[2_PIN_NAME].

Arg (data in): panf_knock_window The knock window type to use. Must be set to:

• PIO_KNOCK_WINDOW_ACTIVE - Use active knock window Note that this parameter is unused, and is only provided for future expandability.

Arg (data in): panf_gain Gain applied to the knock transducer signal for the selected cylinder. Use the macros included by the pio.h file, of the form PIO_KNOCK_GAIN_[GAIN]

Arg (data in): panf_bandpass Bandpass centre frequency applied to the knock transducer signal for the selected cylinder. Use the macros included by the pio.h file, of the form PIO_KNOCK_BANDPASS_FREQ_[FREQ]_KHZ

Arg (data in): panf_int_time_const Integration time constant applied to the knock transducer signal for the selected cylinder. See the HIP901x data sheet for further details. Use the macros included by the pio.h file, of the form PIO_KNOCK_TIME_CONST_[TIMECONST]_US

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error 5.23.3.3.52. pan_convert_knock_filter_hip901x_values()

Definition: PAN_RC_T pan_convert_knock_filter_hip901x_values(F32 panf_gain_real, F32 panf_bandpass_real, F32 panf_int_time_const_real, PIO_KNOCK_GAIN_T *panf_gain_enum, PIO_KNOCK_BANDPASS_FREQ_T *panf_bandpass_enum, PIO_KNOCK_TIME_CONST_T *panf_int_time_const_enum)

Supported targets:

Required license: None (Main library).

Copyright 2019, Pi Innovo 434 Library interface

Description: Convert real values for HIP901x filter values into enumeration values.

Arg (data in): panf_gain_real Gain applied to the knock transducer signal. Range: [0.111, 2] unitless

Arg (data in): panf_bandpass_real Bandpass centre frequency applied to the knock transducer signal. Range: [1.22, 19.98] kHz

Arg (data in): panf_int_time_const_real Integration time constant applied to the knock transducer signal. See the HIP901x data sheet for further details. Range: [40, 600] microseconds

Arg (data out): panf_gain_enum Enum for gain closest to panf_gain_real. selected cylinder. Type: PIO_KNOCK_GAIN_T

Arg (data out): panf_bandpass_enum Enum for bandpass closest to panf_bandpass_real. Type: PIO_KNOCK_BANDPASS_FREQ_T

Arg (data out): panf_int_time_const_enum Enum for integration time constant closest to panf_int_time_const_real. Type: PIO_KNOCK_TIME_CONST_T

Return:

• PAN_RC_OK - successful action

• PAN_RC_BAD_ARGS - configuration error

5.23.3.3.53. pan_config_sparks()

Definition: PAN_RC_T pan_config_sparks(volatile const PDX_LCHAN_T *panf_lchans, U32 panf_chans, PIO_SPARK_TYPE_T panf_spark_type, BOOL panf_invert, BOOL panf_do_presync_360)

Supported targets:

Required license: None (Main library).

Description: Function to configure spark output channels and type.

This function is used to configure outputs for use as spark output channels

Warning

The function must be called during application initialisation and never during application run.

Copyright 2019, Pi Innovo 435 Library interface

Arg (data in): panf_lchans This is an array of output channels that will be configured as spark outputs. The first element will be applied to cylinder 1, the second to cylinder 2 and so on. Must not be NULL. Use the macros included by the pio.h file, of the form PIO_IGNOT_[NAME].

Arg (data in): panf_chans The number of spark channels to configure, i.e, the number of elements in panf_lchans. This must be the same as the number of cylinders in the engine. Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_spark_type The spark type required, coil-on-plug or wasted spark. i.e., one of the PIO_SPARK_TYPE_* macros included by the pio.h file.

Arg (data in): panf_invert Set to true to invert the polarity of the output, false otherwise.

Arg (data in): panf_do_presync_360 Set to true to fire sparks every 360 degrees until full engine cycle synchronisation is obtained, to aid starting.

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM

5.23.3.3.54. pan_set_spark()

Definition: PAN_RC_T pan_set_spark(U8 panf_cyl, F32 panf_rel_on_angle, F32 panf_rel_off_angle)

Supported targets:

Required license: None (Main library).

Description: Function to request a spark pulse for a given cylinder.

This function is used to request a spark on a given cylinder. The request must be made before the panf_rel_on_angle or else the spark will not be scheduled until the next cycle.

Up to 4 sparks will be emitted using the parameters provided before the platform will stop sparking and wait for a further update. Either make sufficiently fast periodic updates, or use the angular task, to ensure that sparks are emitted continually.

If a spark is already in progress, then the update will be used on the next spark.

Copyright 2019, Pi Innovo 436 Library interface

Some ECUs can schedule the spark events in a wasted-spark mode, where one coil drive output is used to cause sparks for two cylinders. In this mode, the ECU causes two spark events per engine cycle. The pairing of cylinders sharing one spark coil is currently inferred from the firing angles of all cylinders, assuming that those furthest apart in firing angle are paired.

Arg (data in): panf_cyl This is the cylinder to update. Range: [1, PIO_ANG_MAX_CYLINDERS]

Arg (data in): panf_rel_on_angle This is angle on which to begin the spark pulse, relative to TDC for this cylinder. Note that a positive value indicates an angle before TDC. Range: [-720, 720] degrees

Arg (data in): panf_rel_off_angle This is angle on which to end the spark pulse, relative to TDC for this cylinder. Note that a positive value indicates an angle before TDC. Range: [-720, 720] degrees

Return:

• PAN_RC_OK - successful action

• PAN_RC_SW_ERROR - channel not supported

• PAN_RC_BAD_ARGS - configuration error

• PAN_RC_SDM_ALLOC_ERROR - error allocating ram in SDM 5.23.3.3.55. pan_spark_config_successful()

Definition: BOOL pan_spark_config_successful(PAN_RC_T *panf_config_result)

Supported targets:

Required license: None (Main library).

Description: Function to discover if spark configuration was successful.

Some aspects of the spark configuration have to occur after the initialisation functions are called. This is because the ordering of calls to the various initialisation functions cannot be guaranteed. This function reports whether or not spark configuration post-initialisation was successful.

Arg (data in): panf_config_result If non-NULL, a return code will be written here to allow a higher level of detail in the case of an error occuring during configuration. If configuration has yet to take place, a value of PAN_RC_INVALID will be written here. Range: [NULL or valid address]

Return:

• TRUE - configuration was successful

Copyright 2019, Pi Innovo 437 Library interface

• FALSE - configuration failed 5.24. Waveform properties (PROP) 5.24.1. Overview

The feature provides a way to define the properties of a software configurable output waveform, for solenoid injector or valve control.

The output waveform can be configured to match the required drive profile for the load, and then associated with different output channels. The output channels are driven using the time-based or angular-based interfaces, and driven according to the waveform when active. Refer to the technical specification for a description of the types of outputs available for an ECU (Section A.1, “ECU hardware reference documentation”). 5.24.2. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and prop.h Enumerations PROP_RC_T

An enumerated type which contains success and failure codes returned by some digital input feature (PROP) functions. PROP_ERROR_CODE_T

Error values for debugging when an error is found when calling the waveform properties feature (PROP), the API calls a function with an enumeration from this type. PROP_WAVEFORM_T

This enumeration gives the selectable waveform to configure. PROP_PHASE_NUM_T

This enumeration gives the selectable phase to set waveform properties for. Data types PROP_LCHAN_T

This declares a type with enough value range to represent all logical channels for all targets. Functions PROP_RC_T prop_set_phase_for_waveform_33816

Define the properties of a particular phase of a desired waveform.

Copyright 2019, Pi Innovo 438 Library interface

Type Identifier PROP_RC_T prop_set_waveform_for_output

Associate an output channel with a waveform. PROP_RC_T prop_configure_boost

Configure the boost supply. 5.24.3. Interface detail 5.24.3.1. Enumerations

5.24.3.1.1. PROP_RC_T

Summary: An enumerated type which contains success and failure codes returned by some digital input feature (PROP) functions.

Enumerations:

PROP_RC_OK Return code if everything progressed as expected.

PROP_RC_UNCONFIGURABLE_PHASE_OR_WAVEFORM Return code if trying to configure more than the maximum number of phases or waveforms.

PROP_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PROP_RC_VBOOST_TOO_LOW Return code if the boost supply voltage is configured too low.

PROP_RC_VBOOST_TOO_HIGH Return code if the boost supply voltage is configured too high.

PROP_RC_DURATION_TOO_LOW Return code if the phase duration is configured too low.

PROP_RC_DURATION_TOO_HIGH Return code if the phase duration is configured too high.

PROP_RC_CURRENT_TOO_LOW Return code if the phase current is configured too low.

PROP_RC_CURRENT_TOO_HIGH Return code if the phase duration is configured too high.

PROP_RC_BOOST_NOT_ALLOWED Return code if the phase is configured to drive boost, but is not allowed in that phase high.

5.24.3.1.2. PROP_ERROR_CODE_T

Summary: Error values for debugging when an error is found when calling the waveform properties feature (PROP), the API calls a function with an enumeration from this type.

Copyright 2019, Pi Innovo 439 Library interface

Enumerations:

PROP_CHANNEL_INVALID Error raised if the channel 'n' is invalid.

'n' is (error_code - PROP_CHANNEL_INVALID).

PROP_DEVICE_INVALID Error raised if the device 'n' is invalid.

'n' is (error_code - PROP_DEVICE_INVALID).

PROP_WAVEFORM_INVALID Error raised if the waveform number 'n' is invalid.

'n' is (error_code - PROP_WAVEFORM_INVALID).

PROP_PHASE_INVALID Error raised if the waveform number 'n' is invalid.

'n' is (error_code - PROP_PHASE_INVALID).

PROP_PHASE_1_3_NOT_CONFIGURED Error raised if the waveform number 'n' phases 1 and 3 are not configred.

'n' is (error_code - PROP_PHASE_1_3_NOT_CONFIGURED).

PROP_PHASE_3_NOT_CONFIGURED Error raised if the waveform number 'n' phase 3 is not configred.

'n' is (error_code - PROP_PHASE_3_NOT_CONFIGURED).

PROP_NO_PHASES_CONFIGURED Error raised if the waveform number 'n' phase 1, 2, and 3 are not configred.

'n' is (error_code - PROP_NO_PHASES_CONFIGURED).

PROP_BOOST_NOT_CONFIGURED Error raised if any phase attempts to configure a phase as boosted, but the boost supply has not been configured.

5.24.3.1.3. PROP_WAVEFORM_T

Summary: This enumeration gives the selectable waveform to configure.

Enumerations:

PROP_WAVEFORM_1 Waveform type 1.

PROP_WAVEFORM_2 Waveform type 2.

PROP_WAVEFORM_3 Waveform type 3.

PROP_WAVEFORM_4 Waveform type 4.

Copyright 2019, Pi Innovo 440 Library interface

PROP_WAVEFORM_MAX

5.24.3.1.4. PROP_PHASE_NUM_T

Summary: This enumeration gives the selectable phase to set waveform properties for.

Enumerations:

PROP_PHASE_1 Phase 1 properties.

PROP_PHASE_2 Phase 2 properties.

PROP_PHASE_3 Phase 3 properties.

PROP_PHASE_MAX 5.24.3.2. Data types

5.24.3.2.1. PROP_LCHAN_T

Definition: typedef U16 PROP_LCHAN_T

Description: This declares a type with enough value range to represent all logical channels for all targets.

See pio.h for a list of relevant channels for a specific target. 5.24.3.3. Functions

5.24.3.3.1. prop_set_phase_for_waveform_33816()

Definition: PROP_RC_T prop_set_phase_for_waveform_33816(PIO_WAVEFORM_T propf_waveform, PIO_PHASE_T propf_phase, F32 propf_t_drive_on, F32 propf_t_drive_off, F32 propf_t_dither_off, F32 propf_c_max, BOOL propf_vboost, BOOL propf_switch_at_c)

Required license: None (Main library).

Description: Define the properties of a particular phase of a desired waveform.

Define the properties for a phase of a waveform.

Can raise the following errors: PROP_WAVEFORM_INVALID + propf_waveform

Arg (data in): propf_waveform The waveform to configure. Use values of the enum PIO_WAVEFORM_T included by the pio.h file.

Copyright 2019, Pi Innovo 441 Library interface

Arg (data in): propf_phase The phase of the waveform to configure. Use values of the enum PIO_PHASE_T included by the pio.h file.

Arg (data in): propf_t_drive_on The total duration of the phase to configure, in microseconds. Range: [0, 3000] us if phase is boosted or [0, 10922.5] us if non-boosted.

Arg (data in): propf_t_drive_off The total duration of the switch time. This is the time when the waveform switches from one phase to the next. Range: [0, 10922.5] us.

Arg (data in): propf_t_dither_off The off time for the hysteresis during the current control. Range: [10, 10922.5] us.

Arg (data in): propf_c_max The current threshold value to trip for current control. Range: [0, 25] A if phase is boosted or [0, 16] A if non-boosted.

Arg (data in): propf_vboost Whether or not this phase uses the boost supply for current control. This property is ignored if the boost supply has not been configured. Range: 0 if this phase uses battery, 1 if this phase is boosted.

Arg (data in): propf_switch_at_c Whether or not this phase immediately switches to the next phase when the current threshold is reached. Range: 0 if this phase continues for a duration after it reaches maximum current, 1 if it switches immediately to the next phase.

Return:

• PROP_RC_OK - successful action

• PROP_RC_UNCONFIGURABLE_PHASE_OR_WAVEFORM - phase or waveform cannot be configured

• PROP_RC_DURATION_TOO_HIGH - the time duration is too high

• PROP_RC_DURATION_TOO_LOW - the time duration is too low

• PROP_RC_CURRENT_TOO_HIGH - the current threshold is too high

• PROP_RC_CURRENT_TOO_LOW - the current threshold is too low

• PROP_RC_BOOST_NOT_ALLOWED - the phase or waveform does not allow boost

5.24.3.3.2. prop_set_waveform_for_output()

Definition: PROP_RC_T prop_set_waveform_for_output(PIO_WAVEFORM_T propf_waveform, PROP_LCHAN_T propf_lchan)

Copyright 2019, Pi Innovo 442 Library interface

Required license: None (Main library).

Description: Associate an output channel with a waveform.

Sets one of the output channels to a particular configured waveform.

Can raise the following errors: PROP_CHANNEL_INVALID + propf_lchan

Arg (data in): propf_waveform The waveform to associate with an output. Use macros from PIO_WAVEFORM_T enum. The waveform must be properly configured before platform post initialisation.

Arg (data in): propf_lchan The channel to use for the output. Use the macros included by the pio.h file, of the form PIO_PHOT_[NAME] or PIO_BPHOT_[NAME].

Return:

• PROP_RC_OK - successful action

• PROP_RC_BAD_ARGS - configuration error

5.24.3.3.3. prop_configure_boost()

Definition: PROP_RC_T prop_configure_boost(F32 propf_boost_voltage)

Required license: None (Main library).

Description: Configure the boost supply.

Configure the boost supply of the ECU.

Arg (data in): propf_boost_voltage The desired boost voltage to set. Range: [40, 65] V.

Return:

• PROP_RC_OK - successful action

• PROP_RC_VBOOST_TOO_LOW - desired boost value is too low

• PROP_RC_VBOOST_TOO_HIGH - desired boost value is too high

Copyright 2019, Pi Innovo 443 Chapter 6. Extended Diagnostics Functions

6.1. Introduction to Diagnostics ...... 444 6.2. Diagnostic Legislation ...... 445 6.3. Approach ...... 447 6.4. Diagnostic Trouble Codes and Freeze-Frames ...... 448 6.5. Diagnostic Monitors, Tests and Performance Ratios ...... 449 6.6. Worked Example - building a diagnostic system ...... 450 6.6.1. Step 1 — Test Conditions at the Monitor level ...... 450 6.6.2. Step 2 — Individual Flow Tests ...... 451 6.6.3. J1979/ISO 15031 Scan tool request/response ...... 452 6.7. Extended Diagnostic Functions ...... 454 6.7.1. J1939 Extended Diagnostics feature (PJ1939) ...... 454 6.7.2. Diagnostics (ISO-15765 and KWP2000) feature (PDG) ...... 511 6.7.3. Diagnostic Trouble Code Extended (DTC) feature (PDTC) ...... 532 6.7.4. Freeze Frame feature (PFF) ...... 564 6.7.5. Parameter Identifier feature (PPID) ...... 567 6.7.6. In-Use Performance Ratio feature (PPR) ...... 580

This section gives details on the Extended Diagnostics Functions which are an optional addition to the OpenECU platform. 6.1. Introduction to Diagnostics

The legislated requirements for the infrastructure to manage on-board diagnostics data has grown steadily over the years. This section describes the OpenECU approach to providing that support in a flexible way. This allows the users of OpenECU and related systems to concentrate on the system they are developing and at the same time meet the legislated requirements for emissions related control systems.

The diagnostic infrastructure support has been designed to meet both CARB and EURO diagnostics requirements and communicate with scan tools according to both heavy duty (J1939) and passenger car (ISO15765) protocols. It is aimed at vehicles which have to comply with 2010 and beyond legislation (eg EURO6).

It is important that the user understands general OBD terminology and the interactions between the various SAE/ISO standards and emissions/OBD legislated requirements. The standards are generally very good at describing their own terms and acronyms; therefore they have not been repeated here. There is no substitute for reading the relevant standard. A quick browse is absolutely essential, so that you will know where to look when the time comes for more detailed information.

The term diagnostics can be taken to mean many different tasks on different levels. The following diagram shows some of these. Details of how the user's application has to interact with the OpenECU platform are described below.

Copyright 2019, Pi Innovo 444 Extended Diagnostics Functions

Figure 6.1. Functional Levels within a Diagnostics System

Diagnostics related task Who should implement?

High System-specific tests and data collection User’s application Level

Storage, management and reporting of OpenECU platform application gathered data

Flash reprogramming over CAN OpenECU platform

Low-level communications over CAN OpenECU platform

Low Detected hardware errors (e.g., short circuit) OpenECU platform Level

6.2. Diagnostic Legislation

The OpenECU diagnostics infrastructure has been tailored to meet the following legislation. In many cases, the exact description for a particular behaviour has to be extracted from more than one document.

For European OBD documents, most of the emissions related legislation is held within Directive 70/220/EEC, which has been amended many times over the years. OBD requirements are held within Annex XI, which itself was created and subsequently modified by directives:

• 1998/69/EC

• 1999/102/EC

• 2002/80/EC

• 2003/76/EC

For heavy-duty diesel vehicles the Commission brought in Directive 2003/522. Subsequently, Directive 2005/55/EC introduced additional requirements for Euro-V emissions compliant diagnostic systems from 2008 or 2009 onwards. This was in turn amended by:

• 2005/78/EC

• 2006/51/EC

• 2008/74/EC

For Euro-VI heavy duty diesel vehicles, the previous regulations were revoked and a new Commission Directive 582/2011 was put in place.

The Californian (CARB) diagnostics requirements are captured within Title 13 California Code of Regulations in either section 1962.8 for passenger cars, light and medium duty vehicles or section 1971.1 for heavy duty vehicles.

Scan tool communications fall into two main categories: heavy duty using J1939 and light duty using ISO15765 based protocols. The second (light duty) category also includes the original J1979 diagnostic service requirements (also described in ISO15031-5) as well as the higher numbered KWP2000 and UDS services.

Copyright 2019, Pi Innovo 445 Extended Diagnostics Functions

The J1939 requirements are based on the SAE standards:

• J1939-03 On Board Diagnostics Implementation Guide

• J1939-73 Application Layer - Diagnostics

• J1939-21 Network Layer (Transport Protocol)

The ISO related requirements are based on:

• ISO15031, parts 5,6 and 7

• ISO15765, parts 2,3 and 4

The implementation within the OpenECU platform attempts to steer a course through these various diagnostics requirements. At times they conflict and in such cases, the implementation allows the user to select one alternative or another. There are also cases where a user may want to deliberately over-ride some aspect of the protocol or diagnostic requirements (e.g. during manufacturing). In these cases, the platform provides the user application with the ability to make those changes. Therefore it is essential that the application works together with the platform to provide a coherent and legally compliant diagnostic system. It cannot be left to just one side or the other.

One of the more confusing areas is the overlap between J1939-73 and ISO15031-5 (J1979) services for the generic, mandatory services. Both protocols have the ability to transmit more or less the same information, but in wildly different ways. The following table is loosly derived from one in J1939-73 and attempts to translate between the two.

Table 6.1. Diagnostic Service Comparisons

ISO/ ISO Description J1939 J1939 Description J1979 DM Service 0x01 PID Request Powertrain Data - index DM24 Use DM24 to declare emissions 00 of supported PIDs related support for powertrain data and DM25 freeze frame 0x01 PID Number of DTCs, MIL status, DM5 OBD compliance, previously 01 supported monitors and their active and active DTC count status (readiness) monitors supported and their status (readiness) 0x01 Actual current powertrain Various Normally provided PGs will be PIDs parameter data used to retrieve the parameter 03-1B data 0x01 PID OBD legislation supported DM5 Which OBD legislation is 1C supported 0x01 PID Distance and time while MIL on, DM21 Diagnostic Readiness 2 reports 21, 4D, Distance and time since DTCs this data 31, 4E cleared 0x01 PID Continuously monitored systems DM26 Diagnostic Readiness 3 reports 41, 1F, 30 status, time since engine start, status of monitors on this data number of warm ups since DTCs cleared 0x02 Freeze frame data - byte00 says DM4, DM 4 contains basic freeze which PIDs supported, byte02 DM24/ frames - note the PG tells what says which DTC caused each DM25 DTC caused it and the PG contains standard parameter

Copyright 2019, Pi Innovo 446 Extended Diagnostics Functions

ISO/ ISO Description J1939 J1939 Description J1979 DM Service freeze frame, bytes 04-FF have data. DM25 provides more the data parameter support than DM4. DM24 says which SPNs are supported. 0x03 Emission-related powertrain DM1 or Emissions related active(MIL DTCs DM12, on) DTCs and lamp status DM23 regular message on DM1 or when required on DM12. DM23 can report DTCs which are confirmed but the MIL is off. 0x04 Clear all emissions related OBD DM3 or DM3 clears previously active data DM11 DTCs and DM11 clears all DTCs 0x05 Oxygen sensor test data (use Not used No planned support for specific service 0x06 instead) oxygen sensor data 0x06 Test results for non-continuously DM10, DM10 gives the test IDs monitored systems DM7, supported, DM7 invokes the test DM8, and DM8 or DM30 are used to DM30 report the test results 0x07 Emissions-related Pending DM6, DM6 has emissions related DTCs DM27 Pending DTCs and DM27 has all Pending DTCs 0x08 Request control of onboard DM7, DM7 commands the test and system, test or component DM8 DM8 reports the results 0x09 Infotype 00 declares which other Various Individual DMs used for specific Infotype infotypes are supported infotype data 00 0x09 Vehicle's VIN number Data Reported on Data Stream Infotype Stream (J1939-71), using PGN 65260 01 / 02 0x09 Vehicle information - Calibration DM19 Bytes 5-20 contain calibration Infotype ID information 03 / 04 0x09 Vehicle information - Calibration DM19 Bytes 1-4 contain CVN Infotype verification number (CVN) 05 / 06 0x09 In use performance ratios for DM20 Indicates how often monitors Infotype diagnostic monitors complete compared to vehicle 07 / 08 operation 0x09 ECU acronym and name Infotype 09 / 0A 0x0A Permanent DTCs (emissions DM28 Permanent DTCs (emissions related) related) 6.3. Approach

The approach to implementing the diagnostics functions is a balance between providing flexibility and requiring minimal intervention. The user needs the ability to configure their

Copyright 2019, Pi Innovo 447 Extended Diagnostics Functions

data and choose which services to support. In some cases, the scan tool interactions do not require additional user code as the data is well structured and can be reported simply by the OpenECU platform.

The user needs to define the diagnostic data through the C-API tool. This will then allow functions to be called relating to DTCs, freeze-frames, PIDs, monitors etc.

The diagnostics system works closely with the NVM file system. Again, the user has some flexibility in terms of allocating certain amounts of memory or choosing when data is written, but for the most part, this interface is seamless. Diagnostic data can be stored when desired (e.g. when the ignition key is turned off) and is retrieved safely with minimal input from the user.

Communications with the scan tool behave slightly differently for J1939 compared to ISO15765 and related protocols. For J1939, the user's application is required to check for scan tool requests and emit replies as required. However, for most of the ISO15765 standard services, the data is retrieved by the platform and sent back to the scan tool with minimal intervention from the user's application. However, the application must keep the required data up to date.

Figure 6.2. Scan tool link via Platform

ECU

SCAN TOOL

User’s Application NVM data, DTCs, API Freeze-frames, Test results IUPR CAN etc OpenECU platform

6.4. Diagnostic Trouble Codes and Freeze- Frames

Diagnostic Trouble Codes (a.k.a. DTCs or fault codes) are the basic building blocks of the diagnostic infrastructure. There are multiple standards for the fault information to follow as well as choices for its life-cycle depending on whether it is emissions-related or permanent and the legislation being followed. These details are selected as part of the function call for each DTC thereby allowing the user to configure the system for various aspects of diagnostic legislation.

DTCs may be grouped into tables to help the user manipulate them. They can then be cleared (by table name) if required.

DTCs will also have an associated freeze-frame that is stored when the fault occurs. The user may specify several different types of freeze-frame for use with different DTCs. The various freeze-frame definitions may include more or less data to be captured when a fault occurs. Note that the legislation requires some specific pieces of data to be captured for emissions related faults.

Copyright 2019, Pi Innovo 448 Extended Diagnostics Functions

For a specific piece of data to be captured in a freeze-frame, the application needs to provide it to the platform. This is one of the uses of the ppid_update_pid() function (also used for J1939 SPN data). The platform can grab the latest data the application supplied when required. The same update mechanism allows the OpenECU platform to provide real-time data from within the user's application to a scan tool (e.g. for J1979 service $01 or J1939 DM24).

There are user configurations related to freeze-frames, which determine the total number to capture and the maximum amount of RAM and NV memory to allocate for freeze-frames. This allows the user to limit the allocation of memory (e.g. in the event of repeated faults) while at the same time making maximum use of the resources available in the ECU. This flexibility means that the system can be tailored to be more useful during development phases (when extra memory may be available) and then scaled back for the production version without changes to the application structure. See also Section 7.1.4.25, “Compound statement: ff- data”.

There are various interface file options (see Section 7.1.4.28, “Compound statement: dtc- data”) describing how the faults should behave. In particular, note the distinctions between CARB permanent and Euro non-eraseable DTCs. In each case the conditions required to clear the DTC are fully specified in the relevant legislation. 6.5. Diagnostic Monitors, Tests and Performance Ratios

A complete emissions related diagnostic system will have a have a set of diagnostic monitors to check the performance of each of the various components on a vehicle. These diagnostic monitors are in turn made of a series of diagnostic tests. The individual tests may be performed continuously, for example checking the range of an analogue input or the state of an output signal. Alternatively the tests may be classed as non-continuous which means that they can only be performed when the vehicle is in a certain operating state for example checking the performance of a catalyst or the EGR sub-system.

The OpenECU platform allows the user to define the monitors and related tests in the system using interface file statements. See Section 7.1.4.34, “Compound statement: dme-data” and Section 7.1.4.32, “Compound statement: dte-data”.

The user's application can use the functions ppr_update_dme_in_use_status() and ppr_update_dte_in_use_status() to indicate whether a DME or DTE is in-use in the current application build. This is useful in allowing the run-time configuration of an application for a system if required.

The user's application must use the functions ppr_update_dme_data(), ppr_update_dte_data() and ppr_update_dte_test_value() in conjunction with their individual diagnosis algorithms and provide data from each time an individual test is performed. The data is used in two ways by the platform:

• Firstly, each time a test is run, this allows the platform to update the numerator and denominator to be used in calculating the In-Use-Performance-Ratio for that particular diagnostic.

• Secondly the most recent test results (and limits) must be available for communication to a scan tool. The platform will store this data in NVM (to keep it in the event of a power down) for future communication to a scan tool.

Note that the legislation has some specific values (MonitorID) that must be used for specific sub-system emissions monitors.

Copyright 2019, Pi Innovo 449 Extended Diagnostics Functions

6.6. Worked Example - building a diagnostic system

In this example, we will build a hypothetical flow monitor which is to be part of an emissions compliant system and therefore needs to meet legal diagnostic requirements. We shall build it to meet Californian OBD regulations and the scan tool will use ISO 15765 to communicate with the ECU. 6.6.1. Step 1 — Test Conditions at the Monitor level

The flow monitor is made up of two individual flow tests, each of which can only be performed under certain conditions. The application needs to select the conditions to trigger each of the actual tests. In legal terms, this is a non-continuous monitor and therefore needs to inform the system when it can run for use in determining the In Use Performance Ratio (numerator / denominator).

The application code below shows a set of conditions for each of the tests being used to control whether two functions are run. Each of those functions will contain an individual flow test and associated interfaces. A Diagnostic Test Entity is updated for each test, maintaining a performance ratio for each.

static BOOL low_flow_complete = FALSE; static BOOL high_flow_complete = FALSE;

BOOL both_tests_run;

BOOL normal_state = (Operational_state == mftc_normal_operation_state ); BOOL at_temperature = (Measured_temperature > mftc_temperature_thresh_high); BOOL flow_low = (Flow_parameter < Another_flow_parameter ); BOOL pressure_high = (Measured_pressure >= mftc_pressure_thresh_high ); BOOL pressure_low = (Measured_pressure <= mftc_pressure_thresh_low );

BOOL run_low_flow_test = (normal_state && at_temperature && pressure_high && flow_low); BOOL run_high_flow_test = (normal_state && at_temperature && pressure_low && !flow_low);

BOOL monitor_enabled = (run_low_flow_test || run_high_flow_test);

if (run_low_flow_test) { Low_Flow_Test(&low_test_value, &low_test_limit, &low_flow_complete); }

if (run_high_flow_test) { High_Flow_Test(&low_test_value, &high_test_limit, &high_flow_complete); }

ppr_update_dte_data(LOW_FLOW_DTE_ID, /* U8 pprf_dte_id */ run_low_flow_test, /* BOOL pprf_sp_den_update_enable */ low_flow_complete); /* BOOL pprf_sp_num_update_enable */

ppr_update_dte_test_value(LOW_FLOW_DTE_ID, /* U8 pprf_dte_id */ low_test_value, /* U16 pprf_test_value */ low_test_limit, /* U16 pprf_test_limit_min */ mftc_low_max_fixed, /* U16 pprf_test_limit_max */ run_low_flow_test, /* BOOL pprf_test_run */ FALSE); /* BOOL pprf_reset_dte */

/* Similarly for HIGH_FLOW_DTE, omitted here for brevity */

The overall diagnostic monitor entity (DME) is updated depending on whether all of the possible DTEs in the group have been run. It is possible to force the DME state update for development purposes, but these parameters have been left FALSE.

both_tests_run = (low_flow_complete && high_flow_complete);

Copyright 2019, Pi Innovo 450 Extended Diagnostics Functions

ppr_update_dme_data(FLOW_DME_ID, /* U8 pprf_dme_id */ both_tests_run, /* BOOL pprf_monitor_run */ FALSE, /* BOOL pprf_force_complete */ FALSE, /* BOOL pprf_force_not_complete */ monitor_enabled); /* BOOL pprf_monitor_enabled */

For an ISO based scan tool, the data is accessed by a Service $06 command. Passing the data to the scan tool is handled directly by the platform. 6.6.2. Step 2 — Individual Flow Tests

We’ve invented two individual tests which make up our flow monitor. The principle is the same for each, so will only consider one here.

The example code below shows how an individual pass/fail result is used to set and clear DTCs. In practice a more complex debouncing strategy might be used (e.g. using put_leaky_bucket_f32()).

static void High_Flow_Test(U16* test_value, U16* test_limit, BOOL* test_complete) { F32 test_limit_float;

put_cal_map_2d_f32(Flow_data.pressure, Flow_data.temperature, MFTM_HIGH_FLOW_NX, MFTM_HIGH_FLOW_NY S32 putf_nx, mftm_high_flow_lim_x, mftm_high_flow_lim_y, mftm_high_flow_lim_z, &test_limit_float); *test_limit = (U16) test_limit_float;

*test_value = Flow_test_algorithm(Flow_data.parameter1, Flow_data.parameter2);

millisec_since_last = ptm_ms_time_diff_update(&time_last_ran); sec_since_power_on = ptm_s_time_diff(startup_time);

if (*test_value <= *test_limit) { out_of_range_time_ms += millisec_since_last; }

test_failed = (out_of_range_time_ms > Hi_flow_time);

if (sec_since_power_on > Hi_flow_test_duration) { *test_complete = TRUE; }

pdtc_update_plat_obd_dtc(&HighFlowDtc, /* const PDTC_DTC_T *const pdtcf_const_dtc */ test_failed, /* BOOL pdtcf_test_failed */ *test_complete); /* BOOL pdtcf_test_completed */ }

We’ve made up some imaginary table which provides a test limit. The flow test algorithm computes a value which is compared against this limit. If the value is greater than the limit, then an integrator adds up the time for which it is over the limit. Once suitable time has passed, the test is considered to have failed and a fault code will be stored by calling the DTC update function.

The duration timer allows for sufficient time to pass and if the test value was not above the limit, the test will be completed and passed.

Recall that the test limits and test value are passed out to the DTE for use in the event of a scan tool service $06 request. The platform is asked to store the new results after a short delay. This is required, as the service $06 request needs to be given the most recent test results, even if those results are days or even weeks old.

When a DTC is triggered (via the test_failed flag as shown above) an emissions related system must capture a freeze frame. This mechanism uses the PID and freeze-frame facilities; see also Section 7.1.4.30, “Compound statement: pid-data” and Section 7.1.4.25, “Compound statement: ff-data”.

Copyright 2019, Pi Innovo 451 Extended Diagnostics Functions

6.6.3. J1979/ISO 15031 Scan tool request/response

Once a model has been built with the diagnostics integrated, there is very little left for the application to do to respond correctly to J1939/ISO 15031 scan tool requests. The platform keeps track of any DTCs and whether they are classed as “pending” or “active” etc. The data entered into each DTC block will define this. As drive-cycles and warm-up cycles go by, fault data and freeze-frame data will be erased if they don’t recur. Similarly as individual tests happen, the test result data is stored, together with the numerator/denominator counts for each of the defined monitors.

If a scan tool now follows the J1979/ISO 15031 standard to request emissions data, the OpenECU system will respond with the correctly formatted data for each request. The full list of emissions related diagnostic services are detailed below.

The build process will automatically create a calibration variable named pdgc_emissions_report_min_sev with a default value of "sev-c". This calibration is used to determine the emissions severity level at or above which the platform will include a DTC when transmitting DM32 data.

The build process will create entries for this value in the A2L file for sev-a (highest), sev-b1, sev-b2, sev-c, or sev-none (lowest). To emit all DTCs regardless of their emissions severity level, use sev-none.

In order to change the default value, use the emissions-report-min-severity statement in the configuration file.

Table 6.2. PDG supported services

ID Service Notes 0x01 Request Current Powertrain Used to read PID values that have Diagnostic Data (J1979) a J1979 8-bit identifier defined 0x02 Request Powertrain Freeze Frame Used to read PID values that Data (J1979) have been captured when a DTC occurred 0x03 ReadEmissionDTCs (J1979) Reports only DTCs defined as emission-related 0x04 ClearEmissionDTCs (J1979) Clears only DTCs defined as emission-related 0x06 RequestOBDTestResults (J1979) Reports test results for ISO test IDs 0x07 ReadEmissionDTCsPending Reports only DTCs defined as (J1979) emission-related that are pending 0x09 RequestVehicleInformation Used to read Vehicle Information (J1979) data stored as InfoTypes 0x0A ReadEmissionDTCsPermanent Reports only DTCs defined (J1979) as emission-related that are permanent 0x10 StartDiagnosticSession Used to request a change between (KW2000-3) or diagnostic sessions. (Default, DiagnosticSessionControl (UDS) Extended and Programming) 0x11 ECUReset (KW2000-3, UDS) Used to reset the ECU. Only supported by Bootloader to exit reprogramming mode

Copyright 2019, Pi Innovo 452 Extended Diagnostics Functions

ID Service Notes 0x14 ClearDiagInfo (KW2000-3, UDS) Clears all or subgroup of ISO DTCs (not J1939-only DTCs) 0x17 ReadStatusOfDTC (KW2000-3) Reports the status of the specified DTC 0x18 ReadDTCByStatus (KW2000-3) All DTCs, regardless of emissions severity 0x19 ReadDTCInfo (UDS) 16-bit DTCs currently output, lower byte zero; many subfunctions 0x21 ReadDataByLocalIdentifier Used to read PID values using an (KW2000-3) 8-bit identifier 0x22 ReadDataByCommonID Used to read PID values using an (KW2000-3, UDS) 16-bit identifier 0x23 ReadMemoryByAddress Used to read raw memory contents (KW2000-3, UDS) (subject to security restrictions) 0x24 ReadScalingDataByIdentifier Used to read scaling data for a PID (UDS) 0x27 SecurityAccess (KW2000-3, UDS) Used to grant security access in boot loader mode 0x28 CommunicationControl (UDS) Used to switch on/off the transmission and or the reception of certain messages 0x28 DisableNormalMessageTransmissionUsed to switch off the transmission (J2190) of non-diagnostic and non-network management messages 0x29 EnableNormalMessageTransmissionUsed to switch on the transmission (J2190) for all messages 0x2A ReadDataByPeriodicIdentifier Used to request automatic periodic (UDS) transmission of selected PIDs 0x2C DynamicallyDefineDataIdentifier Used to specify a new PID (UDS) composed of other PIDs or memory reads 0x2E WriteDataByLocalIdentifier Used to write PIDs specified by 16- (KW2000-3, UDS) bit identifier (eg NV PID data) 0x2F IOControlByCommonID Used to override PID values using (KW2000-3, UDS) a 16-bit identifier 0x30 IOControlByLocalID (KW2000-3, Used to override PID values UDS) (identified by KW2000 8-bit local identifier) 0x31 RoutineControl (UDS) Used to initiate a specified process in boot loader mode, e.g. erase memory 0x34 RequestDownload (KW2000-3, Used to initiate a downloading of UDS) a block of memory in boot loader mode (only the downloading of unencrypted, uncompressed data is currently supported)

Copyright 2019, Pi Innovo 453 Extended Diagnostics Functions

ID Service Notes 0x36 TransferData (KW2000-3, UDS) Used to download data in boot loader mode (only the downloading to flash is currently supported) 0x37 RequestTransferExit (KW2000-3, Used to terminate data transfer UDS) between the tester and the ECU in boot loader mode 0x3E TesterPresent “Ping” to maintain communications 0x85 ControlDTCSetting Used to Stop or Start the setting of DTCs

Note

Services $14, $17 and $18 use the ISO 15031-6 values for groupOfDTC groups in KW2000-3 style (powertrain 0x0000, chassis 0x4000, body 0x8000, network/other 0xC000, all 0xFF00). For $14, the equivalent 24-bit UDS values may alternatively be used (0x000000, 0x400000, ... and 0xFFFFFF for 'all').

Note

Please contact Pi Innovo for support with flash reprogramming. The EraseMemory routine ($FF00) typically specified by OEMs is supported in two formats:

• Numeric range: If a length is supplied, the address value is interpreted as an actual device address and the specified range is erased.

• Logical index: If no length is supplied, the address value is interpreted as the zero- based index of the eraseable flash block, which is device-dependent. For example, the MPC5534 M0 block (0x40000 - 0x5FFFF) has index 6. This follows the HIS group reprogramming specification.

6.7. Extended Diagnostic Functions 6.7.1. J1939 Extended Diagnostics feature (PJ1939) 6.7.1.1. Overview

This section covers the extended diagnostics functions available in addition to the basic J1939 functions (see Section 5.17, “J1939 (SAE) messaging feature (PJ1939)”):

SAE J1939/73 Defines the application layer diagnostics, which includes (amongst other things) support for Diagnostic Trouble Codes (DTC).

The library supports the following diagnostic messages (to deal with Diagnostic Trouble Codes):

DM1 All active Diagnostic Trouble Codes

DM2 All previously active Diagnostic Trouble Codes

Copyright 2019, Pi Innovo 454 Extended Diagnostics Functions

DM3 Clear all previously active Diagnostic Trouble Codes

DM6 Pending emissions-related Diagnostic Trouble Codes

DM11 Clear all Diagnostic Trouble Codes

DM12 Active emissions-related Diagnostic Trouble Codes

DM23 Previously active emissions-related Diagnostic Trouble Codes

DM27 All pending Diagnostic Trouble Codes

DM28 Permanent Diagnostic Trouble Codes

DM35 Transient Diagnostic Trouble Codes

DM40 Harmonized B1 Diagnostic Trouble Codes

The library supports the following diagnostic messages, to deal with freeze frame data:

DM4 Freeze Frame Parameters

DM24 SPN Support

DM25 Expanded Freeze Frame

The library supports the following diagnostic messages, to deal with diagnostic readiness data:

DM5 Diagnostic Readiness 1 Data.

DM20 Monitor Performance Ratio.

DM21 Diagnostic Readiness 2 Data.

DM26 Diagnostic Readiness 3 Data.

The library supports the following diagnostic messages, deal with World Wide Harmonization and Global Technical Regulation:

DM36 Harmonized Vehicle Roadworthiness.

DM37 Harmonized System Roadworthiness.

DM38 Harmonized Global Technical Regulation Description.

Copyright 2019, Pi Innovo 455 Extended Diagnostics Functions

DM39 System Cumulative Continuous MI.

It is assumed throughout this document, that the reader is familiar with the SAE J1939 specifications. 6.7.1.2. Extended Diagnostic messages

The extended diagnostics library provides functions to help deal with diagnostic messaging in addition to the basic DM1 and DM1 functions in the core library, specifically DM3, DM4, DM5, DM6, DM7, DM8, DM10, DM11, DM12, DM20, DM21, DM23, DM24, DM25, DM26, DM27, DM28, DM30, DM35, DM36, DM37, DM38, DM39 and DM40 messages through the functions pj1939_dm4_transmit() , pj1939_dm5_transmit() , pj1939_dm6_transmit() , pj1939_get_dm7_commanded_test(), pj1939_dm8_transmit() , pj1939_dm10_transmit() , pj1939_dm12_transmit(), pj1939_dm20_transmit(), pj1939_dm21_transmit() , pj1939_dm23_transmit(), pj1939_dm24_transmit(), pj1939_dm25_transmit() , pj1939_dm26_transmit(), pj1939_dm27_transmit(), pj1939_dm28_transmit() , pj1939_dm30_transmit(), pj1939_dm35_transmit(), pj1939_dm36_transmit() , pj1939_dm37_transmit(), pj1939_dm38_transmit(), pj1939_dm39_transmit() , pj1939_dm40_transmit().

The extended library provides functions to help deal with additional diagnostic messaging, specifically DM32, DM33 and DM34 messages, through the functions pj1939_dm32_transmit(), pj1939_dm33_transmit() and pj1939_dm34_transmit().

In accordance to the J1939/73 specification, section 5.7, these messages are transmitted on request.

The library provides a function to set the status of engine operating in the NTE control areas for pollutants NOx and PM pj1939_set_control_area_status().

The library provides functions to set the engine hour timers for AECDs pj1939_update_aecd_eng_timer1() and pj1939_update_aecd_eng_timer2(). 6.7.1.3. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pj1939.h Macros PJ1939_RX_DATA

Indicates that a fresh message has been received since last polled. PJ1939_RX_OVERRUN

Indicates that more than one message has been received since last polled. PJ1939_RX_ERROR

Indicates that a receive error occurred associated with a message. PJ1939_SAE_RESERVED_1

SAE reserved.

Copyright 2019, Pi Innovo 456 Extended Diagnostics Functions

Type Identifier PJ1939_OBD_II

OBD II (CARB). PJ1939_OBD

OBD (Federal, EPA). PJ1939_OBD_OBD_II

OBD and OBD II. PJ1939_OBD_I

OBD I. PJ1939_NO_OBD_II

Not intended to meet OBD II requirements. PJ1939_EOBD

EOBD. PJ1939_EOBD_OBD_II

EOBD and OBD II. PJ1939_EOBD_OBD

EOBD and OBD. PJ1939_JOBD

JOBD. PJ1939_JOBD_OBD_II

JOBD and OBD II. PJ1939_JOBD_EOBD_OBD_II

JOBD, EOBD and OBD II. PJ1939_HDV_B1

Heavy Duty Vehicles (EURO 1V) B1. PJ1939_HDV_B2

Heavy Duty Vehicles (EURO V) B2. PJ1939_HDV_C

Heavy Duty Vehicles (EURO EEC) C (gas engines). PJ1939_EMD

Engine Manufacturer Diagnostics. PJ1939_EMD_PLUS

Engine Manufacturer Diagnostics Enhanced (EMD+). PJ1939_HDV_OBD

Heavy Duty/OBD.

Copyright 2019, Pi Innovo 457 Extended Diagnostics Functions

Type Identifier PJ1939_WWH_OBD

World Wide Harmonized OBD. PJ1939_OBD_II_REV

OBD II (CARB) Revised. PJ1939_HD_EOBD_REV

Heavy Duty Vehicles (EURO IV and V) Revised. PJ1939_SAE_RESERVED_2

SAE reserved. PJ1939_OBD_M_SI_SD_I

OBD-M Compliance for Spark_Ignition Sterndrive and Inboard Engines. PJ1939_EURO_VI

Heavy Duty Vehicles EURO VI (revisions specified in 2010-2011). PJ1939_OBD_OBD_II_HD_OBD

OBD, OBD II, and Heavy Duty/On-Board Diagnostics (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 20]. PJ1939_OBD_OBD_II_HD_OBD_P

OBD, OBD II, and Heavy Duty/On-Board Diagnostics Partial (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 19]. Enumerations PJ1939_ACK_AND_CONTROL_BYTE_T

The type of PGN response required A J1939 acknowledgement message can be of type Positive Acknowledgedment(ACK), Negative Acknowledgement(NACK), Access Denied(ACCESS_DENIED) or Cannot Respond(BUSY). PJ1939_INHIBIT_REPR_REASONS_T

The type of inhibit reason for the J1939 memory access reprogramming-inhibit function If the application inhibits ECU reprogramming (a jump to the Bootloader), it must supply a reason defined by this type. PJ1939_NTE_CNTRL_AREA_STATUS_T

The NTE control area status. PJ1939_NTE_CNTRL_AREA_T

The NTE control areas. Data types

Copyright 2019, Pi Innovo 458 Extended Diagnostics Functions

Type Identifier PJ1939_DM7_BUFFER_T

This is a structure to store details of requested tests received in DM7 message. PJ1939_AECD_T

This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data. PJ1939_SEED_KEY_CONFIG_T

Structure configuring security J1939. PJ1939_SEED_REQUEST_CALLBACK_T

Typedef for the callback function used to generate a seed for a J1939 seed-key exchange. PJ1939_KEY_VALIDATION_CALLBACK_T

Typedef for the callback function used to validate a key for a J1939 seed-key exchange. Variables const U8 pj1939_dm7_request_buf_size

This is the number of DM7 test requests that are to be buffered. PJ1939_DM7_BUFFER_T pj1939_req_test_list

This is the stored buffer of DM7 requests which have been received but have not yet been processed. const U8 pj1939_num_aecd

The total number of EI-AECDs that are declared. PJ1939_AECD_T *const pj1939_aecd_table

The list of AECDs that the library will maintain. Functions BOOL pj1939_pgn_send_ack

This function attempts to send an acknowledgement in response to a J1939 request. void pj1939_dm5_transmit

This function attempts to transmit a J1939 DM5 response message. void pj1939_dm20_transmit

This function attempts to transmit a J1939 DM20 response message. void pj1939_dm21_transmit

This function attempts to transmit a J1939 DM21 response message.

Copyright 2019, Pi Innovo 459 Extended Diagnostics Functions

Type Identifier void pj1939_dm26_transmit

This function attempts to transmit a J1939 DM26 response message. BOOL pj1939_check_dm7_commanded_test

Determine the requested test(s) to be run - as commanded by the DM7 message. BOOL pj1939_get_dm7_commanded_test

Get a DM7 request for running a test or for test results, if received. void pj1939_dm8_transmit

This function attempts to transmit a J1939 DM8 response message. void pj1939_dm30_transmit

This function attempts to transmit a J1939 DM30 response message. void pj1939_dm10_transmit

This function attempts to transmit a J1939 DM10 response message. void pj1939_dm6_transmit

This function attempts to transmit a J1939 DM6 message. void pj1939_dm12_transmit

This function attempts to transmit a J1939 DM12 message. void pj1939_dm23_transmit

This function attempts to transmit a J1939 DM23 message. void pj1939_dm27_transmit

This function attempts to transmit a J1939 DM27 message. void pj1939_dm28_transmit

This function attempts to transmit a J1939 DM28 message. void pj1939_dm29_transmit

This function attempts to transmit a J1939 DM29 message. void pj1939_dm31_transmit

This function attempts to transmit a J1939 DM31 message.

Copyright 2019, Pi Innovo 460 Extended Diagnostics Functions

Type Identifier void pj1939_dm35_transmit

This function attempts to transmit a J1939 DM35 message. void pj1939_dm40_transmit

This function attempts to transmit a J1939 DM40 message. void pj1939_dm41_transmit

This function attempts to transmit a J1939 DM41 message. void pj1939_dm42_transmit

This function attempts to transmit a J1939 DM42 message. void pj1939_dm43_transmit

This function attempts to transmit a J1939 DM43 message. void pj1939_dm44_transmit

This function attempts to transmit a J1939 DM44 message. void pj1939_dm45_transmit

This function attempts to transmit a J1939 DM45 message. void pj1939_dm46_transmit

This function attempts to transmit a J1939 DM46 message. void pj1939_dm47_transmit

This function attempts to transmit a J1939 DM47 message. void pj1939_dm48_transmit

This function attempts to transmit a J1939 DM48 message. void pj1939_dm49_transmit

This function attempts to transmit a J1939 DM49 message. void pj1939_dm50_transmit

This function attempts to transmit a J1939 DM50 message. void pj1939_dm51_transmit

This function attempts to transmit a J1939 DM51 message.

Copyright 2019, Pi Innovo 461 Extended Diagnostics Functions

Type Identifier void pj1939_dm52_transmit

This function attempts to transmit a J1939 DM52 message. void pj1939_dm32_transmit

This function attempts to transmit a J1939 DM32 response message. BOOL pj1939_set_control_area_status

This function sets the NTE control area status. void pj1939_dm34_transmit

This function attempts to transmit a J1939 DM34 response message. void pj1939_update_aecd_eng_timer1

This function updates the EI-AECD engine hours timer1 for the specified AECD. void pj1939_update_aecd_eng_timer2

This function updates the EI-AECD engine hours timer2 for the specified AECD. void pj1939_dm33_transmit

This function attempts to transmit a J1939 DM33 response message. void pj1939_dm4_transmit

Call a function to transmit a J1939 DM4 message. void pj1939_dm25_transmit

Call a function to transmit a J1939 DM25 message. void pj1939_dm24_transmit

This function attempts to transmit a J1939 DM24. void pj1939_dm16_transmit

This function attempts to transmit a J1939 DM16 data message. void pj1939_dm36_transmit

This function attempts to transmit a J1939 DM36 message. void pj1939_dm37_transmit

This function attempts to transmit a J1939 DM37 message. void pj1939_dm38_transmit

This function attempts to transmit a J1939 DM38 message.

Copyright 2019, Pi Innovo 462 Extended Diagnostics Functions

Type Identifier void pj1939_dm39_transmit

This function attempts to transmit a J1939 DM39 message.

6.7.1.4. Interface detail

6.7.1.4.1. Macros

6.7.1.4.1.1. PJ1939_RX_DATA

Definition: #define PJ1939_RX_DATA 1

Description:

Indicates that a fresh message has been received since last polled.

6.7.1.4.1.2. PJ1939_RX_OVERRUN

Definition: #define PJ1939_RX_OVERRUN 2

Description:

Indicates that more than one message has been received since last polled.

6.7.1.4.1.3. PJ1939_RX_ERROR

Definition: #define PJ1939_RX_ERROR 4

Description:

Indicates that a receive error occurred associated with a message.

6.7.1.4.1.4. PJ1939_SAE_RESERVED_1

Definition: #define PJ1939_SAE_RESERVED_1 ((U8)0)

Description:

SAE reserved.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.5. PJ1939_OBD_II

Definition: #define PJ1939_OBD_II ((U8)1)

Description:

OBD II (CARB).

Copyright 2019, Pi Innovo 463 Extended Diagnostics Functions

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.6. PJ1939_OBD

Definition: #define PJ1939_OBD ((U8)2)

Description:

OBD (Federal, EPA).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.7. PJ1939_OBD_OBD_II

Definition: #define PJ1939_OBD_OBD_II ((U8)3)

Description:

OBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.8. PJ1939_OBD_I

Definition: #define PJ1939_OBD_I ((U8)4)

Description:

OBD I.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.9. PJ1939_NO_OBD_II

Definition: #define PJ1939_NO_OBD_II ((U8)5)

Description:

Not intended to meet OBD II requirements.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.10. PJ1939_EOBD

Definition: #define PJ1939_EOBD ((U8)6)

Description:

EOBD.

Copyright 2019, Pi Innovo 464 Extended Diagnostics Functions

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.11. PJ1939_EOBD_OBD_II

Definition: #define PJ1939_EOBD_OBD_II ((U8)7)

Description:

EOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.12. PJ1939_EOBD_OBD

Definition: #define PJ1939_EOBD_OBD ((U8)8)

Description:

EOBD and OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.13. PJ1939_JOBD

Definition: #define PJ1939_JOBD ((U8)10)

Description:

JOBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.14. PJ1939_JOBD_OBD_II

Definition: #define PJ1939_JOBD_OBD_II ((U8)11)

Description:

JOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.15. PJ1939_JOBD_EOBD_OBD_II

Definition: #define PJ1939_JOBD_EOBD_OBD_II ((U8)13)

Description:

JOBD, EOBD and OBD II.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

Copyright 2019, Pi Innovo 465 Extended Diagnostics Functions

6.7.1.4.1.16. PJ1939_HDV_B1

Definition: #define PJ1939_HDV_B1 ((U8)14)

Description:

Heavy Duty Vehicles (EURO 1V) B1.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.17. PJ1939_HDV_B2

Definition: #define PJ1939_HDV_B2 ((U8)15)

Description:

Heavy Duty Vehicles (EURO V) B2.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.18. PJ1939_HDV_C

Definition: #define PJ1939_HDV_C ((U8)16)

Description:

Heavy Duty Vehicles (EURO EEC) C (gas engines).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.19. PJ1939_EMD

Definition: #define PJ1939_EMD ((U8)17)

Description:

Engine Manufacturer Diagnostics.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.20. PJ1939_EMD_PLUS

Definition: #define PJ1939_EMD_PLUS ((U8)18)

Description:

Engine Manufacturer Diagnostics Enhanced (EMD+).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.21. PJ1939_HDV_OBD

Definition: #define PJ1939_HDV_OBD ((U8)20)

Copyright 2019, Pi Innovo 466 Extended Diagnostics Functions

Description:

Heavy Duty/OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.22. PJ1939_WWH_OBD

Definition: #define PJ1939_WWH_OBD ((U8)21)

Description:

World Wide Harmonized OBD.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.23. PJ1939_OBD_II_REV

Definition: #define PJ1939_OBD_II_REV ((U8)22)

Description:

OBD II (CARB) Revised.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.24. PJ1939_HD_EOBD_REV

Definition: #define PJ1939_HD_EOBD_REV ((U8)23)

Description:

Heavy Duty Vehicles (EURO IV and V) Revised.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.25. PJ1939_SAE_RESERVED_2

Definition: #define PJ1939_SAE_RESERVED_2 ((U8)24)

Description:

SAE reserved.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.26. PJ1939_OBD_M_SI_SD_I

Definition: #define PJ1939_OBD_M_SI_SD_I ((U8)25)

Copyright 2019, Pi Innovo 467 Extended Diagnostics Functions

Description:

OBD-M Compliance for Spark_Ignition Sterndrive and Inboard Engines.

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.27. PJ1939_EURO_VI

Definition: #define PJ1939_EURO_VI ((U8)26)

Description:

Heavy Duty Vehicles EURO VI (revisions specified in 2010-2011).

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.28. PJ1939_OBD_OBD_II_HD_OBD

Definition: #define PJ1939_OBD_OBD_II_HD_OBD ((U8)34)

Description:

OBD, OBD II, and Heavy Duty/On-Board Diagnostics (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 20].

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.1.29. PJ1939_OBD_OBD_II_HD_OBD_P

Definition: #define PJ1939_OBD_OBD_II_HD_OBD_P ((U8)35)

Description:

OBD, OBD II, and Heavy Duty/On-Board Diagnostics Partial (CARB CCR 1971.1 and EPA 86.010-18) [Compliance codes 3 and 19].

This is one of the definitions for OBD compliance values as given in the J1939-73 description for DM5 byte 3.

6.7.1.4.2. Enumerations

6.7.1.4.2.1. PJ1939_ACK_AND_CONTROL_BYTE_T

Summary: The type of PGN response required A J1939 acknowledgement message can be of type Positive Acknowledgedment(ACK), Negative Acknowledgement(NACK), Access Denied(ACCESS_DENIED) or Cannot Respond(BUSY).

Enumerations:

ACK

NACK

Copyright 2019, Pi Innovo 468 Extended Diagnostics Functions

ACCESS_DENIED

BUSY

6.7.1.4.2.2. PJ1939_INHIBIT_REPR_REASONS_T

Summary: The type of inhibit reason for the J1939 memory access reprogramming- inhibit function If the application inhibits ECU reprogramming (a jump to the Bootloader), it must supply a reason defined by this type.

Enumerations:

PJ1939_REPR_GENERAL_ERROR

PJ1939_REPR_NOT_IN_DIAG_MODE

PJ1939_REPR_NOT_IN_ENG_MODE

PJ1939_REPR_NOT_IN_DEV_MODE

PJ1939_REPR_ENGINE_RUNNING

PJ1939_REPR_VEH_NOT_IN_PARK

PJ1939_REPR_VEH_NOT_STATIONARY

6.7.1.4.2.3. PJ1939_NTE_CNTRL_AREA_STATUS_T

Summary: The NTE control area status.

Enumerations:

PJ1939_NTE_OUTSIDE_CNTRL_AREA

PJ1939_NTE_INSIDE_CNTRL_AREA

PJ1939_NTE_RESERVED

PJ1939_NTE_AREA_NOT_AVAILABLE

6.7.1.4.2.4. PJ1939_NTE_CNTRL_AREA_T

Summary: The NTE control areas.

Enumerations:

PJ1939_NOX_NTE_AREA

PJ1939_NOX_NTE_CARVE_OUT_AREA

PJ1939_NOX_NTE_DEFICIENCY_AREA

PJ1939_PM_NTE_AREA

PJ1939_PM_NTE_CARVE_OUT_AREA

PJ1939_PM_NTE_DEFICIENCY_AREA

Copyright 2019, Pi Innovo 469 Extended Diagnostics Functions

6.7.1.4.3. Data types

6.7.1.4.3.1. PJ1939_DM7_BUFFER_T

Summary: This is a structure to store details of requested tests received in DM7 message.

Members:

U32 PJ1939_DM7_BUFFER_T::spn This is the suspect parameter number (SPN) of the received J1939 DM7 message.

Range: [0, 524287]

U8 PJ1939_DM7_BUFFER_T::tid This is the test identifier (TID) of the received J1939 DM7 message.

Range: [0, 255]

U8 PJ1939_DM7_BUFFER_T::fmi This is the failure mode indicator (FMI) of the received J1939 DM7 message.

Range: [0, 31]

U8 PJ1939_DM7_BUFFER_T::tool_addr This is the source address of the received J1939 DM7 message or destination for a corresponding DM30 message.

Range: [0, 255]

U8 PJ1939_DM7_BUFFER_T::ecu_addr This is the destination address of the received J1939 DM7 message or source for the corresponding DM30 message.

Range: [0, 255]

Description:

This is a structure to store details of requested tests received in DM7 message.

Note that source and destination address must be stored because DM30 requires a destination address; and the application may also want to permit/refuse requests from specific sources.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

6.7.1.4.3.2. PJ1939_AECD_T

Summary: This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data.

Members:

U8 PJ1939_AECD_T::aecd_number This is the EI-AECD number.

Copyright 2019, Pi Innovo 470 Extended Diagnostics Functions

U32 PJ1939_AECD_T::engine_hours_timer1 This is the EI-AECD Engine Hours Timer 1.

Will indicate total active time when commanding up to, but not including, 75% reduction of the maximum emissions control effectiveness.

U32 PJ1939_AECD_T::engine_hours_timer2 This is the (optional) EI-AECD Engine Hours Timer 2.

Will indicate total active time when 75% or more reduction of the maximum emissions control effectiveness.

Description:

This is the structure for the Emission Increasing Auxiliary Emission Conrol Device (EI-AECD) Active time data.

Present in the C-API description only for build time size requirements. The typedef is not to be used by application code.

6.7.1.4.3.3. PJ1939_SEED_KEY_CONFIG_T

Summary: Structure configuring security J1939.

Members:

BOOL PJ1939_SEED_KEY_CONFIG_T::security_required If security_required is set FALSE, no seed-key exchange is required.

The callback structure elements are ignored.

If security_required is set TRUE, the callbacks provided are used to unlock the security.

If security_required is set TRUE but either callback is NULL, it will not be possible to unlock security and the calibration tool will be permanently prohibited from invoking reprogramming activities.

PJ1939_SEED_REQUEST_CALLBACK_T PJ1939_SEED_KEY_CONFIG_T::seed_request_callback Pointer to callback function which is called to request a seed value when the calibration tool attempts to jump to bootloader.

Set this value to NULL if security is not required.

PJ1939_KEY_VALIDATION_CALLBACK_T PJ1939_SEED_KEY_CONFIG_T::key_validation_callback Pointer to callback function which is called to validate a key value returned by the calibration tool against a previously generated seed.

Set this value to NULL if security is not required.

6.7.1.4.3.4. PJ1939_SEED_REQUEST_CALLBACK_T

Definition: typedef U16(* PJ1939_SEED_REQUEST_CALLBACK_T)(void)

Copyright 2019, Pi Innovo 471 Extended Diagnostics Functions

Description: Typedef for the callback function used to generate a seed for a J1939 seed-key exchange.

This function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

In future software, the callback function will be copied to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Return: The function must return a 16-bit seed value. Typically this will be generated through a random or pseudo-random process.

6.7.1.4.3.5. PJ1939_KEY_VALIDATION_CALLBACK_T

Definition: typedef BOOL(* PJ1939_KEY_VALIDATION_CALLBACK_T)(U16 key, U16 seed)

Description: Typedef for the callback function used to validate a key for a J1939 seed- key exchange.

The function must validate if the passed seed and key values match.

This function is run by a processing task which is scheduled every 5ms. The function must therefore take no more than 5ms to execute, and preferably should be significantly faster. As usual for embedded programming, excessive stack requirements and the use of dynamic memory allocation should be avoided. There is currently no requirement for this function to be re-entrant.

In future software, the callback function will be copied to NV storage so that application security algorithms may also be used by the bootloader when reprogramming. In order for this to be possible, the callback function must be relocatable. The function should therefore make no calls to other functions, or refer to application variables or calibratables, otherwise existing callback functions may be incompatible with new releases of OpenECU. Note that direct access to registers and hardcoded memory locations is still permitted.

Arg: key The key is a 16-bit value returned by the calibration tool.

Arg: seed This is the 16-bit seed value.

Return: The function must return TRUE if the key is correct, or FALSE if not.

Copyright 2019, Pi Innovo 472 Extended Diagnostics Functions

6.7.1.4.4. Variables

6.7.1.4.4.1. pj1939_dm7_request_buf_size

Definition: const U8 pj1939_dm7_request_buf_size

Description: This is the number of DM7 test requests that are to be buffered.

Range: [1, 255] buffers.

6.7.1.4.4.2. pj1939_req_test_list

Definition: PJ1939_DM7_BUFFER_T pj1939_req_test_list[]

Description: This is the stored buffer of DM7 requests which have been received but have not yet been processed.

The array is sized by pj1939_dm7_request_buf_size.

Note

The array is private to the library and should only be defined by the application. It is exposed as part of the API so it can be sized at build time.

6.7.1.4.4.3. pj1939_num_aecd

Definition: const U8 pj1939_num_aecd

Description: The total number of EI-AECDs that are declared.

6.7.1.4.4.4. pj1939_aecd_table

Definition: PJ1939_AECD_T* const pj1939_aecd_table[]

Description: The list of AECDs that the library will maintain.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal pj1939_num_aecd. The array is not to be accessed by application code.

6.7.1.4.5. Functions

6.7.1.4.5.1. pj1939_pgn_send_ack()

Definition: BOOL pj1939_pgn_send_ack(const U32 pj1939f_pgn_to_ack, const PJ1939_ACK_AND_CONTROL_BYTE_T pj1939f_required_response)

Copyright 2019, Pi Innovo 473 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to send an acknowledgement in response to a J1939 request.

Arg (data in): pj1939f_pgn_to_ack The PGN request that is being acknowledged.

Arg (data in): pj1939f_required_response The required response - ACK/NACK/ACCESS_DENIED/BUSY.

Return:

• TRUE - if transmission succeeds

• FALSE - if transmission fails

6.7.1.4.5.2. pj1939_dm5_transmit()

Definition: void pj1939_dm5_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_priority, U8 pj1939f_obd_compliance, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM5 response message.

Can raise the following errors: PJ1939_DM5_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM5 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_obd_compliance The OBD compliance to be reported in DM5 byte 3. Range: [0, 255]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise.

Copyright 2019, Pi Innovo 474 Extended Diagnostics Functions

Cannot be NULL.

6.7.1.4.5.3. pj1939_dm20_transmit()

Definition: void pj1939_dm20_transmit(const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM20 response message.

Can raise the following errors: PJ1939_DM20_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.4. pj1939_dm21_transmit()

Definition: void pj1939_dm21_transmit(const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U16 pj1939f_time_while_mil_on, U16 pj1939f_distance_while_mil_on, U16 pj1939f_time_since_dtc_clear, U16 pj1939f_distance_since_dtc_clear, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM21 response message.

Copyright 2019, Pi Innovo 475 Extended Diagnostics Functions

Can raise the following errors: PJ1939_DM21_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data in): pj1939f_time_while_mil_on The accumulated count (in minutes) run by the engine while the MIL is activated. Refer to J1939-73 Feb2010 section 5.7.21.3 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 64255] minutes

Arg (data in): pj1939f_distance_while_mil_on The distance travelled (in kilometres) while the MIL is activated. Refer to J1939-73 Feb2010 section 5.7.21.1 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 64255] kilometres

Arg (data in): pj1939f_time_since_dtc_clear The engine running time (in minutes) accumulated since emission related DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.21.4 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 64255] minutes

Arg (data in): pj1939f_distance_since_dtc_clear The distance accumulated (in kilometres) since emission related DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.21.2 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 64255] kilometres

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise. Cannot be NULL.

6.7.1.4.5.5. pj1939_dm26_transmit()

Definition: void pj1939_dm26_transmit(const U8 pj1939f_priority, U16 pj1939_eng_time_since_ign_start, U8 pj1939_warmup_count_since_dtc_clear, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM26 response message.

Copyright 2019, Pi Innovo 476 Extended Diagnostics Functions

Can raise the following errors: PJ1939_DM26_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939_eng_time_since_ign_start The time (in seconds), since key-on, that the engine has been running. Refer to J1939-73 Feb2010 section 5.7.26.1 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 64255] seconds

Arg (data in): pj1939_warmup_count_since_dtc_clear The number of warm-up cycles since all DTCs were cleared. Refer to J1939-73 Feb2010 section 5.7.26.2 for details. The platform will limit the transmitted value to the range specified below. Range: [0, 250]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise. Cannot be NULL.

6.7.1.4.5.6. pj1939_check_dm7_commanded_test()

Definition: BOOL pj1939_check_dm7_commanded_test(U8 pj1939f_tid, U32 pj1939f_spn, U8 pj1939f_fmi, U8 *pj1939f_source_addr, U8 *pj1939f_dest_addr)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Determine the requested test(s) to be run - as commanded by the DM7 message.

Arg (data in): pj1939f_tid The J1939 'test identifier' value to match. Range: [0, 255]

Arg (data in): pj1939f_spn The 'suspect parameter number' value to match (when a DM30 response is required). Range: [0, 524287]

Arg (data in): pj1939f_fmi The 'failure mode indicator' value to match (when a DM30 response is required). Range: [0, 31]

Arg (data out): pj1939f_source_addr The source address for the DM7 request message requesting this test. May be NULL.

Copyright 2019, Pi Innovo 477 Extended Diagnostics Functions

Arg (data out): pj1939f_dest_addr The destination address for the DM7 request message requesting this test. May be NULL.

Return: TRUE - if the requested test is to be run. FALSE - if no request was received for the specified test.

6.7.1.4.5.7. pj1939_get_dm7_commanded_test()

Definition: BOOL pj1939_get_dm7_commanded_test(PJ1939_DM7_BUFFER_T *pj1939f_test)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Get a DM7 request for running a test or for test results, if received.

Arg (data out): pj1939f_test Pointer to structure which will be populated with details of the test requested, if a DM7 request has been received. Must not be NULL.

Return: TRUE - if a DM7 request has been received. FALSE - if no DM7 request requires processing.

Note

If multiple DM7 requests are received between calls to this function, the DM7 requests are not guaranteed to be reported in the order in which they are received. To ensure this does not cause a problem, it is recommended that the function is called repeatedly and each DM7 request returned is serviced, until the function returns FALSE indicating that there are no more DM7 requests.

6.7.1.4.5.8. pj1939_dm8_transmit()

Definition: void pj1939_dm8_transmit(U8 pj1939f_tid, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM8 response message.

Can raise the following errors:

Copyright 2019, Pi Innovo 478 Extended Diagnostics Functions

PJ1939_DM8_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_tid The test identifier for which the results are to be transmitted.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.9. pj1939_dm30_transmit()

Definition: void pj1939_dm30_transmit(const PJ1939_DM7_BUFFER_T *pj1939f_req_test, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM30 response message.

Can raise the following errors: PJ1939_DM30_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_req_test The structure containing the details of the requested test. This may be obtained directly from pj1939_get_dm7_commanded_test. The response will be sent to the tool_addr unless the ecu_addr is 255 (i.e. the request was sent to the global address).

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Copyright 2019, Pi Innovo 479 Extended Diagnostics Functions

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.10. pj1939_dm10_transmit()

Definition: void pj1939_dm10_transmit(const U8 pj1939f_priority, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM10 response message.

Supported by targets: M250, M460, M461.

Can raise the following errors: PJ1939_DM10_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there is a problem in transmission. Written false otherwise. Cannot be NULL.

6.7.1.4.5.11. pj1939_dm6_transmit()

Definition: void pj1939_dm6_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM6 message.

Request that a J1939 DM6 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

Copyright 2019, Pi Innovo 480 Extended Diagnostics Functions

The DM6 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM6 messages are transmitted on request.

Can raise the following errors: PJ1939_DM6_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM6 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM6 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM6 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM6 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.12. pj1939_dm12_transmit()

Definition: void pj1939_dm12_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM12 message.

Request that a J1939 DM12 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM12 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

Copyright 2019, Pi Innovo 481 Extended Diagnostics Functions

DM12 messages are transmitted on request.

Can raise the following errors: PJ1939_DM12_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM12 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM12 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM12 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM12 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.13. pj1939_dm23_transmit()

Definition: void pj1939_dm23_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM23 message.

Request that a J1939 DM23 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM23 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM23 messages are transmitted on request.

Copyright 2019, Pi Innovo 482 Extended Diagnostics Functions

Can raise the following errors: PJ1939_DM23_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM23 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM23 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM23 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM23 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.14. pj1939_dm27_transmit()

Definition: void pj1939_dm27_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM27 message.

Request that a J1939 DM27 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM27 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM27 messages are transmitted on request.

Can raise the following errors: PJ1939_DM27_TRANSMIT_INVALID_ARG.

Copyright 2019, Pi Innovo 483 Extended Diagnostics Functions

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM27 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM27 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM27 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM27 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.15. pj1939_dm28_transmit()

Definition: void pj1939_dm28_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM28 message.

Request that a J1939 DM28 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM28 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM28 messages are transmitted on request.

Can raise the following errors: PJ1939_DM28_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM28 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).

Copyright 2019, Pi Innovo 484 Extended Diagnostics Functions

Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM28 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM28 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM28 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.16. pj1939_dm29_transmit()

Definition: void pj1939_dm29_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM29 message.

Request that a J1939 DM29 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM29 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM29 messages are transmitted on request.

Can raise the following errors: PJ1939_DM29_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM29 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Copyright 2019, Pi Innovo 485 Extended Diagnostics Functions

Arg (data in): pj1939f_transmit Set true if the DM29 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM29 message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM29 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.17. pj1939_dm31_transmit()

Definition: void pj1939_dm31_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM31 message.

Request that a J1939 DM31 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM31 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM31 messages are transmitted on request.

Can raise the following errors: PJ1939_DM31_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM31 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Copyright 2019, Pi Innovo 486 Extended Diagnostics Functions

Arg (data in): pj1939f_transmit Set true if the DM31 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM31 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM31 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.18. pj1939_dm35_transmit()

Definition: void pj1939_dm35_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_force_transmission, const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM35 message.

Request that a J1939 DM35 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM35 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

The transmission of a DM35 message can involve many CAN packets and to avoid overloading the CAN bus, the J1939 specification provides some guidance for transmission rates. This can be overridden if necessary.

• forced transmission - causes the function to attempt to transmit a DM35 message regardless of any change in transient fault status of any DTC.

Copyright 2019, Pi Innovo 487 Extended Diagnostics Functions

• unforced transmission - causes the function to attempt to transmit a DM35 message. This will occur if there is at least one DTC with a change in transient fault status from the last time that DTC was transmitted AND the minimum allowed interval has elapsed since that last transmission.

Can raise the following errors: PJ1939_DM35_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM35 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_force_transmission Set true if the DM35 message should be transmitted regardless of DTC transient fault changes.

Arg (data in): pj1939f_priority The priority of the DM35 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM35 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.19. pj1939_dm40_transmit()

Definition: void pj1939_dm40_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM40 message.

Request that a J1939 DM40 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

Copyright 2019, Pi Innovo 488 Extended Diagnostics Functions

The DM40 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM40 messages are transmitted on request.

Can raise the following errors: PJ1939_DM40_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM40 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_priority The priority of the DM40 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM40 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.20. pj1939_dm41_transmit()

Definition: void pj1939_dm41_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM41 message.

Request that a J1939 DM41 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM41 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM41 messages are transmitted on request.

Copyright 2019, Pi Innovo 489 Extended Diagnostics Functions

Can raise the following errors: PJ1939_DM41_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM41 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM41 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM41 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM41 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.21. pj1939_dm42_transmit()

Definition: void pj1939_dm42_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM42 message.

Request that a J1939 DM42 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM42 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM42 messages are transmitted on request.

Can raise the following errors: PJ1939_DM42_TRANSMIT_INVALID_ARG.

Copyright 2019, Pi Innovo 490 Extended Diagnostics Functions

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM42 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM42 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM42 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM42 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.22. pj1939_dm43_transmit()

Definition: void pj1939_dm43_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM43 message.

Request that a J1939 DM43 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM43 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM43 messages are transmitted on request.

Can raise the following errors: PJ1939_DM43_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM43 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored).

Copyright 2019, Pi Innovo 491 Extended Diagnostics Functions

Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM43 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM43 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM43 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.23. pj1939_dm44_transmit()

Definition: void pj1939_dm44_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM44 message.

Request that a J1939 DM44 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM44 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM44 messages are transmitted on request.

Can raise the following errors: PJ1939_DM44_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM44 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Copyright 2019, Pi Innovo 492 Extended Diagnostics Functions

Arg (data in): pj1939f_transmit Set true if the DM44 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM44 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM44 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.24. pj1939_dm45_transmit()

Definition: void pj1939_dm45_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM45 message.

Request that a J1939 DM45 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM45 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM45 messages are transmitted on request.

Can raise the following errors: PJ1939_DM45_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM45 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM45 message should be transmitted, false otherwise.

Copyright 2019, Pi Innovo 493 Extended Diagnostics Functions

Arg (data in): pj1939f_priority The priority of the DM45 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM45 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.25. pj1939_dm46_transmit()

Definition: void pj1939_dm46_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM46 message.

Request that a J1939 DM46 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM46 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM46 messages are transmitted on request.

Can raise the following errors: PJ1939_DM46_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM46 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM46 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM46 message to be transmitted. The lower the priority value, the higher the message priority. Note that this

Copyright 2019, Pi Innovo 494 Extended Diagnostics Functions

value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM46 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.26. pj1939_dm47_transmit()

Definition: void pj1939_dm47_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM47 message.

Request that a J1939 DM47 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM47 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM47 messages are transmitted on request.

Can raise the following errors: PJ1939_DM47_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM47 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM47 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM47 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi

Copyright 2019, Pi Innovo 495 Extended Diagnostics Functions

assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM47 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.27. pj1939_dm48_transmit()

Definition: void pj1939_dm48_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM48 message.

Request that a J1939 DM48 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM48 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM48 messages are transmitted on request.

Can raise the following errors: PJ1939_DM48_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM48 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM48 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM48 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Copyright 2019, Pi Innovo 496 Extended Diagnostics Functions

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM48 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.28. pj1939_dm49_transmit()

Definition: void pj1939_dm49_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM49 message.

Request that a J1939 DM49 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM49 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM49 messages are transmitted on request.

Can raise the following errors: PJ1939_DM49_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM49 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM49 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM49 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM49 message for transmission, Written false otherwise.

Copyright 2019, Pi Innovo 497 Extended Diagnostics Functions

Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.29. pj1939_dm50_transmit()

Definition: void pj1939_dm50_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM50 message.

Request that a J1939 DM50 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM50 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM50 messages are transmitted on request.

Can raise the following errors: PJ1939_DM50_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM50 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM50 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM50 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM50 message for transmission, Written false otherwise. Cannot be NULL.

Copyright 2019, Pi Innovo 498 Extended Diagnostics Functions

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.30. pj1939_dm51_transmit()

Definition: void pj1939_dm51_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM51 message.

Request that a J1939 DM51 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM51 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM51 messages are transmitted on request.

Can raise the following errors: PJ1939_DM51_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM51 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM51 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM51 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM51 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered.

Copyright 2019, Pi Innovo 499 Extended Diagnostics Functions

Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.31. pj1939_dm52_transmit()

Definition: void pj1939_dm52_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_transmit, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM52 message.

Request that a J1939 DM52 message is constructed from the contents of a diagnostic trouble code table and transmitted (broadcast).

The DM52 message contents are constructed from the diagnostic trouble codes stored in one DTC table. Diagnostic trouble codes which do not have J1939 type are ignored.

DM52 messages are transmitted on request.

Can raise the following errors: PJ1939_DM52_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM52 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Cannot be NULL.

Arg (data in): pj1939f_transmit Set true if the DM52 message should be transmitted, false otherwise.

Arg (data in): pj1939f_priority The priority of the DM52 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM52 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

Copyright 2019, Pi Innovo 500 Extended Diagnostics Functions

6.7.1.4.5.32. pj1939_dm32_transmit()

Definition: void pj1939_dm32_transmit(const PDTC_TABLE_T *const pj1939f_table, const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM32 response message.

Can raise the following errors: PJ1939_DM32_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_table A pointer to a diagnostic trouble code table. The contents of the DM32 message are derived from DTCs of J1939 type in this table (DTCs of other types are ignored). Only DTCs with emissions severities greater than the calibrated pdgc_emissions_report_min_sev are reported. See the documentation for the CAPI interface tool regarding the emissions-severity statement for more information. Cannot be NULL.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.33. pj1939_set_control_area_status()

Definition: BOOL pj1939_set_control_area_status(PJ1939_NTE_CNTRL_AREA_T pj1939f_cntrl_area, PJ1939_NTE_CNTRL_AREA_STATUS_T pj1939f_cntrl_area_status)

Copyright 2019, Pi Innovo 501 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function sets the NTE control area status.

Arg (data in): pj1939f_cntrl_area The NTE control area for which the status has to be set.

Arg (data in): pj1939f_cntrl_area_status The status for the selected NTE control area.

Return:

• TRUE - if the status was updated successfully

• FALSE - if the status was not updated due to invalid arguments

6.7.1.4.5.34. pj1939_dm34_transmit()

Definition: void pj1939_dm34_transmit(const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM34 response message.

Supported by targets: M250, M460, M461.

Can raise the following errors: PJ1939_DM34_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise. Cannot be NULL.

6.7.1.4.5.35. pj1939_update_aecd_eng_timer1()

Definition: void pj1939_update_aecd_eng_timer1(const U8 pj1939f_aecd_number, const U32 pj1939f_engine_hours)

Copyright 2019, Pi Innovo 502 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function updates the EI-AECD engine hours timer1 for the specified AECD.

Arg (data in): pj1939f_aecd_number The AECD number for which the timer is to be updated.

Arg (data in): pj1939f_engine_hours The engine hours value in minutes to be set. J1939 spec refers to this as 'engine hours', however the actual value is in minutes

6.7.1.4.5.36. pj1939_update_aecd_eng_timer2()

Definition: void pj1939_update_aecd_eng_timer2(const U8 pj1939f_aecd_number, const U32 pj1939f_engine_hours)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function updates the EI-AECD engine hours timer2 for the specified AECD.

Arg (data in): pj1939f_aecd_number The AECD number for which the timer is to be updated.

Arg (data in): pj1939f_engine_hours The engine hours value in minutes to be set. J1939 spec refers to this as 'engine hours', however the actual value is in minutes.

6.7.1.4.5.37. pj1939_dm33_transmit()

Definition: void pj1939_dm33_transmit(const U8 pj1939f_priority, const U8 pj1939f_dest_addr, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM33 response message.

Can raise the following errors: PJ1939_DM33_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will

Copyright 2019, Pi Innovo 503 Extended Diagnostics Functions

be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined. Range: [0, 7]

Arg (data in): pj1939f_dest_addr Destination address for the message to be transmitted (usually the source address for the corresponding request). Range: [0, 254]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission or there is a problem in transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.38. pj1939_dm4_transmit()

Definition: void pj1939_dm4_transmit(const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Call a function to transmit a J1939 DM4 message.

Request that a J1939 DM4 (standard freeze frame) message is transmitted.

DM4 messages are transmitted on request.

Can raise the following errors: PJ1939_DM4_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the DM4 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM4 message for transmission,written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered.

Copyright 2019, Pi Innovo 504 Extended Diagnostics Functions

Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.39. pj1939_dm25_transmit()

Definition: void pj1939_dm25_transmit(const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Call a function to transmit a J1939 DM25 message.

Request that a J1939 DM25 (expanded freeze frame) message is transmitted.

DM25 messages are transmitted on request.

Can raise the following errors: PJ1939_DM25_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the DM25 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM25 message for transmission,written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.40. pj1939_dm24_transmit()

Definition: void pj1939_dm24_transmit(const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM24.

The DM24 messages is constructed from the lists of SPNs defining:

Copyright 2019, Pi Innovo 505 Extended Diagnostics Functions

• the expanded freeze frame (J1939, DM25)

• support for Data Stream messages

• support for Scaled Test Results (J1939, DM30)

• SPN data lengths

The supported expanded freeze frame SPNs are those defined via the calibration vector identified by the j1939-dm25-ff-name assignment statement in the CAPI file. The Data Stream SPNs comprise those PIDS defined in the CAPI file that have SPN IDs. Whilst SPNs supporting Scaled Test Results are those associated with DTEs (Diagnostic Test Entities) in the CAPI file.

DM24 messages are transmitted on request.

Note: it is up to the user to package the datastream SPNs into a PGN and transmit them on request using the pj1939_pg_transmit() function.

Can raise the following errors: PJ1939_DM24_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the DM24 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM24 message for transmission,written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL. Range: [0, 255] errors

6.7.1.4.5.41. pj1939_dm16_transmit()

Definition: void pj1939_dm16_transmit(U8 pj1939f_priority, U8 pj1939f_dest_addr, U16 pj1939f_buf_len, const U8 *pj1939f_buf, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM16 data message.

Can raise the following errors: PJ1939_DM16_TRANSMIT_INVALID_ARG.

Copyright 2019, Pi Innovo 506 Extended Diagnostics Functions

Arg (data in): pj1939f_priority The priority of the message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_dest_addr The J1939 destination node address for the message. Range: [0, 253] or 255

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM message for transmission. Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A saturated count of the transport transmit errors encountered while transmitting a J1939 message. The transport layer is only involved if the message must be broken into more than one CAN message (i.e., the data content of the message exceeds 8 data bytes). Cannot be NULL. Range: [0, 255] errors

Arg (data in): pj1939f_buf_len The length in bytes for the data buffer to send. Range: [1, 1785]

Arg (data in): pj1939f_buf Pointer to array of bytes to be transmitted. Cannot be NULL.

6.7.1.4.5.42. pj1939_dm36_transmit()

Definition: void pj1939_dm36_transmit(const U8 pj1939f_priority, U8 pj1939f_vnrw_component_count, U8 pj1939f_continuous_mil, U8 pj1939f_mil_display_strategy, U8 pj1939f_mil_activation_mode, U16 pj1939f_incomplete_monitor_count, U16 pj1939f_mil_accumulated_time, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM36 message.

The DM36 message contents are constructed from the supplied parameters and platform internal data (where necessary).

DM36 messages are transmitted on request.

Can raise the following errors: PJ1939_DM36_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the DM36 message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Copyright 2019, Pi Innovo 507 Extended Diagnostics Functions

Arg (data in): pj1939f_vnrw_component_count The sum of the system or component non-roadworthiness counts. Refer to J1939-73 Feb2010 section 5.7.36.1 for details. The platform will limit the value to the range specified below. Range: [0, 250]

Arg (data in): pj1939f_continuous_mil A code indicating whether one or more systems or components requires that the MIL be steady (continuous) burning. Refer to J1939-73 Feb2010 section 5.7.36.2 for details. The platform will limit the value to the range specified below. Range: [0, 3]

Arg (data in): pj1939f_mil_display_strategy A code indicating whether any system is configured to employ a discriminatory MIL display. Refer to J1939-73 Feb2010 section 5.7.36.3 for details. The platform will limit the value to the range specified below. Range: [0, 3]

Arg (data in): pj1939f_mil_activation_mode A code indicating the most severe form of MIL display required by the failure status of any system or component. Refer to J1939-73 Feb2010 section 5.7.36.4 for details. The platform will limit the value to the range specified below. Range: [0, 15]

Arg (data in): pj1939f_incomplete_monitor_count The number of incomplete diagnostic monitors for a given sub- system or component. Refer to J1939-73 Feb2010 section 5.7.36.5 for details. The platform will limit the value to the range specified below. Range: [0, 64255]

Arg (data in): pj1939f_mil_accumulated_time The accumulated count, in minutes, that the MIL is activated for the current MIL activation. Refer to J1939-73 Feb2010 section 5.7.36.6 for details. The platform will limit the value to the range specified below. This range is chosen to match that of the accumulated time sent on DM21 message. Range: [0, 64255] minutes

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM36 message for transmission, Written false otherwise. Cannot be NULL.

6.7.1.4.5.43. pj1939_dm37_transmit()

Definition: void pj1939_dm37_transmit(const BOOL pj1939f_force_transmission, const U8 pj1939f_priority, U8 pj1939f_snrw_component_count, U8 pj1939f_continuous_mil, U8 pj1939f_mil_display_strategy, U8 pj1939f_mil_activation_mode, U16 pj1939f_incomplete_monitor_count, U8 *pj1939f_error_flag)

Supported targets: All targets

Copyright 2019, Pi Innovo 508 Extended Diagnostics Functions

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM37 message.

The DM37 message contents are constructed from the supplied parameters and platform internal data (where necessary).

DM37 messages are transmitted in accordance with the transmission rates defined in J1939-73 Feb2010 section 5.7.37 This function must be scheduled at a 0.1Hz or faster rate in order to fulfil those requirements.

Can raise the following errors: PJ1939_DM37_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_force_transmission Set to TRUE if the DM37 message should be transmitted in addition to the periodic transmission and regardless of any change in input data. Refer to J1939-73 Feb2010 section 5.7.37 for details of transmission rates.

Arg (data in): pj1939f_priority The priority of the DM37 message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_snrw_component_count The number of components that the system has determined to be non-roadworthy. Refer to J1939-73 Feb2010 section 5.7.37.1 for details. The platform will limit the value to the range specified below. Range: [0, 250]

Arg (data in): pj1939f_continuous_mil A code indicating whether the system requires that the MIL be steady (continuous) burning. Refer to J1939-73 Feb2010 section 5.7.37.2 for details. The platform will limit the value to the range specified below. Range: [0, 3]

Arg (data in): pj1939f_mil_display_strategy A code indicating whether the system is configured to employ a discriminatory MIL display. Refer to J1939-73 Feb2010 section 5.7.37.3 for details. The platform will limit the value to the range specified below. Range: [0, 3]

Arg (data in): pj1939f_mil_activation_mode A code indicating the most severe form of MIL display required by the failure status the system or component. Refer to J1939-73 Feb2010 section 5.7.37.4 for details. The platform will limit the value to the range specified below. Range: [0, 15]

Arg (data in): pj1939f_incomplete_monitor_count The number of incomplete diagnostic monitors for a given sub- system or component. Refer to J1939-73 Feb2010 section 5.7.37.5 for details. The platform will limit the value to the range specified below. This range is chosen to match that of the 'Vehicle Incomplete Monitor Count' sent on DM36 message. Range: [0, 64255]

Copyright 2019, Pi Innovo 509 Extended Diagnostics Functions

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM37 message for transmission, Written false otherwise. Cannot be NULL.

6.7.1.4.5.44. pj1939_dm38_transmit()

Definition: void pj1939_dm38_transmit(const U8 *pj1939f_gtr_description, U8 pj1939f_string_length, const U8 pj1939f_priority, U8 *pj1939f_error_flag, U8 *pj1939f_transport_error)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM38 message.

The DM38 message contents are constructed from the supplied parameter.

DM38 messages are transmitted on request.

Can raise the following errors: PJ1939_DM38_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_gtr_description A description of the UN/ECE WWH OBD Global Technical Regulation (GTR) to which the sub-system or component complies. See J1939-73 Feb2010 section 5.7.38.1 for details. The platform will limit the individual character ASCII value to the range specified below. Should a character fall outside, it is rejected and no further characters are processed. Range: [0, 127]

Arg (data in): pj1939f_string_length The length of the UN/ECE WWH OBD Global Technical Regulation (GTR) string. See J1939-73 Feb2010 section 5.7.38.1 for details. The platform will limit the length to the range specified below. Range: [0, 200] characters

Arg (data in): pj1939f_priority The priority of the DM38 message to be transmitted. The lower the priority value, the higher the message priority. Note that this value will be overridden for multi-frame transmissions if the capi assignment statement multiframe-priority is defined (but will still be used for single-frame transmissions). Range: [0, 7]

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM38 message for transmission, Written false otherwise. Cannot be NULL.

Arg (data out): pj1939f_transport_error A pointer to the location to write the saturated count of transport errors encountered. Cannot be NULL.

Copyright 2019, Pi Innovo 510 Extended Diagnostics Functions

Range: [0, 255] errors

6.7.1.4.5.45. pj1939_dm39_transmit()

Definition: void pj1939_dm39_transmit(const U8 pj1939f_priority, U32 pj1939f_sys_cumulative_mil_time, U16 pj1939f_total_b1_time, U8 *pj1939f_error_flag)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function attempts to transmit a J1939 DM39 message.

The DM39 message contents are constructed from the supplied parameters.

DM39 messages are transmitted on request.

Can raise the following errors: PJ1939_DM39_TRANSMIT_INVALID_ARG.

Arg (data in): pj1939f_priority The priority of the DM39 message to be transmitted. The lower the priority value, the higher the message priority. Range: [0, 7]

Arg (data in): pj1939f_sys_cumulative_mil_time The total amount of time that the MIL has been demanded to be illuminated during the life of the system or component. Refer to J1939-73 Feb2010 section 5.7.39.1 for details. The platform will limit the value to the range specified below. Range: [0, 4204501215] scaled at 0.05 hr/bit

Arg (data in): pj1939f_total_b1_time The total amount of time that one or more DTCs with emission severity B1 have been active. Refer to J1939-73 Feb2010 section 5.7.39.2 for details. The platform will limit the value to the range specified below. Range: [0, 64255] scaled at 0.1 hr/bit

Arg (data out): pj1939f_error_flag A pointer to the location to write with the status of the transmission. Written true if there was no free transmit buffer available to hold the DM39 message for transmission, written false otherwise. Cannot be NULL. 6.7.2. Diagnostics (ISO-15765 and KWP2000) feature (PDG) 6.7.2.1. Overview

The library's diagnostic feature handles communications with an external test tool using ISO 15765-2 based protocols (J1979, Keyword Protocol 2000-3, and ISO 14229-1 UDS).

This feature provides few callable functions. To use it, configure the required communication settings in the interface file (see Section 7.1.4.18, “Compound statement: iso-diagnostics”).

Copyright 2019, Pi Innovo 511 Extended Diagnostics Functions

Also specify the diagnostic trouble codes (Section 7.1.4.28, “Compound statement: dtc- data”), parameter identifiers (Section 7.1.4.30, “Compound statement: pid-data”), and routines (Section 7.1.4.37, “Compound statement: routine-data”).

The application software should then use the functionality described in Section 5.18, “Diagnostic Trouble Code (DTC) feature (PDTC)”, Section 6.7.5, “Parameter Identifier feature (PPID)” Section 6.7.6, “In-Use Performance Ratio feature (PPR)”, and Section 6.7.2.3, “Routine Control - service 0x31”. 6.7.2.2. Supported Diagnostic Services

The diagnostic services supported are drawn from three standards: SAE J1979 (ISO 15031-5, "OBD2"), Keyword Protocol 2000-3 (ISO 14230-3) and Unified Diagnostic Services (UDS, ISO 14229-1). They all work in the same way, with the first byte of each request message indicating the required service. Some services are the same (or compatible) in KW2000-3 and UDS.

Table 6.3. PDG supported services

ID Service Notes 0x01 Request Current Powertrain Used to read PID values that have Diagnostic Data (J1979) a J1979 8-bit identifier defined 0x02 Request Powertrain Freeze Frame Used to read PID values that Data (J1979) have been captured when a DTC occurred 0x03 ReadEmissionDTCs (J1979) Reports only DTCs defined as emission-related 0x04 ClearEmissionDTCs (J1979) Clears only DTCs defined as emission-related 0x06 RequestOBDTestResults (J1979) Reports test results for ISO test IDs 0x07 ReadEmissionDTCsPending Reports only DTCs defined as (J1979) emission-related that are pending 0x09 RequestVehicleInformation Used to read Vehicle Information (J1979) data stored as InfoTypes 0x0A ReadEmissionDTCsPermanent Reports only DTCs defined (J1979) as emission-related that are permanent 0x10 StartDiagnosticSession Used to request a change between (KW2000-3) or diagnostic sessions. (Default, DiagnosticSessionControl (UDS) Extended and Programming) 0x11 ECUReset (KW2000-3, UDS) Used to reset the ECU. Only supported by Bootloader to exit reprogramming mode 0x14 ClearDiagInfo (KW2000-3, UDS) Clears all or subgroup of ISO DTCs (not J1939-only DTCs) 0x17 ReadStatusOfDTC (KW2000-3) Reports the status of the specified DTC 0x18 ReadDTCByStatus (KW2000-3) All DTCs, regardless of emissions severity 0x19 ReadDTCInfo (UDS) 16-bit DTCs currently output, lower byte zero; many subfunctions

Copyright 2019, Pi Innovo 512 Extended Diagnostics Functions

ID Service Notes 0x21 ReadDataByLocalIdentifier Used to read PID values using an (KW2000-3) 8-bit identifier 0x22 ReadDataByCommonID Used to read PID values using an (KW2000-3, UDS) 16-bit identifier 0x23 ReadMemoryByAddress Used to read raw memory contents (KW2000-3, UDS) (subject to security restrictions) 0x24 ReadScalingDataByIdentifier Used to read scaling data for a PID (UDS) 0x27 SecurityAccess (KW2000-3, UDS) Used to grant security access in boot loader mode 0x28 CommunicationControl (UDS) Used to switch on/off the transmission and or the reception of certain messages 0x28 DisableNormalMessageTransmissionUsed to switch off the transmission (J2190) of non-diagnostic and non-network management messages 0x29 EnableNormalMessageTransmissionUsed to switch on the transmission (J2190) for all messages 0x2A ReadDataByPeriodicIdentifier Used to request automatic periodic (UDS) transmission of selected PIDs 0x2C DynamicallyDefineDataIdentifier Used to specify a new PID (UDS) composed of other PIDs or memory reads 0x2E WriteDataByLocalIdentifier Used to write PIDs specified by 16- (KW2000-3, UDS) bit identifier (eg NV PID data) 0x2F IOControlByCommonID Used to override PID values using (KW2000-3, UDS) a 16-bit identifier 0x30 IOControlByLocalID (KW2000-3, Used to override PID values UDS) (identified by KW2000 8-bit local identifier) 0x31 RoutineControl (UDS) Used to initiate a specified process in boot loader mode, e.g. erase memory 0x34 RequestDownload (KW2000-3, Used to initiate a downloading of UDS) a block of memory in boot loader mode (only the downloading of unencrypted, uncompressed data is currently supported) 0x36 TransferData (KW2000-3, UDS) Used to download data in boot loader mode (only the downloading to flash is currently supported) 0x37 RequestTransferExit (KW2000-3, Used to terminate data transfer UDS) between the tester and the ECU in boot loader mode 0x3E TesterPresent “Ping” to maintain communications 0x85 ControlDTCSetting Used to Stop or Start the setting of DTCs

Copyright 2019, Pi Innovo 513 Extended Diagnostics Functions

Note

Services $14, $17 and $18 use the ISO 15031-6 values for groupOfDTC groups in KW2000-3 style (powertrain 0x0000, chassis 0x4000, body 0x8000, network/other 0xC000, all 0xFF00). For $14, the equivalent 24-bit UDS values may alternatively be used (0x000000, 0x400000, ... and 0xFFFFFF for 'all').

Note

Please contact Pi Innovo for support with flash reprogramming. The EraseMemory routine ($FF00) typically specified by OEMs is supported in two formats:

• Numeric range: If a length is supplied, the address value is interpreted as an actual device address and the specified range is erased.

• Logical index: If no length is supplied, the address value is interpreted as the zero- based index of the eraseable flash block, which is device-dependent. For example, the MPC5534 M0 block (0x40000 - 0x5FFFF) has index 6. This follows the HIS group reprogramming specification.

6.7.2.3. Routine Control - service 0x31

The library's Routine Control feature provides support for diagnostic routines accessed by numeric identifier using the ISO 14229-1 (UDS) protocol.

Routines can be used to allow a diagnostic tool to perform a custom function within the ECU. For example, a function of the ECU can be started and stopped from the diagnostic tool, or a set of values can be written to or read from ECU memory. The actual routine is defined by the application software. 6.7.2.3.1. Use of Routines

Routines are declared in the interface file (see Section 7.1.4.37, “Compound statement: routine-data”). The C-API tool generates a C identifier for each routine based on the name specified in the interface file, which can be passed to the functions pdg_update_routine_ctrl_data() and pdg_get_routine_rqst().

Routine requests from the diagnostic tool must be retrieved by the application by calling pdg_get_routine_rqst(). pdg_get_routine_rqst() will inform the application if the routine ID has been requested, which sub-function is requested, and any optional routineControlOptionRecord bytes. Note: the requestRoutineResults subfunction is handled internally by the library based on the data passed to the library by the pdg_update_routine_ctrl_data() function.

The application must keep the library informed of the status of all routines by calling pdg_update_routine_ctrl_data(). pdg_update_routine_ctrl_data() is used to inform the library of the following information:

• If the routine is capable of running. If the routine is not capable of running, the library will respond to a startRoutine request with a conditionsNotCorrect negative response.

• If the routine is currently running.

• If the routine has valid results available. If valid results are not available, the library will respond to a requestResults request with a requestSequenceError negative response.

• The routine results bytes.

Copyright 2019, Pi Innovo 514 Extended Diagnostics Functions

• The routine statusRecord bytes.

Routines can be configured to be timed or untimed. See ISO 14229-1 section 13 for the description of "Method A" (untimed) and "Method B" (timed) routines.

If the routine is configured as an untimed routine, the diagnostic tool must send a startRoutine request, and the library will pass this request to the application once the application calls pdg_get_routine_rqst(). The application is then responsible for starting the routine and informing the library that the routine has started by calling pdg_update_routine_ctrl_data(). To stop the routine after it has been started, the diagnostic tool must send a stopRoutine request, and the library will pass this request to the application once the application calls pdg_get_routine_rqst(). The application is responsible for stopping the routine and informing the library that the routine is no longer running by calling pdg_update_routine_ctrl_data().

If the routine is configured as a timed routine, the application is responsible for stopping the routine after it has completed. However, the application shall allow for the routine to stop if a stopRoutine request is received from the diagnostic tool. In all cases, the applciation is responsible for informing the platform that the routine is either running or not running by calling pdg_update_routine_ctrl_data().

The following flow chart summarizes how to use the service $31 routine control interface functions in a typical application.

Figure 6.3. Routine control usage flowchart

start

Retrieve Service Tool Request Inform platform software of routine status pdg_get_routine_rqst() pdg_update_routine_ctrl_data()

startRoutine request? Yes start application routine

No

stopRoutine request? Yes stop application routine

No

Copyright 2019, Pi Innovo 515 Extended Diagnostics Functions

6.7.2.3.2. Platform Routines

Some routines are handled by the platform without any input from the application. These routines have routine IDs that may not be used by the application. The reserved routine IDs are: 0x0202, 0x0203, 0xFF00, and 0xFF01. 6.7.2.4. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pdg.h Macros PDG_SECURITY_FN_MAX_SIZE

The maximum supported size of UDS security callback function (see PDG_SECURITY_CALLBACK_FN_T). PDG_MAX_SEED_SIZE

The maximum supported size of UDS security seed (see PDG_SECURITY_CALLBACK_FN_T). PDG_SESSION_UDS_DEFAULT

Default session entered automatically at startup, by tool request or by timeout of another session type. PDG_SESSION_UDS_PROGRAMMING

Programming session entered by tool request (will not be seen in application running mode) PDG_SESSION_UDS_EXTENDED

Extended session entered by tool request. PDG_NUM_SEC_LEVELS_PER_SERVICE

Limit on number of specific security levels that can be assigned to a service. Enumerations PDG_RC_T

Diagnostic feature return codes. PDG_ROUTINE_RC_T

An enumerated type which contains success and failure codes returned by some routine control functions. PDG_CALLBACK_OUTCOME_T

Return codes by the application to indicate how it would like the PDG feature to continue handling the message just received. PDG_CC_COMM_TYPE_T

Copyright 2019, Pi Innovo 516 Extended Diagnostics Functions

Type Identifier Communication type parameter for the communication control diagnostic service. PDG_CC_CTRL_TYPE_T

The subfunction parameter controlType for the communication control diagnostic service. PDG_SECURITY_OPTION_T

Controls whether certain services are allowed to run, and if so whether they require any or specific security levels to have been unlocked. PDG_ROUTINE_CTRL_T

An enumerated type which contains the routine request subfunction definitions as defined in ISO 14229-1. Data types PDG_ROUTINE_T

This structure collates the data associated with each routine. PDG_GENERAL_CALLBACK_FN_T

Callback function pointer type for general callback. PDG_ID_REQUEST_CALLBACK_FN_T

Callback function pointer type for the ID request callback. PDG_SECURITY_CALLBACK_FN_T

Callback function pointer type for the security callback. PDG_SECURITY_END_FN_T

Function pointer type to mark the end of the security callback. Variables const volatile pdgc_emissions_report_min_sev PIO_EMISSION_SEV_TYPE_T Calibration to determine the minimum emissions severity of DTCs to be reported. struct PDG_ROUTINE_T pdg_routine_table

This is a list of the ISO 16-bit routines the library will maintain. const U16 pdg_num_routines

This is the total number of ISO 16-bit routines the library will maintain. Functions U8 pdg_get_active_session_type

Retrieves type of currently active diagnostic session.

Copyright 2019, Pi Innovo 517 Extended Diagnostics Functions

Type Identifier void pdg_set_active_session_type

Sets the type of currently active diagnostic session. PDG_RC_T pdg_set_infotype

Function to set the InfoType data. PDG_CC_CTRL_TYPE_T pdg_get_comm_ctrl_state

Function to retrieve status of communication control diagnostic service. PDG_RC_T pdg_comm_ctrl_cond_not_correct

Function to indicate the conditions for communications control (service $28) are not correct. PDG_ROUTINE_RC_T pdg_update_routine_ctrl_data

Update platform-cached values for this routine with fresh application values. PDG_ROUTINE_RC_T pdg_get_routine_rqst

Retrieve routine requests from the diagnostic tool.

6.7.2.5. Interface detail

6.7.2.5.1. Macros

6.7.2.5.1.1. PDG_SECURITY_FN_MAX_SIZE

Definition: #define PDG_SECURITY_FN_MAX_SIZE 2048

Description:

The maximum supported size of UDS security callback function (see PDG_SECURITY_CALLBACK_FN_T).

6.7.2.5.1.2. PDG_MAX_SEED_SIZE

Definition: #define PDG_MAX_SEED_SIZE ((U8) 8u)

Description:

The maximum supported size of UDS security seed (see PDG_SECURITY_CALLBACK_FN_T).

6.7.2.5.1.3. PDG_SESSION_UDS_DEFAULT

Definition: #define PDG_SESSION_UDS_DEFAULT ((U8) 0x01)

Description:

Default session entered automatically at startup, by tool request or by timeout of another session type.

Copyright 2019, Pi Innovo 518 Extended Diagnostics Functions

6.7.2.5.1.4. PDG_SESSION_UDS_PROGRAMMING

Definition: #define PDG_SESSION_UDS_PROGRAMMING ((U8) 0x02)

Description:

Programming session entered by tool request (will not be seen in application running mode)

6.7.2.5.1.5. PDG_SESSION_UDS_EXTENDED

Definition: #define PDG_SESSION_UDS_EXTENDED ((U8) 0x03)

Description:

Extended session entered by tool request.

6.7.2.5.1.6. PDG_NUM_SEC_LEVELS_PER_SERVICE

Definition: #define PDG_NUM_SEC_LEVELS_PER_SERVICE 3 /* If altered, NVM must change! */

Description:

Limit on number of specific security levels that can be assigned to a service.

6.7.2.5.2. Enumerations

6.7.2.5.2.1. PDG_RC_T

Summary: Diagnostic feature return codes.

Enumerations:

PDG_RC_OK Everything okay.

PDG_RC_BAD_INFOTYPE The requested infotype is not recognised.

PDG_RC_BAD_ARGS A null pointer was passed as an argument or an incorrect string length was given or unable to find the given subnet.

PDG_RC_PLATFORM_INFOTYPE The requested infotype is handled by the platform.

PDG_RC_BAD_LICENSE User is not licensed for this feature.

6.7.2.5.2.2. PDG_ROUTINE_RC_T

Summary: An enumerated type which contains success and failure codes returned by some routine control functions.

Copyright 2019, Pi Innovo 519 Extended Diagnostics Functions

Enumerations:

PDG_ROUTINE_RC_OK Return code if everything progressed as expected.

PDG_ROUTINE_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PDG_ROUTINE_RC_BAD_CONFIG_DATA Return code if the routine configuration data was invalid for requested operation.

PDG_ROUTINE_RC_NOT_FOUND No such routine ID found.

PDG_ROUTINE_RC_ERROR Unspecified error.

6.7.2.5.2.3. PDG_CALLBACK_OUTCOME_T

Summary: Return codes by the application to indicate how it would like the PDG feature to continue handling the message just received.

Enumerations:

PDG_STANDARD_PLATFORM_REPLY Construct reply according to normal platform behaviour.

PDG_STAY_SILENT Do not send any response to this message at all.

PDG_SEND_WHOLE_APP_MSG Cease normal processing of this message, and transmit the data loaded into the transmit buffer by the application callback routine instead.

PDG_SEND_WITH_APP_ID_DATA For a PID request, use the ID value bytes placed in the transmit buffer by the application callback routine and continue processing the rest of the message as normal.

PDG_SEND_OMITTING_THIS_ID For a PID request, omit the ID echo and value bytes for this PID, but continue processing the rest of the request (which may include requests for other PIDs) as usual.

6.7.2.5.2.4. PDG_CC_COMM_TYPE_T

Summary: Communication type parameter for the communication control diagnostic service.

Enumerations:

PDG_NORMAL_MSGS All application-related communication (inter-application signal exchange between multiple in-vehicle servers).

PDG_NETWORK_MSGS All network-management-related communication.

Copyright 2019, Pi Innovo 520 Extended Diagnostics Functions

PDG_NORMAL_AND_NETWORK_MSGS All network management and application-related communication.

Description: Communication type parameter for the communication control diagnostic service.

Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E).

6.7.2.5.2.5. PDG_CC_CTRL_TYPE_T

Summary: The subfunction parameter controlType for the communication control diagnostic service.

Enumerations:

PDG_MSG_CTRL_INCONSISTENT Indicates inconsistent control types for network and normal messages where the application requested communication type is both network and normal messages.

PDG_ENABLE_RX_AND_TX Indicates the reception and transmission of messages are enabled for the specified communication type.

PDG_ENABLE_RX_AND_DISABLE_TX For the specified communication type indicates the reception of messages are enabled and the transmission of messages are disabled.

PDG_DISABLE_RX_AND_ENABLE_TX For the specified communication type indicates the reception of messages are disable and the transmission of messages are enabled.

PDG_DISABLE_RX_AND_TX Indicates the reception and transmission of messages are disabled for the specified communication type.

Description: The subfunction parameter controlType for the communication control diagnostic service.

Encoded as per table 53 of IS0 14229-1:2006(E).

6.7.2.5.2.6. PDG_SECURITY_OPTION_T

Summary: Controls whether certain services are allowed to run, and if so whether they require any or specific security levels to have been unlocked.

Enumerations:

PDG_SECURITY_WORKS_WITHOUT Always allowed regardless of security status.

PDG_SECURITY_ANY_LEVEL Allowed so long as some security level has been unlocked.

PDG_SECURITY_SPECIFIED_LEVELS Allowed only if a security level has been unlocked that is in the specific list required for this service to be enabled.

Copyright 2019, Pi Innovo 521 Extended Diagnostics Functions

PDG_SECURITY_NEVER_ALLOWED Service is never allowed regardless of security.

6.7.2.5.2.7. PDG_ROUTINE_CTRL_T

Summary: An enumerated type which contains the routine request subfunction definitions as defined in ISO 14229-1.

Enumerations:

PDG_ROUTINE_CTRL_NO_RQST No Request.

ISO defines this as Reserved.

PDG_ROUTINE_CTRL_START_ROUTINE Start routine.

PDG_ROUTINE_CTRL_STOP_ROUTINE Stop routine.

PDG_ROUTINE_CTRL_RQST_RESULTS Request results. 6.7.2.5.3. Data types

6.7.2.5.3.1. PDG_ROUTINE_T

Summary: This structure collates the data associated with each routine.

Members:

U16 PDG_ROUTINE_T::routine_id The 16-bit ID of the routine, used by the test tool to address it.

This is a "CommonIdentifier" in KW2000-3 or just "Identifier" in UDS.

U16 PDG_ROUTINE_T::RCOR_byte_len The number of bytes this routine receives in the routineControlOptionRecord.

U16 PDG_ROUTINE_T::results_byte_len The number of bytes this routine's results.

U16 PDG_ROUTINE_T::status_record_byte_len The number of bytes this routine's status record.

U8* PDG_ROUTINE_T::RCOR_data This points to the routine control option record input values.

Initialised to zero by the platform Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when requested by an external diagnostic test tool.

U8* PDG_ROUTINE_T::results_data This points to the results of the routine.

Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

Copyright 2019, Pi Innovo 522 Extended Diagnostics Functions

U8* PDG_ROUTINE_T::status_record_data This points to the status record of the routine.

Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

BOOL PDG_ROUTINE_T::results_valid This is a flag that informs the platform if the results are valid.

It should be set to FALSE during initialization. It should be set to TRUE at the successful completion of a routine. It should be reset to FALSE when a routine is started. Do not access this data in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

BOOL PDG_ROUTINE_T::routine_ready This is a flag that informs the platform if the routine is capable of running.

Do not access this data in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

BOOL PDG_ROUTINE_T::routine_running This is a flag that informs the platform if the routine is currently running.

Do not access this data in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

PDG_ROUTINE_CTRL_T PDG_ROUTINE_T::routine_request_tool This is the routine request subfunction that is received from the diagnostic test tool.

Do not access this data in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

PDG_ROUTINE_CTRL_T PDG_ROUTINE_T::routine_request_app This is the routine request subfunction that is passed to the application after arbitration by the platform.

Do not access this data in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

PDG_ROUTINE_STATE_T PDG_ROUTINE_T::routine_state This is the state of the $31 communication handler.

Do not access this data in user code. It is only to be used internally by the platform.

BOOL PDG_ROUTINE_T::routine_type_timed This is a boolean that describes if the routine is timed (Method B in the ISO 14229 spec) or if it must be stopped by a tool command (Method A in the ISO spec).

Do not access this in the user code - it is only to be used internally by the platform.

Copyright 2019, Pi Innovo 523 Extended Diagnostics Functions

Description:

This structure collates the data associated with each routine.

Note

The application may use the ID and size elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

6.7.2.5.3.2. PDG_GENERAL_CALLBACK_FN_T

Definition: typedef PDG_CALLBACK_OUTCOME_T(* PDG_GENERAL_CALLBACK_FN_T)(const U8 *pdgf_rx_msg_buff, S16 pdgf_rx_msg_len, U8 *pdgf_tx_msg_buff, S16 *pdgf_tx_msg_len, S16 pdgf_max_tx_msg_len, BOOL pdgf_physically_addressed)

Description: Callback function pointer type for general callback.

Every time PDG receives a request, if a callback function of this type is supplied, it will be called. This gives the application code the opportunity to perform any specific processing that overrides the normal platform behaviour.

Arg (data in): pdgf_rx_msg_buff The start of the ISO16765-2 receive buffer containing the request message bytes (e.g. element 0 will be the service ID).

Arg (data in): pdgf_rx_msg_len The length of the ISO16765-2 request received.

Arg (data in,out): pdgf_tx_msg_buff A pointer to the start of the transmit buffer in which any response message should be constructed.

Arg (data out): pdgf_tx_msg_len The size of the message (if any) which has been constructed by the application in the transmit buffer is returned through this pointer.

Arg (data in): pdgf_max_tx_msg_len The available space in the ISO16765-2 transmit buffer. The application must not attempt to construct a message longer than this.

Arg (data in): pdgf_physically_addressed Whether the request message was received using the physical address for this ECU rather than the functional address used to interrogate all ECUs.

Return: See PDG_CALLBACK_OUTCOME_T.

6.7.2.5.3.3. PDG_ID_REQUEST_CALLBACK_FN_T

Definition: typedef PDG_CALLBACK_OUTCOME_T(* PDG_ID_REQUEST_CALLBACK_FN_T)(const struct PPID_PID_CONST_T *pdgf_id_requested,const U8 *pdgf_rx_msg_buff, S16 pdgf_rx_msg_len, S16 pdgf_rx_id_offset, U8

Copyright 2019, Pi Innovo 524 Extended Diagnostics Functions

*pdgf_tx_msg_buff, S16 *pdgf_tx_msg_len, S16 pdgf_max_tx_len, S16 pdgf_tx_id_data_offset, S16 *pdgf_tx_id_data_len, S16 pdgf_max_id_data_len, BOOL pdgf_physically_addressed)

Description: Callback function pointer type for the ID request callback.

Every time PDG receives a request for an ID value, if a callback function of this type is supplied, it will be called. This gives the application code the opportunity to inject custom values computed at the time of the request for the corresponding PID. Alternatively, the application may opt to override the entire message response.

Arg (data in): pdgf_id_requested A pointer to the PID structure for the ID that has been requested, if it is defined; otherwise NULL for an unknown PID (which the application may still choose to provide a value for).

Arg (data in): pdgf_rx_msg_buff The start of the ISO16765-2 receive buffer containing the request message bytes (e.g. element 0 will be the service ID).

Arg (data in): pdgf_rx_msg_len The length of the ISO16765-2 request received.

Arg (data in): pdgf_rx_id_offset The index into the receive message buffer at which the first byte of the ID being requested exists. This will be a single byte for KW2000-3 LocalIdentifier or J1979 $01 requests, but two bytes for KW20003 CommonIdentifier or UDS Identifier requests.

Arg (data in,out): pdgf_tx_msg_buff A pointer to the start of the transmit buffer in which any complete response message should be constructed.

Arg (data out): pdgf_tx_msg_len The size of the complete response message (if any) which has been constructed by the application in the transmit buffer is returned through this pointer.

Arg (data in): pdgf_max_tx_msg_len The available space in the ISO16765-2 transmit buffer. The application must not attempt to construct a message longer than this.

Arg (data in): pdgf_tx_id_data_offset The index into the transmit message buffer at which the first byte of the ID value should be placed by the application, if it does so.

Arg (data out): pdgf_tx_id_data_len The size of the value (if any) which has been placed in the transmit buffer for this ID by the application is returned through this pointer.

Arg (data in): pdgf_max_id_data_len The maximum size allowed for the value bytes for this ID to avoid transmit buffer overrun. The application must not attempt to write more bytes for this ID than this size.

Arg (data in): pdgf_physically_addressed Whether the request message was received using the physical address for this ECU rather than the functional address used to interrogate all ECUs.

Copyright 2019, Pi Innovo 525 Extended Diagnostics Functions

Return: See PDG_CALLBACK_OUTCOME_T.

6.7.2.5.3.4. PDG_SECURITY_CALLBACK_FN_T

Definition: typedef U8(* PDG_SECURITY_CALLBACK_FN_T)(const U8 *pdgf_request_message, U16 pdgf_request_message_len, U8 *pdgf_seed_buffer, U8 *pdgf_seed_len, U32 pdgf_random)

Description: Callback function pointer type for the security callback.

Every time PDG receives a SecurityAccess ($27) request, it will call a function of this type if provided in your application. Using a callback in this way allows you to implement your own, confidential algorithm. You must provide a function of this type if the use-security-fn setting in the interface file is TRUE.

In order to work during flash reprogramming, this function is copied to non-volatile memory before the application code is erased. This means that the code must be relocatable.

Warning

If this function calls another function, including a compiler- generated arithmetic utility, it will fail to run correctly once relocated. This function must be written with great care.

Note

Your function must be immediately followed in memory by an end marker (see PDG_SECURITY_END_FN_T). The second byte of the request message is the securityAccessType parameter (refer to the UDS/ISO 14229-1 specification). Which values you support to is your own choice. However, odd values must be used for requestSeed and even values for sendKey.

If the request is requestSeed, you are required to provide seed bytes which will then be sent back to the test tool in a positive response message.

If the request is sendKey, you should validate the key in the request message against the previously sent seed, and return a negative response code if you consider the key invalid or zero otherwise.

If the option to enable security during UDS flash reprogramming is enabled then the platform will only proceed if a valid key has been accepted. (See iso-diagnostics group .capi file options for details and an example security algorithm function.)

Arg (data in): pdgf_request_message A pointer to the complete request message from the diagnostic test tool.

Arg (data in): pdgf_request_message_len The complete byte length (including service ID) of the request message from the diagnostic test tool.

Copyright 2019, Pi Innovo 526 Extended Diagnostics Functions

Arg (data in,out): pdgf_seed_buffer The buffer in which this function should place the seed bytes to return to the diagnostic test tool; the same seed bytes are made available if the function is being called to validate a key. Fill the buffer from element zero first.

Arg (data out): pdgf_seed_len The size in bytes of the seed value that this function is providing, if a seed is requested. Range: [1, PDG_MAX_SEED_SIZE].

Arg (data in): pdgf_random A 32-bit pseudorandom number provided by the platform library that may be used as the basis of a seed value.

Note

This is not a random number of high cryptographic quality.

Return: Zero if the platform should emit a positive response; otherwise, the negative response code that should be sent.

6.7.2.5.3.5. PDG_SECURITY_END_FN_T

Definition: typedef void(* PDG_SECURITY_END_FN_T)(void)

Description: Function pointer type to mark the end of the security callback.

See also PDG_SECURITY_CALLBACK_FN_T.

The function you provide of this type must immediately follow the security callback function you provide for UDS. It is used by the platform to compute the size of the security function so that it can be copied to non- volatile memory. 6.7.2.5.4. Variables

6.7.2.5.4.1. pdgc_emissions_report_min_sev

Definition: const volatile PIO_EMISSION_SEV_TYPE_T pdgc_emissions_report_min_sev

Description: Calibration to determine the minimum emissions severity of DTCs to be reported.

6.7.2.5.4.2. pdg_routine_table

Definition: struct PDG_ROUTINE_T pdg_routine_table[]

Description: This is a list of the ISO 16-bit routines the library will maintain.

6.7.2.5.4.3. pdg_num_routines

Definition: const U16 pdg_num_routines

Copyright 2019, Pi Innovo 527 Extended Diagnostics Functions

Description: This is the total number of ISO 16-bit routines the library will maintain. 6.7.2.5.5. Functions

6.7.2.5.5.1. pdg_get_active_session_type()

Definition: U8 pdg_get_active_session_type(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Retrieves type of currently active diagnostic session.

Return: One of PDG_SESSION_UDS_DEFAULT, PDG_SESSION_UDS_EXTENDED or PDG_SESSION_UDS_PROGRAMMING. The UDS state value is returned even if the test tool used a KW2000-3 value to request entry to the session.

6.7.2.5.5.2. pdg_set_active_session_type()

Definition: void pdg_set_active_session_type(U8 pdgf_session)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Sets the type of currently active diagnostic session.

Arg (data in): pdgf_session One of PDG_SESSION_UDS_DEFAULT, PDG_SESSION_UDS_EXTENDED or PDG_SESSION_UDS_PROGRAMMING. The UDS state value is returned even if the test tool used a KW2000-3 value to request entry to the session.

6.7.2.5.5.3. pdg_set_infotype()

Definition: PDG_RC_T pdg_set_infotype(PIO_INFOTYPE_T pdgf_infotype_id, const U8 *pdgf_infotype_data, U8 pdgf_infotype_length, BOOL pdgf_pending)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Function to set the InfoType data.

Copyright 2019, Pi Innovo 528 Extended Diagnostics Functions

Call this function from initialisation and when the application is running if necessary to set or update the J1979 Infotype data.

Arg (data in): pdgf_infotype_id An enumerated constant that matches the INFOTYPE id.

Arg (data in): pdgf_infotype_data Pointer to the array containing the data to be written.

Arg (data in): pdgf_infotype_length Length of the array containing the data to be written.

Arg (data in): pdgf_pending Indicates the availability of the application data. False indicates the data is available. When true, a J1979 request for the data will result in the negative response code $78 (requestCorrectlyReceived- ResponsePending) followed by a negative response code $78 message at 4.5s intervals until pdgf_pending transistions to false where upon the supplied infotype data is sent. Only applicable to the CVN infotype.

Return:

• PDG_RC_OK - everything ok

• PDG_RC_BAD_LICENSE - not licensed to execute this function

• PDG_RC_BAD_INFOTYPE - infotype not supported by platform

• PDG_RC_BAD_ARGS - null pointer or undefined infotype

• PDG_RC_PLATFORM_INFOTYPE - infotype handled exclusively by platform

6.7.2.5.5.4. pdg_get_comm_ctrl_state()

Definition: PDG_CC_CTRL_TYPE_T pdg_get_comm_ctrl_state(PDG_CC_COMM_TYPE_T pdgf_communication_type, U8 pdgf_subnet_id)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Function to retrieve status of communication control diagnostic service.

Service $28 switches on/off the transmission and or the reception of certain CAN messages. The onus is on the application to dictate which messages to switch on/off, as such the status of communication control service is provided to the application via this function.

Arg (data in): pdgf_communication_type Communication type parameter. Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E)

Arg (data in): pdgf_subnet_id The subnet identifier. Only 4 subnets supported 0x0, 0x1, 0x2 and 0xF. Subnet encoded as per table B.1 in Annex B of IS0 14229-1:2006(E). ID 0x0 receiving node and all connected

Copyright 2019, Pi Innovo 529 Extended Diagnostics Functions

networks. ID 0x1 and 0x2 specific network identity. ID 0xF Network which the request is recieved on.

Return:

• PDG_MSG_CTRL_INCONSISTENT - inconsistent control types for network and normal messages where the application requested communication type is both network and normal messages

• PDG_ENABLE_RX_AND_TX - reception and transmission of messages are enabled

• PDG_ENABLE_RX_AND_DISABLE_TX - reception of messages are enabled and the transmission of messages are disabled

• PDG_DISABLE_RX_AND_ENABLE_TX - reception of messages are disable and the transmission of messages are enabled

• PDG_DISABLE_RX_AND_TX - reception and transmission of messages are disabled

6.7.2.5.5.5. pdg_comm_ctrl_cond_not_correct()

Definition: PDG_RC_T pdg_comm_ctrl_cond_not_correct(BOOL pdgf_conditions_not_correct, U8 pdgf_subnet_id, PDG_CC_COMM_TYPE_T pdgf_comm_type)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Function to indicate the conditions for communications control (service $28) are not correct.

Where the conditions are not correct a negative response code of conditionsNotCorrect (NRC $22) is sent in reply to a service $28 request. NRC $22 indicates the server (ECU) is in a critical normal mode activity and therefore cannot disable/enable the requested communication type.

Call this function from initialisation and/or periodically.

Arg (data in): pdgf_conditions_not_correct True if conditions are not correct to disable/enable the requested communication type otherwise false if conditions are ok.

Arg (data in): pdgf_subnet_id The subnet identifier. Only 5 subnets supported 0x0, 0x1, 0x2, 0x3 and 0xF. Subnet encoded as per table B.1 in Annex B of IS0 14229-1:2006(E). ID 0x0 receiving node and all connected networks. ID 0x1, 0x2 and 0x3 specific network identity. ID 0xF Network which the request is recieved on.

Arg (data in): pdgf_comm_type Communication type parameter. Encoded as per table B.1 in Annex B of IS0 14229-1:2006(E)

Return:

• PDG_RC_OK - everything okay

Copyright 2019, Pi Innovo 530 Extended Diagnostics Functions

• PDG_RC_BAD_LICENSE - not licensed to execute this function

• PDG_RC_BAD_ARGS - unable to find the subnet

6.7.2.5.5.6. pdg_update_routine_ctrl_data()

Definition: PDG_ROUTINE_RC_T pdg_update_routine_ctrl_data(struct PDG_ROUTINE_T *const pdgf_routine_data, BOOL pdgf_routine_ready, BOOL pdgf_routine_running, const U8 *pdgf_routine_status_record, BOOL pdgf_routine_results_valid, const U8 *pdgf_routine_results)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Update platform-cached values for this routine with fresh application values.

Arg (data in,out): pdgf_routine_data Pointer to the routine control data structure to be updated

Arg (data in): pdgf_routine_ready Flag from the application to signal that the routine is able to run if requested.

Arg (data in): pdgf_routine_running Flag from the application to signal that the routine is currently running.

Arg (data in): pdgf_routine_status_record Pointer to the routine status record bytes to be transmitted in the response message.

Arg (data in): pdgf_routine_results_valid Flag from the application to signal that valid routine results are available.

Arg (data in): pdgf_routine_results Pointer to the routine results bytes.

Return:

• PDG_ROUTINE_RC_BAD_ARGS - if the input parameters are invalid

• PDG_ROUTINE_RC_BAD_CONFIG_DATA - if there is a mismatch in the byte-length of routine data

• PDG_ROUTINE_RC_OK - if operation is successful

6.7.2.5.5.7. pdg_get_routine_rqst()

Definition: PDG_ROUTINE_RC_T pdg_get_routine_rqst(struct PDG_ROUTINE_T *const pdgf_routine_data, PDG_ROUTINE_CTRL_T *const pdgf_routine_rqst, U8 *const pdgf_routine_ctrl_option_record)

Copyright 2019, Pi Innovo 531 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Retrieve routine requests from the diagnostic tool.

Arg (data in): pdgf_routine_data Pointer to the routine control data structure. Cannot be NULL.

Arg (data out): pdgf_routine_rqst Pointer to an enumeration which will hold the routine control request. Cannot be NULL.

Arg (data out): pdgf_routine_ctrl_option_record Pointer to a buffer to hold the routine control option record bytes. Can be NULL if routine control options are not used for this routine.

Return:

• PDG_ROUTINE_RC_BAD_ARGS - if the input parameters are invalid

• PDG_ROUTINE_RC_OK - if operation is successful 6.7.3. Diagnostic Trouble Code Extended (DTC) feature (PDTC) 6.7.3.1. Overview

This section covers the extended diagnostics functions available in addition to the basic diagnostic trouble code (DTC) functionality (see Section 5.18, “Diagnostic Trouble Code (DTC) feature (PDTC)”):

Library controlled OBD state handling The library supports platform controlled On-Board Diagnostics and DTC state handling as per CARB OBD standards, including freeze frame capture.

DTC ageing The library ages DTCs based on drive cycles and warm-up cycles.

ISO DTC type The library adds an ISO DTC type in addition to the J1939 DTC type provided as standard. 6.7.3.2. Platform On-Board Diagnostic support

The library supports platform controlled On-Board Diagnostics and DTC state handling as per CARB OBD standards. This functionality, available at extra cost, can be used by calling the pdtc_update_plat_obd_dtc() C-API function.

An OBD DTC can have up to three freeze frames associated with it: an ISO freeze frame, a J1939 DM4 freeze frame, and/or a J1939 DM25 expanded freeze frame. See section Section 6.7.4, “Freeze Frame feature (PFF)” for details.

The application declares the PDTC_DTC_T data structure per DTC of interest during build time which contains the configuration for that DTC: J1939 SPN/FMI/CM, ISO-15765 DTC

Copyright 2019, Pi Innovo 532 Extended Diagnostics Functions

ID, lamps to light when DTC is active, and so on. The PDTC_DTC_T data structure then references two further data structures, PDTC_DTC_NV_T and PDTC_DTC_VAR_T, which store the DTC's non-volatile variables (stored in flash between power cycles) and volatile variables (held in RAM and lost on power-off) respectively.

Each DTC can be in one of four states. Its state is Clear if its fault conditions have never been present, or if a previously active fault has healed itself (its fault conditions have not been present for a sufficient amount of time). Its state is Pending if its fault conditions are present, but have not been present for long enough to confirm the fault. Its state becomes Active if a Pending DTC's fault conditions persist long enough for it to be confirmed, or if a Previously Active DTC's fault conditions return. Its state becomes Previously Active if an Active DTC's fault conditions have been not been present for a sufficient amount of time.

The library will transition through the different states, Clear, Pending, Active and Previously Active based upon the inputs from the application, pdtcf_test_failed and pdtcf_test_completed as well as information regarding current drive cycle and warm up cycle count.

State transitions are also affected by whether transitions between Previously Active and Pending states are permitted when a previously active fault recurs. Behaviour in this situation is not specified by CARB (and therefore not by other OBD specifications deriving from CARB), so behaviour is manufacturer-specific and has therefore been made configurable. Calibration pdtc_transition_prev_act_to_pend specifies whether this transition is enabled or not (set to TRUE to enable). In the C-API configuration file, this is controlled by the setting transition- previously-active-to-pending (see Section 7.1.4.28, “Compound statement: dtc-data”).

If transitions between Previously Active and Pending states are disabled, the following diagram describes the DTC state transitions.

Figure 6.4. Platform OBD state machine — no transitions between Previously Active and Pending

if ‘pdtcf_test_failed’ = FALSE if ‘pdtcf_test_failed’ = if ‘pdtcf_test_failed’ = if ‘pdtcf_test_failed’ = TRUE for required TRUE TRUE drive cycles

Clear Active Pending 1 2 4 if ‘pdtcf_test_failed’ = FALSE for required if ‘pdtcf_test_failed’ = drive cycles FALSE throughout if ‘pdtcf_test_failed’ = OR last drive cycle TRUE required engine running time elapsed

Previously Active

3 If ‘pdtcf_test_failed’ = FALSE for required warm-up cycles OR if ‘pdtcf_test_failed’ = required engine running time elapsed FALSE

Transitions take place only when pdtcf_test_completed = TRUE

If transitions between Previously Active and Pending states are enabled, the following diagram describes the DTC state transitions.

Copyright 2019, Pi Innovo 533 Extended Diagnostics Functions

Figure 6.5. Platform OBD state machine — transitions between Previously Active and Pending

if ‘pdtcf_test_failed’ = FALSE if ‘pdtcf_test_failed’ = if ‘pdtcf_test_failed’ = TRUE for required drive if ‘pdtcf_test_failed’ = TRUE TRUE cycles

Clear Active if ‘pdtcf_test_failed’ = Pending FALSE for required 1 2 drive cycles 4 OR required engine running time elapsed if ‘pdtcf_test_failed’ = FALSE throughout last drive cycle if ‘pdtcf_test_failed’ = AND TRUE was not previously active

if ‘pdtcf_test_failed’ = FALSE throughout last drive cycle Previously AND Active was previously active 3 If ‘pdtcf_test_failed’ = FALSE for required warm-up cycles OR if ‘pdtcf_test_failed’ = required engine running time elapsed FALSE

Transitions take place only when pdtcf_test_completed = TRUE

The library keeps track of a new drive cycle or warm-up cycle based on inputs from the application, pdtcf_start_of_dc and pdtcf_start_of_wup respectively, to the following functions:

• pdtc_plat_obd_update_ign_cyc()

• pdtc_plat_obd_update_dc_count()

• pdtc_plat_obd_update_wup_count()

6.7.3.2.1. DTC ageing in Previously Active state

Detection of warm-up and DTC ageing in the Previously Active state is not as straightforward as it might at first appear. OBD regulations (in particular CARB and European regulations) define drive cycles unambiguously, but are less clear on the definition of a warm- up cycle. It has therefore been necessary to adopt an interpretation which is believed to be the most stringent possible interpretation, so that regulatory compliance can be assured.

The OpenECU interpretation of a warm-up cycle is “an ignition cycle in which a warm-up (as reported by the customer) occurs”. The test causing a DTC to be raised must also run and pass during the same ignition cycle in which the warm-up occurs, in order for the DTC to be aged by one warm-up count. The following diagram describes scenarios which illustrate how this will work in an application.

A B C DE F G H J K L M Power cycle

Ignition cycle reported

Warm-up cycle reported

Test run and passed

Warm-up count incremented

Copyright 2019, Pi Innovo 534 Extended Diagnostics Functions

At points A and B a test has not been run and passed in the same warm-up cycle, so the warm-up count is not incremented.

At point C the warm-up has not yet occurred when the test is run and passed, so the warm- up count is not incremented. At point D the warm-up occurs, and as a result of the test having been previously run and passed, the warm-up count is incremented. Further instances of the test running and passing during this ignition cycle (E) do not affect the warm-up count, because this is required to count warm-ups and not test executions.

At point F the test is run and passed when the warm-up has already occurred, so the warm-up count is incremented immediately. Further instances of the test running and passing during this ignition cycle (G) again do not affect the warm-up count.

Due to power-hold relays, capacitors or other system behaviour, the ECU may not lose power when the ignition is cycled. Points H and J illustrate that tests carried out on subsequent ignition cycles with warm-ups will increment the warm-up count, even if the ECU has not been powered off. Point K illustrates that the requirement for test run and warm-up remains.

Tests may also be required to take place during the power-hold period. Point L illustrates that the warm-up count will be incremented during the power-hold period if a warm-up cycle has previously taken place this ignition cycle. Point M illustrates that the requirement for warm- up still exists during the power-hold period.

Note that this diagram does not mention drive cycles, as these are calculated independently and do not affect warm-up (except insofar as they are based on conditions arising in the same vehicle). Note also that the diagram does not mention warm-ups reported with the ignition off, because the regulatory definition of a warm-up requires the engine to be on (and hence the ignition to be on). 6.7.3.3. Diagnostic trouble codes — J1939

The library maintains an internal state for a J1939 DTC as described by Section 5.18.3, “Diagnostic trouble codes — J1939”. 6.7.3.4. Diagnostic trouble codes — ISO

The library maintains an internal state for an ISO DTC based on the pdtcf_state_in parameter to the function pdtc_update_iso_dtc(). State transitions depend on whether transitions from Inactive state to Pending state are enabled, as shown by the following state diagrams. This is enabled or disabled by the calibration pdtc_transition_prev_act_to_pend. This calibrations's value is controlled in the C-API configuration file by the setting transition- previously-active-to-pending (see Section 7.1.4.28, “Compound statement: dtc-data”).

If transitions from Inactive state to Pending state are disabled, the following diagram describes the DTC state transitions.

Copyright 2019, Pi Innovo 535 Extended Diagnostics Functions

Figure 6.6. ISO DTC state machine — no transitions from Inactive to Pending

if ‘pdtcf_state_in’ = CLEAR if ‘pdtcf_state_in’ = if ‘pdtcf_state_in’ = if ‘pdtcf_state_in’ = ACTIVE PENDING ACTIVE

clear active pending 1 2 4

if ‘pdtcf_state_in’ = if ‘pdtcf_state_in’ = CLEAR INACTIVE

if ‘pdtcf_state_in’ = ACTIVE

inactive

3

if ‘pdtcf_state_in’ = INACTIVE

If transitions from Inactive state to Pending state are enabled, the following diagram describes the DTC state transitions.

Figure 6.7. ISO DTC state machine — transitions from Inactive to Pending

if ‘pdtcf_state_in’ = CLEAR if ‘pdtcf_state_in’ = if ‘pdtcf_state_in’ = if ‘pdtcf_state_in’ = ACTIVE or PENDING PENDING ACTIVE

clear active pending 1 2 if ‘pdtcf_state_in’ = 4 CLEAR

if ‘pdtcf_state_in’ = CLEAR if ‘pdtcf_state_in’ = AND ACTIVE not previously active if ‘pdtcf_state_in’ = PENDING

if ‘pdtcf_state_in’ = CLEAR inactive AND previously active 3

if ‘pdtcf_test_failed’ = CLEAR

Copyright 2019, Pi Innovo 536 Extended Diagnostics Functions

Not shown in the above figures is that the DTC state can be forcefully set to clear through the use of the pdtc_clear_all(), pdtc_clear_all_if_active() or pdtc_clear_all_if_inactive() or pdtc_clear_dtcs() functions. 6.7.3.5. Storage of data across power cycles

As described in Section 5.18.4, “Storage of data across power cycles”, if the DTC information stored across power cycles cannot be recalled correctly then DTCs are reset to default start- up conditions:

Table 6.4. DTC initialisation values

DTC information Initial value State Clear Test Never Completed Since OBD Reset Yes (reported by ISO-15765) Number of Times Set Active Count 0 (reported by J1939) Lamp States (Section 6.7.3.4, “Diagnostic All off trouble codes — ISO” and Section 5.18.3, “Diagnostic trouble codes — J1939” only) Drive Cycle Count (Section 6.7.3.2, 0 “Platform On-Board Diagnostic support” only) Warm-up Cycle Count (Section 6.7.3.2, 0 “Platform On-Board Diagnostic support” only) Test Run/Passed/Failed This Drive Cycle Test not run (Section 6.7.3.2, “Platform On-Board Diagnostic support” only) Total time in "Active" state 0 Total time in "Previously Active" state 0 Time remaining until torque derate (relevant Maximum (62.5 hours) only for DTCs which have torque derate)

6.7.3.6. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and pdtc.h Macros PDTC_LAMPS_OFF

Value for all lamps OFF. PDTC_OBD_CLEAR_EMISSIONS_RELATED

Bit 0 set for reporting ISO-15765 emissions-related DTCs cleared via ISO-15765 service $04 OBD request. PDTC_OBD_CLEAR_ALL

Copyright 2019, Pi Innovo 537 Extended Diagnostics Functions

Type Identifier Bit 1 set for reporting all ISO-15765 DTCs cleared via ISO-15765 service $14 OBD request (regardless of groupOfDTC option). PDTC_OBD_CLEAR_PREV_ACTIVE

Bit 2 set for reporting J1939 DTCs in Previously Active state cleared via J1939 DM3 OBD request. PDTC_OBD_CLEAR_ACTIVE

Bit 3 set for reporting J1939 DTCs in Active state cleared via J1939 DM11 OBD request. PDTC_DISABLE_COUNTER_TRANSITION

Value used to disable DTC transitions based on counters of drive cycles or warm-up cycles. PDTC_DISABLE_ENGINE_RUNNING_TRANSITION

Value used for DTC time_to_deactive and time_to_clear settings to disable the DTC transitions from "Active" to "Previously Active" or from from "Previously Active" to "Clear" based on time with engine running and fault not present. Enumerations PDTC_LAMP_T

This enumeration declares the different lamps which may be controlled by DTC states, where certain types of lamp require special reporting by on-board diagnostics. PDTC_COMBINED_LAMP_STATE_T

This enumeration declares all possible states for a lamp. PDTC_MI_MODE_T

This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no. PDTC_IT_TYPE_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's state. PDTC_IT_ESEV_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's emissions severity. PDTC_IT_STATE_COMPARATOR_T

This enumeration declares the comparison tests for a DTC's state. Data types PDTC_DTC_NV_T

Copyright 2019, Pi Innovo 538 Extended Diagnostics Functions

Type Identifier This structure declares the run-time data to be stored with each DTC. PDTC_DTC_VAR_T

This structure declares the variable data to be stored in RAM with each DTC type. PDTC_DTC_T

This structure declares the constant data to be stored with each DTC type. PDTC_TABLE_VAR_T

This structure declares all per-DTC-table variable data. Variables const BOOL pdtc_lamp_flashing_is_priority

This calibration selects the lamp priority system used to select the desired state for a lamp when multiple DTCs are active and request different states. const BOOL pdtc_transition_prev_act_to_pend

This calibration selects the DTC state behaviour when a fault recurs whilst the DTC is in the "previously active" state. const PDTC_TABLE_T pdtc_table_all

This is a table of all DTCs defined in the system. Functions PDTC_MI_MODE_T pdtc_get_mi_activation_mode

Supplies the current MI activation mode. U32 pdtc_get_b1_cumulative_counter

Supplies the cumulative time in seconds for which any B1 fault has been active. U32 pdtc_get_b1_continuous_counter

Supplies the time in seconds for which any B1 fault has been active continuously. U32 pdtc_get_mil_cumulative_counter

Supplies the cumulative time in seconds for which the MI has been demanded to be illuminated. PDTC_ERROR_CODE_T pdtc_clear_all_tables

Clear the state of each DTC of matching type in all the DTC tables. PDTC_ERROR_CODE_T pdtc_clear_all_by_severity

Clear the state of each DTC of matching type emission severity level in a DTC table. void pdtc_clear_dtcs

Copyright 2019, Pi Innovo 539 Extended Diagnostics Functions

Type Identifier Clear DTCs, within a DTC table, which match the supplied criteria. PIO_DTC_LAMP_STATES_T pdtc_get_lamp_state

This function returns the current state of a lamp, based on DTCs set in the selected table. PIO_DTC_LAMP_STATES_T pdtc_get_MIL_status

Indicates whether the MIL has to be ON due to DTCs (CARB), based on all DTC tables in the system. PIO_DTC_LAMP_STATES_T pdtc_get_RSL_status

Indicates whether the Red lamp has to be ON due to DTCs (CARB). PIO_DTC_LAMP_STATES_T pdtc_get_AWL_status

Indicates whether the Amber lamp has to be ON due to DTCs (CARB). PIO_DTC_LAMP_STATES_T pdtc_get_Protect_lamp_status

Indicates whether the Protect lamp has to be ON due to DTCs (CARB). BOOL pdtc_match_exists

Determine the existence and count of DTCs, within a DTC table, which match the supplied criteria. U32 pdtc_check_table_cleared

Reports whether DTCs have been cleared by OBD request. PDTC_ERROR_CODE_T pdtc_get_dtc_status

Retrieve the status data of a DTC. void pdtc_plat_obd_update_clr_perm_ok

Keeps track of whether conditions have been met for clearing CARB permanent DTCs after an OBD clear request. void pdtc_plat_obd_update_engine_running

Keeps track of engine running state for DTCs. void pdtc_plat_obd_update_ign_cyc

Keeps track of new ignition cycle. void pdtc_plat_obd_update_dc_count

Keeps track of new drive cycle for DTCs. void pdtc_plat_obd_update_wup_count

Keeps track of new warmup cycle for DTCs. PDTC_ERROR_CODE_T pdtc_update_iso_dtc

Copyright 2019, Pi Innovo 540 Extended Diagnostics Functions

Type Identifier Function to update the state and data of an ISO DTC. PDTC_ERROR_CODE_T pdtc_update_plat_obd_dtc

Function to update the state and data of the DTC when controlled by platform.

Type Identifier Include file openecu.h and pio.h Enumerations @8

This enumeration declares the different types of DTC lamp state available. Data types PIO_DTC_LAMP_STATES_T

This enumeration declares the different types of DTC lamp state available. 6.7.3.7. Interface detail

6.7.3.7.1. Macros

6.7.3.7.1.1. PDTC_LAMPS_OFF

Definition: #define PDTC_LAMPS_OFF ((U8)0xFF)

Description:

Value for all lamps OFF.

6.7.3.7.1.2. PDTC_OBD_CLEAR_EMISSIONS_RELATED

Definition: #define PDTC_OBD_CLEAR_EMISSIONS_RELATED ((U32)0x01)

Description:

Bit 0 set for reporting ISO-15765 emissions-related DTCs cleared via ISO-15765 service $04 OBD request.

Reported by function pdtc_check_table_cleared.

6.7.3.7.1.3. PDTC_OBD_CLEAR_ALL

Definition: #define PDTC_OBD_CLEAR_ALL ((U32)0x02)

Description:

Bit 1 set for reporting all ISO-15765 DTCs cleared via ISO-15765 service $14 OBD request (regardless of groupOfDTC option).

Reported by function pdtc_check_table_cleared.

Copyright 2019, Pi Innovo 541 Extended Diagnostics Functions

6.7.3.7.1.4. PDTC_OBD_CLEAR_PREV_ACTIVE

Definition: #define PDTC_OBD_CLEAR_PREV_ACTIVE ((U32)0x04)

Description:

Bit 2 set for reporting J1939 DTCs in Previously Active state cleared via J1939 DM3 OBD request.

Reported by function pdtc_check_table_cleared.

6.7.3.7.1.5. PDTC_OBD_CLEAR_ACTIVE

Definition: #define PDTC_OBD_CLEAR_ACTIVE ((U32)0x08)

Description:

Bit 3 set for reporting J1939 DTCs in Active state cleared via J1939 DM11 OBD request.

Reported by function pdtc_check_table_cleared.

6.7.3.7.1.6. PDTC_DISABLE_COUNTER_TRANSITION

Definition: #define PDTC_DISABLE_COUNTER_TRANSITION ((U8)0xFF)

Description:

Value used to disable DTC transitions based on counters of drive cycles or warm-up cycles.

6.7.3.7.1.7. PDTC_DISABLE_ENGINE_RUNNING_TRANSITION

Definition: #define PDTC_DISABLE_ENGINE_RUNNING_TRANSITION ((U32)0xFFFFFFFF)

Description:

Value used for DTC time_to_deactive and time_to_clear settings to disable the DTC transitions from "Active" to "Previously Active" or from from "Previously Active" to "Clear" based on time with engine running and fault not present. 6.7.3.7.2. Enumerations

6.7.3.7.2.1. PDTC_LAMP_T

Summary: This enumeration declares the different lamps which may be controlled by DTC states, where certain types of lamp require special reporting by on-board diagnostics.

Enumerations:

PDTC_LAMP_PROTECT This is the Protect lamp.

PDTC_LAMP_AMBER_WARNING This is the Amber Warning lamp.

Copyright 2019, Pi Innovo 542 Extended Diagnostics Functions

PDTC_LAMP_RED_STOP This is the Red Stop lamp.

PDTC_LAMP_MIL This is the MIL.

PDTC_NUM_LAMPS Count number of lamp types supported.

6.7.3.7.2.2. PDTC_COMBINED_LAMP_STATE_T

Summary: This enumeration declares all possible states for a lamp.

Enumerations:

PDTC_COMBINED_SLOW_FLASH Slow flash (1Hz, 50% duty cycle)

PDTC_COMBINED_FAST_FLASH Fast flash (2Hz or faster, 50% duty cycle)

PDTC_COMBINED_ON Lamp on continuous.

PDTC_COMBINED_SHORT_MIL_ACTV_ON MIL only - lamp on, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) active and lamp required to be on.

PDTC_COMBINED_SHORT_MIL_ACTV_OFF MIL only - lamp off, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) active and lamp required to be off.

PDTC_COMBINED_SHORT_MIL_INACTIVE MIL only - lamp off, due to Short MIL ("short-MI" in WWH OBD) from class B DTC(s) present but Short MIL sequence inactive.

PDTC_COMBINED_CLASS_C_ACTIVE_ON MIL only - lamp on, due to WWH OBD Class C DTC(s) set and lamp required to be on for reporting.

PDTC_COMBINED_CLASS_C_ACTIVE_OFF MIL only - lamp off, due to WWH OBD Class C DTC(s) set and lamp required to be off for reporting.

PDTC_COMBINED_CLASS_C_INACTIVE MIL only - lamp off, due to WWH OBD Class C DTC(s) set and reporting not in progress.

PDTC_COMBINED_SELF_TEST_ON MIL only - lamp on, due to self-test in progress.

PDTC_COMBINED_SELF_TEST_OFF MIL only - lamp off, due to self-test in progress.

PDTC_COMBINED_OFF Lamp off, no relevant DTCs set.

6.7.3.7.2.3. PDTC_MI_MODE_T

Summary: This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no.

Copyright 2019, Pi Innovo 543 Extended Diagnostics Functions

Enumerations:

PDTC_MODE_MI_OFF Off = No malfunction.

PDTC_MODE_ON_DEMAND_MI On Demand MI = Class C malfunction.

PDTC_MODE_SHORT_MI Short MI = Class B malfunction and B1 counter < 200 hours.

PDTC_MODE_CONTINUOUS_MI Continuous MI = Class A malfunction or B1 counter > 200 hours.

Description: This enumeration declares the MI activation modes as per the Euro VI specification - UN ECE Regulation no.

49, Addendum 48.

6.7.3.7.2.4. PDTC_IT_TYPE_COMPARATOR_T

Summary: This enumeration declares the comparison tests for a DTC's state.

Enumerations:

PDTC_IT_TYPE_DC Don't care.

PDTC_IT_TYPE_CT Contains.

6.7.3.7.2.5. PDTC_IT_ESEV_COMPARATOR_T

Summary: This enumeration declares the comparison tests for a DTC's emissions severity.

Enumerations:

PDTC_IT_ESEV_DC Don't care.

PDTC_IT_ESEV_EQ Equals.

PDTC_IT_ESEV_NE Not equal.

PDTC_IT_ESEV_LT Less than.

PDTC_IT_ESEV_LTE Less than or equal.

PDTC_IT_ESEV_GT Greater than.

PDTC_IT_ESEV_GTE Greater than or equal.

Copyright 2019, Pi Innovo 544 Extended Diagnostics Functions

6.7.3.7.2.6. PDTC_IT_STATE_COMPARATOR_T

Summary: This enumeration declares the comparison tests for a DTC's state.

Enumerations:

PDTC_IT_STATE_DC Don't care.

PDTC_IT_STATE_EQ Equals.

PDTC_IT_STATE_NE Not equal. 6.7.3.7.3. Data types

6.7.3.7.3.1. PDTC_DTC_NV_T

Summary: This structure declares the run-time data to be stored with each DTC.

Members:

U8 PDTC_DTC_NV_T::dtc_dc_count This keeps track of the number of drive cycles, and is used for different purposes depending on the DTC state.

On entry to "Pending" state, this is reset to zero. On each subsequent drive cycle where the test for this DTC is run and fails, the counter is incremented until the limit is reached for transition to "Active" state.\n On entry to "Active" state, this is reset to zero. If the test for this DTC runs and fails, the counter is reset to zero. On each subsequent drive cycle where the test for this DTC is run and passed, and the test did not run and fail during the same drive cycle, the counter is incremented until the limit is reached for transition to "Previously Active" state.

U8 PDTC_DTC_NV_T::dtc_wup_count This keeps track of the number of warm-up cycles.

This will be reset each time a DTC state transitions to Previously active state. It will be incremented each subsequent warm up cycle that the fault is not present.

U16 PDTC_DTC_NV_T::test_status_flags This keeps track of test status flags that are required to be stored over power cycles, using individual bits to store/report each flag.

Bit 0: Test run this drive cycle. Set to 1 if the test for the DTC has been run in the current drive cycle. Set to 0 on starting a new drive cycle.\n Bit 1: Test failed this drive cycle. Set to 1 if the test for the DTC has failed in the current drive cycle. Set to 0 on starting a new drive cycle.\n Bit 2: Test not completed. Set to 0 if the test for the DTC has been run since the last ClearDiagnostics request has been performed.\n Set to 1 when ClearDiagnostics request is serviced. Bit 3: DTC previously active. Set to 1 if a DTC transitions from the "Previously Active" state to the "Pending" state as a result of a test failure occurring whilst the DTC is in the "Previously Active" state. Set to 0 if a DTC transitions from the "Clear" state to the "Pending" state as a result of a test failure occurring whilst the DTC is in the

Copyright 2019, Pi Innovo 545 Extended Diagnostics Functions

"Clear" state.\n Bit 4: Permanent DTC OBD clear requested. Set to 0 on entry to "Active" state. Set to 1 if a DTC is permanent, the DTC is in the "Active" state, an OBD request to clear the DTC has been received, and test has not failed this drive cycle. Set to 0 if test runs and fails, or on the DTC leaving the "Active" state.\n Bit 5: Permanent DTC ageing conditions met. Set to 0 on entry to "Active" state. Set to 1 if "Permanent DTC OBD clear requested" is set and vehicle/operating conditions to clear permanent DTC are met (by function pdtc_plat_obd_update_clr_perm_ok()). Set to 0 if test runs and fails. Bit 6: Most recent test failed. Set to 0 when DTCs are cleared. Set to 1 if test is completed and fails. Set to 0 if test is completed and passes, even if it has previously failed.\n Bit 7: Used internally for B1 timer processing.\n Bit 8: Test failed previous drive cycle. Set to 1 if the test for the DTC has failed in the previous drive cycle. Set to 0 if the test for the DTC did not run or passed in the previous drive cycle\n

U16 PDTC_DTC_NV_T::time_until_derate This keeps track of the time left until derate will occur.

This parameter will only be applicable when the DTC attribute 'has_torque_derate' is TRUE and DTC is in state ACTIVE. In all other cases, this will be set to the maximum value of 62.5 hours, as required for J1939 DM32. Scaled as 1 bit = 1 minute.

U16 PDTC_DTC_NV_T::total_prev_active_time This keeps track of the total time that the DTC is in state PREVIOUSLY_ACTIVE.

Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements. This also meets J1939 DM32 resolution requirement.

U16 PDTC_DTC_NV_T::total_active_time This keeps track of the total time that the DTC is in state ACTIVE.

Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements. This also meets J1939 DM32 resolution requirement.

U16 PDTC_DTC_NV_T::engine_running_time This keeps track of the time that the engine is running when the DTC is in states ACTIVE and PREVIOUSLY_ACTIVE and the DTC's fault is not present.

This is used for the time-based ageing/clearing of DTCs as per Euro regulations (directive 2005-78-EC Annex IV section 3.9). Scaled as 1 bit = 12 minutes (resolution 0.2hr/bit) with maximum value of 9600 hours, to minimise per-DTC non-volatile storage requirements.

Description:

This structure declares the run-time data to be stored with each DTC.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

Copyright 2019, Pi Innovo 546 Extended Diagnostics Functions

6.7.3.7.3.2. PDTC_DTC_VAR_T

Summary: This structure declares the variable data to be stored in RAM with each DTC type.

Members:

U8 PDTC_DTC_VAR_T::test_status_flags This keeps track of test status flags that are not required to be stored over power cycles, using individual bits to store/report each flag.

Bit 3: Engine running timer is currently measuring time spent in "Active" state with engine running and DTC fault not present. Set to 1 when timer is running. Set to 0 when timer is not running. Bit 4: Engine running timer is currently measuring time spent in "Previously Active" state with engine running and DTC fault not present. Set to 1 when timer is running. Set to 0 when timer is not running. Bit 5: Test passed this ignition cycle. Set to 1 when test has been run and passed in the current ignition cycle. Set to 0 on starting a new ignition cycle. Only set when DTC is in "Previously Active" state. Bit 6: DTC active this ignition cycle. Set to 1 when DTC state is "Active" in the current ignition cycle. Set to 0 on starting a new ignition cycle with DTC not in "Active" state. Bit 7: Transient fault. Set to 1 when test is run and failed. Set to 0 when test is run and passed.

U8 PDTC_DTC_VAR_T::minutes_this_hour This increments every minute up to 60, when it resets back to zero, using previous_time_stamp to track the time interval.

This timer allows updating of time in "Active" or "Previously Active" states and time to derate at appropriate intervals, without requiring storage of more data in NV.

U32 PDTC_DTC_VAR_T::previous_time_stamp This is the time stamp for computing time in states "Active" or "Previously Active".

• valid only when platform decides DTC states. The time stamp can be used for both, because the resolution used for timing in these states is such that any time "lost" on a change between "Active" and "Previously Active" is not significant.

U32 PDTC_DTC_VAR_T::engine_running_time_stamp This is the time stamp for measuring the time spent in states "Active" or "Previously Active" with the engine running and the DTC not set.

Description:

This structure declares the variable data to be stored in RAM with each DTC type.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

Copyright 2019, Pi Innovo 547 Extended Diagnostics Functions

6.7.3.7.3.3. PDTC_DTC_T

Summary: This structure declares the constant data to be stored with each DTC type.

Members:

PIO_EMISSION_SEV_TYPE_T PDTC_DTC_T::severity This is the emission severity associated with a DTC.

Range: [0, 4]

PIO_DTC_UDS_SEV_T PDTC_DTC_T::uds_severity This is the UDS $19 service severity field associated with a DTC.

Range: [0, 255]

U16 PDTC_DTC_T::iso_16bit_id This is the KW2000-3/ISO15031-6 ID to use for CAN OBD diagnostics.

Range: [0, 65535]

U8 PDTC_DTC_T::ftb This is the UDS failure type byte (LSB of 24-bit ID) to use for CAN OBD diagnostics.

Range: [0, 255]

PDTC_LAMPS_SET_FOR_DTC_T PDTC_DTC_T::lamps_set This is a structure controlling the status of each lamp when this DTC is set.

If a lamp is unused in an application, its status should always be set to "off", to avoid confusion if a non-existent lamp is reported as being "on".

BOOL PDTC_DTC_T::permanent_storage This indicates whether the DTC is to be treated as permanent when it is "Active", according to CARB regulations.

BOOL PDTC_DTC_T::requires_conditions_to_clear This indicates that a permanent DTC requires vehicle/operating conditions to be met as specified by CARB (19711 section (d)(2.3.1) (C)(ii)b.) before the DTC may be cleared.

To meet CARB requirements, this should always be set for permanent DTCs reporting faults for monitors that are not subject to minimum ratio requirements as specified by CARB (19711 section (d)(3.2)). Optionally, permanent DTCs reporting faults for monitors that are subject to minimum ratio requirements may also require these conditions to be met.

U8 PDTC_DTC_T::dc_count_limit This is the number of drive cycles required for a DTC in state 'Pending' to progress to state 'Active'.

This is valid only for DTCs whose state is controlled by the platform. It is not used for DTCs whose state is set directly by the legacy J1939/ISO-15765 interface.

Copyright 2019, Pi Innovo 548 Extended Diagnostics Functions

If set to zero, the DTC does not remain in state 'Pending' but immediately transitions to state 'Active'.

U8 PDTC_DTC_T::error_free_dc_count_limit This is the number of drive cycles required for a DTC in state 'Active' to progress to state 'Previously Active'.

This is valid only for DTCs whose state is controlled by the platform. It is not used for DTCs whose state is set directly by the legacy J1939/ISO-15765 interface.

If set to zero, the DTC immediately transitions to state 'Previously Active' when the test runs and passes.

If set to 255, the DTC will not transition to state 'Previously Active' based on drive cycles with the test passed. This is not required by any current OBD legislation, but may be necessary for manufacturer-specific DTCs.

If set to any other value, the DTC will transition from 'Active' to 'Previously Active' either when the engine running time is reached OR when sufficient drive cycles without faults are reached, whichever happens first. See Directive 2005-78-EC Annex IV section 3.8.1.

U8 PDTC_DTC_T::self_heal_wup_count_limit This is the number of warm-up cycles required for a DTC in state 'Previously Active' to progress to state 'Clear'.

If set to zero, the DTC does not remain in state 'Previously Active' but immediately transitions to state 'Clear'.\n If set to 255, the DTC will not transition to state 'Clear' based on warm-up cycles. This is required for permanent DTCs under Euro regulations, as per Directive 2005-78-EC Annex IV section 3.9.2.\n If set to any other value, the DTC will transition from 'Previously Active' to 'Clear' either when the engine running time is reached OR when sufficient warm- up cycles without faults are reached, whichever happens first. See Directive 2005-78-EC Annex IV section 3.9.1.

U8 PDTC_DTC_T::fault_symptom This is a 4-bit code for the DTC's fault symptom.

0x0 = NONE 0x1 = ABOVE_MAX 0x2 = BELOW_MIN 0x4 = NO_SIGNAL 0x8 = INVALID_SIGNAL

The symptom for other values up to 0xF can be defined by the application

BOOL PDTC_DTC_T::non_erasable This indicates whether the DTC is a 'non-erasable' DTC, as defined by Euro regulations.

BOOL PDTC_DTC_T::reg_exh_emission_lvl_exceedance This indicates whether the DTC is a 'regulated exhaust level exceedance' DTC, as required for constructing the J1939 DM32 message.

Copyright 2019, Pi Innovo 549 Extended Diagnostics Functions

BOOL PDTC_DTC_T::has_torque_derate This indicates whether this DTC is required by the applicable OBD regulation to have a torque derate.

U32 PDTC_DTC_T::time_to_derate The number of hours (specified in seconds) the malfunction can be active until the OBD required derate will occur.

This parameter will only be applicable when parameter 'has_torque_derate' is TRUE. Range [0, 62.5] hours i.e. [0, 225000] seconds

U32 PDTC_DTC_T::time_to_deactivate The number of hours (specified in seconds) with engine running and the fault not present, in order for the DTC to transition from "Active" to "Previously Active".

If set to 0xFFFFFFFF, this condition will never be checked. Note that the internal timer cannot store times greater than 0x02D00000 seconds, so any value greater than this effectively amounts to disabling the condition. If enabled, typically this time will be set to 24 hours, as per Directive 2005-78-EC Annex IV section 3.8.1.

If this condition is enabled, the DTC will transition from "Active" to "Previously Active" either when this engine running time is reached OR when sufficient drive cycles without faults are reached, whichever happens first. (See Directive 2005-78-EC Annex IV section 3.8.1.)

U32 PDTC_DTC_T::time_to_clear The number of hours (specified in seconds) with engine running and the fault not present, in order for the DTC to transition from "Previously Active" to "Clear".

If set to 0xFFFFFFFF, this condition will never be checked. Note that the internal timer cannot store times greater than 0x02D00000 seconds, so any value greater than this effectively amounts to disabling the condition. If enabled, typically this time will be set to 100 hours for non-permanent DTCs or 9600 hours for permanent DTCs, as per Directive 2005-78-EC Annex IV sections 3.9.1 and 3.9.2.

If this condition is enabled and the condition on warm-ups is enabled, the DTC will transition from "Previously Active" to "Clear" either when this engine running time is reached OR when sufficient warm-up cycles without faults are reached, whichever happens first. (See Directive 2005-78-EC Annex IV section 3.9.1.)

const PFF_FF_CONST_T* PDTC_DTC_T::freeze_frame This points to a freeze frame structure if this DTC has any associated freeze frames.

May be NULL if no freeze frames associated with this DTC. Though this shall be defaulted to freeze frame ID 1.

Description:

This structure declares the constant data to be stored with each DTC type.

Copyright 2019, Pi Innovo 550 Extended Diagnostics Functions

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

6.7.3.7.3.4. PDTC_TABLE_VAR_T

Summary: This structure declares all per-DTC-table variable data.

Members:

BOOL PDTC_TABLE_VAR_T::emissions_related_dtcs_cleared This stores whether emissions-related DTCs in the table have recently been cleared using ISO service $04.

BOOL PDTC_TABLE_VAR_T::all_dtcs_cleared This stores whether all DTCs in the table have recently been cleared using ISO service $14.

BOOL PDTC_TABLE_VAR_T::prev_active_dtcs_cleared This stores whether previously active DTCs in the table have recently been cleared using J1939 DM3 (by call to function pdtc_clear_all_if_inactive).

BOOL PDTC_TABLE_VAR_T::active_dtcs_cleared This stores whether previously active DTCs in the table have recently been cleared using J1939 DM11 (by call to function pdtc_clear_all_if_active).

Description:

This structure declares all per-DTC-table variable data.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

6.7.3.7.4. Variables

6.7.3.7.4.1. pdtc_lamp_flashing_is_priority

Definition: const BOOL pdtc_lamp_flashing_is_priority

Description: This calibration selects the lamp priority system used to select the desired state for a lamp when multiple DTCs are active and request different states.

If TRUE, flashing states take priority, giving the order (highest to lowest) of: fast flash, slow flash, continuous on, off. If FALSE, continuous on takes priority over flashing states, giving the order (highest to lowest) of: continuous on, fast flash, slow flash, off.

Care must be taken to ensure that DTC lamp states, in combination with the priority system selected and the effects of the fault which caused the

Copyright 2019, Pi Innovo 551 Extended Diagnostics Functions

DTC, meet any relevant OBD regulations. For instance, CARB requires emissions-related faults to set the MIL continuous-on during a drive cycle, and do not permit the MIL to flash during a drive cycle if emissions- related faults are active.

6.7.3.7.4.2. pdtc_transition_prev_act_to_pend

Definition: const BOOL pdtc_transition_prev_act_to_pend

Description: This calibration selects the DTC state behaviour when a fault recurs whilst the DTC is in the "previously active" state.

This behaviour is not specified by CARB (and hence is also unspecified in CARB-derived OBD schemes), so the desired behaviour will be manufacturer-specific.

If this calibration is TRUE, the DTC will transition from the "previously active" state to the "pending" state when a fault recurs. If the fault remains set, the DTC will transition to "active" as normal. If the fault does not recur, the DTC will transition back to the "previously active" state, and will clear all aging counters so that aging is restarted.

If this calibration is FALSE, the DTC will transition directly from the "previously active" state to the "active" state when a fault recurs.

6.7.3.7.4.3. pdtc_table_all

Definition: const PDTC_TABLE_T pdtc_table_all

Description: This is a table of all DTCs defined in the system.

It is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

This table is intended to group all const/NV data for all DTCs, so that operations on all DTCs can be carried out without the risk of carrying out these operations multiple times on DTCs that are referenced by multiple tables.

This table is not intended to be used for carrying out lamp state checks or other per-table operations. Since this is the case, no per-table data exists for this table. 6.7.3.7.5. Functions

6.7.3.7.5.1. pdtc_get_mi_activation_mode()

Definition: PDTC_MI_MODE_T pdtc_get_mi_activation_mode(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Supplies the current MI activation mode.

Copyright 2019, Pi Innovo 552 Extended Diagnostics Functions

Return: PDTC_MI_MODE_T as per the Euro VI - UN ECE Regulation No. 49, Addendum 48 definitions

6.7.3.7.5.2. pdtc_get_b1_cumulative_counter()

Definition: U32 pdtc_get_b1_cumulative_counter(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Supplies the cumulative time in seconds for which any B1 fault has been active.

Return: Cumulative continuous-B1 counter as required by DM39 in the J1939-73 specification

• in seconds

Note

The limits required by DM messages are not applied here, the application will have to scale and apply limits as required when used.

6.7.3.7.5.3. pdtc_get_b1_continuous_counter()

Definition: U32 pdtc_get_b1_continuous_counter(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Supplies the time in seconds for which any B1 fault has been active continuously.

Return: Single-B1 counter as required to define the MI activation mode as per the UN-ECE Regulation No.49, Addendum 48

• in seconds

6.7.3.7.5.4. pdtc_get_mil_cumulative_counter()

Definition: U32 pdtc_get_mil_cumulative_counter(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Copyright 2019, Pi Innovo 553 Extended Diagnostics Functions

Description: Supplies the cumulative time in seconds for which the MI has been demanded to be illuminated.

Return: Cumulative MI time as required by DM39 in the J1939-73 specification

• in seconds

Note

The limits required by DM messages are not applied here, the application will have to scale and apply limits as required when used.

6.7.3.7.5.5. pdtc_clear_all_tables()

Definition: PDTC_ERROR_CODE_T pdtc_clear_all_tables(const PIO_DTC_TYPE_T pdtcf_type)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Clear the state of each DTC of matching type in all the DTC tables.

For each DTC table the function to clear all DTCs in the table is called.

Freeze frame data associated with the cleared DTCs is also cleared. Monitor (DME and DTE) data is also cleared other than persistent data which is never cleared (e.g. numerators and denominators).

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Return:

• PDTC_OK - if the function completes without issue

• PDTC_CLEAR_ALL_INVALID_ARG - if the input parameters are invalid

• PDTC_BAD_LICENSE - if the user is not licensed to use this function

6.7.3.7.5.6. pdtc_clear_all_by_severity()

Definition: PDTC_ERROR_CODE_T pdtc_clear_all_by_severity(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type, const PIO_EMISSION_SEV_TYPE_T pdtcf_emissions_min_sev)

Supported targets: All targets

Copyright 2019, Pi Innovo 554 Extended Diagnostics Functions

Required license: EXT_DIAG (Extended diagnostics library).

Description: Clear the state of each DTC of matching type emission severity level in a DTC table.

For each DTC in a DTC table (pdtcf_table), if the DTC type matches pdtcf_type and severity is equal to or higher than pdtcf_emissions_min_sev then clear the DTC information.

For J1939 DTC types, a DTC is cleared by setting its state to PDTC_STATE_CLEAR, its activation count to zero and its lamp states to off.

Can raise the following errors: PDTC_CLEAR_ALL_INVALID_ARG

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Arg (data in): pdtcf_emissions_min_sev Emission level of the DTC to match against

Return:

• PDTC_OK - if the function completes without issue

• PDTC_CLEAR_ALL_INVALID_ARG - if the input parameters are invalid

• PDTC_BAD_LICENSE - if the user is not licensed to use this function

6.7.3.7.5.7. pdtc_clear_dtcs()

Definition: void pdtc_clear_dtcs(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type, const PDTC_IT_TYPE_COMPARATOR_T pdtcf_type_comparator, const PIO_EMISSION_SEV_TYPE_T pdtcf_esev, const PDTC_IT_ESEV_COMPARATOR_T pdtcf_esev_comparator, const PDTC_STATE_T pdtcf_state, const PDTC_IT_STATE_COMPARATOR_T pdtcf_state_comparator, const BOOL pdtcf_clear_unconditionally)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Clear DTCs, within a DTC table, which match the supplied criteria.

Can raise the following errors: PDTC_CLEAR_DTCS_INVALID_ARG

Copyright 2019, Pi Innovo 555 Extended Diagnostics Functions

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to clear. See the PIO header files for more details.

Arg (data in): pdtcf_type_comparator The comparison to apply to the type of DTCs to clear e.g. PDTC_IT_TYPE_DC

Arg (data in): pdtcf_esev Emissions severity of DTC to clear. See the PIO header files for more details.

Arg (data in): pdtcf_esev_comparator The comparison to apply to the emissions severity of DTCs to clear e.g. PDTC_IT_ESEV_LT

Arg (data in): pdtcf_state State of DTCs to clear (e.g., PDTC_STATE_ACTIVE).

Arg (data in): pdtcf_state_comparator The comparison to apply to the state of DTCs to clear e.g. PDTC_IT_STATE_NE

Arg (data in): pdtcf_clear_unconditionally If set TRUE, all DTCs meeting the terms of the comparator(s) will be cleared immediately, regardless of whether they are CARB permanent DTCs or Euro non-erasable DTCs. If set FALSE, any CARB permanent DTCs will be cleared under the conditions of the CARB regulations, and Euro non-erasable DTCs will never be cleared. Typically this would be set FALSE for clearing DTCs via OBD scan tool request, and would be set TRUE for a full reset of DTCs during production or in other situations where OBD regulations on clearing DTCs are not relevant (e.g. moving the ECU to a different vehicle).

6.7.3.7.5.8. pdtc_get_lamp_state()

Definition: PIO_DTC_LAMP_STATES_T pdtc_get_lamp_state(const PDTC_TABLE_T *const pdtcf_dtc_table, const PDTC_LAMP_T pdtcf_lamp)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function returns the current state of a lamp, based on DTCs set in the selected table.

Arg (data in): pdtcf_dtc_table Table of DTCs for which lamp status is to be reported

Arg (data in): pdtcf_lamp Lamp for which status is to be reported

Copyright 2019, Pi Innovo 556 Extended Diagnostics Functions

Return:

• PIO_DTC_LAMP_SLOW_FLASH - Slow flash (1Hz, 50% duty cycle)

• PIO_DTC_LAMP_FAST_FLASH - Fast flash (2Hz or faster, 50% duty cycle)

• PIO_DTC_LAMP_ON - Continuously ON

• PIO_DTC_LAMP_OFF - Continuously OFF

6.7.3.7.5.9. pdtc_get_MIL_status()

Definition: PIO_DTC_LAMP_STATES_T pdtc_get_MIL_status(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Indicates whether the MIL has to be ON due to DTCs (CARB), based on all DTC tables in the system.

Return:

• PIO_DTC_LAMP_SLOW_FLASH - Slow flash (1Hz, 50% duty cycle)

• PIO_DTC_LAMP_FAST_FLASH - Fast flash (2Hz or faster, 50% duty cycle)

• PIO_DTC_LAMP_ON - Continuously ON

• PIO_DTC_LAMP_OFF - Continuously OFF

6.7.3.7.5.10. pdtc_get_RSL_status()

Definition: PIO_DTC_LAMP_STATES_T pdtc_get_RSL_status(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Indicates whether the Red lamp has to be ON due to DTCs (CARB).

Return:

• PIO_DTC_LAMP_SLOW_FLASH - Slow flash (1Hz, 50% duty cycle)

• PIO_DTC_LAMP_FAST_FLASH - Fast flash (2Hz or faster, 50% duty cycle)

• PIO_DTC_LAMP_ON - Continuously ON

• PIO_DTC_LAMP_OFF - Continuously OFF

Copyright 2019, Pi Innovo 557 Extended Diagnostics Functions

6.7.3.7.5.11. pdtc_get_AWL_status()

Definition: PIO_DTC_LAMP_STATES_T pdtc_get_AWL_status(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Indicates whether the Amber lamp has to be ON due to DTCs (CARB).

Return:

• PIO_DTC_LAMP_SLOW_FLASH - Slow flash (1Hz, 50% duty cycle)

• PIO_DTC_LAMP_FAST_FLASH - Fast flash (2Hz or faster, 50% duty cycle)

• PIO_DTC_LAMP_ON - Continuously ON

• PIO_DTC_LAMP_OFF - Continuously OFF

6.7.3.7.5.12. pdtc_get_Protect_lamp_status()

Definition: PIO_DTC_LAMP_STATES_T pdtc_get_Protect_lamp_status(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Indicates whether the Protect lamp has to be ON due to DTCs (CARB).

Return:

• PIO_DTC_LAMP_SLOW_FLASH - Slow flash (1Hz, 50% duty cycle)

• PIO_DTC_LAMP_FAST_FLASH - Fast flash (2Hz or faster, 50% duty cycle)

• PIO_DTC_LAMP_ON - Continuously ON

• PIO_DTC_LAMP_OFF - Continuously OFF

6.7.3.7.5.13. pdtc_match_exists()

Definition: BOOL pdtc_match_exists(const PDTC_TABLE_T *const pdtcf_table, const PIO_DTC_TYPE_T pdtcf_type, const PIO_EMISSION_SEV_TYPE_T pdtcf_esev, BOOL pdtcf_esev_gte_test, BOOL pdtcf_use_confirmed, const PDTC_STATE_T pdtcf_state, U16 *pdtcf_count)

Supported targets: All targets

Copyright 2019, Pi Innovo 558 Extended Diagnostics Functions

Required license: EXT_DIAG (Extended diagnostics library).

Description: Determine the existence and count of DTCs, within a DTC table, which match the supplied criteria.

Can raise the following errors: PDTC_MATCH_EXISTS_INVALID_ARG

Arg (data in): pdtcf_table Pointer to table of DTCs. Cannot be NULL.

Arg (data in): pdtcf_type Type of DTC (J1939, ISO, etc.) to match against. See the PIO header files for more details.

Arg (data in): pdtcf_esev Emissions severity of DTC to match against. See the PIO header files for more details.

Arg (data in): pdtcf_esev_gte_test Set to TRUE if the function is to match against DTCs with an emissions severity greater than or equal to that supplied in parameter pdtcf_esev. Set to FALSE if the function is to match against DTCs with an emissions severity equal to that supplied in parameter pdtcf_esev.

Arg (data in): pdtcf_use_confirmed Set to TRUE if the function is to match against DTCs with that have had test failures for enough drive cycles to be considered "confirmed" when in the "active state. Set to FALSE if the function is to ignore the number of drive cycles with test failures when matching against DTCs.

Arg (data in): pdtcf_state State of DTC to match against (e.g., PDTC_STATE_ACTIVE).

Arg (data out): pdtcf_count Count of the number of matching DTCs.

Return: TRUE - At least one matching DTC exists. FALSE - Otherwise.

6.7.3.7.5.14. pdtc_check_table_cleared()

Definition: U32 pdtc_check_table_cleared(const PDTC_TABLE_T *const pdtcf_table_to_check)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Reports whether DTCs have been cleared by OBD request.

If, since the last call to this function, one or more OBD requests have been received that caused DTCs in this DTC table to be cleared, these OBD request(s) are reported to the application.

Copyright 2019, Pi Innovo 559 Extended Diagnostics Functions

Arg (data in): pdtcf_table_to_check DTC table for which OBD clear request(s) will be reported.

Return: Bitmask indicating OBD clear request(s) since last call to this function:

• Bit 0 = ISO-15765 emissions-related DTCs cleared via $04 (PDTC_OBD_CLEAR_EMISSIONS_RELATED)

• Bit 1 = ISO-15765 DTCs cleared (regardless of groupOfDTC) via $14 (PDTC_OBD_CLEAR_ALL)

• Bit 2 = J1939 DTCs in Previously Active state cleared (PDTC_OBD_CLEAR_PREV_ACTIVE)

• Bit 3 = J1939 DTCs in Active state cleared (PDTC_OBD_CLEAR_ACTIVE)

6.7.3.7.5.15. pdtc_get_dtc_status()

Definition: PDTC_ERROR_CODE_T pdtc_get_dtc_status(const PDTC_DTC_T *const pdtcf_dtc, U8 *pdtcf_lamp_bitmap, PDTC_STATE_T *pdtcf_state, U8 *pdtcf_count)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Retrieve the status data of a DTC.

Arg (data in): pdtcf_dtc Pointer to DTC to retrieve values from. Cannot be NULL.

Arg (data out): pdtcf_lamp_bitmap Pointer to location to accept bitmap of lamp information (relevant to J1939 DTCs only). This location will be set to the value of the pdtcf_lamp_bitmap_in parameter used in the most recent call to pdtc_update_j1939_dtc. May be NULL, in which case no output is written for this value. Note that this is only used by the legacy (deprecated) interface for J1939 DTCs, to allow backwards compatibility for existing applications, and may be removed in a future version of the API. Instead of this parameter, use one of pdtc_get_lamp_state(), pdtc_get_MIL_status() , pdtc_get_RSL_status(), pdtc_get_AWL_status() , pdtc_get_Protect_lamp_status(), or pdtc_get_j1939_current_lamps().

Arg (data out): pdtcf_state Pointer to where the current DTC state will be written. One of PDTC_STATE_CLEAR, PDTC_STATE_ACTIVE , PDTC_STATE_INACTIVE or PDTC_STATE_PENDING will be written. May be NULL, in which case no output is written for this value.

Copyright 2019, Pi Innovo 560 Extended Diagnostics Functions

Arg (data out): pdtcf_count Pointer to where the current J1939-style DTC activation count will be written. May be NULL in which case no output is written for this value. Range: [0, 127] counts

Return:

• PDTC_OK - if the function completes without issue

• PDTC_GET_DTC_STATUS_INVALID_ARG - if the input parameters are invalid

• PDTC_BAD_LICENSE - if the user is not licensed to use this function

6.7.3.7.5.16. pdtc_plat_obd_update_clr_perm_ok()

Definition: void pdtc_plat_obd_update_clr_perm_ok(BOOL pdtcf_ok_to_clear_perm)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Keeps track of whether conditions have been met for clearing CARB permanent DTCs after an OBD clear request.

When an OBD clear request is received, permanent DTCs for some monitors may be cleared as soon as the test is complete. Permanent DTCs for other monitors require certain vehicle/operating conditions to be met, according to CARB 19711 section (d)(2.3.1)(C)(ii)b..

Arg (data in): pdtcf_ok_to_clear_perm If TRUE, indicates that vehicle/operating conditions are met according to CARB 19711 section (d)(2.3.1)(C)(ii)b..

6.7.3.7.5.17. pdtc_plat_obd_update_engine_running()

Definition: void pdtc_plat_obd_update_engine_running(BOOL pdtcf_engine_is_running)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Keeps track of engine running state for DTCs.

Arg (data in): pdtcf_engine_is_running If TRUE, indicates that engine is running

6.7.3.7.5.18. pdtc_plat_obd_update_ign_cyc()

Definition: void pdtc_plat_obd_update_ign_cyc(BOOL pdtcf_start_of_ignc)

Copyright 2019, Pi Innovo 561 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Keeps track of new ignition cycle.

Arg (data in): pdtcf_start_of_ignc Indicates whether it is the start of an ignition cycle or otherwise. Application should call pdtc_plat_obd_update_ign_cyc with pdtcf_start_of_ignc set to TRUE when transitioning into a new ignition cycle.

6.7.3.7.5.19. pdtc_plat_obd_update_dc_count()

Definition: void pdtc_plat_obd_update_dc_count(BOOL pdtcf_start_of_dc)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Keeps track of new drive cycle for DTCs.

Arg (data in): pdtcf_start_of_dc Indicates whether it is the start of drive cycle or otherwise. Application should call pdtc_plat_obd_update_dc_count(TRUE) while transitioning into a new drive cycle.

6.7.3.7.5.20. pdtc_plat_obd_update_wup_count()

Definition: void pdtc_plat_obd_update_wup_count(BOOL pdtcf_start_of_wup)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Keeps track of new warmup cycle for DTCs.

Arg (data in): pdtcf_start_of_wup Indicates whether it is the start of warmup cycle or otherwise. Application should call pdtc_plat_obd_update_wup_count(TRUE) while transitioning into a new warm-up cycle.

6.7.3.7.5.21. pdtc_update_iso_dtc()

Definition: PDTC_ERROR_CODE_T pdtc_update_iso_dtc(const PDTC_DTC_T *const pdtcf_dtc, PDTC_STATE_T pdtcf_state_in)

Supported targets: All targets

Copyright 2019, Pi Innovo 562 Extended Diagnostics Functions

Required license: EXT_DIAG (Extended diagnostics library).

Description: Function to update the state and data of an ISO DTC.

Can raise the following errors: PDTC_UPDATE_INVALID_ARG.

Arg (data in,out): pdtcf_dtc Pointer to DTC to update. Cannot be NULL.

Arg (data in): pdtcf_state_in The state to change to (or remain at).

Return:

• PDTC_OK - if the function completes without issue

• PDTC_UPDATE_INVALID_ARG - if the input parameters are invalid

• PDTC_BAD_LICENSE - if the user is not licensed to use this function

6.7.3.7.5.22. pdtc_update_plat_obd_dtc()

Definition: PDTC_ERROR_CODE_T pdtc_update_plat_obd_dtc(const PDTC_DTC_T *const pdtcf_const_dtc, BOOL pdtcf_test_failed, BOOL pdtcf_test_completed)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Function to update the state and data of the DTC when controlled by platform.

Can raise the following errors: PDTC_UPDATE_INVALID_ARG.

Arg (data in): pdtcf_const_dtc Pointer to DTC to update. Cannot be NULL.

Arg (data in): pdtcf_test_failed

• TRUE = Test failed for this DTC in current run

• FALSE = Test passed for this DTC in current run

Arg (data in): pdtcf_test_completed

• TRUE = Test for this DTC has been run before current call

• FALSE = Test for this DTC has not been run before current call

Return:

• PDTC_OK - if the function completes without issue

Copyright 2019, Pi Innovo 563 Extended Diagnostics Functions

• PDTC_UPDATE_INVALID_ARG - if the input parameters are invalid

• PDTC_BAD_LICENSE - if the user is not licensed to use this function 6.7.3.8. Interface detail - PIO

Some enumerations and variables for the DTC feature are included in pio.h 6.7.3.8.1. Enumerations

6.7.3.8.1.1. @8

Summary: This enumeration declares the different types of DTC lamp state available.

Enumerations:

PIO_DTC_LAMP_SLOW_FLASH Slow Flash.

PIO_DTC_LAMP_FAST_FLASH Fast Flash.

PIO_DTC_LAMP_ON Continuously On.

PIO_DTC_LAMP_OFF No Effect.

PIO_DTC_LAMP_STATES_LAST 6.7.3.8.2. Data types

6.7.3.8.2.1. PIO_DTC_LAMP_STATES_T

Definition: typedef PSY_PACK_ENUM enum @8 PIO_DTC_LAMP_STATES_T

Description: This enumeration declares the different types of DTC lamp state available. 6.7.4. Freeze Frame feature (PFF) 6.7.4.1. Overview

The freeze frame feature is a diagnostic feature used to capture a snapshot of PID or SPN data at the point a Diagnostic Trouble Code is activated. This data snapshot is stored in NVM using the PFS feature. Access to this data is then provided over the J1979 / J1939 / UDS diagnostic protocols.

A freeze frame may be one of four types:

• ISO freeze frame: available over J1979 service $02.

• J1939 Freeze Frame Parameters (DM4).

• J1939 Expanded Freeze Frames (DM25).

• UDS Snapshot: available over ISO 14229-1 (UDS) service $19.

Copyright 2019, Pi Innovo 564 Extended Diagnostics Functions

A given DTC may be associated with (up to) one freeze frame of each type. However, for non-emissions DTCs, ISO J1979 service $02 freeze frames will not be captured.

There is no direct interface to the PFF feature, as actions causing freeze frame instances to be captured or deleted are triggered by the PDTC feature.

If a DTC has one or more associated freeze frames, an instance of each of these freeze frames is captured each time a DTC undergoes one of the following state transitions:

• Clear to Active

• Clear to Pending

• Previously Active to Pending

• Previously Active to Active

Note in particular that a DTC can acquire multiple instances of freeze frames if it transitions from Previously Active to Pending or Active repeatedly. The number of freeze frame instances of a given freeze frame type is capped at 126. All freeze frame instances associated with a particular DTC are deleted when that DTC transitions to the Clear state. Additionally the last freeze frame instance captured for a particular DTC is deleted when the DTC transitions from state Pending to state Previously Active for all freeze frame types other than UDS snapshots.

Snapshot storage gives preference to the first and the most recent occurrence of a particular DTC. The snapshot captured as a result of the first occurrence of a DTC is assigned DTCSnapshotRecordNumber 0. The snapshot captured as a result of the next occurrence of a DTC is assigned DTCSnapshotRecordNumber 1 and is replaced upon subsequent occurrences of the DTC.

Stored freeze frame data may be accessed over the ISO 15765-2 J1979, ISO 14229-1 UDS, or the J1939 (SAE) communication protocols using the following features, respectively:

• PDG - Service $02 (J1979).

• PDG - Service $19 (UDS).

• PJ1939 - DM4, DM24 and DM25.

Note: non-volatile PIDs are not supported in freeze frames. If a freeze frame is defined by the application to contain a non-volatile PID, this PID is ignored by the PFF feature when capturing or accessing the freeze frame data. 6.7.4.2. ISO J1979 Freeze frame

A stored ISO J1979 freeze frame contains the following data:

• 16 bit ID of DTC that triggered the freeze frame.

• Captured data for each J1979 PID identified in the calibratable freeze frame vector, (see section Section 7.1.4.27, “Compound statement: protocol” for details).

Note: if the following PIDs are included in a freeze frame definition, they shall be ignored by the platform code: the service PIDs (i.e. $00, $20, $40, etc.); unsupported PIDs; PID $02. PID $02 is always captured alongside the freeze frame, but not separately as one of the listed PIDs in the freeze frame definition. 6.7.4.3. UDS Snapshot

A stored ISO 14229-1 UDS snapshot contains the following data:

• 16 bit ID of DTC that triggered the freeze frame.

Copyright 2019, Pi Innovo 565 Extended Diagnostics Functions

• Captured data for each ISO 16-bit PID identified in the calibratable freeze frame vector, (see section Section 7.1.4.27, “Compound statement: protocol” for details). 6.7.4.4. J1939 Freeze Frame Parameters (DM4)

A stored DM4 freeze frame contains the following data, as specified in J1939-73 FEB2010:

• Freeze Frame Length (1 byte)

• SPN of the setting DTC (19 bits)

• FMI of the setting DTC (5 bits)

• SPN Conversion Method (1 bit)

• DTC Occurrence Count (7 bits)

• Mandatory SPN data values (8 bytes)

• Manufacturer Specific SPN data (0 to 1772 bytes)

Note: similar to J1939-73 FEB2010 the SPN, FMI, conversion method and DTC occurrence count are packed into 4 bytes in NVM. The DTC occurrence count in the freeze frame may be out of sync when DTC becomes Active.

Any unsupported Mandatory SPNs shall have each date byte stored as 0xFF. Any unsupported Manufacturer SPNs specified are ignored by the platform code. The vector defining the Manufacturer SPNs is calibratable. 6.7.4.5. J1939 Expanded Freeze Frame (DM25)

A stored DM25 freeze frame contains the following data, as specified in J1939-73 FEB2010:

• Expanded Freeze Frame Length (1 byte)

• SPN of the setting DTC (19 bits)

• FMI of the setting DTC (5 bits)

• SPN Conversion Method (1 bit)

• DTC Occurrence Count (7 bits)

• SPN data (0 to 1780 bytes)

Note: similar to J1939-73 FEB2010 the SPN, FMI, conversion method and DTC occurrence count are packed into 4 bytes in NVM. The DTC occurrence count in the freeze frame may be out of sync when DTC becomes Active.

A calibratable vector is used to identify the SPNs that are captured in the DM25 freeze frame. Only supported SPN data may be captured. Unsupported SPNs are ignored by the platform code. 6.7.4.6. Freeze Frame Calibrations

As noted above, with the exception of the J1939 DM4 Mandatory freeze frame SPNs, the SPNs and PIDs defining each freeze frame are calibratable. The vector calibration simply consists of a list of PID or SPN identifiers. If one of these calibrations is changed, any existing freeze frames will no longer match their corresponding freeze frame definition. As a result, if 'old' freeze frame data is read, the data received will not be in the expected format or match the expected PID or SPN. It is therefore strongly recommended that the calibrations defining the freeze frames are not changed on-the-fly, and that all DTCs are cleared following any changes to the freeze frame calibrations.

Copyright 2019, Pi Innovo 566 Extended Diagnostics Functions

6.7.5. Parameter Identifier feature (PPID) 6.7.5.1. Overview

The library's PID feature provides support for parameters accessed by numeric identifier (hence PID) using the ISO 15765-2 based protocols SAE J1979, Keyword Protocol 2000-3 or ISO 14229-1 (UDS). The PID feature also allows parameters to be defined as Suspect Parameter Numbers (SPNs), which will eventually enable them to be accessed using the SAE J1939 protocol. At the present time, however, these SPNs are only able to be used to capture freeze frames for J1939 Diagnostic Trouble Codes.

A PID can be used to make internal values (e.g. sensor values or identification strings) visible on an external service test tool.

Additionally, PIDs can be configured to allow override, so that the application-calculated value of the PID is temporarily replaced with a value specified by the external tool. This can be used to test actuators (by overriding a value used to command an output position) or simulate the effect of particular sensor input values, for example. 6.7.5.2. Use of PIDs

PIDs are declared in the interface file (see Section 7.1.4.30, “Compound statement: pid- data”). The C-API tool generates a C identifier for each PID, based on the name specified in the interface file, which can be passed to the functions ppid_update_pid() and ppid_get_pid().

PID values must be set by the application by calling ppid_update_pid(). For constant values, this need be done only once. For varying values (e.g. sensor readings), the application should repeatedly do this to keep the PID value up to date, because the external tool may read the PID value at any time without the application's prior knowledge.

PIDs can be configured to allow override by the external test tool, and for the PID value to be automatically replaced by the test tool value. For this to work, the application cannot assume that the current PID value is the same as the value it most recently set using ppid_update_pid(). Instead, the application should read the latest value using ppid_get_pid() before use. Usually the application-set value will be returned, but if the external test tool requests an override of the value using an inputOutputControlByIdentifier service, then a different value may be returned.

Alternatively, a PID can be configured to allow the receipt of inputOutputControl data from the test tool, but not have the received data replace the normal reported value (resend-input-as- output = false). In this case the ppid_get_override_data() function can be used to retrieve the data sent by the test tool, and that data need not be the same size as the reported PID data.

Some applications may need to dynamically compute or fetch PID values at the time they are requested, or perform some other application-specific processing or response. For this purpose the PDG feature callback functions can be used. In particular see the PDG_ID_REQUEST_CALLBACK_FN_T type of callback. 6.7.5.3. Platform PIDs

Some PIDs are handled by the platform without any input from the application. In the J1979 standard, PID 0x02 is defined to hold the DTC that caused a freeze frame to be stored. For service $02, the freeze frame in question is identified by the request message, but for service $01 it is just the first freeze frame that has been stored. To satisfy this context-dependent definition, PID 0x02 is handled directly by the platform. The application should not define such a PID and any such PID that is defined will be ignored in the case of a standard platform reply. (This behaviour can still be overridden through the use of PDG_ID_REQUEST_CALLBACK_FN_T type callbacks).

Copyright 2019, Pi Innovo 567 Extended Diagnostics Functions

Similar remarks apply to PIDs 0x00, 0x20, 0x40, etc. which are defined in the J1979 standard as bitfields that identify which other PIDs are supported in various contexts. 6.7.5.4. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and ppid.h Macros PPID_MAX_PID_BYTE_LEN

This is the maximum length of PID data currently supported. PPID_ECU_CONTROLLED

Indicates that ControlParameter from InputOutputControl request from test tool was "return control to ECU", or this PID is not currently subject to IOControl. PPID_CURRENT_STATE_FROZEN

Indicates that ControlParameter from InputOutputControl request from test tool was "freeze current state", indicating that this PID is currently subject to override by the tool. PPID_SHORT_TERM_ADJUSTMENT

Indicates that ControlParameter from InputOutputControl request from test tool was "short term adjustment", indicating that this PID is currently subject to override by the tool. PPID_J1939_SPN_PID

Flag masks used for attributes of PIDs; low values are used where they may be used in a bitfield to save space when stored as non-volatile PIDs. PPID_KWP_8BIT_PID

Bitmask for a KWP2000 8-bit based PID. PPID_ISO_16BIT_PID

Bitmask for a KWP2000 16-bit based PID. PPID_VAR_LENGTH

Bitmask for a variable length based PID. PPID_J1979_8BIT_PID

Bitmask for a J1979 8-bit based PID. PPID_RESEND_IN_OUT

Bitmask for a PID that can pass its overridden data to the application.

Copyright 2019, Pi Innovo 568 Extended Diagnostics Functions

Type Identifier PPID_NON_VOLATILE

Bitmask for a PID stored across power-cycles in non- volatile memory. PPID_ALPHANUMERIC

Bitmask for a ASCII string based PID. Enumerations PPID_RC_T

An enumerated type which contains success and failure codes returned by some ISO diagnostic parameter ID (PPID) functions. Data types PPID_PID_CONST_T

This structure collates the data associated with each PID. Variables struct PPID_PID_CONST_T ppid_table

This is a list of the ISO 16-bit PIDs the library will maintain. const U16 ppid_num_pids

This is the total number of ISO 16-bit PIDs the library will maintain. struct ppid_j1979_8bit_map PPID_8BIT_ID_LOOKUP_T This is a list of the J1979 8-bit PIDs that the library will maintain. const U16 ppid_num_j1979_ids

This is the total number of J1979 8-bit PIDs the library will maintain. struct ppid_kwp_8bit_map PPID_8BIT_ID_LOOKUP_T This is a list of the KW2000 8-bit PIDs that the library will maintain. const U16 ppid_num_kwp_ids

This is the total number of KW2000 8-bit PIDs the library will maintain. struct ppid_j1939_spn_map PPID_J1939_SPN_LOOKUP_T This is a list of the J1939 SPNs that the library will maintain. const U16 ppid_num_j1939_spns

This is the total number of J1939 SPNs the library will maintain.

Copyright 2019, Pi Innovo 569 Extended Diagnostics Functions

Type Identifier Functions PPID_RC_T ppid_update_pid

Update platform-cached values for this PID with fresh application values. PPID_RC_T ppid_get_pid

Retrieve current value of PID, which may be an override value. PPID_RC_T ppid_get_override_data

Retrieve a range of data representing the value of a PID, which may be an overridden value. PPID_RC_T ppid_set_nv_pid

This function sets a new value for the nonvolatile PID specified. PPID_RC_T ppid_get_nv_commit_status

Use this function to determine whether nonvolatile PID data is saved. PPID_RC_T ppid_get_nv_pid

This function can be used to determine whether a nonvolatile PID exists (with a value set), what size it is, and to retrieve the content. PPID_RC_T ppid_delete_nv_pid

This function deletes a nonvolatile PID. PPID_RC_T ppid_delete_all_nv_pids

This function deletes all nonvolatile PIDs. 6.7.5.5. Interface detail 6.7.5.5.1. Macros

6.7.5.5.1.1. PPID_MAX_PID_BYTE_LEN

Definition: #define PPID_MAX_PID_BYTE_LEN 512

Description:

This is the maximum length of PID data currently supported.

6.7.5.5.1.2. PPID_ECU_CONTROLLED

Definition: #define PPID_ECU_CONTROLLED 0x00

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "return control to ECU", or this PID is not currently subject to IOControl.

Copyright 2019, Pi Innovo 570 Extended Diagnostics Functions

6.7.5.5.1.3. PPID_CURRENT_STATE_FROZEN

Definition: #define PPID_CURRENT_STATE_FROZEN 0x05

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "freeze current state", indicating that this PID is currently subject to override by the tool.

6.7.5.5.1.4. PPID_SHORT_TERM_ADJUSTMENT

Definition: #define PPID_SHORT_TERM_ADJUSTMENT 0x07

Description:

Indicates that ControlParameter from InputOutputControl request from test tool was "short term adjustment", indicating that this PID is currently subject to override by the tool.

6.7.5.5.1.5. PPID_J1939_SPN_PID

Definition: #define PPID_J1939_SPN_PID 0x01

Description:

Flag masks used for attributes of PIDs; low values are used where they may be used in a bitfield to save space when stored as non-volatile PIDs.

Bitmask for a J1939 SPN based PID.

6.7.5.5.1.6. PPID_KWP_8BIT_PID

Definition: #define PPID_KWP_8BIT_PID 0x02

Description:

Bitmask for a KWP2000 8-bit based PID.

6.7.5.5.1.7. PPID_ISO_16BIT_PID

Definition: #define PPID_ISO_16BIT_PID 0x04

Description:

Bitmask for a KWP2000 16-bit based PID.

6.7.5.5.1.8. PPID_VAR_LENGTH

Definition: #define PPID_VAR_LENGTH 0x08

Description:

Bitmask for a variable length based PID.

6.7.5.5.1.9. PPID_J1979_8BIT_PID

Definition: #define PPID_J1979_8BIT_PID 0x10

Copyright 2019, Pi Innovo 571 Extended Diagnostics Functions

Description:

Bitmask for a J1979 8-bit based PID.

6.7.5.5.1.10. PPID_RESEND_IN_OUT

Definition: #define PPID_RESEND_IN_OUT 0x20

Description:

Bitmask for a PID that can pass its overridden data to the application.

6.7.5.5.1.11. PPID_NON_VOLATILE

Definition: #define PPID_NON_VOLATILE 0x40

Description:

Bitmask for a PID stored across power-cycles in non-volatile memory.

6.7.5.5.1.12. PPID_ALPHANUMERIC

Definition: #define PPID_ALPHANUMERIC 0x80

Description:

Bitmask for a ASCII string based PID.

6.7.5.5.2. Enumerations

6.7.5.5.2.1. PPID_RC_T

Summary: An enumerated type which contains success and failure codes returned by some ISO diagnostic parameter ID (PPID) functions.

Enumerations:

PPID_RC_OK Return code if everything progressed as expected.

PPID_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PPID_RC_BAD_CONFIG_DATA Return code if the PID configuration data was invalid for requested operation.

PPID_RC_NOT_FOUND No such PID found.

PPID_RC_ALREADY_SET PID value already set so it does not require any initialisation write.

PPID_NV_SAVE_PENDING Saving of PIDs to nonvolatile memory is in progress.

PPID_RC_ERROR Unspecified error.

Copyright 2019, Pi Innovo 572 Extended Diagnostics Functions

6.7.5.5.3. Data types

6.7.5.5.3.1. PPID_PID_CONST_T

Summary: This structure collates the data associated with each PID.

Members:

U16 PPID_PID_CONST_T::pid_id The 16-bit ID of the PID, used by the test tool to address it.

This is a "CommonIdentifier" in KW2000-3 or just "Identifier" in UDS. The PID may or may not support this type of ID. This may instead be used for RoutineControl services if appropriate for this ID.

U16 PPID_PID_CONST_T::byte_len The number of bytes of data this PID consists of.

U8* PPID_PID_CONST_T::app_supplied_data This points to the current (application-supplied) values.

Initialised to zero by the platform Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when requested by an external diagnostic test tool.

U8* PPID_PID_CONST_T::override_data This points to override values set temporarily by the external test tool.

May be NULL if no overrides allowed for this PID. Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

U8* PPID_PID_CONST_T::override_state This points to the value which records how this PID is currently being overridden by the external test tool via IOControl messages.

Zero means no override. Do not access the data this points to in user code. If modified the platform will be unable to correctly process data overrides.

U8* PPID_PID_CONST_T::control_enable_mask_data This points to controlEnableMask values last requested by the external during a freeze or short-term adjustment.

May be NULL if no overrides are allowed for this PID. Do not access the data this points to in user code. It is accessed by the library asynchronously to application execution when required by an external diagnostic test tool.

const U8* PPID_PID_CONST_T::scaling_data This points to the scaling data bytes, which are constants determined at build time.

U32 PPID_PID_CONST_T::j1939_spn_id The ID used to identify if this PID represents a J1939 SPN.

U8 PPID_PID_CONST_T::j1979_8bit_id The 8-bit ID used if this PID should be sent in response to a J1979 service $01 request.

Copyright 2019, Pi Innovo 573 Extended Diagnostics Functions

U8 PPID_PID_CONST_T::kwp_8bit_lid The 8-bit LocalIdentifier used if this PID should be sent in response to a KW2000-3 service $21 request, or modified via a $30 InputOutputControlByLocalID request.

U8 PPID_PID_CONST_T::control_enable_mask_size This defines the maximum number of controlEnableMask byte values allowed for this PID.

U8 PPID_PID_CONST_T::scaling_byte_len The number of byte in the scaling data for this PID.

Description:

This structure collates the data associated with each PID.

Note

The application may use the ID and size elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

6.7.5.5.4. Variables

6.7.5.5.4.1. ppid_table

Definition: struct PPID_PID_CONST_T ppid_table[]

Description: This is a list of the ISO 16-bit PIDs the library will maintain.

6.7.5.5.4.2. ppid_num_pids

Definition: const U16 ppid_num_pids

Description: This is the total number of ISO 16-bit PIDs the library will maintain.

6.7.5.5.4.3. ppid_j1979_8bit_map

Definition: struct PPID_8BIT_ID_LOOKUP_T ppid_j1979_8bit_map[]

Description: This is a list of the J1979 8-bit PIDs that the library will maintain.

6.7.5.5.4.4. ppid_num_j1979_ids

Definition: const U16 ppid_num_j1979_ids

Description: This is the total number of J1979 8-bit PIDs the library will maintain.

6.7.5.5.4.5. ppid_kwp_8bit_map

Definition: struct PPID_8BIT_ID_LOOKUP_T ppid_kwp_8bit_map[]

Description: This is a list of the KW2000 8-bit PIDs that the library will maintain.

Copyright 2019, Pi Innovo 574 Extended Diagnostics Functions

6.7.5.5.4.6. ppid_num_kwp_ids

Definition: const U16 ppid_num_kwp_ids

Description: This is the total number of KW2000 8-bit PIDs the library will maintain.

6.7.5.5.4.7. ppid_j1939_spn_map

Definition: struct PPID_J1939_SPN_LOOKUP_T ppid_j1939_spn_map[]

Description: This is a list of the J1939 SPNs that the library will maintain.

6.7.5.5.4.8. ppid_num_j1939_spns

Definition: const U16 ppid_num_j1939_spns

Description: This is the total number of J1939 SPNs the library will maintain. 6.7.5.5.5. Functions

6.7.5.5.5.1. ppid_update_pid()

Definition: PPID_RC_T ppid_update_pid(const struct PPID_PID_CONST_T *const ppidf_pid_const_data, const U8 *ppidf_app_supplied_data)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Update platform-cached values for this PID with fresh application values.

Arg (data in,out): ppidf_pid_const_data Pointer to the PID data structure to be updated

Arg (data in): ppidf_app_supplied_data Application supplied data to be used for the update

Return:

• PPID_RC_BAD_ARGS - if the input parameters are invalid

• PPID_RC_BAD_CONFIG_DATA - if there is a mismatch in the byte-length of PID data

• PPID_RC_OK - if operation is successful Note: ppidf_app_supplied_data is initialised to zero by the platform

6.7.5.5.5.2. ppid_get_pid()

Definition: PPID_RC_T ppid_get_pid(const struct PPID_PID_CONST_T *ppidf_pid_const_data, U8 *ppidf_pid_data, U8 *ppidf_override_state)

Copyright 2019, Pi Innovo 575 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Retrieve current value of PID, which may be an override value.

Arg (data in): ppidf_pid_const_data Pointer to the PID data structure. Cannot be NULL.

Arg (data out): ppidf_pid_data Pointer to the buffer (address of array) provided by the application to receive the PID data. Cannot be NULL.

Arg (data out): ppidf_override_state Pointer to variable set to nonzero code if the PID is overridden, zero otherwise. The code value will be one of:

• PPID_ECU_CONTROLLED

• PPID_CURRENT_STATE_FROZEN

• PPID_SHORT_TERM_ADJUSTMENT Can be NULL if overridden status is not required.

Return:

• PPID_RC_BAD_ARGS - if the input parameters are invalid

• PPID_RC_BAD_CONFIG_DATA - if the length of PID data is too long or data is invalid

• PPID_RC_OK - if operation is successful

6.7.5.5.5.3. ppid_get_override_data()

Definition: PPID_RC_T ppid_get_override_data(const struct PPID_PID_CONST_T *ppidf_pid_const_data, U8 *ppidf_override_data, U8 *ppidf_override_state, U8 *ppidf_control_enable_mask_data, U8 *ppidf_num_cem_bytes)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Retrieve a range of data representing the value of a PID, which may be an overridden value.

Retrieve current value of PID bytes as last sent by diagnostic tool as IOControl states.

Arg (data in): ppidf_pid_const_data Pointer to the PID data structure. Cannot be NULL.

Copyright 2019, Pi Innovo 576 Extended Diagnostics Functions

Arg (data out): ppidf_override_data Pointer to the buffer (address of array) provided by the application to receive the PID data. This must be at least large enough for the input byte length declared for this PID (or the output length if that was not explicitly specified, and so assumed equal). Can be NULL if the actual data is not required.

Arg (data out): ppidf_override_state Pointer to variable set to nonzero code if the PID is overridden, zero otherwise. The code is the IOControl parameter from the request message. Can be NULL if overridden status is not required.

Arg (data out): ppidf_control_enable_mask_data Pointer to the buffer (address of array) provided by the application to receive the controlEnableMask data (if the PID is configured to accept it). Both this and ppidf_num_cem_bytes must be non-NULL if the data is required.

Arg (data out): ppidf_num_cem_bytes Pointer to variable set to the number of controlEnableMask bytes last received for this PID when an IOControl override was requested. Both this and ppidf_control_enable_mask_data must be non-NULL if the data is required.

Return:

• PPID_RC_BAD_ARGS - if the input parameters are invalid

• PPID_RC_BAD_CONFIG_DATA - if the length of PID data is too long or data is invalid

• PPID_RC_OK - if operation is successful

6.7.5.5.5.4. ppid_set_nv_pid()

Definition: PPID_RC_T ppid_set_nv_pid(U8 ppidf_type_flags, U8 ppidf_kwp_8bit_id, U16 ppidf_pid_id, U32 ppidf_j1939_spn_id, const U8 *ppidf_new_data_ptr, U8 ppidf_new_size, BOOL ppidf_only_if_uninit)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function sets a new value for the nonvolatile PID specified.

In a running application, only the PIDs that are predefined for that application will be accepted by this function.

Note

This function is also available in boot loader mode, when any PID is acceptable. However, any PIDs set in boot mode that are not

Copyright 2019, Pi Innovo 577 Extended Diagnostics Functions

defined by an application will be discarded when that application starts.

Arg (data in): ppidf_type_flags One or more of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID ORd together to indicate which type(s) of ID this PID shall be identified by.

Arg (data in): ppidf_kwp_8bit_id If relevant, the KW2000 LID for this PID. Otherwise unused.

Arg (data in): ppidf_pid_id If relevant, the KW2000/UDS 16-bit ID for this PID. Otherwise unused.

Arg (data in): ppidf_j1939_spn_id If relevant, the J1939 SPN for this PID. Otherwise unused.

Arg (data in): ppidf_new_data_ptr Pointer to the byte data from which the new value of this PID will be copied. Cannot be NULL if any data is to be written, but other error status values can still be obtained if it is NULL.

Arg (data in): ppidf_new_size New size for the value of this PID. Must be within the specific range set for this PID.

Arg (data in): ppidf_only_if_uninit If TRUE, the PID value is set only if no prior value existed for this PID (intended for initialisation to a default in a newly-flashed application). Otherwise, the new value is always set.

Return:

• PPID_RC_ALREADY_SET - if ppidf_only_if_uninit=TRUE and a value was already set for this PID

• PPID_RC_ERROR - if the new value could not be written (e.g. if not defined for this application)

• PPID_RC_OK - if operation is successful

6.7.5.5.5.5. ppid_get_nv_commit_status()

Definition: PPID_RC_T ppid_get_nv_commit_status(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Use this function to determine whether nonvolatile PID data is saved.

Saving is performed asynchronously in a background task while application execution continues.

Return:

• PPID_NV_SAVE_PENDING - if save currently in progress

Copyright 2019, Pi Innovo 578 Extended Diagnostics Functions

• PPID_RC_ERROR - if the last save operation failed

• PPID_RC_OK - if the last save was successful

6.7.5.5.5.6. ppid_get_nv_pid()

Definition: PPID_RC_T ppid_get_nv_pid(U8 ppidf_type_flag, U32 ppidf_id, U8 *ppidf_data_ptr, U16 ppidf_min_size, U16 ppidf_max_size, U16 *ppidf_current_size)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function can be used to determine whether a nonvolatile PID exists (with a value set), what size it is, and to retrieve the content.

Arg (data in): ppidf_type_flag One of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID indicating which type of ID is being provided to identify the PID.

Arg (data in): ppidf_id Identifies this PID. The value passed will be interpreted as a KW2000 LID, KW2000/UDS 16-bit ID or J1939 SPN depending on ppidf_type_flag.

Arg (data out): ppidf_data_ptr If a value is set for this PID, the data content will be written to this location unless it is set to NULL. The caller must ensure that this points to a buffer of sufficient size to accept the data. Set to NULL if the actual data is not required.

Arg (data in): ppidf_min_size If the stored data length is less than this value, PPID_RC_ERROR will be returned and no data will be written through ppidf_data_ptr, but the actual size will still be returned through ppidf_current_size.

Arg (data in): ppidf_max_size Similar to ppidf_min_size, but the maximum size allowable.

Arg (data out): ppidf_current_size Unless this is NULL, the current data size of the PID will be written through this pointer if a value currently exists.

Return:

• PPID_RC_ERROR - if the PID does not currently have a value set or the size was out of range

• PPID_RC_OK - if operation is successful

6.7.5.5.5.7. ppid_delete_nv_pid()

Definition: PPID_RC_T ppid_delete_nv_pid(U8 ppidf_type_flag, U32 ppidf_id)

Supported targets: All targets

Copyright 2019, Pi Innovo 579 Extended Diagnostics Functions

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function deletes a nonvolatile PID.

Arg (data in): ppidf_type_flag One of the constants PPID_ISO_16BIT_PID, PPID_KWP_8BIT_PID or PPID_J1939_SPN_PID indicating which type of ID is being provided to identify the PID.

Arg (data in): ppidf_id Identifies this PID. The value passed will be interpreted as a KW2000 LID, KW2000/UDS 16-bit ID or J1939 SPN depending on ppidf_type_flag.

Return:

• PPID_RC_ERROR - if the PID did not currently have a value set (nothing to delete)

• PPID_RC_OK - if operation is successful

6.7.5.5.5.8. ppid_delete_all_nv_pids()

Definition: PPID_RC_T ppid_delete_all_nv_pids(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: This function deletes all nonvolatile PIDs.

Return:

• PPID_RC_OK - currently no error conditions so always succeeds 6.7.6. In-Use Performance Ratio feature (PPR) 6.7.6.1. Overview

The library's In-Use Performance Ratio feature provides a mechanism to declare Diagnostic test entities (DTEs), belonging to particular Diagnostic monitor entities(DMEs), and track their individual as well as overall performance ratio.

The library groups DTEs and DMEs into separate tables. These tables allow the application to act on a group of DTEs or DMEs as one action.

DTEs and DMEs and their corresponding data may be reported over ISO 15765-2 based protocols, or J1939, or both. 6.7.6.2. Diagnostic Test Entities (DTE)

The application declares the DTEs of interest during build time by defining the feature variables ppr_num_dte and ppr_dte_table Individual DTEs are declared in the interface file (see Section 7.1.4.32, “Compound statement: dte-data”).

Copyright 2019, Pi Innovo 580 Extended Diagnostics Functions

The library calculates the current numerator and denominator count of a DTE based on the inputs from application, pprf_dte_id, pprf_sp_den_update_enable and pprf_sp_num_update_enable to the platform function ppr_update_dte_data()

The library also maintains the current test value and limits of a DTE based on inputs from the application, pprf_dte_id, pprf_test_value and pprf_test_valid to the platform function ppr_update_dte_test_value()

The information for a DTE is recalled from non-volatile store after application initialisation occurs. If DTEs cannot be recalled from non-volatile store, then the DTEs are reset to a default value.

On receipt of J1939 DM3 or DM11 messages, the application can call the platform function ppr_update_dte_test_value() with argument pprf_reset_dte set to TRUE for each DTE defined, in order to clear the monitor test results. 6.7.6.3. Diagnostic Monitor Entities (DME)

The application declares the DMEs of interest during build time by defining the feature variables ppr_num_dme and ppr_dme_table Individual DMEs are declared in the interface file (see Section 7.1.4.34, “Compound statement: dme-data”).

The library calculates information related to a DME based on inputs from the application, pprf_dme_id, pprf_monitor_run, pprf_force_complete, pprf_force_not_complete and pprf_monitor_enabled parameters to the platform function ppr_update_dme_data()

The information for a DME is recalled from non-volatile store after application initialisation occurs. If DMEs cannot be recalled from non-volatile store, then the DMEs are reset to a default value. 6.7.6.4. Storage of data across power cycles

On start-up, the library attempts to retrieve the DTE and DME table data prior to running the application. While the application is running, the time at which these tables are stored back to non-volatile memory is determined by the application itself.

The DTE and DME table data is check-summed using a 16-bit CRC. Failure to match the check-sum against the table data during library initialisation means that the data cannot be recovered. In this case, the table data is reverted to the default start-up conditions for each type of DTE or DME respectively.

Similar to the case of DTCs, the two types of non-volatile memory dedicated to DTEs and DMEs are:

Battery backed RAM and

Flash 6.7.6.5. Build time buffer sizing

To reduce the memory footprint of the library, the feature requires that the application define and size various arrays that belong to the feature. This puts additional emphasis on keeping the application code and interface specification in sync, but is beneficial to the final system (especially for resource constrained ECUs).

Note

This mechanism exposes some of the internal implementation of the library but the application need only understand the internals, only size the necessary arrays. The application must not otherwise access the arrays.

Copyright 2019, Pi Innovo 581 Extended Diagnostics Functions

6.7.6.6. Interface index

An index of interface objects for this feature.

Type Identifier Include file openecu.h and ppr.h Macros PPR_STORE_IN_BBRAM

This macro defines the value for ppr_store when non- volatile data is to be stored in battery backed RAM across power cycles. PPR_STORE_IN_FLASH

This macro defines the value for ppr_store when non- volatile data is to be stored in Flash across power cycles. PPR_TEST_AND_MON_TYPE_ISO

The bit position for DTE type definition Bit 0 - to define whether DTE is relevant to ISO (J1979) protocol. Enumerations PPR_RC_T

An enumerated type which contains success and failure codes returned by some In-Use Performance Ratio (PPR) functions. PPR_TEST_RUN_STATE_T

An enumerated type which contains the state of the test run. Data types PPR_DTE_NV_T

This structure declares the run-time data to be stored with each DTE. PPR_DTE_CONST_T

This structure collates the data associated with each DTE. PPR_DME_NV_T

This structure declares the run-time data to be stored with each DME. PPR_DME_CONST_T

This structure collates the data associated with each Monitor ID. PPR_DME_DATA_T

This structure is for the data calculated for reporting the DME data.

Copyright 2019, Pi Innovo 582 Extended Diagnostics Functions

Type Identifier Variables const U8 ppr_store

This defines which memory type will be used to store non-volatile PPR data. const U16 ppr_num_dte

The total number of DTEs that are declared. const U16 ppr_num_dme

The total number of DMEs that are declared. const PPR_DTE_CONST_T ppr_dte_table

The table of DTEs. const PPR_DME_CONST_T ppr_dme_table

The table of DMEs. const U8 ppr_j1939_test_mapping_list

This is a sorted list of bit mapping for J1939 Test Ids - used for DM10 message. Functions PPR_RC_T ppr_update_dte_data

Update the Numerator and Denominator values for this DTE depending on whether application says that it is ready to be updated. PPR_RC_T ppr_update_dte_test_value

Update the test value for this DTE depending on whether application says that it is ready to be updated. PPR_RC_T ppr_update_dte_in_use_status

The application can configure itself at run-time to include or remove the DTE from those considered for diagnostic reporting. PPR_RC_T ppr_update_dme_data

Update the DME data depending on whether application says that it is ready to be updated. PPR_RC_T ppr_update_dme_in_use_status

The application can configure itself at run-time to include or remove the DME from those considered for diagnostic reporting. void ppr_update_gen_denominator

Update the General denominator depending on whether application says that it is ready to be updated. void ppr_update_ign_cyc_counter

Copyright 2019, Pi Innovo 583 Extended Diagnostics Functions

Type Identifier Update the Ignition cycle count depending on whether application says that it is ready to be updated. PPR_RC_T ppr_get_dme_ratio

Obtain the In-Use performance ratio values for this DME. PPR_RC_T ppr_get_monitor_group_data

Obtain the In-Use performance data values for this monitor group. PPR_RC_T ppr_get_dme_status

Obtain the Monitor enable, readiness complete, completed status for the DME. U16 ppr_get_dme_incomplete_count

Obtain the total number of monitors (DMEs) that are enabled and not complete. PPR_RC_T ppr_get_dte_status

Obtain the NV data for the DTE. void ppr_handle_new_ign_cyc

Handles any data updates needed at start of new ignition cycle. void ppr_handle_new_drive_cycle

Handles any data updates needed at start of new drive cycle. U16 ppr_get_ign_cycle_count

Obtain the ignition cycle count. U16 ppr_get_gen_denominator

Obtain the general denominator. void ppr_commit_to_store

Commit RAM data to non-volatile store. BOOL ppr_is_store_intact

Test whether there are data changes not yet committed to NV store.

6.7.6.7. Interface detail

6.7.6.7.1. Macros

6.7.6.7.1.1. PPR_STORE_IN_BBRAM

Definition: #define PPR_STORE_IN_BBRAM 0

Copyright 2019, Pi Innovo 584 Extended Diagnostics Functions

Description:

This macro defines the value for ppr_store when non-volatile data is to be stored in battery backed RAM across power cycles.

6.7.6.7.1.2. PPR_STORE_IN_FLASH

Definition: #define PPR_STORE_IN_FLASH 1

Description:

This macro defines the value for ppr_store when non-volatile data is to be stored in Flash across power cycles.

6.7.6.7.1.3. PPR_TEST_AND_MON_TYPE_ISO

Definition: #define PPR_TEST_AND_MON_TYPE_ISO 0x1

Description:

The bit position for DTE type definition Bit 0 - to define whether DTE is relevant to ISO (J1979) protocol.

Bit 1 - to define whether DTE is relevant to J1939 protocol.

6.7.6.7.2. Enumerations

6.7.6.7.2.1. PPR_RC_T

Summary: An enumerated type which contains success and failure codes returned by some In-Use Performance Ratio (PPR) functions.

Enumerations:

PPR_RC_OK Return code if everything progressed as expected.

PPR_RC_BAD_ARGS Return code if at least one of the arguments could not be used.

PPR_RC_BAD_CONFIG_DATA Return code if the PPR configuration data was invalid for requested operation.

6.7.6.7.2.2. PPR_TEST_RUN_STATE_T

Summary: An enumerated type which contains the state of the test run.

Enumerations:

PPR_TEST_NOT_RUN Test has not been run (ever).

PPR_TEST_RUN_THIS_DC Test has been run this drive cycle.

PPR_TEST_RUN Test has been run, but not this drive cycle.

Copyright 2019, Pi Innovo 585 Extended Diagnostics Functions

6.7.6.7.3. Data types

6.7.6.7.3.1. PPR_DTE_NV_T

Summary: This structure declares the run-time data to be stored with each DTE.

Members:

U16 PPR_DTE_NV_T::numerator The Specific Numerator for the test.

U16 PPR_DTE_NV_T::denominator The Specific Denominator for the test.

U16 PPR_DTE_NV_T::test_value The Test value for the test.

U16 PPR_DTE_NV_T::test_lim_max The maximum limit of the test value for the test Pass/Fail criteria.

U16 PPR_DTE_NV_T::test_lim_min The minimum limit of the test value for the test Pass/Fail criteria.

BOOL PPR_DTE_NV_T::dte_in_use Specifies if the DTE is in-use for current application.

BOOL PPR_DTE_NV_T::numerator_updated_this_cycle This keeps track of whether the Numerator has been updated this drive cycle.

BOOL PPR_DTE_NV_T::denominator_updated_this_cycle This keeps track of whether the Denominator has been updated this drive cycle.

PPR_TEST_RUN_STATE_T PPR_DTE_NV_T::test_run_status This keeps track of whether the Test has been run this cycle / ever.

Description:

This structure declares the run-time data to be stored with each DTE.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

6.7.6.7.3.2. PPR_DTE_CONST_T

Summary: This structure collates the data associated with each DTE.

Members:

U8 PPR_DTE_CONST_T::dte_id The DTE identifier - calibratable by the application.

U8 PPR_DTE_CONST_T::dte_type The DTE type - ISO or J1939 or BOTH Bit 0 = 1 implies ISO Bit 1 = 1 implies J1939.

Copyright 2019, Pi Innovo 586 Extended Diagnostics Functions

U8 PPR_DTE_CONST_T::dme_id The DME to which this DTE belongs - calibratable by the application.

U8 PPR_DTE_CONST_T::iso_tid The ISO specified Test ID that requires ratio monitoring.

U8 PPR_DTE_CONST_T::j1939_tid The J1939 specified Test ID that requires ratio monitoring.

U8 PPR_DTE_CONST_T::mon_id The Monitor group ID to which the DTE belongs Applicable only for reporting over ISO.

U8 PPR_DTE_CONST_T::scaling_id The identifier is used to reference the scaling and unit to be used by the external test equipment to calculate and display the test values/ results Applicable only for reporting over ISO.

U16 PPR_DTE_CONST_T::slot_id The SLOT identifier for the DTE Applicable only for reporting over J1939.

U32 PPR_DTE_CONST_T::spn The SPN associated with the DTE Applicable only for reporting over J1939.

U8 PPR_DTE_CONST_T::fmi The FMI associated with the DTE Applicable only for reporting over J1939.

U8 PPR_DTE_CONST_T::component_id The Component identifier for the DTE Applicable only for reporting over J1939.

PPR_DTE_NV_T* PPR_DTE_CONST_T::dte_data_nv Pointer to the modifiable data part of the Test data.

Description:

This structure collates the data associated with each DTE.

Note

The application may use the ISO and J1939 Test IDs, Monitor group ID and Component ID elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

6.7.6.7.3.3. PPR_DME_NV_T

Summary: This structure declares the run-time data to be stored with each DME.

Members:

U16 PPR_DME_NV_T::dme_run_count The Run count used for setting Readiness 'complete' status for the DME.

BOOL PPR_DME_NV_T::dme_in_use Specifies if the DME is in-use for current application.

Copyright 2019, Pi Innovo 587 Extended Diagnostics Functions

BOOL PPR_DME_NV_T::dme_readiness_complete The Readiness 'complete' status for the DME.

BOOL PPR_DME_NV_T::dme_enabled Indicates whether the monitoring for the DME is enabled.

BOOL PPR_DME_NV_T::dme_completed Indicates whether the monitoring conditions for the DME are met.

Description:

This structure declares the run-time data to be stored with each DME.

Note

The structure is private to the library and should not be used by the application. It is exposed as part of the API so that various arrays can be sized at build time to minimise the library memory footprint.

6.7.6.7.3.4. PPR_DME_CONST_T

Summary: This structure collates the data associated with each Monitor ID.

Members:

U8 PPR_DME_CONST_T::dme_id The DME identifier - calibratable by the application.

U8 PPR_DME_CONST_T::dme_type The DME type - ISO or J1939 or BOTH Bit 0 = 1 implies ISO Bit 1 = 1 implies J1939.

U8 PPR_DME_CONST_T::mon_id The Monitor ID that requires ratio monitoring.

PIO_MONITOR_GROUP_T PPR_DME_CONST_T::mon_grp The Monitor group which this DME belongs to.

U16 PPR_DME_CONST_T::readiness_count_lim The readines count limit - the number of times monitor has to be run before declared as Readiness COMPLETE.

U32 PPR_DME_CONST_T::spn The SPN for the DME Applicable only for reporting DM20 messages over J1939.

PPR_DME_NV_T* PPR_DME_CONST_T::dme_data_nv Pointer to the modifiable data part of the Monitor data.

Description:

This structure collates the data associated with each Monitor ID.

Note

The application may use the Monitor ID and rediness count limit elements. Access to other elements should be made exclusively through library API calls, to avoid data coherency issues.

Copyright 2019, Pi Innovo 588 Extended Diagnostics Functions

6.7.6.7.3.5. PPR_DME_DATA_T

Summary: This structure is for the data calculated for reporting the DME data.

Members:

U16 PPR_DME_DATA_T::dme_numerator The Specific Numerator for the monitor group.

U16 PPR_DME_DATA_T::dme_denominator The Specific Denominator for the monitor group.

F32 PPR_DME_DATA_T::dme_ratio The Ratio for the monitor group.

6.7.6.7.4. Variables

6.7.6.7.4.1. ppr_store

Definition: const U8 ppr_store

Description: This defines which memory type will be used to store non-volatile PPR data.

If set to PPR_STORE_IN_BBRAM then non-volatile data is stored in battery backed RAM, and if set to PPR_STORE_IN_FLASH then the non-volatile data is stored in Flash.

Warning

Some memory stores are not implemented on some target ECUs. See the technical specification of the ECU to determine if the store type is available.

6.7.6.7.4.2. ppr_num_dte

Definition: const U16 ppr_num_dte

Description: The total number of DTEs that are declared.

6.7.6.7.4.3. ppr_num_dme

Definition: const U16 ppr_num_dme

Description: The total number of DMEs that are declared.

6.7.6.7.4.4. ppr_dte_table

Definition: const PPR_DTE_CONST_T ppr_dte_table[]

Description: The table of DTEs.

Copyright 2019, Pi Innovo 589 Extended Diagnostics Functions

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal ppr_num_dte (or one if there are DTEs). The array is not to be accessed by application code.

6.7.6.7.4.5. ppr_dme_table

Definition: const PPR_DME_CONST_T ppr_dme_table[]

Description: The table of DMEs.

Present in the C-API description only for build time size requirements. The array must be declared and sized by the application. The size of the array must equal ppr_num_dme (or one if there are no DMEs). The array is not to be accessed by application code.

6.7.6.7.4.6. ppr_j1939_test_mapping_list

Definition: const U8 ppr_j1939_test_mapping_list[64]

Description: This is a sorted list of bit mapping for J1939 Test Ids - used for DM10 message.

6.7.6.7.5. Functions

6.7.6.7.5.1. ppr_update_dte_data()

Definition: PPR_RC_T ppr_update_dte_data(U8 pprf_dte_id, BOOL pprf_sp_den_update_enable, BOOL pprf_sp_num_update_enable)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Update the Numerator and Denominator values for this DTE depending on whether application says that it is ready to be updated.

Arg (data in): pprf_dte_id The DTE ID for which the N & R are to be updated

Arg (data in): pprf_sp_den_update_enable Indicates whether the Denominator is ready to be updated

Arg (data in): pprf_sp_num_update_enable Indicates whether the Numerator is ready to be updated

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

Copyright 2019, Pi Innovo 590 Extended Diagnostics Functions

6.7.6.7.5.2. ppr_update_dte_test_value()

Definition: PPR_RC_T ppr_update_dte_test_value(U8 pprf_dte_id, U16 pprf_test_value, U16 pprf_test_limit_min, U16 pprf_test_limit_max, BOOL pprf_test_run, BOOL pprf_reset_dte)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Update the test value for this DTE depending on whether application says that it is ready to be updated.

For J1939 DTEs the guidelines for the use of test results is as detailed below as per J1939-73 spec dated Sept 2010. The application is expected to set the right combination of test results in order to convey the correct results over J1939 messages to the test tools:- Test_Value Test_Max Test_Min Interpretation 0x0000 to 0xFAFF 0xFFFF 0xFFFF Test Pass 0xFE00 0xFFFF 0xFFFF Test Fail with error 0xFB00 0xFFFF 0xFFFF Test Not Complete 0xFB01 0xFFFF 0xFFFF Test cannot be performed less than 0xFFFF any value 0xFFFF Test Fail (value less than min) any value 0xFFFF 0xFFFF Test fail without values

For ISO-15765 DTEs, all test values within the range specified by min and max will be interpreted as "Test Pass" including values equal to min or max.

Arg (data in): pprf_dte_id The DTE ID for which the test value is to be updated

Arg (data in): pprf_test_value The test value, supplied by the application

Arg (data in): pprf_test_limit_min The minimum test limit for this test, supplied by the application

Arg (data in): pprf_test_limit_max The maximum test limit for this test, supplied by the application

Arg (data in): pprf_test_run Indicates whether the test has been run and new values are available. If set to TRUE, the stored test values will be set to the values passed. If set to FALSE, the stored values will be left unchanged.

Arg (data in): pprf_reset_dte If set to TRUE, the stored test values will be reset. This will typically be used by the application when starting a new monitor cycle (see note). If set to FALSE, the stored values will be left unchanged. If both pprf_test_run and pprf_reset_dte are set TRUE, pprf_test_run takes precedence.

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

Copyright 2019, Pi Innovo 591 Extended Diagnostics Functions

Note

After a monitor completes, the application must update all the Test ID that were used by the monitor with appropriate passing or failing results. If a test result was not utilised during the monitoring event, the Test values must be reset. Test results from previous completed monitoring events must not be mixed with test results from current event.

6.7.6.7.5.3. ppr_update_dte_in_use_status()

Definition: PPR_RC_T ppr_update_dte_in_use_status(U8 pprf_dte_id, BOOL pprf_in_use)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: The application can configure itself at run-time to include or remove the DTE from those considered for diagnostic reporting.

Arg (data in): pprf_dte_id The DTE ID for which the status is to be updated

Arg (data in): pprf_in_use Indicates whether the DTE is in-use

• TRUE - indicates that the DTE is in use.

• FALSE - indicates that the DTE is not in use.

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

Note

All DTEs are enabled by default

6.7.6.7.5.4. ppr_update_dme_data()

Definition: PPR_RC_T ppr_update_dme_data(U8 pprf_dme_id, BOOL pprf_monitor_run, BOOL pprf_force_complete, BOOL pprf_force_not_complete, BOOL pprf_monitor_enabled)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Copyright 2019, Pi Innovo 592 Extended Diagnostics Functions

Description: Update the DME data depending on whether application says that it is ready to be updated.

Arg (data in): pprf_dme_id The DME identifier for which the data is to be updated

Arg (data in): pprf_monitor_run Indicates whether the monitor has been run. When the application asks for forceful Readiness COMPLETE or NOT COMPLETE, the flag indicating whether the monitoring conditions for the DME are met (completed) is set depending on the value of this parameter.

Arg (data in): pprf_force_complete Indicates whether the monitor has to be forced to COMPLETE readiness status

• TRUE - indicates that the readiness status should be forced to COMPLETE independent of the number of times monitor has been run.

• FALSE - indicates that the readiness status has to be set depending on the number of times the monitor has been run and if it is enabled.

Arg (data in): pprf_force_not_complete Indicates whether the monitor has to be forced to NOT COMPLETE readiness status

• TRUE - indicates that the readiness status should be forced to NOT COMPLETE independent of the number of times monitor has been run.

• FALSE - indicates that the readiness status has to be set depending on the number of times the monitor has been run and if it is enabled. Both pprf_force_complete and pprf_force_not_complete should not be set to TRUE in the same time.

Arg (data in): pprf_monitor_enabled Indicates whether the monitor is Enabled

• TRUE - indicates that the monitor is enabled.

• FALSE - indicates that the monitor is disabled for some reason.

• Readiness complete count will not be computed if the monitor is DISabled

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

6.7.6.7.5.5. ppr_update_dme_in_use_status()

Definition: PPR_RC_T ppr_update_dme_in_use_status(U8 pprf_dme_id, BOOL pprf_in_use)

Copyright 2019, Pi Innovo 593 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: The application can configure itself at run-time to include or remove the DME from those considered for diagnostic reporting.

Arg (data in): pprf_dme_id The DME ID for which the status is to be updated

Arg (data in): pprf_in_use Indicates whether the DME is in-use

• TRUE - indicates that the DME is in use.

• FALSE - indicates that the DME is not in use.

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

Note

All DMEs are enabled by default

6.7.6.7.5.6. ppr_update_gen_denominator()

Definition: void ppr_update_gen_denominator(BOOL pprf_gen_den_update_enable)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Update the General denominator depending on whether application says that it is ready to be updated.

Arg (data in): pprf_gen_den_update_enable Indicates whether the denominator has to be updated

6.7.6.7.5.7. ppr_update_ign_cyc_counter()

Definition: void ppr_update_ign_cyc_counter(BOOL pprf_ign_cyc_update_enable)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Copyright 2019, Pi Innovo 594 Extended Diagnostics Functions

Description: Update the Ignition cycle count depending on whether application says that it is ready to be updated.

Arg (data in): pprf_ign_cyc_update_enable Indicates start of ignition cycle

6.7.6.7.5.8. ppr_get_dme_ratio()

Definition: PPR_RC_T ppr_get_dme_ratio(U8 pprf_dme_id, PPR_DME_DATA_T *pprf_dme_data)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the In-Use performance ratio values for this DME.

Arg (data in): pprf_dme_id The DME for which the ratio, numerator and denominator data is needed

Arg (data in,out): pprf_dme_data Pointer to the DME data - which will be updated Cannot be NULL

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

6.7.6.7.5.9. ppr_get_monitor_group_data()

Definition: PPR_RC_T ppr_get_monitor_group_data(PIO_MONITOR_GROUP_T pprf_mon_grp, PPR_DME_DATA_T *pprf_dme_data)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the In-Use performance data values for this monitor group.

Arg (data in): pprf_mon_grp The Monitor group for which the numerator and denominator data is needed

Arg (data out): pprf_dme_data Pointer to the data - which will be updated Cannot be NULL

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

Copyright 2019, Pi Innovo 595 Extended Diagnostics Functions

6.7.6.7.5.10. ppr_get_dme_status()

Definition: PPR_RC_T ppr_get_dme_status(U8 pprf_dme_id, PPR_DME_NV_T *pprf_dme_nv_data)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the Monitor enable, readiness complete, completed status for the DME.

Arg (data in): pprf_dme_id The DME for which data is needed

Arg (data in,out): pprf_dme_nv_data Pointer to the DME data - which will be updated Cannot be NULL

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

6.7.6.7.5.11. ppr_get_dme_incomplete_count()

Definition: U16 ppr_get_dme_incomplete_count(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the total number of monitors (DMEs) that are enabled and not complete.

Return: The number of enabled and incomplete monitors (DMEs)

6.7.6.7.5.12. ppr_get_dte_status()

Definition: PPR_RC_T ppr_get_dte_status(U8 pprf_dte_id, PPR_DTE_NV_T *pprf_dte_nv_data)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the NV data for the DTE.

Arg (data in): pprf_dte_id The DTE for which data is needed

Copyright 2019, Pi Innovo 596 Extended Diagnostics Functions

Arg (data in,out): pprf_dte_nv_data Pointer to the DTE data - which will be updated Cannot be NULL

Return:

• PPR_RC_BAD_ARGS - if the input parameters are invalid

• PPR_RC_OK - if operation is successful

6.7.6.7.5.13. ppr_handle_new_ign_cyc()

Definition: void ppr_handle_new_ign_cyc(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Handles any data updates needed at start of new ignition cycle.

Resets the ignition cycle count's "update status"

6.7.6.7.5.14. ppr_handle_new_drive_cycle()

Definition: void ppr_handle_new_drive_cycle(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Handles any data updates needed at start of new drive cycle.

6.7.6.7.5.15. ppr_get_ign_cycle_count()

Definition: U16 ppr_get_ign_cycle_count(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the ignition cycle count.

Return: U16 - The ignition cycle count.

6.7.6.7.5.16. ppr_get_gen_denominator()

Definition: U16 ppr_get_gen_denominator(void)

Copyright 2019, Pi Innovo 597 Extended Diagnostics Functions

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Obtain the general denominator.

Return: The general denominator.

6.7.6.7.5.17. ppr_commit_to_store()

Definition: void ppr_commit_to_store(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Commit RAM data to non-volatile store.

Update the validity status for the non-volatile data, and if the data is stored in Flash, then write the data to Flash.

Warning

This function suspends the scheduler for a period of time. The period of time depends on the size of data and the storage location. If storing information to Flash, the worst case Flash erase time given worst case environmental conditions, can be around 1.8 seconds.

6.7.6.7.5.18. ppr_is_store_intact()

Definition: BOOL ppr_is_store_intact(void)

Supported targets: All targets

Required license: EXT_DIAG (Extended diagnostics library).

Description: Test whether there are data changes not yet committed to NV store.

Return: True if there are no data changes since the last commit to the non- volatile store (from calling ppr_commit_to_store()), false otherwise

Copyright 2019, Pi Innovo 598 Chapter 7. Support tools

7.1. Interface and DDE tool ...... 599 7.1.1. Simple interface file example ...... 599 7.1.2. Running the interface tool ...... 601 7.1.3. Warning and error messages ...... 609 7.1.4. Interface file contents ...... 610 7.1.5. DDE specification ...... 647 7.1.6. Units file ...... 653 7.1.7. Automatic ASAP2 entries ...... 653 7.1.8. OpenECU software versioning ...... 661 7.2. Supporting build scripts ...... 662 7.2.1. Creating a binary image with a supported compiler ...... 663 7.1. Interface and DDE tool

The interface and DDE tool performs two main functions:

1. The interface tool reads a specification of the interface between the application and library, and generates the interface code to link the application and library together. Although the interface code could be written by hand, some sections of the interface code are hard to maintain by hand. The interface tool will replace the hard to maintain code with a simple text based specification.

2. The interface tool reads a specification of the data items in the application and generates an output file which can be used to inspect the application and library code when it is executing on the ECU. At the moment, only the ASAP2 output file format is supported, but other formats may be added in the future.

How the interface tool fits into the OpenECU system is explained in more detail in Section 4.6.1, “Building an application”. 7.1.1. Simple interface file example

Perhaps the best way to understand what the interface tool and interface specification is all about, is to describe a simple example. The following example of an interface file covers the target ECU, the application and basic CCP settings.

target-ecu { hw-part-number = "01T-068276"; hw-issue-number = 2; hw-option = "000"; }

application { major-version = 1; minor-version = 0; subminor-version = 0;

name = "Simple application"; copyright = "Copyright 2016, Pi Innovo"; description = "A simple application showing how to use OpenECU at a minimum.";

os-native { stack-size = 8192;

task

Copyright 2019, Pi Innovo 599 Support tools

{ name = application_processing; function = app_proc_task; priority = 10; period = 100; } } }

ccp-messaging { cro = 1784; dto = 1785; station-address = 0; can-bus = 0;

enabled-during-application-mode = true; }

All statements regarding the target ECU to be used are written here. The statements are included between the opening and closing brace ({}) and this is a common mechanism to group common statements together.

In this case, there are three statements that identify the ECU that the application is to be built and run on.

All statements about the application are written here. This includes identifying the application name, version and so on, as well as identifying the operating system and tasks to schedule.

This collection of statements identifies the version to be assigned to the application. The version number is available to the calibration tool.

This collection of statements provides information about the application, which is embedded into the binary image of the application during compilation. The information is available to the calibration tool.

Within the application statements, the operating system is identified and the application tasks defined.

The application and library require some memory to be dedicated to a stack and this statement does just that. More details about how OpenECU handles the stack can be found in Section 5.6.1.3, “Stack sharing”.

Each application task has a number of attributes, including a general name for reference within the interface file, the C identifier for the application function that implements the task, a task priority and a period in milliseconds. More details about how OpenECU treats tasks can be found in Section 5.6, “Task scheduling (PKN)”.

Although only one task is shown here, multiple application tasks can be declared.

The primary communication mechanism from the ECU to the reprogramming and calibration tools is with CCP (see Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)” and Appendix C, Supporting tools for more).

All statements regarding CCP communication are written here.

In this example, the default CCP settings have been chosen.

And in this example, CCP messaging is enabled during application mode so that the calibration tool can view the application variables as the application runs on the ECU.

As part of the build process at step 1, the interface tool is run against the interface file to generate the interface code:

Copyright 2019, Pi Innovo 600 Support tools

Figure 7.1. Building the interface code

Inputs from application

Data Interface Application dictionary description source files file code

1

Interface source code

2 Intermediate build steps build Intermediate

Object files

which is then compiled at step 2, ready to be linked with the application and library in later steps.

The interface tool is a command line tool and naturally fits into software build environments (e.g., from within make). In this example, if the interface file were named sample.capi, then the command to generate the interface code files would look like this:

capi.py --interface-file sample.capi --output-code sample_capi

The result of running this command would be a set of files named sample_capi*.* which contains the data definitions and function definitions required to link the application with the library.

The following sections cover how to run the interface tool and what contents an interface tool should contain. 7.1.2. Running the interface tool

The interface tool has a command line interface. It is invoked by running the command:

capi.py arguments

The list of arguments can be specified in different forms:

argument A string entered on the command line following the tool command. E.g., running the interface tool as if it accepts one file-name argument would be:

capi.py file-name.txt

Copyright 2019, Pi Innovo 601 Support tools

option An argument, used to provide specific information, starts with a hyphen. There are two types of options: with a single hyphen and with a double hyphen.

single — starts with a single hyphen and ends with a single character. E.g., the option to print the interface tool's arguments is:

-h

Single hyphen options can be merged. For instance, the options:

-f -W

can be represented as:

-fW

double — starts with a double hyphen and ends with a string. E.g., the option to specify the interface file is:

--interface-file sample.capi

option argument An argument that follows an option that requires an argument. The following argument can be disjoint, or joint, to the option. For instance, the following options show the disjoint form:

-i file-name.txt

--interface-file file-name.txt

and the joint form is:

-offline.txt

--input=file-name.txt

7.1.2.1. Options (input)

-i FILE, --interface-file=FILE Specify the file-name for the interface file.

This argument is optional. If this argument is not present then the tool will attempt to read the interface file from the console. 7.1.2.2. Options (target identification and configuration)

--cfg-flags Obtain the -DCFG flags to pass to the compiler in order to correctly identify the hardware being used in the platform source code. It should be used in conjunction with the -- interface-file option. The capi.py tool reads target-ecu information given in the interface file and maps that to the internal names used to identify that ECU within the software domain.

Copyright 2019, Pi Innovo 602 Support tools

See the batch files in the C-API examples for an example of how to use this option

This argument is optional. However, it is recommended that it is used in batch files for compiling the C-API applications to remove any dependencies on the internal names used to identify the ECU within the software domain, which these names may change from time to time.

--target-path Obtain the path to the platform code appropriate to the target ECU. This option should be used in conjunction with the --interface-file option. The capi.py tool reads target- ecu information given in the interface file and maps that to the internal names used to identify that ECU within the software domain.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

This argument is optional. However, it is recommended that it is used in batch files for compiling the C-API applications to remove any dependencies on the internal names used to identify the ECU within the software domain, since these names may change from time to time.

--output-linker-file=FILE Generate the correct linker file depending on the target and memory configuration (for those targets that support this option) as specified in the interface file: see Section 7.1.4.7, “Compound statement: target-ecu” and Section 7.1.4.13, “ Compound statement: memory-config ” for details of how to specify these items.

This argument is optional. However, it is particularly useful for non-standard memory configurations where it will automatically create the correct linker file for that configuration.

When using this command line option, the base path to the OpenECU installation must also be specified using the --oe-base-path=PATH command line option. Furthermore, some targets support more than one compiler. For these targets the compiler should be specified using the --compiler-id=COMPILER command line option.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--ld-excerpt-file=FILE Insert the specified linker file excerpt created with --diab-ldfile=FILE or --gcc- ldfile=FILE into the linker file.

This argument is optional. It particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

When using this command line option, the base path to the OpenECU installation must also be specified using the --oe-base-path=PATH command line option and the output linker file must be specified using the --output-linker-file=FILE command line option. Furthermore, some targets support more than one compiler. For these targets the compiler should be specified using the --compiler-id=COMPILER command line option.

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--oe-base-path=PATH Specify the path to the OpenECU installation. This is required when using the -- output-linker-file=FILE command line option.

Copyright 2019, Pi Innovo 603 Support tools

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option.

--compiler-id=COMPILER Specify the compiler. This is (only) required when using the --output-linker- file=FILE command line option for those targets that support more than one compiler. The COMPILER must be one of:

• diab_5_5_1_0

• diab_5_8

• diab_5_9

• diab_5_9_4_8

• gcc_4_7_3

See the batch files in the examples\c_api folders in the OpenECU installation for examples of how to use this option. 7.1.2.3. Options (code output)

--output-code=FILE Specify the template file-name for code output. Interface code is written to more than one file. For instance, if the option

--output-code

is given, then the tool will generate files api.h and api.c.

This argument is optional. If this argument is not specified then the interface tool will not generate any interface code files. 7.1.2.4. Options (ASAP2 output)

--asap2-naming=ASAP2_NAMING Specify the ASAP2 naming scheme to be applied to DDEs taken from prefix-style data dictionary files included by the interface specification file (see options -i, -- interface-file). Must be one of: prefix_name, prefix.name prefix.name_prefix, name, or name_prefix.

The scheme determines how the name for a prefix-style DDE is transformed into the name of the equivalent ASAP2 object. For instance, if the scheme prefix.name_prefix was selected

--asap2-naming prefix.name_prefix

then the DDE name mbe_engine_speed would be transformed into mbe.engine_speed_mbe when generating an ASAP2 description file.

This argument is optional. If the argument is not specified then the tool uses a default of prefix_name

-b TYPE, --bool-type=TYPE Specify the implementation type for booleans. Must be one of: u8 (booleans are represented using the unsigned 8-bit integer type), or float (booleans are represented using the 32-bit IEEE floating point type).

This is an optional argument. If the argument is not specified then the tool uses a default of u8.

Copyright 2019, Pi Innovo 604 Support tools

--diab-ddumpfile=FILE Specify the file-name of the output from the Diab ddump command. The ddump command extracts information from the ELF file, including details about structures, enumerations and addresses of variables. This information is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The ddump command should be executed as follows:

ddump -Dht [file-name].elf > [file- name].ddump.tmp

resulting in a textual representation of the ELF information.

The option --diab-ddumpfile cannot be specified at the same time as any of the --diab-mapfile, --gcc-objfile , or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

--gcc-objfile=FILE Specify the file-name of the output from the GNU objdump command. The objdump command extracts information from the ELF file, including details about structures, enumerations and addresses of variables. This information is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The objdump command should be executed as follows:

objdump -W -h -t [file-name].elf > [file- name].objdump.tmp

resulting in a textual representation of the ELF information.

The option --gcc-objfile cannot be specified at the same time as any of the -- diab-mapfile, --diab-ddumpfile, or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

-m FILE, --diab-mapfile=FILE Specify the file-name of the Diab linker MAP file. The MAP file is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The option --diab-mapfile cannot be specified at the same time as any of the -- gcc-objfile, --diab-ddumpfile , or --gcc-mapfile options. If generating an ASAP2 file, one of the options must be specified.

If generating an ASAP2 file, one of the above must be specified.

If generating a final application image, --diab-mapfile or --gcc-mapfile must be specified.

-m FILE, --gcc-mapfile=FILE Specify the file-name of the Diab linker MAP file. The MAP file is used to resolve the addresses of data dictionary entries included in the ASAP2 description files.

The option --diab-mapfile cannot be specified at the same time as any of the -- gcc-objfile, --diab-ddumpfile, or --diab-mapfile options. If generating an ASAP2 file, one of the options must be specified.

If generating an ASAP2 file, one of the above must be specified.

If generating a final application image, --diab-mapfile or --gcc-mapfile must be specified.

Copyright 2019, Pi Innovo 605 Support tools

--diab-ldfile=FILE Specify the file-name of the Diab linker definition file excerpt produced to allow specific linkage of certain functions and symbols. This linker definition file excerpt must be inserted into the main linker definition file after the line containing the text "APP_CODE_FLASH_INSERT".

This particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

If this option is not specified, a linker definition file excerpt will not be produced. This may be acceptable if an application does not require it. --gcc-ldfile=FILE Specify the file-name of the GCC linker definition file excerpt produced to allow specific linkage of certain functions and symbols. This linker definition file excerpt must be inserted into the main linker definition file after the line containing the text "APP_CODE_FLASH_INSERT".

This particularly relates to CCP security (see Section 5.16.1.4, “CCP seed/key security”) and other features where function size must be determined.

If this option is not specified, a linker definition file excerpt will not be produced. This may be acceptable if an application does not require it. -n LENGTH, --name-length=LENGTH Specify maximum length of identifier names in ASAP2 files. Names longer than the specified length will be modified to a unique name of the specifed length.

If LENGTH is given a value of 0, then there will be no limit on identifier lengths.

This is an optional argument. If the argument is not specified then the tool uses a default of 32. --output-asap2-canape=FILE Specify the file-name to write the Vector CANape specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to Vector CANape. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an Vector CANape ASAP2 file. --output-asap2-generic=FILE Specify the file-name to write the an ASAP2 description to. The ASAP2 contains a generic description, without elements for specific calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate a generic ASAP2 file. --output-asap2-inca=FILE Specify the file-name to write the ETAS INCA specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to ETAS INCA. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an ETAS INCA ASAP2 file. --output-asap2-vision=FILE Specifies the file-name to write the ATI Vision specific ASAP2 description to. The ASAP2 file has portions of the data description which are specific to ATI Vision. The ASAP2 is not suitable for other calibration tools.

This argument is optional. If the argument is not specified then the interface tool will not generate an ATI Vision ASAP2 file.

Copyright 2019, Pi Innovo 606 Support tools

--old-format Specifies that the OpenECU build process will generate old-style ASAP2 map names. Old style ASAP2 map names contain _z at the end of the map name. This usage was used in releases older than version 1.9.0 and this option was introduced to allow for backwards compatibility of calibration files.

This argument is optional. If the argument is not specified then the interface tool will not generate old style ASAP2 map names. 7.1.2.5. Options (final application image generation)

--output-s-rec=FILE Specifies the file in which to write the final application image in s-record format. The CCP settings, and checksum are populated in the applicaiton and calibration headers.

--img-app, --img-cal and --diab-mapfile must be specified.

If --crc or --ipv4-sum are specified, then the application or calibration headers will be poplated with the specified CRC or IPv4 checksum.

If this argument is not specified, then the interface tool will not generate a final application s-record.

-A FILE, --img-app=FILE Specifies the file containing the application binary image generated by the compiler.

For the diab compiler, this file is generated as follows:

ddump -Rv -u -n .text_app,.data,.sdata [name].elf -o image_app_[name].bin.tmp

If generating a final application image, --img-app must be specified.

-C FILE, --img-cal=FILE Specifies the file containing the calibration binary image generated by the compiler.

For the diab compiler, this file is generated as follows:

ddump -Rv -u -n .rodata,.sdata2,.cal_sec [name].elf -o image_cal_[name].bin.tmp

If generating a final application image, --img-cal must be specified.

-c VALUE, --crc=VALUE If specified with --output-s-rec this option can be used to populate the headers with a CRC checksum, according to the specified value:

Option Function --crc a Calculate crc for application header. --crc c Calculate crc for calibration header. --crc ac Calculate crc for both.

--ipv4-sum=VALUE If specified with --output-s-rec this option can be used to populate the headers with a IPv4 checksum, according to the specified value:

Option Function --ipv4-sum a Calculate checksum for application header.

Copyright 2019, Pi Innovo 607 Support tools

Option Function --ipv4-sum c Calculate checksum for calibration header. --ipv4-sum ac Calculate checksum for both.

7.1.2.6. Options (data dictionary output)

--output-elf-contents=FILE Specifies the file-name to write a C-style data dictionary to. The data dictionary entries are those found in the application ELF information (see --diab-ddumpfile) and not already listed in a data dictionary file included from an interface specification (see -i, --interface-file). This option may help when incrementally building up new DD files from existing C code.

Unreferenced C objects do not contain enough information in the ELF file to generate an equivalent DD entry. For instance, if a data dictionary file were created from the following snippet:

U32 unreferenced_var; U32 var;

void main(void) { do_something(var); }

an entry for var would be created but no entry for unreferenced_var would be created.

If this option is specified then the --diab-ddumpfile option must also be specified.

--include-platform-vars The --output-elf-contents option will filter out most of the library variables. And in most circumstances this is the better option, presenting only variables which are relevant to the application. However, this filtering can be turned off by specifying this option if the filtering inadvertently removes application variables.

--warn-missing-ddes Generate a warning if a DDE cannot be found in the MAP or ELF file, and continue to create the ASAP2 file (rather than raise an error and stop generating the ASAP2 file).

This argument is optional. If the argument is not specified then the interface tool will raise an error when a DDE cannot be found.

--check-dde-data-types Generate a warning if the data type of a DDE does not match the equivalent variable data type from the ELF file.

This argument is optional. If the argument is not specified then the interface tool will not warn the user of data type mismatches. 7.1.2.7. Options (miscellaneous)

-h, --help Show a summary of the command line arguments to the interface tool, then exit.

This argument is optional.

--version Show the version of the interface tool, then exit.

This argument is optional.

Copyright 2019, Pi Innovo 608 Support tools

--cleanup Remove temporary files when an error is found (see the details on removing temporary files [610] for more). This is the default behaviour of the tool.

This argument is optional. If the argument is not specified then the tool will default to removing temporary files when an error is found.

--dont-cleanup Do not remove temporary files when an error is found (see the details on removing temporary files [610] for more).

This argument is optional. If the argument is not specified then the tool will default to removing temporary files when an error is found.

--output-ast=FILE Specify the file-name template that the tool writes a representation of its internal workings for technical support purposes. The files written to are: FILE_pre_default.ast and FILE_post_default.ast. To be used in conjunction with the see --dont-cleanup argument.

This argument is optional. If the argument is not specified then the interface tool will not generate the technical support files.

--output-mscript=FILE Specifies the file-name to write a MATLAB script which executes to fill the MATLAB workspace with details on the prefix-style DDEs (C-style DDEs are not acted on as their naming style cannot always be expressed in MATLAB).

This argument is optional. If the argument is not specified then the interface tool will not generate an m-script file.

This option is provided for other OpenECU products and is not necessary to use the C- API OpenECU product. 7.1.3. Warning and error messages

The interface tool reports warnings and error messages is a consistent way. A typical error message might look like:

(capi.py): OpenECU interface tool (version , built ) (capi.py): (error 601) line 9 of 'test.capi' : unexpected input. (capi.py): (capi.py): hw-part-number-bad (capi.py): ^

If a warning or error occurs, the interface tool always prints an identification line, detailing the tool version number and build date.

Each warning or error message has a unique code which can be referenced in Appendix B, OpenECU error and warning codes, where each message is explained in more detail.

If applicable, the location of the error in the form of either a file-name, or a file-name and line number, is given. Some warnings and errors occur after all input files have been processed, and as there is no specific file-name or line number to refer to, the message will contain a useful reference (e.g., the name of the DDE which caused the message).

The actual warning or error message itself. In this case, the keyword hw-part-number has been modified so that it is no longer a keyword, and the error message shows that the input text is unexpected.

If applicable, the line which caused the problem is shown.

Copyright 2019, Pi Innovo 609 Support tools

If applicable, the point in the line which caused the error is shown. In this case, the keyword which caused the tool to raise the error is highlighted.

If an error occurs then the interface tool does two things:

1. The tool returns with a code signalling failure. This code can be used to stop the build process, for instance, when using make. Stopping the build process ensures that the build of an application does not complete with an incorrect mix of files.

2. The tool attempts to remove any files it created. By removing files, any subsequent process which relies on files from the interface tool will fail, thus ensuring that the build of an application does not complete with an incorrect mix of files. 7.1.4. Interface file contents

The interface file contains a set of statements, with whitespace and comments to aid readability. The format of these statements is explained in the following sections. 7.1.4.1. White space

The interface file can contain whitespace. Space characters, tab characters and so on can be used between and within comments and statements to aid readability. 7.1.4.2. Comments

The interface file may contain comments. A comment starts with /*, ends with */ , and contains arbitrary text and new lines in between. For instance, the following:

target-ecu { /* Specify the M250-000 issue 2 as the target ECU. */ hw-part-number = "01T-068276"; hw-issue-number = 2; hw-option = "000"; }

shows a valid comment on the third line. Comments cannot be nested. For instance, the following:

/* Here is a comment. * * /* Which contains a nested comment when it should not. */ */

would cause the interface tool to raise a syntax error. 7.1.4.3. Numbers

The interface file may contain numbers. A number must range between 0 and 2147483647 inclusive, cannot be negative. The number can be represented as decimal or , as shown here (both major-version and minor-version are assigned 1010):

major-version = 10; minor-version = 0xa;

Decimal numbers must only contain digits ('0' through '9'), hexadecimal numbers may contain digits, lower case 'a' through 'f' and upper case 'A' through 'F'. 7.1.4.4. Identifiers

The interface file may contain identifiers. Identifiers are unique names given to objects so that they can be identified by other parts of the interface file.

Copyright 2019, Pi Innovo 610 Support tools

name = identifier;

Identifiers must be 31 characters or less in length, can contain the '_' character, digit characters, 'a' through 'z' characters and 'A' through 'Z' characters, but cannot start with a digit.

When naming an object, all identifiers must be unique (an error message is reported if a duplicated identifier is found). 7.1.4.5. Strings

The interface tool may contain strings. Strings start and end with a double quote '"' character, and can contain any printable ASCII character from space (ASCII 32) through to tilde (ASCII 126).

description = "string";

7.1.4.6. Statements

The interface file contains a set of statements which describe the interface between the application and library. There are two types of statement:

compound statement These statements contain a group of related statements between an opening and closing brace ({}). For instance:

target-ecu { /* Further assignment and compound statements go here */ }

is a compound statement. A compound statement typically contains at least one assignment or compound statement. Although the braces are shown on separate lines, there is no need to do so — in this case, placing the braces on separate lines aids readability.

assignment statement These statements associate an attribute with a value or string, or a list of values or strings, and end with a semi-colon. For instance:

hw-part-number = "01T-068276";

is an assignment statement.

An interface file can contain the following compound statements:

target-ecu { ... } application { ... } memory-config { ... } can-messaging { ... } ccp-messaging { ... } iso-diagnostics { ... } j1939-messaging { ... } ff-data { ... } dtc-data { ... } pid-data { ... } dte-data { ... } dme-data { ... } adaptives { ... } tunes { ... } ddes { ... }

Copyright 2019, Pi Innovo 611 Support tools

nonvolatile-filesystem { ... } routine-data { ... }

The required target-ecu compound statement groups information about what target ECU the application must be built against. This compound statement is covered in Section 7.1.4.7, “Compound statement: target-ecu” in more detail.

The required application compound statement groups information about the application, its version, name, description, tasks, resources and choice of scheduler. This compound statement is covered in Section 7.1.4.8, “Compound statement: application” in more detail.

The optional memory-config compound statement groups information about memory configuration options. This compound statement is covered in Section 7.1.4.13, “ Compound statement: memory-config ” in more detail.

The optional can-messaging compound statement groups information about CAN messaging. This compound statement is covered in Section 7.1.4.14, “Compound statement: can-messaging” in more detail.

The optional ccp-messaging compound statement groups information about CCP messaging, including the CAN identifiers to be used for CRO and DTO messages, the station identifier, baud rate, and CAN bus. It also configures seed-key security for CCP. This compound statement is covered in Section 7.1.4.15, “Compound statement: ccp- messaging” in more detail.

The optional iso-diagnostics compound statement groups information about ISO 15765-2 based diagnostics over CAN (selected services from J1979 OBD, ISO 14229-1 Unified Diagnostic Services and Keyword Protocol 2000-3). This compound statement is covered in Section 7.1.4.18, “Compound statement: iso-diagnostics” in more detail.

The optional j1939-messaging compound statement groups information about J1939 messaging, including whether J1939 is enabled or not, the network name, preferred network addresses, PGNs to listen for, and so on. This compound statement is covered in Section 7.1.4.19, “Compound statement: j1939-messaging” in more detail.

The optional ff-data compound statement groups information about freeze frames. This compound statement is covered in Section 7.1.4.25, “Compound statement: ff-data” in more detail.

The optional dtc-data compound statement groups information about diagnostic trouble codes (DTCs), including DTC tables. This compound statement is covered in Section 7.1.4.28, “Compound statement: dtc-data” in more detail.

The optional pid-data compound statement groups information about parameters accessed by identifier (PIDs) via ISO diagnostic protocols. This compound statement is covered in Section 7.1.4.30, “Compound statement: pid-data” in more detail.

The optional dte-data compound statement groups information about parameters accessed by In-Use performance ratios via ISO diagnostic protocols. This compound statement is covered in Section 7.1.4.32, “Compound statement: dte-data” in more detail.

The optional dme-data compound statement groups information about parameters accessed by In-Use performance ratios via ISO diagnostic and J1939 protocols. This compound statement is covered in Section 7.1.4.34, “Compound statement: dme-data” in more detail.

The optional adaptives compound statement groups information about non-volatile memory data and how it is to be stored by the target ECU. This compound statement is covered in Section 7.1.4.36, “Compound statement: adaptives” in more detail.

Copyright 2019, Pi Innovo 612 Support tools

The optional tunes compound statement groups information about Tunes, which are RAM based calibrations. Note that Tunes are supported on only a few target ECUs. This compound statement is covered in Section 7.1.4.39, “Compound statement: tunes” in more detail.

The optional ddes compound statement groups information about data dictionary elements (DDEs), including the units and DDE files to process, and whether to automatically generate library DDE (see Section 7.1.7, “Automatic ASAP2 entries”). This compound statement is covered in Section 7.1.4.40, “Compound statement: ddes” in more detail.

The optional nonvolatile-filesystem compound statement groups information related to the non-volatile file system, including maximum write queue size and maximum number of user and platform files. This compound statement is covered in Section 7.1.4.12, “Compound statement: nonvolatile-filesystem” in more detail.

The optional routine-data compound statement groups information about routines accessed by identifier via ISO diagnostic protocols. This compound statement is covered in Section 7.1.4.37, “Compound statement: routine-data” in more detail. 7.1.4.7. Compound statement: target-ecu

The required target-ecu compound statement can contain the following statements:

target-ecu { hw-part-number = string; hw-issue-number = integer; hw-option = string; }

In this case, there are three statements that identify the ECU that the application is to be built and run on. The ECU is identified by its hardware part-number, issue number and option. These items can be found on the label of the ECU. For example, an M250 Developer module might have the following information on its label:

Part No. 01T-068276-000 2m1

The required hw-part-number assignment statement should match the "01T-XXXXXX" part of the text, so here it would be set to 01T-068276.

The required hw-issue-number assignment statement is the number immediately before the "m", so in this example it would be set to 2. (The number after the "m" should always be ignored.) Note that for some modules the issue number is preceded by the letters "iss". These should be ignored: the hw-issue-number must always be a number.

The optional hw-option assignment statement corresponds to the final three characters attached by a hyphen to the hw-part-number text string. In the example this is simply "000". For some modules, these three trailing characters are not present on the label. In that case, the hw-option statement can be omitted. 7.1.4.8. Compound statement: application

The required application compound statement can contain the following statements:

application { major-version = integer; minor-version = integer; subminor-version = integer;

name = string; description = string;

Copyright 2019, Pi Innovo 613 Support tools

copyright = string;

os-native { ... } }

The required major-version , minor-version and subminor-version assignment statements identify the version of the application. The integer for each must be in the range [0, 65535].

The required name, description and copyright assignment statements identify information about the application which is embedded into the interface code and ASAP2 description files.

In the name statement can include tokens which are automatically converted during application build. Tokens are single words starting and ending in the “%” character. For instance, the string “Application for %target%” contains one token named target, which is converted to the target ECU name during a model build. The following table lists the available tokens:

Token Replacement %copyright% Replaced with the string from the copyright statement. %target% Replaced with a string representing the ECU target and option. %ver-major% Replaced with the string from the major-version statement. %ver-minor% Replaced with the string from the minor-version statement. %ver-subminor% Replaced with the string from the subminor-version statement.

The required os-native compound statement identifies that the library will use the OpenECU scheduler (see Section 5.6, “Task scheduling (PKN)” for more). The list of supported schedulers may be extended in the future. The compound statement is covered in Section 7.1.4.9, “Compound statement: os-native” in more detail. 7.1.4.9. Compound statement: os-native

The required os-native compound statement can contain the following statements:

os-native { stack-size = integer; watchdog = library or application; mem-runtime-checks-enabled = true or false;

task { ... } resource { ... } }

The required stack-size assignment statements specify the size of the scheduler's shared stack (Section 5.6.1.3, “Stack sharing”). The integer must be in the range [1024, ..].

The optional watchdog assignment statement can be used to assign responsibility for kicking the watchdog (Section 5.3.1.7, “System watchdog handling”) to the platform or application. If this statement is omitted then responsibility is taken by the platform and the application should not call psc_kick_watchdog().

The optional mem-runtime-checks-enabled assignment statement can be used to disable background memory checks, which are otherwise enabled on most targets. Usually this option should be omitted to allow the memory checks to proceed.

The required task compound statement, which can be repeated, identifies an application task that the library must schedule together with the library's own tasks (see

Copyright 2019, Pi Innovo 614 Support tools

Section 4.6.4, “Application and library tasks”). The compound statement is covered in Section 7.1.4.10, “Compound statement: task” in more detail.

The optional resource compound statement, which can be repeated, identifies a resource and the group of tasks which access that resource (see Section 5.6.1.6, “Resource locking”). The compound statement is covered in Section 7.1.4.11, “Compound statement: resource” in more detail. 7.1.4.10. Compound statement: task

The required task compound statement, which can be repeated up to 12 times, can contain the following statements:

task { name = string; function = identifier; trigger = string;

priority = integer; period = integer; offset = integer; }

The required name assignment statement identifies the name for this task. The task name is referred to in various places throughout the interface file.

The task name must not be repeated in another task compound statement.

The required function assignment statement identifies the C function name for this task. The library calls the function when the task becomes the highest priority task ready to run. The application must implement the C function, to match the prototype:

extern void identifier(void);

The interface tool will generate a warning if the task's function is repeated in another task compound statement. It is the responsibility of the application to ensure that the C function is re-entrant.

The optional trigger assignment statement identifies the cause for making the task ready to run. The trigger-type can be either periodic (meaning the task is made ready to run some many milliseconds since the last time it was made ready to run) or tdc-firing (meaning the task is made ready to run per cylinder event — see Section 5.23, “Angular function feature (PAN)” for more).

If the task is specified as periodic, then the period assignment statement must also be specified.

The required priority assignment statement specifies the priority of this application task relative to other application tasks. The higher the value of the task's priority statement, the higher priority the task has relative to others.

The application tasks fit into a larger priority ordering as given in Section 4.6.4, “Application and library tasks”. The integer must positive.

The value of the task priority must not be repeated in another task compound statement.

The optional period assignment statement specifies the period of the task in milliseconds. The library will make the task ready to run every period millisecond.

If the task trigger is specified as periodic, then the period must be specified.

The integer must be in the range [1, 3600000] milliseconds.

Copyright 2019, Pi Innovo 615 Support tools

The optional offset assignment statement specifies the offset to the task's period in milliseconds. The library will delay the first time the task is made ready to run by offset milliseconds.

The integer must be positive.

If the offset assignment statement isn't given then the interface tool sets the task's offset to zero milliseconds.

The interface tool will generate a warning message if the task's offset is more than twice the task's period in case the offset was mis-specified. 7.1.4.11. Compound statement: resource

The optional resource compound statement, which can be repeated, can contain the following statements:

resource { name = identifier; used-by-task task-list; }

The required name assignment statement gives a name to this resource, which can then be referenced by other parts of the interface file and in the application code.

The resource's name must not be repeated in another resource compound statement.

The required used-by-task assignment statement identifies the tasks which use this resource. The task-list must be the name of one task, or the names of multiple tasks separated by commas. The library will record a fault if any task which was not in the list tried to claim the resource. 7.1.4.12. Compound statement: nonvolatile-filesystem

The optional nonvolatile-filesystem compound statement can contain the following statements:

nonvolatile-filesystem { write-queue-size = integer; max-num-of-user-files = integer; max-num-of-platform-files = integer; }

The write-queue-size assignment statement identifies the maximum number of files allowed in the write queue.

The max-num-of-user-files assignment statement identifies the maximum number of user files that can to be stored.

The max-num-of-platform-files assignment statement identifies the maximum number of platform files that can to be stored.

The interface tool will set this value to a minimum value if the user specifies a number less than that. If the freeze frame feature is supported, this minimum value is 10 plus the sum of the maximum number of freeze frames that may be stored for each freeze frame type: ISO, J1939 DM4 and J1939 DM25. If the freeze frame feature is not supported, the minimum value is 10. 7.1.4.13. Compound statement: memory-config

The optional memory-config compound statement can contain the following statement:

Copyright 2019, Pi Innovo 616 Support tools

memory-config { config-id = identifier; }

The required config-id assignment statement identifies the memory configuration to be used. The different memory configurations are designated by a letter, and should be written in the format config-a for configuration A, and so on. See Appendix D, Memory configurations for details of the memory configurations available for different targets.

Note

Different linker files are required for different memory configurations. See -- output-linker-file=FILE for a command line option that generates the correct linker file automatically based on the config-id identifier and other information gleaned from the interface file.

7.1.4.14. Compound statement: can-messaging

The optional can-messaging compound statement can contain the following statements:

can-messaging { number-of-receive-messages = integer; number-of-transmit-messages = integer; }

The optional number-of-receive-messages and number-of-transmit-messages assignment statements identify the number of receive and transmit messages the library will handle (see Section 5.15, “CAN messaging feature (PCX)” for more).

The interface tool will adjust the number of receive and transmit messages given here if CCP and J1939 messaging requires additional messages.

The integer for each statement must be in the range [0, 100].

If the number-of-receive-messages assignment statement is not given then the interface tool assumes zero receive messages. Similarly for the number of transmit messages. 7.1.4.15. Compound statement: ccp-messaging

The optional ccp-messaging compound statement can contain the following statements:

ccp-messaging { enabled-during-application-mode = boolean;

cro = integer; cro-ext-id = boolean; dto = integer; dto-ext-id = boolean;

station-address = integer;

can-bus = integer; baud = integer;

raster { ... }

security-dev-mode = boolean;

security { ... } }

Copyright 2019, Pi Innovo 617 Support tools

The optional enabled-during-application-mode assignment statement identifies whether CCP communications is enabled during application mode or not (see Section 4.3, “System modes” for more on system modes and Section 5.16, “CAN Calibration Protocol (CCP) messaging feature (PCP)” for more on CCP).

If the enabled-during-application-mode statement is not given then the interface tool assumes CCP is enabled during application mode.

The optional cro and dto assignment statements identify the CAN identifiers to be used for CCP communication with the PC based tool (see Section 5.16.1.1, “Messaging”).

The integer for each statement must be in the range [0, 2047] (or the range [0, 536870911] when in extended ID mode). The integers must not be equal.

If the cro assignment statement is not given then the interface tool assumes a CAN identifier of 1785. If the dto assignment statement is not given then the interface tool assumes a CAN identifier of 1784. The values match the default CCP settings (Table 4.2, “CCP defaults”).

The optional cro-ext-id and dto-ext-id assignment statements configure the cro and dto to use extened 29 bit identifiers, respectively. If either of these values are not provided, they will default to false.

The optional station-address assignment statement identifies the CCP station address of the ECU. Multiple ECUs can use the same CRO and DTO CAN identifiers so long as each has a unique station address.

The integer value of the statement must be in the range [0, 255].

If the station-address assignment statement is not given then the interface tool assumes a value of zero (matching the default CCP settings from Table 4.2, “CCP defaults”).

The optional can-bus assignment statement identifies the CAN bus to use for CCP messaging.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 7.1.4.7, “Compound statement: target- ecu”).

If the can-bus assignment statement is not given then the interface tool assumes the first CAN bus will be used.

The optional baud assignment statement identifies the baud rate in kBps of the CAN bus to use for CCP messaging during reprogramming mode. The baud rate of the CAN bus during application mode is controlled by the application code.

The integer for the statement must be one of: 1000, 500, 250, 125, 100, 83 (corresponding to 83.333 kBps), 62 (corresponding to 62.5 kBps), 50, 33 (corresponding to 33.333 kBps).

If the baud assignment statement is not given then the interface tool assumes a baud rate of 500 kBps.

The optional raster compound statement allows the application to vary the size and transmission rate of ECU DAQ rasters.

Note

If there are no raster statements then the following default configuration is applied.

Copyright 2019, Pi Innovo 618 Support tools

M110, M550, M220, M670 M221, M250, M460, M461 Rate (milliseconds) Size Size 10 15 30 100 15 30 200 15 30 1000 15 30

The security-dev-mode statement specifies whether the reprogramming security function is in development. This statement is optional and defaults to false. If the statement is present and assigned a value of true, then all CCP security functions will be ignored by the firmware when the ECU is power cycled with the FEPS voltage applied.

This statement allows a security algorithm to be tested without the risk of putting the ECU in a state where it cannot be reprogrammed. Otherwise, an error in the security algorithm will necessitate returning the ECU to Pi for servicing.

The optional security compound statement specifies the security required to carry out CCP actions. Permission to carry out CCP actions is known in CCP terminology as privilege levels. Current CCP privilege levels are calibration, data acquisition and programming. This statement may appear more than once to configure security separately for each privilege level. If security is not explicitly specified for a privilege level, that privilege level defaults to requiring no security (and therefore if this statement is never used then no CCP actions will require security).

No checks are carried out to ensure that the same CCP privilege level is not specified in more than one security statement. If this occurs, the application will only use the details from the first security statement encountered which specifies the required privilege level. It will ignore any subsequent security statements. 7.1.4.16. Compound statement: raster

The optional raster compound statement can contain the following statements:

raster { name = string; description = string; size = integer; rate = integer; }

The required name assignment statement is a unique name for the CCP DAQ raster. The name is written to the ASAP2 file and used by the calibration tool to identify the raster.

The required desc assignment statement is a description of the CCP DAQ raster's use.

The required size assignment statement gives the number of ODTs for the CCP DAQ raster. The total number of ODTs across raster statements must not exceed the range

Copyright 2019, Pi Innovo 619 Support tools

given below. For instance, on the M550 and M670, it is permissible to have two raster statements each with a size of 127. But adding a third raster statement with a size of 1 brings the total to 255, which exceeds the limit.

Range: [1, 254]

The required rate assignment statement is the suggested period between transmission of the CCP DAQ raster. Some calibration tools will use the suggested period (e.g., INCA) whilst other calibration tools will ignore the suggest period and allow the user to vary the transmission rate on the fly (e.g., Vision). One of 0.005, 0.010, 0.030, 0.050, 0.100, 0.200, 0.500, 1.000 seconds. 7.1.4.17. Compound statement: security

The optional security compound statement can contain the following statements:

security { privilege-level = identifiers; security-required = boolean; ecu-seed-generation-function = string; ecu-key-validation-function = string; asap-dll-file = string; asap-key-generation-function = string; }

The privilege-level statement specifies the privilege level(s) for which the following security specifiers are to be applied. This is a comma-separated list of one or more of the following:

Table 7.1. CCP privilege levels

Privilege levels calibration data_acquisition programming

If a security statement exists, a privilege-level statement is compulsory within that security statement.

The security-required statement specifies whether security is required for the specified privilege level(s). This must be set to False if no security is required for a privilege level, or to True if security is required.

If a security statement exists, a security-required statement is compulsory within that security statement.

The ecu-seed-generation-function statement identifies the C function which will be called when a seed is requested for unlocking the specified privilege level. This is optional; if omitted, the platform will automatically generate a random 32-bit seed value.

If specified, the application must implement the C function, to match the prototype defined by PCP_SEED_GENERATOR_T. See Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for further details relating to how these functions must be implemented.

The ecu-key-validation-function statement identifies the C function which will be called when a key is passed to attempt to unlock the specified privilege level. If security-

Copyright 2019, Pi Innovo 620 Support tools

required has been set to True for this privilege level, a key validation function must be specified, otherwise an error will be reported.

If specified, the application must implement the C function, to match the prototype defined by PCP_KEY_VALIDATOR_T. See Section 5.16.1.4.1, “Specifying functions for use with CCP seed/key security” for further details relating to how these functions must be implemented.

The asap-dll-file statement identifies the ASAP1-standard DLL which will be used by the calibration tool to provide the key generation function for the specified privilege level. This is optional, and is used only when generating ASAP2 files for use by the calibration tool. If the user does not require ASAP2 files, or if the user will be configuring the calibration tool by hand to identify this DLL, it may be omitted.

The asap-key-generation-function statement identifies the C function within the above DLL which will be used by the calibration tool to provide key generation for the specified privilege level. This is optional. ASAP1 specifies that the function name must be ASAP1A_CCP_ComputeKeyFromSeed, and this function name will be used as the default if the statement is omitted.

The ability to specify this function name is currently only supported by the ATI Vision calibration tool. This option should therefore be used with caution in case support for other calibration tools is required. 7.1.4.18. Compound statement: iso-diagnostics

The optional iso-diagnostics compound statement can contain the following statements:

iso-diagnostics { can-bus = integer;

can-rx-id = integer; can-func-rx-id = integer; can-tx-id = integer;

can-rx-id-extd = true or false; can-tx-id-extd = true or false;

size-of-rx-buffer = integer; size-of-tx-buffer = integer;

emissions-report-min-severity = emissions-severity;

general-callback = true or false; id-request-callback = true or false;

use-security-fn = true or false;

flash-allowed = without-security, any-security-level, specified-security-levels or never; flash-security-levels = integer or comma-separated list of integers;

mem-read-allowed = without-security, any-security-level, specified-security-levels or never; mem-read-security-levels = integer or comma-separated list of integers;

max-num-of-uds-periodic-id = integer; uds-periodic-id-base-period-ms = integer; max-num-of-uds-dynamically-defined-id = integer;

active-session-iso-16bit-id = integer; active-session-kwp-8bit-id = integer;

mem-read-ok-def-session = true or false; mem-read-ok-extd-session = true or false; mem-read-ok-prog-session = true or false;

Copyright 2019, Pi Innovo 621 Support tools

service-03-dtcs = no-override | report-active-and-prev-active; service-07-dtcs = no-override | report-pending-and-active; service-0a-dtcs = no-override | report-active-and-prev-active;

uds-dtc-format-id = j2012, uds, iso11992, j1939 or wwh;

extd-data-dc-since-failed-rec-num = none | integer; extd-data-failed-dc-count-rec-num = none | integer; extd-data-occurrence-count-rec-num = none | integer; extd-data-time-active-rec-num = none | integer; extd-data-time-prev-active-rec-num = none | integer; extd-data-time-until-derate-rec-num = none | integer; extd-data-wu-since-failed-rec-num = none | integer; extd-data-time-engine-running-rec-num = none | integer;

}

The optional can-bus assignment statement identifies the CAN bus to use for ISO diagnostics.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 7.1.4.7, “Compound statement: target- ecu”). The baud rate of the CAN bus is specified by the application code.

If the can-bus assignment statement is not given then the interface tool assumes the first CAN bus will be used.

The required can-rx-id, can-func-rx-id and can-tx-id assignment statements identify the CAN identifiers to be used for ISO diagnostic communications with the external tool.

The integer for each statement must be in the range [0, 2047] for standard (11 bit) CAN identifiers or [0,536870911] for extended (29 bit) CAN identifiers. The integers must not be equal.

If these statements are not present, then ISO diagnostic support is disabled.

The optional can-rx-id-extd and can-tx-id-extd assignment statements specify whether extended (29 bit) format CAN identifiers are to be used instead of the default 11 bit format identifiers for ISO diagnostic communications. It is possible to transmit using an 11 bit identifier and receive using a 29 bit identifier and vice versa.

Allowed values are true or false.

The optional size-of-rx-buffer and size-of-tx-buffer assignment statements specify how large (in bytes) the space reserved for the longest diagnostic request message and response message respectively. If omitted, a default is used.

The integer for each statement must be in the range [1, 4095].

Applications which need to support the transmission of a long list of supported DTCs will need a large transmit buffer. Applications which need to accept a long series of inputOutputControlByIdentifier bytes to override a PID value will need a large receive buffer. Otherwise, smaller values can be used to save RAM.

The optional emissions-report-min-severity assignment statement specifies the severity level at (or above) which DTCs will be reported by J1939/DM32 and all J1979/ISO 15031 emissions-related services.

The value of emissions-severity must be one of sev-a (highest), sev-b1, sev-b2, sev-c, or sev-none (lowest). If omitted, sev-c is used by default. To emit all DTCs regardless of their emissions severity level, use sev-none.

The optional general-callback statement specifies whether the application is providing a callback function (which must be named psc_diag_general_callback) to

Copyright 2019, Pi Innovo 622 Support tools

handle custom processing of diagnostic message responses. For details see type PDG_GENERAL_CALLBACK_FN_T.

If omitted, a default of false is used.

The optional id-request-callback statement specifies whether the application is providing a callback function (which must be named psc_diag_id_request_callback) to handle custom generation of PID values on request. For details see type PDG_ID_REQUEST_CALLBACK_FN_T.

If omitted, a default of false is used.

The optional use-security-fn statement specifies whether the application is providing a custom security algorithm to handle seed generation and key validation via the SecurityAccess ($27) service. Whether security has passed can then be used to control access to sensitive services such as flash reprogramming or ReadMemoryByAddress.

If used the function must be named psc_diag_security_callback and be followed immediately by a function named psc_diag_security_end. See types PDG_SECURITY_CALLBACK_FN_T and PDG_SECURITY_END_FN_T for more details. Also, an example function is provided below in this section.

If omitted, a default of false is used.

The optional flash-allowed statement specifies the circumstances under which ISO 14229-1 (UDS) flash reprogramming is allowed by your application. This setting is stored in non-volatile memory and applies even after the current application is erased, until replaced by a new application with its own setting.

The options are as follows:

without-security Always allowed, and no SecurityAccess exchange is required first.

any-security-level Allowed if a SecurityAccess seed-key exchange has been passed successfully, but it does not matter which security level (LEV_SAT_RSD in the UDS standard) was negotiated.

specified-security-levels Only allowed if a SecurityAccess seed-key exchange has been passed successfully, and the security level (LEV_SAT_RSD in the UDS standard) was negotiated is one specified in the list (flash-security-levels option).

never Never allowed, regardless of SecurityAccess exchanges.

For selective run-time control of UDS reprogramming, see also pdg_inhibit_reprogramming().

If omitted, a default of never is normally used. However, if the deprecated allow-reflash = true option is used, use-security-fn = true implies any-security-level and use-security- fn = false implies without-security.

The optional flash-security-levels statement is only relevant if flash-allowed = specified- security-levels has been specified. Specify one or more values of the seed-key security level (LEV_SAT_RSD in the UDS standard) at which flash programming should be permitted. The levels must be odd values as used in the requestSeed request. (The corresponding level in the sendKey message is an even number equal to LEV_SAT_RSD + 1.)

Copyright 2019, Pi Innovo 623 Support tools

Range: [1, 125]

The optional mem-read-allowed statement is very similar to the flash-allowed option described in detail above, but this time controls access to ECU memory via the ReadMemoryByAddress service ($23).

The deprecated option mem-read-needs-security is still supported for backwards compatibility; true implies any-security-level and false implies without-security.

Otherwise, if not specified, a default of never is assumed.

The optional mem-read-security-levels statement is very similar to the flash- security-levels statement described in detail above, but this time relevant to ReadMemoryByAddress.

The deprecated mem-read-needs-security option maps to without-security if set false or any-security-level if set true.

PIDs for automatic periodic sending must be in the 0xF2nn identifier range. Of those, the optional max-num-of-uds-periodic-id parameter is the maximum number that the platform will allow to be simultaneously requested by the test tool for automatic periodic transmission while the application is running via UDS service $2A.

If omitted, this defaults to zero.

The integer for this statement must be in the range [0, 254].

The optional uds-periodic-id-base-period-ms parameter is the "fast" target rate for PIDs requested for automatic transmission via UDS service $2A in milliseconds. The "medium" rate is 2x this period, and the "slow" rate is 4x this period. The platform will send PIDs more slowly than the target rate if this target cannot be met due to the PID size and transport protocol delays.

The integer for this statement must be in the range [20, 65530].

The optional max-num-of-uds-dynamically-defined-id parameter defines the number of internal buffer slots allocated for the construction of dynamically-defined PIDs via UDS service $2C. If necessary one large PID definition may straddle several internal buffers.

If omitted, this defaults to zero.

The integer for this statement must be in the range [0, 255].

The optional active-session-iso-16bit-id assignment statement, if used, defines a PID which will be emitted in response to a ReadDataBy[Common]Identifier (service $22) request in both application mode and during reprogramming (boot loader mode).

The value emitted identifies the active diagnostic session using the same values as the pdg_get_active_session_type() function.

The integer for this statement must be in the range [0, 65535].

The optional active-session-kwp-8bit-id assignment statement, if used, similarly defines a Keyword Protocol 2000-3 LocalIdentifier which will be emitted in response to a ReadDataByLocalIdentifier (service $21) request to indicate the current session type.

The integer for this statement must be in the range [0, 255].

The optional mem-read-ok-def-session , mem-read-ok-extd-session and mem-read- ok-prog-session assignment statements control whether the ReadMemoryByAddress (service $23) service is permitted in the default, extended and programming session

Copyright 2019, Pi Innovo 624 Support tools

respectively. As this service permits access to the code and calibration areas of memory, it is disabled in all session types by default.

The optional service-03-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Active DTCs (service $03) request. If omitted, no override of the standard J1979 service $03 response will be applied.

The value for this statement must be one of no-override (default) or report-active-and- prev-active (transmit Active and Previously Active DTCs).

The optional service-07-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Pending DTCs (service $07) request. If omitted, no override of the standard J1979 service $07 response will be applied.

The value for this statement must be one of no-override (default) or report-pending-and- active (transmit Pending and Active DTCs).

The optional service-0a-dtcs assignment statement, if used, defines the override to be applied to the response to a Read Emission Related Active DTCs with Permanent Status (service $0A) request. If omitted, no override of the standard J1979 service $0A response will be applied.

The value for this statement must be one of no-override (default) or report-active-and- prev-active (transmit Active and Previously Active DTCs).

The optional uds-dtc-format-id assignment statement defines the value of the DTCFormatIdentifier field output in UDS service $19 "NumberOfDTC" responses. This conveys to the test tool the scheme the application designer has followed when allocating 24-bit DTC identifiers. One of the following values will be output, depending on the option specified here:

Table 7.2. UDS DTCFormatIdentifier options

Option Byte value output Description j2012 0 SAE J2012/ISO 15031-6 (the default) uds 1 ISO 14229-1 (UDS) j1939 2 SAE J1939-73 iso11992 3 ISO 11992-4 wwh 4 ISO 27145-2 (Worldwide Harmonized OBD)

Regardless of the option chosen, the platform outputs a 24-bit identifier for each DTC consisting of the most significant 16 bit "ISO" identifier (also used in J1979 or Keyword Protocol 2000-3 reporting) and the least significant "failure type byte" selected for that DTC. In particular the DTC's J1939 SPN and FMI are not currently used in UDS $19 responses, even if the J1939 format option is chosen for this parameter.

The optional DTC extended data record assignment statements, if used, define the extended data record numbers to be applied to the response of a read DTC information (service $19) request to read DTC extended data (sub-function $06).

extd-data-dc-since-failed-rec-num The specified record number reports the one byte record containing the number of drive cycles since the last test failure. The record is only available when the DTC is active.

Copyright 2019, Pi Innovo 625 Support tools

extd-data-failed-dc-count-rec-num The specified record number reports the one byte record containing the number of drive cycles in which the test has failed. The record is only available when the DTC is pending.

extd-data-occurrence-count-rec-num The specified record number reports the one byte record containing the DTC occurrence count.

extd-data-time-active-rec-num The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the DTC has been in the active state.

extd-data-time-engine-running-rec-num The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the engine has been running while the DTC's fault has not been present and the DTC has been in the 'active' or 'previously active' state.

extd-data-time-prev-active-rec-num The specified record number reports the two byte record containing the total time (resolution 0.2hr/bit) that the DTC has been in the previously active state.

extd-data-time-until-derate-rec-num The specified record number reports the two byte record containing total time (resolution 1min/bit) left until derate will occur. The record is only available while the DTC is in the active state and the DTC attribute 'has-torque-derate' is true.

extd-data-wu-since-failed-rec-num The specified record number reports the two byte record containing the number of warm-up cycles in which the fault is not present. It is reset upon the DTC state transition to previously active.

The values used for these statements must be none (default) or an integer in the range [1,239] 7.1.4.18.1. Notes on seed-key function

You must implement your own security function to use seed-key security; it is not supplied by Pi Innovo, because it will be specific and confidential to you. The function must be written such that it does not depend on any statically allocated variables and does not call any functions, including functions inserted by the compiler for maths utilities for example. This is to ensure that it is fully relocatable, which is required for it to run as part of the boot loader in reprogramming mode, as well as in normal application mode.

Your algorithm may be implemented in C for compilation during your application build. It does not matter which source file it is in.

Alternatively, you can compile your C code to make an object (.o) file and link it with the other object files generated in your build. This is useful if you wish to be cautious with confidentiality by avoiding application-builders needing to have the C source code available.

The function name for the security algorithm and the second empty function that marks the end of it are fixed. If they are missing, a linker error will be reported. A complete example block of code is presented below, in which the "secret" algorithm is to reverse the order of the two seed bytes to form the correct key:

#include "openecu.h"

/***************************************************************************** * Purpose: Called by the library when UDS/KW2000 diagnostic security access

Copyright 2019, Pi Innovo 626 Support tools

* is required. * Returns: Return code to send to tool on error, otherwise zero if OK. * Notes: Code is copied to nonvolatile memory and must be relocatable. It * must not call any functions (including compiler arithmetic * utilities). ***************************************************************************** */ U8 psc_diag_security_callback ( const U8* pdgf_request_message, /* The received unpacked request message */ U16 pdgf_request_message_len, /* Total byte length of request message */ U8* pdgf_seed_buffer, /* Place seed here, or access it when computing correct key */ U8* pdgf_seed_len, /* Specify your seed length (in bytes) here (max 8 bytes) */ U32 pdgf_random /* Pseudorandom number you may use to generate seed */ ) {

if (pdgf_request_message_len < 2) { return 0x13; /* invalid length */ }

switch (pdgf_request_message[1]) { case 0x03: /* a requestSeed value we choose to support */ /* Set up the seed bytes, here using the provided random number */ pdgf_seed_buffer[0] = (U8) pdgf_random & 0xff; pdgf_seed_buffer[1] = (U8) (pdgf_random >> 8); *pdgf_seed_len = 2; return 0; break; case 0x04: /* corresponding sendKey value */ if ((pdgf_request_message_len == 4) && (pdgf_request_message[2] == pdgf_seed_buffer[1]) && (pdgf_request_message[3] == pdgf_seed_buffer[0]) ) { /* security passed -- bytes reversed! */ return 0; } else { return 0x35; /* invalid key */ } break; default: return 0x12; /* unsupported parameters */ break; } }

/***************************************************************************** * Purpose: Marks the end of the security function above. * Returns: None. * Notes: Must be placed immediately after the security function. The * platform uses this to calculate the size of the security function * when relocating it to non-volatile memory for use in * reprogramming mode. ***************************************************************************** */ void psc_diag_security_end ( void ) { }

7.1.4.19. Compound statement: j1939-messaging

The optional j1939-messaging compound statement can contain the following statements:

j1939-messaging { enabled = true or false; can-bus = integer;

size-of-message-buffer = integer; num-simultaneous-tx = integer; num-simultaneous-rx = integer; num-rx-tx = integer;

Copyright 2019, Pi Innovo 627 Support tools

listen-for-dm1-message address-list; listen-for-dm2-message address-list; dm7-req-buf-size = integer; multiframe-priority = integer;

this-node { ... } pgn-receive { ... } pgn-requested { ... } aecd-data { ... } }

The optional enabled assignment statement identifies whether J1939 communications is enabled during application mode or not (see Section 4.3, “System modes” for more on system modes and Section 5.17, “J1939 (SAE) messaging feature (PJ1939)” for more on J1939).

If the enabled statement is not given then the interface tool assumes J1939 is disabled during application mode.

The optional can-bus assignment statement identifies the CAN bus to use for J1939 messaging.

The integer for the statement must be for a supported CAN bus for the target specified in the target-ecu compound statement (Section 7.1.4.7, “Compound statement: target- ecu”). The baud rate of the CAN bus is specified by the application code.

If the can-bus assignment statement is not given then the interface tool assumes the first CAN bus will be used.

The optional size-of-message-buffer assignment statement identifies the maximum size of any J1939 message the library will need to receive or transmit for the application. It's provided to help adjust the memory footprint of the library if necessary.

The integer for the statement must be in the range [8, 1785] bytes.

If the size-of-message-buffer assignment statement is not given then the interface tool assumes a buffer size of 1785 bytes.

The optional num-simultaneous-tx and num-simultaneous-rx assignment statements identify the number of simultaneous transmit and receive buffers the library will process. They statements are provided to help adjust the memory footprint of the library if necessary.

The integer for each statement must be in the range [1, 20] buffers.

If the num-simultaneous-tx statement is not given then the interface tool assumes there is one transmit buffer. Similarly for the num-simultaneous-rx statement.

The optional num-rx-tx assignment statement identifies the number of message buffers assigned for J1939 reception and transmission. The statement is provided to help adjust the memory footprint of the library if necessary.

The integer for the statement must be in the range [1, 100] buffers.

If the num-rx-tx assignment statement is not given then the interface tool assumes one buffer.

The optional listen-for-dm1-message and listen-for-dm2-message assignment statements identify the addresses of J1939 nodes which transmit DM1 and DM2 messages that the library must receive for the application. In each statement, the address-list must be a single address, or set of addresses separated by a comma.

Copyright 2019, Pi Innovo 628 Support tools

The address-list values for the statement must be in the range [0, 253].

If the listen-for-dm1-message statement is not given then the interface tool assumes an empty list of addresses. Similarly for the listen-for-dm2-message statement.

The optional dm7-req-buf-size assignment statement identifies the number of Test or SPN requests recieved via DM7 that are to be buffered/ queued.

The integer for the statement must be in the range [1, 10].

If the num-rx-tx assignment statement is not given then the interface tool assumes one test will be queued.

The optional multiframe-priority assignment statement allows the priority for all multi- frame J1939 diagnostic messages (DMs) to be overridden with the value provided. If this statement is absent, the priority for single-frame and multi-frame messages alike is set by the argument passed in the C-API function for that DM. (See Section 5.17.8, “Core Diagnostic messages” for information on these functions.) If this statement is present, however, that function argument only defines the priority for single-frame messages. Note that the generic PG transmit function pj1939_pg_transmit() is unaffected by this, since it transmits only fixed length messages anyway.

The integer for the statement must be in the range [0, 7].

The required this-node compound statement identifies the node name and node address for the J1939 network. The compound statement is covered in Section 7.1.4.20, “Compound statement: this-node” in more detail.

The optional pgn-receive compound statement, which can be repeated, identifies a PGN that the library must receive and present to the application code. The compound statement is covered in Section 7.1.4.21, “Compound statement: pgn_receive” in more detail.

The optional pgn-requested compound statement, which can be repeated, identifies a PGN that another J1939 node may request from the ECU. The library buffers the request information for these PGNs and presents the information to the application. The compound statement is covered in Section 7.1.4.22, “Compound statement: pgn_requested” in more detail.

The optional aecd-data compound statement, identifies the set of EI-AECDs that the application supports. The compound statement is covered in Section 7.1.4.23, “Compound statement: aecd-data” in more detail. 7.1.4.20. Compound statement: this-node

The required this-node compound statement can contain the following statements:

this-node { address = integer;

industry-group = integer; vehicle-system-instance = integer; vehicle-system = integer; function = integer; function-instance = integer; ecu-instance = integer; manufacturer-code = integer; identity-number = integer; }

The required address assignment statement identifies the preferred network address for the ECU. The library will attempt to claim this address according to SAE J1939/81.

Copyright 2019, Pi Innovo 629 Support tools

The automatically generated calibration parameter for this is pj1939c_node_addr_0.

The integer for the statement must be in the range [0, 253].

The required industry-group, vehicle-system-instance, vehicle-system, function, function-instance, ecu-instance, manufacturer-code and identity-number assignment statements identify the unique 64-bit name for the ECU on the J1939 network.

The acceptable value range of each statement is given in Table 7.3, “Value ranges for J1939 name statements”.

Table 7.3. Value ranges for J1939 name statements

Statement Range industry-group [0, 7] vehicle-system-instance [0, 15] vehicle-system [0, 127] function [0, 255] function-instance [0, 31] ecu-instance [0, 7] manufacturer-code [0, 2047] identity-number [0, 2097151] 7.1.4.21. Compound statement: pgn_receive

The optional pgn_receive compound statement, which can be repeated, can contain the following statements:

pgn_receive { pdu-datapage = integer; pdu-format = integer; pdu-specific = integer;

size = integer; }

The required pdu-datapage, pdu-format and pdu-specific assignment statements identify the 17-bit parameter group number for the J1939 message the library will receive and buffer for the application.

The acceptable value range of each statement is given in Table 7.4, “Value ranges for J1939 PDUs”.

Table 7.4. Value ranges for J1939 PDUs

Statement Range pdu-datapage [0, 1] pdu-format [0, 255] pdu-specific [0, 255]

The PDU of the message must not be repeated in another pgn-receive compound statement.

The pdu-specific value must be zero if the pdu-format value is less than 240.

Copyright 2019, Pi Innovo 630 Support tools

The required size assignment statement identifies the expected length of the PG message.

The integer for the statement must be in the range [0, size-of-message-buffer], where size-of-message-buffer is specified in the j1939-messaging compound statement (see Section 7.1.4.19, “Compound statement: j1939-messaging”). 7.1.4.22. Compound statement: pgn_requested

The optional pgn_requested compound statement, which can be repeated, can contain the following statements:

pgn_requested { pdu-datapage = integer; pdu-format = integer; pdu-specific = integer; }

The required pdu-datapage, pdu-format and pdu-specific assignment statements identify the 17-bit parameter group number for the J1939 message the library will note as being requested for the application.

The acceptable value range of each statement is given in Table 7.4, “Value ranges for J1939 PDUs”.

The PDU of the message must not be repeated in another pgn-requested compound statement.

The pdu-specific value must be zero if the pdu-format value is less than 240. 7.1.4.23. Compound statement: aecd-data

The optional aecd-data compound statement can contain the following statements:

aecd-data { aecd { ... } aecd { ... } }

Each aecd compound statement identifies an Emission Increasing Auxiliary Emission Control Device (EI-AECD). The compound statement is covered in Section 7.1.4.24, “Compound statement: aecd” in more detail. 7.1.4.24. Compound statement: aecd

The aecd compound statement, which can be repeated, can contain the following statements:

aecd { name = identifier; aecd-number = integer; }

The required name assignment statement identifies the AECD uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the AECD.

An error is raised if a duplicate AECD name is found.

The required aecd-number assignment statement identifies the AECD number uniquely.

An error is raised if a duplicate AECD number is found.

Copyright 2019, Pi Innovo 631 Support tools

7.1.4.25. Compound statement: ff-data

The optional ff-data compound statement can contain the following statements:

ff-data { nvm-allocation-bytes = integer; ram-allocation-bytes = integer; max-num-of-j1979-ff = integer; max-num-of-j1939-dm4-ff = integer; max-num-of-j1939-dm25-ff = integer; max-num-of-uds-snapshot-ff = integer; num-of-j1939-dm25-ff-spns = integer; j1939-dm25-ff-name = identifier; ff-store-by-dtc-severity = true or false;

freeze-frame { ... } freeze-frame { ... } }

The required nvm-allocation-bytes assignment statement specifies the total number of bytes allocated to freeze frame storage in non-volatile memory.

Each freeze frame is stored in a separate file using the PFS file system. In addition to the stored freeze frame data, there is a maximum of 27 bytes of overhead associated with each stored file. This overhead contributes to the freeze frame allocation in NVM.

An appropriate NVM limit should be selected to meet the needs of the application taking into consideration freeze frame file sizes and the number of freeze frames that may be stored. A description of the data stored for each freeze frame type is provided in Section 6.7.4, “Freeze Frame feature (PFF)”.

The integer for the statement must be in the range [0, 65535] bytes.

The required ram-allocation-bytes assignment statement specifies the size (in bytes) of a RAM buffer used to hold snapshots of freeze frames prior to writing to non-volatile memory.

In addition to the freeze frame data, for each freeze frame held in this buffer an additional 4 bytes of information is also held for the purpose of file storage. Thus, when setting the size of the freeze frame RAM buffer, it must at least be equal to the size of the largest freeze frame's data (in bytes) plus 4 bytes. If multiple freeze frames are to be captured on activation of the same DTC then the buffer must be large enough to hold the freeze frame data of all the DTC's associated freeze frames, plus storage data for each. The RAM allocation should also be enough to take immediate snapshots of all possible freeze frames associated with all DTCs that may occur in very quick succession; so no information is lost while the data is then written to NVM (which happens within a few seconds).

Note: freeze frames are stored at the rate of 8 bytes every 10 ms and freeze frame data is only removed from the buffer once it has been successfully stored in NVM. As a result, if multiple DTCs become active in quick succession, the buffer may become filled and the data of subsequent freeze frames may be lost. In this case, the likelihood of a particular DTCs freeze frame being captured will not just depend upon the order in which each fault actually occurred, but also on the rate at which the application processes each of the DTCs in question.

The integer for the statement must be in the range [0, 8191] bytes.

The optional max-num-of-j1979-ff assignment statement specifies the upper limit to the number of J1979 freeze frame instances that can be stored in non-volatile memory.

Copyright 2019, Pi Innovo 632 Support tools

The integer for the statement must be in the range [0, 254].

The optional max-num-of-j1939-dm4-ff assignment statement specifies the upper limit to the number of J1939 DM4 freeze frame instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 137].

The optional max-num-of-j1939-dm25-ff assignment statement specifies the upper limit to the number of J1939 expanded freeze frame (DM25) instances that can be stored in non-volatile memory.

The integer for the statement must be in the range [0, 254].

The optional max-num-of-uds-snapshot-ff assignment statement specifies the upper limit to the number of ISO 14229-1 (UDS) snapshot instances that can be stored in non- volatile memory.

The integer for the statement must be in the range [0, 254].

The optional num-of-j1939-dm25-ff-spns assignment statement specifies the number of SPNs that will be included in a J1939 expanded freeze frame (DM25).

The integer for the statement must be in the range [0, 255].

The optional j1939-dm25-ff-name assignment statement identifies the calibration vector used to define the the SPNs that are included in a J1939 expanded freeze frame (DM25).

The string identifier must follow the naming convention defined in Section 7.1.5.2, “DDE naming rules (prefix_style)”.

The optional ff-store-by-dtc-severity assignment statement specifies if freeze frames corresponding to DTCs of lower emissions severity must be deleted in order to make space for latest freeze frames of higher severity.

When set to true the platform shall attempt to delete freeze frames corresponding to DTCs of lower emissions severity in order to make space for latest freeze frames of higher severity. If omitted or set to false, latest freeze frames will be discarded if there is no space to store them.

The optional freeze-frame compound statement groups information about freeze frames. This compound statement is covered in Section 7.1.4.26, “Compound statement: freeze-frame” in more detail.

Note: prior to flashing a module after changing any of the above parameters, all DTCs must first be cleared. This will result in all freeze frame data being deleted. This is because freeze frame data is not deleted as a result of re-flashing the module. This means that the stored freeze frame data from a previous version of the application code may negatively affect the operation of freeze frames in the new version of the code, for example by taking up space in NVM. 7.1.4.26. Compound statement: freeze-frame

The optional freeze-frame compound statement, which can be repeated, can contain the following statements:

freeze-frame { name = identifier; protocol { ... } protocol { ... } protocol { ... }

Copyright 2019, Pi Innovo 633 Support tools

}

The required name assignment statement identifies a 'set' of freeze frames uniquely at the application code level. A PFF_FF_CONST_T data structure identified using this name is provided to the application. The code identifier consists of the name prefixed with "pff_".

A freeze frame 'set' may contain 1 to 4 freeze frames. Each freeze frame in a set must be of a different type, e.g. J1979, UDS snapshot, J1939-DM4 or J1939-DM25.

The placeholder identifies the diagnostic standard that a freeze frame in the set adheres to. Replace with one of the supported standards which are:

• j1979 • j1939 • uds

Specifying a diagnostic standard is a required statement.

The protocol compound statement groups information about a freeze frame. This compound statement is covered in Section 7.1.4.27, “Compound statement: protocol” in more detail. 7.1.4.27. Compound statement: protocol

The protocol compound statement can contain the following statements:

protocol { type = ; dde-entry = vector; length = integer; }

Some diagnostic standards may support multiple types of freeze frame. The J1939 diagnostic standard supports two types of freeze frame: Freeze Frame Parameters (DM4) and Expanded Freeze Frames (DM25). The placeholder identifies the freeze frame type within a diagnostic standard which the freeze frame adheres to. Replace with one of the supported freeze frame types which are:

• dm4 • dm25

The platform currently supports a single UDS freeze frame type, but the type identifier is required to promote application compatibility with future versions of the platform. Supported UDS freeze frame types:

• snapshot

Specifying a freeze frame type is only required for J1939 and UDS. It should be omitted for J1979.

The required dde-entry assignment statement identifies the vector entry in the DDE (see Section 7.1.5, “DDE specification”) which lists the parameter identifiers. Using a calibration vector allows the parameters in the list to be re-calibrated at run-time.

The calibration vector must contain U8s for J1979 freeze frames U16s for UDS snapshot freeze frames and U32s for J1939 DM4 freeze frames.

This field is not required for DM25, as DM25 requires only one list.

Copyright 2019, Pi Innovo 634 Support tools

The required length assignment statement identifies the number of parameters in the parameter list. This has a maximum value of 255.

This field is not required for DM25. 7.1.4.28. Compound statement: dtc-data

The optional dtc-data compound statement can contain the following statements:

dtc-data { storage = storage-type; dtc-lamp-state-priority = lamp-priority-type; dtc-transition-prev-active-to-pending = boolean; table identifier;

dtc { ... }

dtc-j1939 { ... }

}

The required storage assignment statement identifies what memory device will be used to store diagnostic trouble code information across power cycles. See Section A.1, “ECU hardware reference documentation” for which memory types are supported for each target ECU.

The value of storage-type must be battery-backed-ram or flash.

The optional dtc-lamp-state-priority assignment statement specifies the priority scheme that will be used to calculate the desired state for each lamp when multiple DTCs are active which each require a different state for a lamp. Lamp states are prioritised so that the highest-priority state is selected as the desired state for the lamp.

The value of dtc-lamp-state-priority must be on-fast-slow-off or fast-slow-on-off. If this statement is omitted, on-fast-slow-off is selected by default. The priority scheme on- fast-slow-off selects continuous-on as the highest-priority state, followed by fast flash, followed by slow flash, followed by off. The priority scheme fast-slow-on-off selects fast flash as the highest-priority state, followed by slow flash, followed by continuous-on, followed by off.

Note that if fast-slow-on-off is selected, care must be taken when configuring desired lamp states for each DTC to ensure that MIL behaviour remains compatible with relevant OBD regulations. CARB requires that emissions-related DTCs set the MIL continuous- on during a drive cycle, for instance, meaning that DTCs should only be allowed to flash the MIL if the fault prevents the engine running and hence a drive cycle being started.

The optional transition-prev-active-to-pending assignment statement specifies whether faults that recur when a DTC is the "previously active" state should cause the DTC to return to "pending" state (if true) or "active" state (if false). See DTC state transition diagrams for further details.

If this statement is omitted, true is selected by default.

The optional table assignment statement, which can be repeated, identifies a table for grouping DTCs together.

The statement's identifier must not be repeated in other table statements.

The optional dtc compound statement identifies a diagnostic trouble code and assigns the DTC to a table. The same DTC can be reported over J1939, ISO diagnostics, or both. The compound statement is covered in Section 7.1.4.29, “Compound statement: dtc (or alternatively dtc-j1939)” in more detail.

Copyright 2019, Pi Innovo 635 Support tools

The optional dtc-j1939 compound statement is an alternative name for dtc retained for backwards compatibility. The compound statement is covered in Section 7.1.4.29, “Compound statement: dtc (or alternatively dtc-j1939)” in more detail. 7.1.4.29. Compound statement: dtc (or alternatively dtc-j1939)

The optional dtc (or dtc-j1939) compound statement, which can be repeated, can contain the following statements:

dtc { name = identifier; table = identifier;

spn = integer; fmi = integer; cm = integer;

iso-16bit-id = integer; uds-ftb = integer;

emissions-severity = emissions-severity; uds-severity = uds-severity;

lamps-to-be-set = hexadecimal value; permanent-storage = boolean; use-conditions-to-clear-perm = boolean; dc-count-limit = integer; error-free-dc-limit = integer | never; self-heal-wup-limit = integer | never; fault-symptom = integer; non-erasable = boolean; reg-exh-emission-lvl-exceedance = boolean; has-torque-derate = boolean; time-to-derate = integer; time-to-deactivate = integer | never; time-to-clear = integer | never; freeze-frame-name = identifier; }

The required name assignment statement identifies the diagnostic trouble code uniquely at the application code level.

The statement's identifier must have been specified as a table in the dtc-data compound statement (see Section 7.1.4.28, “Compound statement: dtc-data”).

The required table assignment statement, identifies the table group for this DTC.

The statement's identifier must have been specified as a table in the dtc-data compound statement (see Section 7.1.4.28, “Compound statement: dtc-data”). Tables are provided for convenient application management of groups of DTCs.

The optional spn, fmi and cm assignment statements gives the diagnostic trouble code's unique J1939 identifier. They are all required if the DTC is to be reported over J1939 but can all be omitted if the DTC is only to be reported over ISO protocols.

The acceptable value range of each statement is given in Table 7.5, “Value ranges for J1939 PDUs”.

Table 7.5. Value ranges for J1939 PDUs

Statement Range spn [0, 524287]

Copyright 2019, Pi Innovo 636 Support tools

Statement Range fmi [0, 31] cm [0, 1]

The optional iso-16bit-id assignment statement gives the diagnostic trouble code's 16- bit identifier when reported over the J1979 and Keyword Protocol 2000-3 protocols. For UDS responses, a 24-bit identifier is output, for which this value defines the most significant 16 bits and the uds-ftb statement defines the low 8 bits.

If two or more DTCs are defined with the same ISO ID but different failure type bytes, both may be listed in response to a J1979 or KWP request as they may well have different status bits set.

This statement is required if the DTC is to be reported over ISO protocols but can be omitted if the DTC is only to be reported over J1939.

The acceptable value range is [0, 65535].

The optional uds-ftb assignment statement specifies the least significant 8 bits of the full 24-bit ID for this DTC, as output in UDS responses to service $19 (where the most significant 16 bits are specified by the iso-16bit-id statement). It defaults to zero.

The acceptable value range is [0, 255].

The optional emissions-severity assignment statement decides whether this DTC is reported by J1979 service $03 (request emission-related diagnostic trouble codes) and cleared by service $04 (clear/reset emission-related diagnostic information). If this DTC is of a severity as high, or higher, than that declared in the emissions-report-min-severity statement (see Section 7.1.4.18, “Compound statement: iso-diagnostics”), it is included in those emissions-related services.

In future, this may be used to decide which message(s) to include this DTC in for the World-Wide Harmonized (WWH) OBD-related services including J1939 messages DM42 to DM52.

The value of emissions-severity must be one of sev-a (highest), sev-b1, sev-b2, sev- c, or sev-none (lowest).

The optional uds-severity assignment statement decides which severity this DTC has for reporting in relevant UDS $19 requests.

The value of emissions-severity must be one of uds-sev-check-imm (highest), uds-sev- next-halt, uds-sev-maint-only, or uds-sev-none (lowest).

The optional lamps-to-be-set assignment statement gives the 8-bit lamp information associated with each of the diagnostic trouble code. This information will be used when platform is responsible for DTC state handling. The value of lamps-to-be-set will indicate which lamps should be illuminated when the corresponding DTC becomes Active.

The bit information for lamps-to-be-set is given in Table 7.6, “Bit information for the lamps to be set per DTC”.

Table 7.6. Bit information for the lamps to be set per DTC

Bits Lamp Type 7-8 MIL lamp 5-6 Red Stop Lamp 3-4 Amber Warning Lamp

Copyright 2019, Pi Innovo 637 Support tools

Bits Lamp Type 1-2 Protect Lamp

The two bits associated with each lamp type are used to decide the illumination type as given in Table 7.7, “Bit information per lamp type”.

Table 7.7. Bit information per lamp type

Bits Illumination type 0 0 Slow Flash 0 1 Fast Flash 1 0 Continuous On 1 1 Unavailable

The acceptable value range is [00, FF].

The optional permanent-storage assignment statement is used to decide if the stored Active Diagnostic Trouble Code is of type Permanent as defined by CARB. permanent- storage must be set to either false (not stored as Permanent) or true (stored as Permanent).

The optional use-conditions-to-clear-perm assignment statement is used to meet CARB requirements on clearing permanent DTCs. Under CARB 1971.1, a permanent DTC must not be cleared immediately on an OBD request to clear DTCs. Instead the request is stored, and section (d)(2.3.1)(C) specifies conditions which must be met before a permanent DTC may be cleared. When (or if) these conditions are met, the DTC is cleared.

If the DTC relates to a monitor which is subject to the minimum ratio requirements of 1971.1 section (d)(3.2) (e.g. catalyst, EGR system, fuel system), the DTC may be cleared at the end of the next drive cycle in which the test has run at least once and no fault is detected. For this behaviour, use-conditions-to-clear-perm must be set to false.

If the DTC relates to any other monitor, the DTC may only be cleared after the end of a drive cycle in which certain vehicle operating conditions (running time, engine speed, vehicle speed) as specified in 1971.1 section (d)(2.3.1)(C)(ii)b.3. are met, and subsequently (possibly in a later drive cycle) the test has run at least once and no fault is detected. For this behaviour, use-conditions-to-clear-perm must be set to true. Under 1971.1 section (d)(2.3.1)(C)(ii)c., manufacturers are also permitted to impose the latter conditions on all permanent DTCs (including those whose monitors are subject to minimum ratio requirements) if they wish.

If the DTC is not permanent (i.e. permanent-storage is not set to true), this statement has no effect.

Note that the conditions on clearing permanent DTCs only applies when the DTCs are Active. DTCs in Pending or Previously Active state are not affected, and will be cleared by an OBD clear request as normal.

The optional dc-count-limit assignment statement is used to decide the number of failed drive cycles required for a DTC in state Pending to progress to state Active. This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 255].

The optional error-free-dc-limit assignment statement is used to decide the number of error free drive cycles required for a DTC in state Active to progress to state Previously

Copyright 2019, Pi Innovo 638 Support tools

active/Inactive. This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 254].

This statement may also be set to "never" if the DTC is not permitted to transition to Previously Active based on the number of error free drive cycles. This is not required under CARB or Euro regulations, but may be required for manufacturer-specific DTCs.

The optional self-heal-wup-limit assignment statement is used to decide the number of error free warm-up cycles required for a DTC in state Previously Active/Inactive to progress to state Clear This information will be used when platform is responsible for DTC state handling.

The acceptable value range is [0, 254].

This statement may also be set to "never" if the DTC is not permitted to transition to Clear based on the number of error free warm-up cycles. This is required for certain classes of DTCs under Euro regulations.

The optional fault-symptom assignment statement is used to set the fault symptom of the DTC

The acceptable value range is [0, 15].

The optional non-erasable assignment statement is used to specify whether the DTC is non-erasable, as specified by Euro regulations (directive 2005-EC-78).

If a DTC is specified as non-erasable, an Active DTC may only be cleared by the self- healing process. Using a diagnostic scan tool to request that DTCs be cleared will result in an Active non-erasable DTC transitioning to Previously Active, but the DTC will remain present until cleared by self-healing.

The optional reg-exh-emission-lvl-exceedance assignment statement is used to decide whether the DTC is to be considered for the regulated exhaust emission level exceedance. If not specified, a default of false is assumed.

The optional has-torque-derate assignment statement is used to decide whether the DTC has a torque derate. If not specified, a default of false is assumed.

The optional time-to-derate assignment statement is used to set the time in seconds the malfunction has until derate occurs. If not specified, a default of 62.5hrs is assumed.

The acceptable value range is [0, 62.5] hours, or [0, 225000] seconds.

The optional time-to-deactivate assignment statement is used to set the engine running time in seconds with no fault present for a DTC in state Active to progress to state Previously Active/Inactive.

This statement may also be set to "never" if the DTC is not permitted to transition to Previously Active/Inactive based on the engine running time. Euro regulations permit this, but CARB regulations do not. If not specified, a default of "never" is assumed.

If this is enabled, the DTC will progress to state Previously Active/Inactive when sufficient drive cycles are completed without fault (see error-free-dc-limit) or sufficient engine running time elapses without fault, whichever happens first.

The optional time-to-clear assignment statement is used to set the engine running time in seconds with no fault present for a DTC in state Previously Active/Inactive to progress to state Clear.

Copyright 2019, Pi Innovo 639 Support tools

This statement may also be set to "never" if the DTC is not permitted to transition to Clear based on the engine running time. Euro regulations permit this, but CARB regulations do not. If not specified, a default of "never" is assumed.

If this is enabled and transition based on warm-up cycles is also enabled (see self- heal-wup-limit), the DTC will progress to state Clear when sufficient warm-up cycles are completed without fault or sufficient engine running time elapses without fault, whichever happens first.

The required name assignment statement identifies the freeze frame associated with this dtc.

This should match the name of one of the defined freeze frames, as described in section Section 7.1.4.26, “Compound statement: freeze-frame”. 7.1.4.30. Compound statement: pid-data

The optional pid-data compound statement can contain the following statements:

pid-data { pid { ... } pid { ... } }

Each optional pid compound statement identifies a diagnostic parameter to be accessed by ID (PID). The compound statement is covered in Section 7.1.4.31, “Compound statement: pid” in more detail. 7.1.4.31. Compound statement: pid

The optional pid compound statement, which can be repeated, can contain the following statements:

pid { name = identifier; iso-16bit-id = integer; byte-length = integer; allow-ioctrl = true or false; input-byte-length = integer; j1979-8bit-id = integer; kwp-8bit-id = integer; j1939-spn-id = integer; resend-input-as-output = true or false; nonvolatile = true or false; min-length = integer; max-length = integer; alphanumeric = true or false; control-enable-mask-length = integer; iso-scaling-bytes = byte-list; }

The required name assignment statement identifies the PID uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the PID.

The required iso-16bit-id assignment statement specifies the numeric ID by which this PID is accessed by an external tool, e.g. using Keyword Protocol 2000-3/UDS service 0x22.

Copyright 2019, Pi Innovo 640 Support tools

The integer for the statement must be in the range [0, 65535], and the same value cannot be used for two or more different PIDs.

The required byte-length assignment statement specifies the number of bytes this PID consists of. For example, 2 bytes may be used to convey an engine speed value, but 12 bytes for a Vehicle Identification Number (VIN) string.

The integer for the statement must be in the range [1, 255].

The optional allow-ioctrl assignment statement specifies whether or not the external test tool is allowed to override or freeze the PID values using inputOutputControlByIdentifier services in Keyword Protocol 2000-3 and UDS. If not specified, a default of false is assumed.

Allowing such overrides significantly increases the RAM consumed by the PID.

The optional input-byte-length assignment statement specifies the number of controlOptionRecord bytes that are expected for this PID when an override value is sent by the test tool, so it is only relevant if allow-ioctrl = true.

If omitted, the same length as byte-length is assumed. Otherwise, this allows a PID to be configured to accept data that does not have a one-to-one match with its normal data in terms of length. The override data can still be obtained in such cases using ppid_get_override_data().

The integer for the statement must be in the range [1, 255].

The optional j1979-8bit-id assignment statement specifies the 8-bit ID to be used for J1979 service $01 request.

The integer for the statement must be in the range [0, 255], and the same value cannot be used for two or more different PIDs.

The optional kwp-8bit-id assignment statement specifies the 8-bit LocalIdentifier to be used for KW2000-3 services $21 and $30.

The integer for the statement must be in the range [0, 255], and the same value cannot be used for two or more different PIDs.

The optional j1939-spn-id assignment statement specifies the J1939 SPN.

The integer for the statement must be in the range [0, 524287], and the same value cannot be used for two or more different PIDs.

The optional resend-input-as-output assignment statement controls the data being returned to the tool and read by the application.

If set true, override values sent by the test tool (controlOptionRecord data) temporarily replace the data in the PID as read by ppid_get_pid(), and echoed to the test tool as ControlStatusRecord bytes.

If set false, override values sent by the test tool do not overwrite the data in the PID, but can still be checked by using ppid_get_override_data(). This is appropriate if the input-byte-length differs from the byte-length.

The is applicable only for the PIDs that have allow-ioctrl set to true.

The optional nonvolatile assignment statement determines if the PID is stored in NVM.

If not defined, it will be set to FALSE by default.

Copyright 2019, Pi Innovo 641 Support tools

The optional min-length assignment statement specifies the minimum number of bytes this PID consists of. Note: min-length only applies to non-volatile PIDs.

The integer for the statement must be in the range [1, 255].

The optional max-length assignment statement specifies the maximum number of bytes this PID consists of. Note: max-length only applies to non-volatile PIDs.

The integer for the statement must be in the range [1, 255].

The optional alphanumeric assignment statement determines the byte ordering of J1939 SPN data. If set TRUE, the data is treated as alphanumeric with the most significant byte transmitted first. If set FALSE the least significant byte is transmitted first.

If not defined, it will be set to FALSE by default.

The optional control-enable-mask-length assignment statement specifies how many bytes should be reserved for optional controlEnableMask data sent by the test tool. The bytes (if supplied by the tool) can be retrieved using ppid_get_override_data().

It is the responsibility of the application to act appropriately on any controlEnableMask bytes, e.g. by restricting the override of physical outputs only to selected signals.

The integer for the statement must be in the range [0, 255], and defaults to zero.

The optional iso-scaling-bytes assignment statement specifies the scaling bytes to be transmitted in response to a service $24 request.

The scaling bytes are entered as a comma-separated list of integer values in either decimal or hex. Example: iso-scaling-bytes = 0x32, 75, 123, 0x7F;

If not defined, scaling bytes will not be used for this PID. 7.1.4.32. Compound statement: dte-data

The optional dte-data compound statement can contain the following statements:

dte-data { dte { ... } dte { ... } }

Each optional dte compound statement identifies a Diagnostic Test Entity. The compound statement is covered in Section 7.1.4.33, “Compound statement: dte” in more detail. 7.1.4.33. Compound statement: dte

The optional dte compound statement, which can be repeated, can contain the following statements:

dte { name = identifier; dte-id = integer; dte-dme-id = integer; j1939-tid = integer; iso-tid = integer; dte-mon-id = integer; scaling-id = integer; slot-id = integer; component-id = integer;

Copyright 2019, Pi Innovo 642 Support tools

dte-spn = integer; dte-fmi = integer; test-lim-min = integer; test-lim-max = integer; }

The required name assignment statement identifies the DTE uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the DTE.

The required dte-id assignment statement identifies the identifier for the DTE uniquely.

An error is raised if a duplicate DTE ID is found. .

The required dte-dme-id assignment statement identifies the DME to which the DTE belongs.

A warning is raised if the assigned ID is not defined with a Section 7.1.4.35, “Compound statement: dme” statement.

The optional j1939-tid assignment statement identifies the J1939 specified Test ID that requires ratio monitoring.

Either this or the iso-tid (or both) must be assigned to a valid value. An error is raised if both iso-tid and j1939-tid assignments are skipped.

The optional iso-tid assignment statement identifies the ISO specified Test ID that requires ratio monitoring.

Either this or the j1939-tid (or both) must be assigned to a valid value. An error is raised if both iso-tid and j1939-tid assignments are skipped.

The optional dte-mon-id assignment statement identifies the Monitor ID to which the DTE belongs.

This is applicable only for reporting for ISO diagnostics.

The optional scaling-id assignment statement identifies scaling and unit to be used by the external test equipment to calculate and display the test values/ results.

This is applicable only for reporting for ISO diagnostics.

The optional slot-id assignment statement identifies the SLOT for the DTE.

This is applicable only for reporting for J1939 diagnostics.

The optional component-id assignment statement identifies the Component for the DTE.

This is applicable only for reporting for J1939 diagnostics.

The optional dte-spn assignment statement identifies the SPN associated with the DTE.

This is applicable only for reporting for J1939 diagnostics.

The optional dte-fmi assignment statement identifies the FMI associated with the DTE.

This is applicable only for reporting for J1939 diagnostics.

The optional test-lim-min assignment statement identifies minimum limit of the test value for the test Pass/Fail criteria.

This is the scaled value of the test limits (matching the scaling-id defined above). This should be in the range [0, 65535]. If not defined, it will be set to 0 by default.

Copyright 2019, Pi Innovo 643 Support tools

The optional test-lim-max assignment statement identifies maximum limit of the test value for the test Pass/Fail criteria.

This is the scaled value of the test limits (matching the scaling-id defined above). This should be in the range [0, 65535]. If not defined, it will be set to 65535 by default. 7.1.4.34. Compound statement: dme-data

The optional dme-data compound statement can contain the following statements:

dme-data { dme { ... } dme { ... } }

Each optional dme compound statement identifies a Diagnostic Monitor Entity. The compound statement is covered in Section 7.1.4.35, “Compound statement: dme” in more detail. 7.1.4.35. Compound statement: dme

The optional dme compound statement, which can be repeated, can contain the following statements:

dme { name = identifier; dme-id = integer; dme-mon-id = integer; monitor-group = monitor-group; dme-spn = integer; readiness-count-lim = integer; }

The required name assignment statement identifies the DME uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the DME.

The required dme-id assignment statement is an arbitrary integer value used to reference this DME.

An error is raised if a duplicate DME ID is found. .

The optional dme-mon-id assignment statement identifies the OBD Monitor ID corresponding to this DME. The OBD Monitor ID is used to identify the supported monitors while servicing the ISO J1979 service request $06.

This is applicable only for reporting for ISO diagnostics. Either this or the dme-spn (or both) must be assigned to a valid value.

The optional monitor-group assignment statement decides which Monitor group this DME belongs to (used for response to service $09 (ReadVehicleInformation), InfoTypes $08 and $0B.

The J1979 spec dated Sept 2010 lists the mapping of Monitor ID to Group in appendix D.

The value of monitor-group must be one of air, bp, cat-bank1, cat-bank2, egr, egs, evap, fuel, nads, ncat, nmhc-cat, o2s-bank1, o2s-bank2, so2s-bank1, so2s-bank2, opm, or other (default).

The optional dme-spn assignment statement identifies the SPN associated with the DME.

Copyright 2019, Pi Innovo 644 Support tools

This is applicable only for reporting for J1939 diagnostics. Either this or the dme-mon- id (or both) must be assigned to a valid value.

An error is raised if both dme-mon-id and dme-spn assignments are skipped.

The optional readiness-count-lim assignment statement identifies the number of times monitor has to be run before declared as Readiness COMPLETE.

If not defined, it will be set to 0 by default. 7.1.4.36. Compound statement: adaptives

The optional adaptives compound statement can contain the following statements:

adaptives { storage = storage-type;

adaptive-list = adaptive-list;

}

The required storage assignment statement identifies what memory device will be used to store adaptive information across power cycles. See Section A.1, “ECU hardware reference documentation” for which memory types are supported for each target ECU.

The value of storage-type must be battery-backed-ram or flash.

The optional adaptive-list assignment statement, which can be repeated, identifies the DDEs which are treated as non-volatile adaptives. The adaptive-list must be the name of one DDE, or the names of multiple DDEs separated by commas.

The interface tool will report an error if any DDE is repeated. 7.1.4.37. Compound statement: routine-data

The optional routine-data compound statement can contain the following statements:

routine-data { routine { ... } routine { ... } }

Each optional routine compound statement identifies a diagnostic routine to be accessed by routine ID. The compound statement is covered in Section 7.1.4.38, “Compound statement: routine” in more detail. 7.1.4.38. Compound statement: routine

The optional routine compound statement, which can be repeated, can contain the following statements:

routine { name = identifier; iso-16bit-id = integer; routine-type-timed = true or false; rcor-byte-length = integer; results-byte-length = integer; status-record-byte-length = integer; }

Copyright 2019, Pi Innovo 645 Support tools

The required name assignment statement identifies the routine uniquely at the application code level. A code identifier based on this name is provided to the application so that it can access the routine.

The required iso-16bit-id assignment statement specifies the numeric ID by which this routine is accessed by an external tool using UDS service 0x31.

The integer for the statement must be in the range [0, 65535], and the same value cannot be used for two or more different routines. Note: routine IDs 0x0202, 0x0203, 0xFF00, and 0xFF01 are reserved by the platform and cannot be used by the application.

The required routine-type-timed assignment statement specifies whether or not the routine is "Method A" (untimed) or "Method B" (timed) as specified in ISO 14229-1. A value of true means that the routine is "Method B" (timed).

The optional rcor-byte-length assignment statement specifies the number of bytes in the routineControlOptionRecord for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default.

The optional results-byte-length assignment statement specifies the number of bytes that will be returned as "routine results" in response to a results request for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default.

The optional status-record-byte-length assignment statement specifies the number of bytes in the statusRecord for this routine.

The integer for the statement must be in the range [0, 65535]. If not defined, it will be set to 0 by default. 7.1.4.39. Compound statement: tunes

The optional tunes compound statement is reserved for future use. 7.1.4.40. Compound statement: ddes

The optional ddes compound statement can contain the following statements:

ddes { include-dde-tabbed string; include-dde-tabbed-prefix string; include-dde-tabbed-c string; include-dde-units string;

generate-library-ddes = true or false; }

The optional include-dde-tabbed assignment statement (became deprecated at version 1.8.1), which can be repeated, identifies a prefix-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a prefix-style tabbed DDE file is described in detail in Section 7.1.5.1, “Data dictionary format (prefix-style)”.

The optional include-dde-tabbed-prefix assignment statement, which can be repeated, identifies a prefix-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a prefix-style tabbed DDE file is described in detail in Section 7.1.5.1, “Data dictionary format (prefix-style)”.

Copyright 2019, Pi Innovo 646 Support tools

The optional include-dde-tabbed-c assignment statement, which can be repeated, identifies a C-style tabbed DDE file to read and include in any ASAP2 generation.

The format of a C-style tabbed DDE file is described in detail in Section 7.1.5.3, “Data dictionary format (C-style)”.

The optional include-dde-units assignment statement, which can be repeated, identifies a units file to read and include in any ASAP2 generation.

The format of a units file is described in detail in Section 7.1.6, “Units file”.

The required generate-library-ddes assignment statement identifies whether to generate library based DDEs or not (see Section 7.1.7, “Automatic ASAP2 entries” for more). 7.1.5. DDE specification

The OpenECU library can interact with calibration tools to read and write application data while the application is executing on the target. To support the interface between the calibration tool and the application, a data description file is required so the calibration tool understands how the application memory is laid out. To support this, the interface tool can read a set of application data dictionary files and create the calibration data description files.

The application data is described in a set of data dictionary files. A data dictionary file is a simple tab delimited text file format and must contain at minimum: the name, default value and type for calibratables; the name and type for displayables. When an application is built, the information stored in the data-dictionary files are transformed into an ASAP2 file for use with a calibration tool.

Note that non-ASCII characters appearing in the data dictionary may not be interpreted correctly by the calibration tool reading the resultant ASAP2 files, since different calibration tools use different extended encoding conventions. It is best therefore to stick to ASCII characters within the data dictionary.

There are two supported data dictionary file formats: prefix-style (described in Section 7.1.5.1, “Data dictionary format (prefix-style)”) and C-style (described in Section 7.1.5.3, “Data dictionary format (C-style)”). 7.1.5.1. Data dictionary format (prefix-style)

Each prefix-style data dictionary follows a simple format, separated into columns and will look something like:

Name Value Units Type Accuracy Min Max Description moi_pressure kPa F32 0.01 20 80 Pressure reading moi_temperature degC F32 0.01 -40 150 Temperature reading

To help readability, comment lines can be inserted into a data dictionary file. Comment lines are ignored and start with the ** character sequence. For example:

Name Value Units Type Accuracy Min Max Description ** A comment line moi_pressure kPa F32 0.01 20 80 Pressure reading

** Another comment line moi_temperature degC F32 0.01 -40 150 Temperature reading

Each column has a heading, followed by as many data dictionary entries as necessary. Each column is separated by a TAB character and because of this, Excel is a very useful tool for editing the files (in Excel, save the file as Text (tab delimited) *.txt).

Copyright 2019, Pi Innovo 647 Support tools

7.1.5.1.1. DDE columns

Each column has a use as described in Table 7.8, “Data dictionary columns (prefix-style)”.

Table 7.8. Data dictionary columns (prefix-style)

Column Description Name The name of the data dictionary entry. The name must conform to the naming convention detailed in Section 7.1.5.2, “DDE naming rules (prefix_style)”. Value The value of a calibration constant, 1d or 2d map. A value should not be created for a non-calibration variable. Units The engineering units for this entry (can be restricted to a set of possibilities with a units file (Section 7.1.6, “Units file”)). Description A description of the data dictionary entry. Must not contain single or double quotes. Type Any one of S8, U8, S16, U16, S32 U32, F32 or BOOL. The type must match the type assigned to the signal by C source code (the interface tool does not check correct type assignment). Accuracy The number of decimal digits to display when viewing the data dictionary entry with a calibration tool. For instance, 1 shows no digits after the decimal point, 0.01 shows two digits after the decimal point. Min The minimum expected value for this data dictionary entry. Max The maximum expected value for this data dictionary entry. Scale This column is optional. It specifies the amount by which the displayed value will be scaled from the raw value read from the ECU. Offset This column is optional. It specifies the amount by which the displayed value will be offset from the raw value read from the ECU. Enums A comma separated list of data dictionary entries which provide the possible values this data dictionary entry can be. Decl Reserved for future use. Defn Reserved for future use. Lookup Reserved for future use, do not use. Group Reserved for future use, do not use. Rate Reserved for future use, do not use.

An example of how the data dictionary can be used to name application variables, constants and map look-ups is given below. Each entry follows the naming convention laid out in (Section 7.1.5.2, “DDE naming rules (prefix_style)”). Explore the C-API examples for more examples (Section 4.6.8, “Examples”).

Name Value Units Type Min Max Description

** example of a signal DDE moi_pressure kPa F32 20 80 Example of a named signal

** example of a constant lookup DDE moic_constant 50 kPa F32 20 80 Example of a calibration constant

** example of set of a 1D table/map lookup DDEs moim_1d_map_x [20 40 80] kPa F32 20 80 Example of a x-axis for a 1d map moim_1d_map_z [0 0 1] state BOOL 0 1 Example of a z-data for a 1d map

** example of set of a 2D table/map lookup DDEs moim_2d_map_x [20 40] kPa F32 20 80 Example of a x-axis for a 2d map

Copyright 2019, Pi Innovo 648 Support tools

moim_2d_map_y [1 5 10] sec F32 0 25 Example of a y-axis for a 2d map moim_2d_map_z [0 1; 4 5; 8 9] steps F32 0 100 Example of a z-data for a 2d map

** example of set of an array DDE moiv [1 2 3 5 8 13] counts F32 0 10 Example of an array

Instead of using values to represent discrete states, enumerations can be used instead. These represent the discrete states using a textual name rather than a number. For instance, in the following example, moi_state can have two enumerations: MOI_RUNNING which represents the value 0 and MOI_STOPPED which represents the value 1.

Name Value Units Type Min Max Enums Description

moi_state state F32 0 1 MOI_RUNNING, MOI_STOPPED Example of a st ...

MOI_RUNNING 0 enum F32 Enumeration for ... MOI_STOPPED 1 enum F32 Enumeration for ...

When each data dictionary file is read by the interface tool, the contents are checked for consistency. A complete list of checks is given in Appendix B, OpenECU error and warning codes. 7.1.5.2. DDE naming rules (prefix_style)

The interface tool makes use of a naming convention to help make names and variables more readily understandable by humans. All names consist of a prefix, a descriptive body, and an optional suffix, separated by underscore characters:

Variable type letter Determines the type of the variable, in this case ‘c’ for calibration scalar. mbec_ign_key_debounce_time

Prefix Name Used to gather variables for the same Used to uniquely identify the variable by name. group of functionality together. E.g., mbe for ‘master base engine’, or alt for ‘alternator control’

The prefix consists of three or four lower case letters, these being:

• A three letter prefix code identifying which group of functionality the named item belongs to. • A single letter identifying the type of the named item (not used for displayable signals). See Table 7.9, “Variable naming convention (prefix-style)” for a list of types.

The item type letter is as follows:

Table 7.9. Variable naming convention (prefix-style)

Named item type Type letter Displayable signals (no type letter) Calibration scalars c Calibration maps m Arrays v

Axes and map data for lookup tables require an addition suffix. 1-d lookup tables have two parameters as follows:

Copyright 2019, Pi Innovo 649 Support tools

Table 7.10. 1-d map lookup naming convention (prefix-style)

Application parameter Suffix Example Vector of input values _x vaim_fuel_cell_temp_x Vector of output values _z vaim_fuel_cell_temp_z

2-d lookup tables have three parameters as follows:

Table 7.11. 2-d map lookup naming convention (prefix-style)

Application parameter Suffix Example Row _x sffm_base_fuel_x Column _y sffm_base_fuel_y Table _z sffm_base_fuel_z

7.1.5.3. Data dictionary format (C-style)

A C-style data dictionary file has a similar layout to a prefix-style data dictionary (described in detail in Section 7.1.5.1, “Data dictionary format (prefix-style)”). The primary differences between the two formats is in column use and DDE naming.

7.1.5.3.1. DDE columns

Each column has a use as described in Table 7.12, “Data dictionary columns (C-style)”.

Table 7.12. Data dictionary columns (C-style)

Column Description Name The name of the data dictionary entry. The name must conform to the naming convention detailed in Section 7.1.5.3.2, “DDE naming rules (C- style)”. Units The engineering units for this entry (can be restricted to a set of possibilities with a units file (Section 7.1.6, “Units file”)). Description A description of the data dictionary entry. Must not contain single or double quotes. Accuracy The number of decimal digits to display when viewing the data dictionary entry with a calibration tool. For instance, 1 shows no digits after the decimal point, 0.01 shows two digits after the decimal point. Min The minimum expected value for this data dictionary entry. Max The maximum expected value for this data dictionary entry. Scale This column is optional. It specifies the amount by which the displayed value will be scaled from the raw value read from the ECU. Offset This column is optional. It specifies the amount by which the displayed value will be offset from the raw value read from the ECU. Class This is the class of DDE. Further details are given in Table 7.13, “Classes of DDE”. Xaxis For a 1d or 2d map entry, this is the name of the DDE to the corresponding X-axis information. Yaxis For a 2d map entry, this is the name of then DDE to the corresponding Y-axis information.

Copyright 2019, Pi Innovo 650 Support tools

Column Description Lookup For a 1d map entry, this is the name of the DDE used to index the X- axis. For a 2d map entry, this is the name of the DDEs used to index the X-axis and then the Y-axis, separated by a comma. The lookup information can be used by a calibration tool to show the current map lookup location in real-time. Group A comma separated list of groups. Each group must start with a “/” and be followed by an ASAP2 identifier, e.g., “/Group_name”. Groups can be combined to form a heirarchy, e.g., “/Group_name/Function/ A”. Each group for a DDE is used to generate a heirachy of ASAP2 FUNCTIONS which a calibration tool uses to present groups of DDE to the user. Rate Reserved for future use.

In comparison with the prefix-style DD format, some columns are not used because information can be extracted from the compiler's ELF file (for instance, variable types and enumeration identifiers).

An example of how the data dictionary can be used to name application variables, constants and map look-ups is given below. Each entry follows the naming convention laid out in (Section 7.1.5.3.2, “DDE naming rules (C-style)”). Explore the C-API examples for more examples (Section 4.6.8, “Examples”).

Name Units Class Min Max Description

** example of a simple variable reference (displayable) vehicle_speed mph d 0 200 Filtered vehicle ...

** example of a simple variable reference (calibration) ign_supplies_vbat flag c 0 1 1 if ignition and...

** example of an array variable reference analog_values[0].fault flag d 0 1 1 if A/D is sense...

The C-style file format has a couple of additional columns: Xaxis, Yaxis and Lookup; which are used to provide additional information about maps.

The Xaxis and Yaxis columns are used to specify the axis information for a map. The map itself can be 1d or 2d in size. The Lookup column is used to specify the DDEs used to lookup the x and y axes of a map. The calibration tool can use the lookup DDEs to show where the map was last indexed. An example of a 1d map would be:

Name Units Class Min Max Xaxis Lookup

** example of a simple variable reference (displayable) inlet_pressure kPa d 0 200

** example of a 1D table/map with lookup pressure_axis kPa caxis 20 80 position_map steps cmap 0 100 pressure_axis inlet_pressure

The Class column specifies whether the DDE is a calibration (write-only) or displayable (read- only).

Displayable Can be read by a tool external to the ECU while the application is running. Displayables typically refer to variables held in RAM, but can also refer to variables in other memory spaces.

Calibration Can be written by a tool external to the ECU while the application is running. Calibrations can be scalar (single variable), map (one or two

Copyright 2019, Pi Innovo 651 Support tools

axes, plus a lookup table), string (array of ASCII characters), or vector/ array (array of variables).

Table 7.13. Classes of DDE

Class Description c DDE is treated as a scalar calibration. cmap DDE is treated as a map calibration. caxis DDE is treated as an axis calibration. cstring DDE is treated as a string calibration. carray DDE is treated as an array calibration. d DDE is treated as a scalar displayable. darray DDE is treated as an array displayable.

7.1.5.3.2. DDE naming rules (C-style)

C-style DDE names closely match the equivalent C identifier for a variable. Structure members can be referenced, as can array indexes and ranges of array indexes. For instance, given the following C code snippet:

typedef struct { real_t a; real_t b; } AB_T; typedef struct { real_t idx; AB_T list[10]; } DATA_T; uint32_t var; real_t axis[4]; DATA_T data[3];

the data can be accessed through various names:

Table 7.14. Examples of C-style DDE names

Names Description var refers to scalar variable of same name axis[0] refers to scalar variable of array, element 0 axis[0..3] refers to scalar variables, elements 0 through 3 axis[2..] refers to scalar variables, elements 2 through 3 axis[..2] refers to scalar variables, elements 0 through 2 axis[..] refers to scalar variables, elements 0 through 3 data[0].idx refers to scalar variable, the idx struct member from data element 0 data[..].list[..].a refers to scalar variables, the a struct member from all elements in data[].list[]

As can be seen in the examples, references to arrays can be explicit (e.g., axis[0]) or ranged (e.g., axis[..]). When a range is provided and the lower or upper bound is not specified, the interface tool will use the lower or upper bound extracted from the compiler's ELF file (if such a bound is specified).

Note

A C-style DDE which refers to a C array, must have an equivalent C variable where the array size is given explicitly. For instance, in the following snippet, array_sized[] is acceptable while array_unsized[] is not.

Copyright 2019, Pi Innovo 652 Support tools

F32 array_sized[3] = { 1, 2, 3 }; F32 array_unsized[] = { 1, 2, 3 };

This requirement is derived from the amount of information embedded in the ELF file. Implicitly sized arrays have pointer type with no size information, neither of which an ASAP2 file can support.

Note

C-style DDE names cannot refer to C variables which are of pointer or bit-field type. These are not supported by the ASAP2 and calibration tool combinations supported by OpenECU.

7.1.6. Units file

A units file is a simple text file format, where each line represents a single allowable unit. When a model is loaded, the data dictionary entries and unit entries are read, and any data dictionary what does not use one of the unit entries raises a warning.

A units file for a model must have the file-name model_name_units.txt where model_name is replaced by the name of the model. An example units file for a model named read_sensor would be named read_sensor_units.txt and might look like:

degC kPa

In this example, only two units, degC and kPa can be used for a data dictionary entry.

To help readability, comment lines can be inserted into the units file. Comment lines are ignored and start with a ** or -- character sequence. For example:

** Allowable units for the read_sensor model degC kPa

7.1.7. Automatic ASAP2 entries

When an application is built, a number of ASAP2 entries are automatically generated. These entries reflect a number of application properties and run-time parameters which are useful to monitor during development and deployment.

The sections below give a complete list of automatically generated ASAP2 entries.

Note

When using PiSnoop be sure to load the ASAP2 (.a2l) file symbols to view these parameters. In many cases they are aliases for C variables with different names in the .elf file, and some have necessary scale factors applied in the ASAP2 attributes.

7.1.7.1. Boot build information

The boot software runs when the ECU is turned on. It conditions the ECU for running the reprogramming software or application software. The version and build date of this software is available through the following ASAP2 entries.

Copyright 2019, Pi Innovo 653 Support tools

Table 7.15. Automatic ASAP2 entries for boot build information

ASAP2 name Description Units mpl_boot_ver_major The boot software major version number. - mpl_boot_ver_minor The boot software minor version number. - mpl_boot_ver_sub The boot software sub-minor version number. - mpl_boot_build_day The numerical day when the boot software days was created. mpl_boot_build_month The numerical month when the boot software months was created. mpl_boot_build_year The numerical year when the boot software years was created. mpl_boot_part_num_group The Group ID numerical value of the boot - software part number. mpl_boot_part_num_letter The Group Letter ASCII value of the boot - software part number. mpl_boot_part_num_id The Part ID numerical value of the boot - software part number. mpl_boot_part_num_issue The Issue numerical value of the boot software - part number.

Past and current boot code version numbering is given in Section 7.1.8, “OpenECU software versioning”. 7.1.7.2. Reprogramming build information

The ECU's reprogramming mode is started as described in Section 3.3.11, “Program the ECU”. The reprogramming code communicates using CCP (version 2.1) and provides a calibration tool with a mechanism to change the application software and/or calibration.

Table 7.16. Automatic ASAP2 entries for reprogramming build information (M220, M221, M250, M460, M461, M550, M670)

ASAP2 name Description Units mpl_prg_ver_major The reprogramming software major version - number. mpl_prg_ver_minor The reprogramming software minor version - number. mpl_prg_ver_sub The reprogramming software sub-minor - version number. mpl_prg_build_day The numerical day when the reprogramming days software was created. mpl_prg_build_month The numerical month when the reprogramming months software was created. mpl_prg_build_year The numerical year when the reprogramming years software was created. mpl_prg_part_num_group The Group ID numerical value of the - reprogramming software part number. mpl_prg_part_num_letter The Group Letter ASCII value of the - reprogramming software part number.

Copyright 2019, Pi Innovo 654 Support tools

ASAP2 name Description Units mpl_prg_part_num_id The Part ID numerical value of the - reprogramming software part number. mpl_prg_part_num_issue The Issue numerical value of the - reprogramming software part number.

Past and current boot code version numbering is given in Section 7.1.8, “OpenECU software versioning”. 7.1.7.3. Platform build information

The platform software creates an environment where by the application software can execute and access the target ECU hardware.

Table 7.17. Automatic ASAP2 entries for platform build information

ASAP2 name Description Units mpl_plat_ver_major The platform software major version number. - mpl_plat_ver_minor The platform software minor version number. - mpl_plat_ver_sub The platform software sub-minor version - number. mpl_plat_build_day The numerical day when the platform software days was created. mpl_plat_build_month The numerical month when the platform months software was created. mpl_plat_build_year The numerical year when the platform software years was created. mpls_plat_build_time The date and time when the platform was - created as a text string. mpls_plat_copyright The platform's copyright notice. - mpls_plat_target The hardware target the application was built - to be run on as a text string. mpls_plat_version The version of the platform the application was - built against as a text string. mpl_plat_part_num_group The Group ID numerical value of the platform - part number the application was build against. mpl_plat_part_num_letter The Group Letter ASCII value of the platform - part number the application was build against. mpl_plat_part_num_id The Part ID numerical value of the platform - part number the application was build against. mpl_plat_part_num_issue The Issue numerical value of the platform part - number the application was build against.

Past and current boot code version numbering is given in Section 7.1.8, “OpenECU software versioning”. 7.1.7.4. Application build information

When the application is built, the automatically generated application code and the platform software are combined, and the result is the application software configured for the target ECU hardware.

Copyright 2019, Pi Innovo 655 Support tools

The application name, description and copyright, as well as the time and date when the application was built, is available through ASAP2 entries. This information is useful when confirming what the ECU is actually executing.

Table 7.18. Automatic ASAP2 entries for application build information

ASAP2 name Description Units mpl_app_ver_major The application software major version - number. mpl_app_ver_minor The application software minor version - number. mpl_app_ver_sub The application software sub-minor version - number. mpl_app_build_sec The seconds when the application software seconds was built. mpl_app_build_min The minute when the application software was minutes built. mpl_app_build_hour The hour (in 24 hour format) when the hours application software was built. mpl_app_build_day The numerical day when the application days software was built. mpl_app_build_month The numerical month when the application months software was built. mpl_app_build_year The numerical year when the application years software was built. mpls_app_build_time The date and time when the application was - built as a text string. mpls_app_copyright The copyright notice for the application. - mpls_app_description The application description. - mpls_app_name The name of the built application. - mpls_app_version The application version number as a text - string. 7.1.7.5. Application and library task timing information

When the application is executing, the platform is maintaining a series of tasks that iterate the application at periodic rates (and possibly on an angular rate if engine functionality is required). These tasks take an amount of time to execute and the following ASAP2 entries record how long the last ran.

Table 7.19. Automatic ASAP2 entries for application rate task timing information

ASAP2 name Description Units mpl_tt_[capi-task-name] The duration of the last microseconds application iteration for a particular task.

When the application is executing, the platform is maintaining a series of tasks that support the application. These tasks perform basic input and output support as well as general housekeeping. Each task takes some time to execute and the following entries record the last execution time of each.

Copyright 2019, Pi Innovo 656 Support tools

Table 7.20. Automatic ASAP2 entries for auxiliary task timing information

ASAP2 name Description Units mpl_tt_pan_task The duration of angular microseconds platform task. This task supports the angular application iteration. mpl_tt_pan_knock The duration of angular microseconds knock support task. mpl_tt_pan_knock_ref The duration of angular microseconds knock reference support task. mpl_tt_pcx_tcan_callback The duration of the CAN microseconds receive and transmit (event) support task. mpl_tt_pcx_queue_emptier The duration of the CAN microseconds receive and transmit (polled) support task. mpl_tt_psp_receive The duration of the serial microseconds input and output support task. mpl_tt_psc_watchdog The duration of the microseconds watchdog support task. mpl_tt_pcp_client The duration of the CCP microseconds support task. This task provides CCP support for the calibration tool. mpl_tt_ppp_client The duration of the PixCal/ microseconds tuning comms protocol task. This task provides support for tunable parameters via the PixCal calibration tool.

These entries support development by showing how long the software takes to run on the target hardware. As development progresses, new functionality can be compared to previous functionality to assess how much processing time is consumed.

The assessment can be made by noting how frequently the tasks run and how long they take, giving an estimated total consumption.

Table 7.21. Automatic ASAP2 entries for CPU loading information

ASAP2 name Description Units mpl_cpu_loaded The amount of CPU used by the percent application and platform software in the last 50 milliseconds as a percentage. The CCP task may cause the loading to reach 100 percent under certain conditions but this is normal. The long running CCP task will not cause application iterations or other functionality to be delayed.

Copyright 2019, Pi Innovo 657 Support tools

Some target ECU support loading measurement for processing devices other than the CPU. The eTPU device, or devices, are used for simple and complex I/O processing.

Table 7.22. Automatic ASAP2 entries for eTPU loading information

ASAP2 name Description Units mpl_etpu_a_loaded The amount of eTPU (device A) used by percent the application and platform software in the last 50 milliseconds as a percentage. mpl_etpu_b_loaded The amount of eTPU (device B) used by percent the application and platform software in the last 50 milliseconds as a percentage.

Although previous entries record how long the last execution took, it is useful to know the longest execution that has occurred since power up. There are ASAP2 entries to support this.

Table 7.23. Automatic ASAP2 entries for maximum application rate task timing information

ASAP2 name Description Units mpl_mtt_[name] The largest value of the microseconds corresponding application duration ASAP2 variable seen since the last power up or reset. mpl_max_cpu_loaded The largest value of percent mpl_cpu_loaded seen since the last power up or reset. mpl_max_etpu_a_loaded The largest value of percent mpl_etpu_a_loaded seen since the last power up or reset. mpl_max_etpu_b_loaded The largest value of percent mpl_etpu_b_loaded seen since the last power up or reset.

Note that the maximum task duration entries record the longest execution seen since power up and not the worst case execution time of the task. It could be that a task will take longer to run if given different stimuli. OpenECU does not support the direct derivation of worst case execution times.

There is also a seconds counter which is cleared to zero when the ECU is turned on or resets. The counter can be used to determine if the ECU is resetting on a regular or irregular basis.

Table 7.24. Automatic ASAP2 entries for run-time information

ASAP2 name Description Units mpl_run_time A seconds counter of the seconds time since power up; range [0, 4294967294].

Expected and unexpected resets are logged and counted. There are ASAP2 entries to report reset counts.

Copyright 2019, Pi Innovo 658 Support tools

Table 7.25. Automatic ASAP2 entries for reset information (M110, M220, M250, M460, M461)

ASAP2 name Description Units mpl_unstable_reset_count Number of resets since events power-up, or since the application was last stable. mpl_reset_count Number of resets since events power-up.

Table 7.26. Automatic ASAP2 entries for number of instances of period overruns or skips of periodic tasks

ASAP2 name Description Units mpl_ovrc_[name] The number of times the task has taken count longer that its period to run. mpl_skipc_[name] The number of times the task has count skipped its period.

7.1.7.6. Memory use information

The platform software provides support for the application execution through the tasks identified above. Each of these tasks requires some memory to record its state and the platform does so dynamically by storing this information on the stack.

Table 7.27. Automatic ASAP2 entries for memory use information

ASAP2 name Description Units mpl_max_used_stack The amount of stack used bytes since power up by the application software.

The size of the stack can be modified via the interface file, see Section 7.1.4.9, “Compound statement: os-native”. 7.1.7.7. Memory error correction events

Some ECUs provide memory error correction functionality. Not all memory errors can be corrected and in all conditions except during initialisation, reading a non-correctable memory area will cause the ECU to reset. During initialisation, the software prevents resets when checking adaptive, DTC and Tune memory to determine if those memory regions have become corrupt. A non-correctable memory area detected during initialisation checks is logged in the following automatic ASAP2 variables.

Table 7.28. Automatic ASAP2 entries for memory error correction events

ASAP2 name Description Units mpl_ecc_ram_address Address of last RAM address non-correctable ECC error, zero if no error has occurred. mpl_ecc_flash_address Address of last Flash address non-correctable ECC

Copyright 2019, Pi Innovo 659 Support tools

ASAP2 name Description Units error, zero if no error has occurred. 7.1.7.8. Floating point conditions

On those ECUs which support floating-point arithmetic, some ECUs provide status information relating to floating-point operations. Given pmax as the most positive normalized value (farthest from zero), pmin the smallest positive normalized value (closest to zero), nmax the most negative normalized value (farthest from zero) and nmin the smallest normalized negative value (closest to zero), floating-point conditions are reflected in the automatic ASAP2 variables in the following table. Table 7.29. Automatic ASAP2 entries for floating point conditions

ASAP2 name Description Units mpl_flp_overflow Set if floating-point flag overflow has occurred since the last reset, clear otherwise. An overflow is said to have occurred if the numerically correct result is such that result > pmax, or result < nmax. See the processor's reference manual for more. mpl_flp_underflow Set if floating-point flag underflow has occurred since the last reset, clear otherwise. An underflow is said to have occurred if the numerically correct result is such that 0 < result < pmin, or nmin < result < 0. See the processor's reference manual for more. mpl_flp_div_by_zero Set if floating-point division flag by zero has occurred since the last reset, clear otherwise. A divide by zero condition arises when the floating-point operation is executed with a +/-0 divisor value and a finite normalized nonzero dividend value. mpl_flp_inexact Set if an inexact floating- flag point result has occurred since the last reset, clear otherwise. An inexact condition arises when the result of a floating- point operation requires rounding (is inexact), or if an overflow or underflow condition arises.

Copyright 2019, Pi Innovo 660 Support tools

ASAP2 name Description Units mpl_flp_invalid Set if an invalid floating- flag point result has occurred since the last reset, clear otherwise. An invalid condition arises when an operand in a floating- point operation contains a denormalized value, infinitity or NaN, or if both operands in a floating-point divide operation are +/-0.

Note

The platform is likely to cause the inexact condition to occur due to rounding. While the platform has been written to avoid other conditions (such as divide by zero), extreme values passed by the application to the platform may result in the platform causing other conditions to occur.

7.1.7.9. J1939 related information

The following ASAP2 entries are provided to work with J1939.

Table 7.30. Automatic ASAP2 entries for J1939 related information

ASAP2 name Description Units pj1939c_node_addr_0 The preferred node - address for this ECU. Sampled on power-up only.

7.1.7.10. Engine related information

The following ASAP2 entries are provided as a development aid on some target ECUs. They may be removed in the future. 7.1.8. OpenECU software versioning

Each target contains a set of software components, each identified by three numbers of the form x.y.z. The first number, x, identifies the major version of the software component. The other numbers, y.z identify the minor and sub-minor versions.

Table 7.31. Software component versions (for M560-000)

Processor Component Version Part-number Primary, Combined firmware code, Combined 507.0.3 36T-070093-ISS-3 MPC5746D boot and reprogramming code (default CCP baud rate, 500kbps). Combined firmware code, Combined 512.0.3 36T-070092-ISS-3 boot and reprogramming code (default CCP baud rate, 250kbps). Firmware upgrade, application 507.0.3 36T-070088-ISS-3 to reprogram boot code and

Copyright 2019, Pi Innovo 661 Support tools

Processor Component Version Part-number reprogramming code (default CCP baud rate, 500kbps). Firmware upgrade, application 512.0.3 36T-070087-ISS-3 to reprogram boot code and reprogramming code (default CCP baud rate, 250kbps). Platform library, application support to 502.0.3 36T-070085-ISS-1 access ECU functionality. ETAC for primary processor, hardware 502.0.3 36T-070086-ISS-1 embedded test application code to support parametric, function and design validation testing.

When providing technical support, Pi may need to know the version numbers for the software components.

Details on how to find out the version numbers for Main processor are given in Section 7.1.7, “Automatic ASAP2 entries”.

Version numbers for HCS12 processor can be retrieved by uploading the software, with FEPS signal applied. Contact technical support for more details. 7.2. Supporting build scripts

At steps 4 and 5 of the build process (see Section 4.6.1, “Building an application”) the compiled and linked application is transformed into two objects:

Figure 7.2. Finishing a build

ELF or ELF MAP file file

5 4

Target Target ASAP2 image file file

Final outputs from build process

4. During step 4, the compiled and linked image is transformed into a binary image. The binary image can be used by a reprogramming tool or calibration tool to reprogram the ECU.

The sub-steps required to complete this step vary depending on the compiler (see Section 7.2.1, “Creating a binary image with a supported compiler” for more).

5. During step 5, the compiled and linked image is transformed into an ASAP2 file. The ASAP2 file can be used by a reprogramming tool or calibration tool to reprogram the ECU or view the application data in real-time.

Copyright 2019, Pi Innovo 662 Support tools

The interface tool is used to create the ASAP2 file. See Section 7.1, “Interface and DDE tool” for details on how to use the interface tool, or inspect the batch files provided with the sample applications for concrete examples on how to use the tool. 7.2.1. Creating a binary image with a supported compiler

Step 4 can be broken out into three stages: creating the binary images which make up the target data; patching the library header (see Section 5.3.1.9, “Library header”); and creating S-records for the reprogramming or calibration tool.

Figure 7.3. Building the binary images

ELF file

4

Application Calibration Adaptive binary binary binary image image image

6 7

Application and Adaptive Calibration S-record S-record

8

Target image file

Final outputs from build process

4. During step 4, Diab's ddump or GNU's objcopy tool is used to extract the binary images from the compiled and linked application (an ELF file). The tool extracts binary data based on linker section names.

6. During step 6, the OpenECU CAPI-interface tool's --output-s-rec option is used to insert information into the headers located in both the library and calibration binary images. The tool inserts information about the build into the header and adds a check-sum (which the bootloader uses after ECU reset to determine whether the target ECU application code is intact or not (see Section 4.3, “System modes”).

Copyright 2019, Pi Innovo 663 Support tools

The tool also transforms the binary data in S-record format, which most reprogramming and calibration tools read.

7. During step 7, there is no need to check-sum the adaptive data and OpenECU's gen_s37_from_bin tool is used to convert the binary image directly to S-record format.

8. During step 8, the S-record files can be left as individual files (each to be programmed separately), or can be combined into a single S-record file using the operating system's copy command.

For details of each step, inspect the batch files provided with the sample applications for concrete examples on how to use the tools.

Copyright 2019, Pi Innovo 664 Appendix A. Reference documentation A.1. ECU hardware reference documentation

For each ECU, there is a technical specification which provides an overview of the electronics and components of the ECU, including a list of connectors, pin outs, pin capabilities, flash codes, and so on. These technical specifications are available from the Windows Start button and from the following links.

Generic ECUs

Available from Pi for general use.

M560-000 technicalHTML PDF specification

Customer ECUs

No Cutomer-specific ECUs are currently supported.

Further information about ECUs, including simplified I/O schematics and mechanical drawings, can be downloaded from the website (registration or purchase of ECU required) or requested through OpenECU technical support as described in Appendix K, Contact information.

Copyright 2019, Pi Innovo 665 Appendix B. OpenECU error and warning codes

This appendix provides additional information on messages generated by OpenECU. Whenever OpenECU encounters an issue, it reports the problem as an error message or as a warning message. Each message contains an integer code which can be used to index the following list. B.1. Interface tool messages B.1.1. Command line option messages

The interface tool can generate the following error and warning messages when it processes the command line options presented to the tool.

100. (error 100): unrecognised command line arguments, try -h or --help for more.

The interface tool has detected that there are command line options which mean nothing to the tool. See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

101. (error 101) file 'file name': could not open interface file for reading, 'error message'.

The interface tool could not read the interface file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

102. (error 102) file 'file name': could not open AST debug file for writing, 'error message'.

The interface tool could not create or write to the first debug file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

103. (error 103) file 'file name': could not open AST debug file for writing, 'error message'.

The interface tool could not create or write to the second debug file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

104. (error 104) file 'file name': could not open code file for writing, 'error message'.

The interface tool could not create or write to the first code file called 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

105. (error 105) file 'file name': could not open code file for writing, 'error message'.

The interface tool could not create or write to the second code file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

Copyright 2019, Pi Innovo 666 OpenECU error and warning codes

106. (error 106) file 'file name': could not open m-script file for writing, 'error message'.

The interface tool could not create or write to the MATLAB m-script file, call file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

107. (error 107) file 'file name': could not open generic ASAP2 file for writing, 'error message'.

The interface tool could not create or write to the generic ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

108. (error 108) file 'file name': could not open INCA ASAP2 file for writing, 'error message'.

The interface tool could not create or write to the ETAS INCA ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

109. (error 109) file 'file name': could not open Vision ASAP2 file for writing, 'error message'.

The interface tool could not create or write to the ATI Vision ASAP2 file called file name and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

110. (error 110): at least one command option required an ASAP2 file to be generated but no MAP file or ELF information file was specified. Try - h or --help for more information.

The interface tool has been asked to generate an ASAP2 file but has not been told the MAP or ELF information file to derive the addresses of DDEs. See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

111. (error 111): the asap2 naming pattern must be one of 'prefix_name', 'prefix.name', 'prefix.name_prefix', 'name', 'name_prefix'.

The interface tool has been told to transform the DDE names when generating an ASAP2 file, but the interface tool does not understand the transformation required (there are only a few pre-determined transforms). See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

112. (error 112): the boolean type must be specified as 'u8' or 'float'.

The interface tool has been told to generate ASAP2 boolean types with a specific type, but the interface tool does not understand the type provided. See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

113. (error 113): you may specify a Diab or GCC MAP file OR an ELF information file as input, but not both.

The interface tool has been given more than one of a Diab MAP file, a GCC MAP file, Diab ddump file, or a GCC objdump file as input but does not know which to use. Specify only one MAP file or ELF information file as input. See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

Copyright 2019, Pi Innovo 667 OpenECU error and warning codes

114. (error 114): you cannot specify data dictionary generation using -- output-elf-contents without also specifying an ELF information file to be read.

Using the command line option --output-elf-contents the interface tool has been told to generate a data dictionary file from the contents of a Diab ddump or GCC objdump file (derived from an ELF file) but no such file has been specified with the --diab-ddumpfile option or -- gcc-objfile option. See Section 7.1.2, “Running the interface tool” for a detailed explanation of the command line options available.

115. (error 115) file 'file name': could not open DDE file for writing, 'error message'.

The interface tool could not write to the data dictionary file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

116. (error 116) file 'file name': could not open [type of] file for writing, 'error message'.

The interface tool could not create or write to the file specified by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

117. (error 117): you cannot specify address list output using --output- address-list without also specifying a ELF information file to be read.

The interface tool has been told which file to output the address list to, but it has not been told which Diab ddump or GCC objdump file to read this information from.

118. (error 118): the compiler must be 'diab_5_5_1_0', 'diab_5_8', 'diab_5_9', or 'diab_5_9_4_8'.

The interface tool has been told which compiler is being used, but it does not recognise the compiler so identified.

119. (error 119) file 'file name': could not open output linker file for writing, 'error message'.

The interface tool could not write to the output linker file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again (the file may be read-only or locked by another application).

120. (error 120): to generate a linker file output you must specify the OpenECU installation base path using the --oe-base-path option.

The interface tool can only output linker file using the --output-linker- file command line option if the --oe-base-path option is also used to specify the path to the OpenECU installation.

121. (error 121) file 'file name': could not open linker source file for reading, 'error message'.

The interface tool could not read from the linker source file given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

Copyright 2019, Pi Innovo 668 OpenECU error and warning codes

122. (error 122): the compiler must be specified when outputting a linker file for the 'target name' target.

For any target that supports more than one compiler, the interface tool needs to be passed the compiler id using the --compiler-id command line option when outputting the linker file using the --output-linker-file option.

123. (error 123): no input program images. Please specify values for --img- app and --img-cal.

In order to use the --output-s-rec option, the options --img-app and --img-cal must be specified.

124. (error 124): no diab mapfile. please specify value for --diab-mapfile.

In order to use the --output-s-rec option, the option --diab-mapfile must be specified.

125. (error 125): could not open s-record file for writing.

The tool tried to create the file specified by --output-s-rec , but failed. This often means that the file already exists and is read-only, or the file was specified in a non-existing directory.

126. (error 126): could not open application image file for reading.

The tool tried to read the file specified by --img-app , but failed. This often means that the file does not exist.

127. (error 127): could not open calibration image file for reading.

The tool tried to read the file specified by --img-cal, but failed. This often means that the file does not exist.

128. (error 128): could not open linker file excerpt for reading.

The tool tried to read the file specified by --ld-excerpt-file, but failed. This often means that the file does not exist.

129. (error 129): cannot check data dictionary entity data types using -- check-dde-data-types.

The tool received an error when checking for the ELF file. When using the --check-dde-data-types option, the ELF file must be specified.

130. (error 130): Unable to validate license.

The tool received an error while verifying the license. Verify that OpenECU is installed correctly with a valid license. B.1.2. File handling messages

200. (error 200): found internal error — attempting to set the handle for file 'filename' a second time.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

201. (error 201) file 'file name': could not close file.

Copyright 2019, Pi Innovo 669 OpenECU error and warning codes

The interface tool could not close the file given by 'file name' after the file was opened to be read or written to. In this case, the interface tool may leave a temporary file called 'file name' after the tool completes.

202. (error 202): found internal error — cannot remove file 'file name' when the type of file is unknown.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

203. (error 203) file 'file name': could not delete temporary file.

The interface tool could not close the file given by 'file name' after the file was opened to be read or written to. In this case, the interface tool may leave a temporary file called 'file name' after the tool completes.

204. (error 204): found internal error — repeated file registration for 'file name'.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs. B.1.3. Interface file messages

500. (error 500) line 'number' of 'file name': incomplete string literal, or string literal containing unsupported characters.

The interface tool has read an interface file called 'file name' and found an error at line 'number' containing a string without a closing quote, or a string containing unsupported characters (only the printable ASCII characters are valid (ranging from character 32 (space) through to character 126 (tilde)). Change the interface file to contain a valid string.

501. (error 501) line 'number' of 'file name': incomplete comment.

The interface tool has read an interface file called 'file name' and found an error at line 'number' containing a comment without the final */ characters. Change the interface file to complete the comment.

502. (error 502) line 'number' of 'file name': unexpected character 'letter'.

The interface tool has read an interface file called 'file name' and found an error at line 'number' containing text which the tool does not expect to see. See Section 7.1.4, “Interface file contents” for a description of what the interface file can contain.

503. (error 503) line 'number' of 'file name': could not read number.

The interface tool has read an interface file called 'file name' and at line 'number' the interface tool could not convert the text into a number. Adjust the number to be valid and in the range [0, 2147483647].

504. (error 504) line 'number' of 'file name': number must be positive.

The interface tool has read an interface file called 'file name' and at line 'number' the interface tool found an unexpected negative number. Adjust the number to be in the range [0, 2147483647].

505. (error 505) line 'number' of 'file name': number must be less than 2147483648.

Copyright 2019, Pi Innovo 670 OpenECU error and warning codes

The interface tool has read an interface file called 'file name' and at line 'number' found a number which was too large. Adjust the number to be in the range [0, 2147483647].

506. (error 506) line 'number' of 'file name': cannot use the '-' character in an identifier.

The interface tool has read an interface file called 'file name' and found a '-' character as part of an identifier at line 'number'. Rename the identifier without the '-' character.

600. (error 600): found internal error — unexpected error.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

601. (error 601) line 'number' of 'file name': repeated identifier.

The interface tool has read an interface file called 'file name' and at line 'number' has found an identifier that has been used elsewhere in the interface file. All identifiers must be unique.

602. (error 602) line 'number' of 'file name': identifier is more than 31 characters in length.

The interface tool has read an interface file called 'file name' and at line 'number' has found an identifier with more than 31 characters. All identifiers must be limited to a maximum of 31 characters.

603. (error 603) line 'number' of 'file name': unexpected input.

The interface tool has read an interface file called 'file name' and at line 'number' has found a syntax error. See Section 7.1.4, “Interface file contents” for a description of what the interface file can contain.

604. (error 604) line 'number' of 'file name': unexpected end of file.

The interface tool has read an interface file called 'file name' and at line 'number' has encountered the end of the file while still expecting to see more detail in the interface file. This may occur if there is a missing close brace (}) in the file. See Section 7.1.4, “Interface file contents” for a description of what the interface file can contain. B.1.4. DDE processing messages

700. (error 700) file 'file name': could not open tabbed DDE file for reading, 'error message'.

The interface tool could not read the DDE file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

800. (error 800) file 'file name': could not open units file for reading, 'error message'.

The interface tool could not read the units file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

Copyright 2019, Pi Innovo 671 OpenECU error and warning codes

900. (error 900) line 'number' of 'file name': from within the 'compound' statement, there is a missing 'assignment' statement.

The interface tool has read an interface specification file called 'file name' and at line 'number' has found a compound statement with a missing assignment statement called 'assignment'. In this case, the interface tool is expecting the assignment statement to be present (i.e., the assignment statement is not optional).

901. (error 901) file 'file name': within the interface file, there is a missing 'compound' statement.

The interface tool has read an interface specification file called 'file name' and at line 'number' has found that the file is missing a compound statement called 'compound'. In this case, the interface tool is expecting the compound statement to be present (i.e., the statement is not optional).

1001. (error 1001): line 'number' of 'file name': 'dde name' is an invalid name for a data dictionary entry (must be greater than 3 characters long).

All data dictionary entry names must be greater than 3 characters long. Change the name so it is at least 4 characters in length.

1002. (error 1002): line 'number' of 'file name': 'dde name' is an invalid name for a data dictionary entry (must be less than 256 characters long).

1003. (error 1003): line 'number' of 'file name': 'dde name' is an invalid name for a prefix-style data dictionary entry (must not start with a digit or a '_' character).

To provide compatibility with C compilers, prefix-style DDE names must not start with a digit. If DDE names must start with an underscore then move the DDE to a C-style DDE file.

1004. (error 1004): line 'number' of 'file name': 'dde name' is an invalid name for a prefix-style data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

C compilers disallow certain characters to appear in variable names. Change the name to avoid the use of these characters.

1005. (error 1005): line 'number' of 'file name': 'dde name' is an invalid name for a calibration map (must end in '_x' or '_y' or '_z').

The tool has recognised that the DDE forms part of a calibration map but does not conform to the rules for naming these entities. See Section 7.1.5.2, “DDE naming rules (prefix_style)” for more details.

1006. (error 1006): line 'number' of 'file name': 'dde name' is an invalid name for an item which is not a calibration map (must not end in '_x' or '_y' or '_z').

The tool has recognised that the DDE does not form part of a calibration map and does not conform to the rules for naming these entities. See Section 7.1.5.2, “DDE naming rules (prefix_style)” for more details.

1007. (error 1007): line 'number' of 'file name': 'dde name' is a calibration but has no value.

The entry is a calibration of some sort but does not contain a default calibration value, which it must do.

Copyright 2019, Pi Innovo 672 OpenECU error and warning codes

1008. (error 1008): line 'number' of 'file name': 'dde name' has an invalid value 'text of value'.

The tool could not convert the text of the value into a numeric value. All numeric values must be scalar and represent a real value. The following are examples of valid values: 3.14, 10, 10., .001, 1e8, 3.14e-10, 0e0.

1009. (error 1009): line 'number' of 'file name': 'dde name' must be a vector or a matrix surrounded by '[' and ']').

The tool has recognised that the entry forms part of a calibration map but that the value or values supplied are not valid expressions, either of a vector or of a matrix. Values for an axis (_x or _y) should be given as a vector. Values for the data points (_z) should be given as a vector for 1-d maps or as a matrix for 2-d maps.

vector A vector takes the form [numbers separated by spaces]. An example of a vector containing three elements would be: [10, 15, 20].

matrix A matrix takes the form [vectors separated by semicolons]. An example of a matrix containing three rows and columns would be: [1 2 3; 10 20 30; 100; 200; 300].

1010. (error 1010): line 'number' of 'file name': the row sizes for 'dde name' differ."

The tool requires map axes and map data to match in size. For instance, a 1-d map with 5 elements in the x-axis, requires 5 elements in the z-data. Change the axis and data elements to match in size.

1011. (error 1011): line 'number' of 'file name': the row size for 'dde name' must be at least 2 entries.

The tool requires that map axes and map data have at least 2 elements. For instance, if a 1-d map had 1 element for the x-axis and therefore 1 element for the z-data, the map lookup would be equivalent to a scalar variable.

1012. (error 1012): line 'number' of 'file name': the row data for 'dde name' must be 1xN matrix.

The tool requires that any map axis be a vector (a 1xN matrix), the OpenECU 1-d and 2-d map lookup functions do not work with other sized matrices.

1013. (error 1013): line 'number' of 'file name': the units for 'dde name' is too long (must be less than 'number' characters long).

The units field must be less than 32 characters long by default so that it can be exported into other file formats (e.g., ASAP2 file) without issues. Either change the units so it contains less than 32 characters, or change the limit using the C-API interface tool command line option '-n' or '--name-length'.

1014. (error 1014): line 'number' of 'file name': the units for 'dde name' cannot contain single quote characters.

The units field must not contain single quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

1015. (error 1015): line 'number' of 'file name': the units for 'dde name' cannot contain double quote characters.

Copyright 2019, Pi Innovo 673 OpenECU error and warning codes

The units field must not contain double quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

1016. (error 1016): line 'number' of 'file name': the description for 'dde name' is too long (must be less than 256 characters long).

The description field must contain less than 256 characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

1017. (error 1017): line 'number' of 'file name': the description for 'dde name' cannot contain single quote characters.

The description field must not contain single quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

1018. (error 1018): line 'number' of 'file name': the description for 'dde name' cannot contain double quote characters.

The description field must not contain double quote characters so that it can be exported into other file formats (e.g., ASAP2 file) without issues.

1019. (error 1019): line 'number' of 'file name': 'dde name' has an unspecified type (must be one of: int8_T, S8, uint8_T, U8, int16_T, S16, uint16_T, U16, int32_T, S32, uint32_T, U32, real_T, F32, BOOL).

The type of the DDE must be specified for ASAP2 generation.

1020. (error 1020): line 'number' of 'file name': 'dde name' has an invalid type 'type text' (must be one of: int8_T, S8, uint8_T, U8, int16_T, S16, uint16_T, U16, int32_T, S32, uint32_T, U32, real_T, F32, BOOL).

The type of the DDE must be well defined for ASAP2 generation.

1021. (error 1021): line 'number' of 'file name': 'dde name' represents map calibration data and must have a real_T or F32 type.

OpenECU 1-d and 2-d map lookup functions only work with floating point types. Change the type of the map axis or map data to be real_T or F32.

1022. (error 1022): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the accuracy column.

The tool was expecting to find a number in the accuracy field but found something else instead.

1023. (error 1023): line 'number' of 'file name': 'dde name' has a maximum value but no minimum.

The tool expects to see both a minimum and a maximum for the DDE if one or the other is present. The DDE must either have no minimum and maximum specified or both.

1024. (error 1024): line 'number' of 'file name': 'dde name' has a minimum value but no maximum.

The tool expects to see both a minimum and a maximum for the DDE if one or the other is present. The DDE must either have no minimum and maximum specified or both.

1025. (error 1025): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the minimum value.

Copyright 2019, Pi Innovo 674 OpenECU error and warning codes

The tool was expecting to find a number in the minimum field but found something else instead.

1026. (error 1026): line 'number' of 'file name': 'dde name' has boolean type so its minimum must be zero.

The type of the DDE is a boolean, so the minimum value must be zero but the tool found a different value for the minimum field.

1027. (error 1027): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the maximum value.

The tool was expecting to find a number in the maximum field but found something else instead.

1028. (error 1028): line 'number' of 'file name': 'dde name' has boolean type so its maximum must be one.

The type of the DDE is a boolean, so the maximum value must be one but the tool found a different value for the maximum field.

1029. (error 1029): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the scale value.

The tool was expecting to find a number in the scale field but found something else instead.

1030. (error 1030): line 'number' of 'file name': 'dde name' has an invalid number 'x' for the offset value.

The tool was expecting to find a number in the scale field but found something else instead.

1032. (error 1032): line 'number' of 'file name': 'dde name' has a different matrix size from the X-axis matrix size.

The tool has detected that the z-data matrix size in for the x-axis differs in size from the x-axis. The size of the axes and data must match.

1033. (error 1033): line 'number' of 'file name': 'dde name' has a different matrix size from the Y-axis matrix size.

The tool has detected that the z-data matrix size in for the y-axis differs in size from the y-axis. The size of the axes and data must match.

1034. (error 1034): line 'number' of 'file name': 'dde name' has multiple rows but no Y-axis data dictionary entry.

The tool has detected that the z-data for a map contains data for both the x and y axes but no y-axis DDE has been declared.

1035. (error 1035): line 'number' of 'file name': 'dde name' does not have a corresponding X-axis data dictionary entry.

The tool has detected that there is z-data for a map lookup but no corresponding x-axis DDE has been declared.

1036. (error 1036): line 'number' of 'file name': 'dde name' must be a scalar.

The tool has read more than one value for the scalar calibration. Only one value can be specified.

Copyright 2019, Pi Innovo 675 OpenECU error and warning codes

1037. (error 1037): line 'number' of 'file name': an unnamed column was found — skipping entire data dictionary.

The tool has found a column without a name. This can occur if two tab characters are placed next to each other

Name Value Units Description Type Accuracy Min Max Offset Scale Cref

1038. (error 1038): line 'number' of 'file name': column 'name' is only allowed in 'style'-style data dictionaries — skipping entire 'style'-style data dictionary.

The tool has found a column in the title line of the data dictionary that it does not recognise. The only valid column names in a prefix-style data dictionary file are:

Name Value Units Description Type Enums Accuracy Min Max Offset Scale Cref

The only valid column names in a C-style data dictionary file are:

Name Units Description Accuracy Min Max Offset Scale Class Xaxis Yaxis Lookup

1039. (error 1039): line 'number' of 'file name': 'dde name' is an invalid Cref for a data dictionary entry (must not start with a digit).

The tool has found an invalid name for the Cref column. This is an internal error. Please contact OpenECU support.

1040. (error 1040): line 'number' of 'file name': 'dde name' is an invalid Cref for a data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

The tool has found an invalid name for the Cref column. This is an internal error. Please contact OpenECU support.

1041. (error 1041): line 'number' of 'file name': 'dde name' is a reserved name for a data dictionary entry (must not use the 'mpl' prefix).

The tool has found a DDE with a name which starts with mpl. This prefix is reserved for OpenECU use. Rename the DDE variable using a different prefix.

1042. (error 1042): line 'number' of 'file name': the 'field_name' field must be present in [style]-style data dictionaries — skipping entire data dictionary.

The tool has found the title line but could not locate all the necessary fields/ columns. At a minimum, the following fields/columns must be present in prefix-style data dictionaries:

Name Value Units Description Type Min Max

And for C-style data dictionaries, the following fields/columns must be present:

Name Units Description Class Min Max

In both cases, the Name field must be first.

Copyright 2019, Pi Innovo 676 OpenECU error and warning codes

1043. (error 1043): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must be greater than 3 characters long).

All data dictionary entry enumeration names must be greater than 3 characters long. Change the name so it is at least 4 characters in length.

1044. (error 1044): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must be less than 'number' characters long).

Some C compilers disallow names that contain more than 31 characters. Some ASAP2 calibration tools disallow names that contain more than 32 characters. Either change the name so it contains less than the character limit, or change the limit using the C-API interface tool command line option '-n' or '--name-length'.

1045. (error 1045): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must not start with a digit or a '_' character).

C compilers disallow names that start with a digit or '_' character. Change the DDE name to start with a letter.

1046. (error 1046): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_').

C compilers disallow certain characters to appear in names. Change the name to avoid the use of these characters.

1047. (error 1047): line 'number' of 'file name': 'dde name' is an invalid [object] name for a data dictionary entry (must not end in '_x' or '_y' or '_z').

The tool has recognised that the referenced enumeration looks like a map DDE. Rename the enumeration reference so it does not end like a map.

1048. (error 1048): line 'number' of 'file name': 'dde name' is a reserved name for a data dictionary enumeration entry (must not use the 'mpl' prefix).

The tool has found a DDE with an enumerated name which starts with mpl. This prefix is reserved for OpenECU use. Rename the DDE variable using a different prefix.

1049. (error 1049): line 'number' of 'file name': 'dde name' uses an enumeration 'enum name' that is not declared in any data dictionary.

The tool has found an enumeration reference for the DDE named 'dde name' that does not exist in any data dictionary. Change the enumeration reference to a data dictionary entry that does exist.

1050. (error 1050): line 'number' of 'file name': 'dde name' uses an enumeration 'enum_name' which has a non-scalar value.

The tool has found a reference to an enumeration which has a non-scalar value. All enumerations must be single valued entries.

1051. (error 1051): line 'number' of 'file name': 'dde name' uses enumerations 'enum_name' and 'enum_name' which have the same value.

Copyright 2019, Pi Innovo 677 OpenECU error and warning codes

The tool has found a data dictionary entry which refers to two enumerations but both enumerations have the same value. Enumerations for one data dictionary entry must have unique values.

1052. (error 1052): line 'number' of 'file name': 'dde name' has a value less than its type allows.

The tool has found a value for a data dictionary entry which has a value outside the range of its type.

1053. (error 1053): line 'number' of 'file name': 'dde name' has a value greater than its type allows.

The tool has found a value for a data dictionary entry which has a value outside the range of its type.

1054. (error 1054): line 'number' of 'file name': 'dde name' must not have a scale value of zero.

The tool has found a DDE with a scaling factor of zero. This is disallowed, as the reciprocal of the factor is used by OpenECU tools and calibration tools.

1055. (error 1055): line 'number' of 'file name': 'dde name' has no corresponding DDE called 'z-data dde name'.

The tool has found a x-axis DDE without a corresponding z-axis DDE, both are needed to create a 1-d map.

1056. (error 1056): line 'number' of 'file name': 'dde name' has no corresponding DDE called 'z-data dde name'.

The tool has found a y-axis DDE without a corresponding z-axis DDE, both are needed to create a 2-d map.

1057. (error 1057): line 'number' of 'file name': 'dde name' is a displayable with a value.

The tool has found a displayable DDE with a value, only calibration DDEs can have values.

1058. (error 1058): line 'number' of 'file name': 'dde name' has a minimum smaller than its type allows.

The tool has found a DDE which has a minimum value less than the type of the DDE can store. The minimum or type must be adjusted.

1059. (error 1059): line 'number' of 'file name': 'dde name' has a maximum larger than its type allows.

The tool has found a DDE which has a maximum value greater than the type of the DDE can store. The maximum or type must be adjusted.

1060. (error 1060): line 'number' of 'file name': 'dde name' has duplicated enumeration 'enum name'."

The tool has found a DDE which has a repeated enumeration in the DDE's enumeration list. Duplicated enumerations are disallowed.

1061. (error 1061): line 'number' of 'file name': 'class' is an invalid Class for a data dictionary entry (must be one of: 'c', 'cmap', 'caxis', 'cstring', 'carray', 'd', 'darray').

Copyright 2019, Pi Innovo 678 OpenECU error and warning codes

The string 'class' given in the Class column is not one of the allowed types for this DDE.

1062. (error 1062): line 'number' of 'file name': enum 'c identifier' has an invalid byte size = 'bytes'.

The interface tool has found an enumeration with name 'c identifier' which has a byte size it does not recognise. If this error occurs please contact OpenECU technical support.

1063. (error 1063): line 'number' of 'file name': variable 'c identifier' is a pointer; this is not supported for ASAP2 generation.

The interface tool can generate ASAP2 files but ASAP2 files cannot represent pointers. DDE references to C variables which have pointer type are therefore rejected.

1064. (error 1064): line 'number' of 'file name': variable 'c identifier' is a bitfield; this is not supported for ASAP2 generation.

The interface tool cannot yet generate ASAP2 files that access bitfields. Adjust the data structure to avoid using bitfields or copy the bitfields of interest to other variables which are accessible.

1065. (error 1065): line 'number' of 'file name': variable 'c identifier' has a type not currently supported for ASAP2 generation of 'value'.

The interface tool has found type information for a C variable that it does not know how to handle. If this message occurs, please contact OpenECU technical support.

1066. (error 1066): line 'number' of 'file name': variable 'c identifier' has class cstring but is not a byte array.

A C-style DDE has been classed as a string but the type of the equivilent C variable is not signed or unsigned char (wide characters are not supported). Either change the C variable to have an appropriate type of change the class of DDE.

1067. (error 1067): line 'number' of 'file name': variable 'dde name' is not class cmap yet has Xaxis, Yaxis and/or Lookup entries.

A C-style DDE has information in the Xaxis, Yaxis or Lookup columns but the DDE is not a calibration map. Only calibration maps should have information in the Xaxis, Yaxis or Lookup columns.

1068. (error 1068): line 'number' of 'file name': variable 'dde name' used in map must have real_T (float) type.

OpenECU 1-d and 2-d map lookup functions only work with floating point types. Change the type of the map axis or map data to be real_T or F32.

1069. (error 1069): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which caused an unexpected error.

An internal error has occurred in the interface tool. If this error occurs, please contact OpenECU technical support.

1070. (error 1070): line 'number' of 'file name': variable 'dde name' has x and y Lookup entries 'string' but no Yaxis entry.

Copyright 2019, Pi Innovo 679 OpenECU error and warning codes

The calibration map with 'dde name' is 2d and has an x-axis Lookup DDE but no y-axis Lookup DDE. Calibration maps must have a lookup DDE for each map axis.

1071. (error 1071): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which is not found in ELF data.

The lookup DDE 'name' for calibration map DDE 'dde name' doesn't exist in the Diab ddump file. Check that the spelling is correct, that the equivalent C variable is declared and not optimised away by the compiler.

1072. (error 1072): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which has no corresponding DDE, removing lookup variables from map.

The lookup DDE 'name' for calibration map DDE 'dde name' doesn't exist as a DDE in any of the other DDE files. The lookup DDE must be declared in one of the DDE files.

1073. (error 1073): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which does not have Class 'd'.

The lookup DDE 'name' for calibration map DDE 'dde name' is declared as something other than a displayable (Class column set to 'd'). Only displayable variables can be used as lookups to calibration maps.

1074. (error 1074): line 'number' of 'file name': variable 'dde name' has Lookup entry 'name' which does not have type real_T (float).

The lookup DDE 'name' for a calibration map DDE 'dde name' must have single precision floating point type to correctly match the C-API to the map lookup functions.

1075. (error 1075): line 'number' of 'file name': variable 'dde name' has Xaxis and Yaxis but only one Lookup entry; should have nothing or two.

The calibration map with 'dde name' is 2d and has one lookup DDE. Calibration maps must have a lookup DDE for each map axis. Check that the Lookup column does not specify only a y-axis lookup DDE.

1076. (error 1076): line 'number' of 'file name': 'dde name' is not found in the ELF information file output, contains an out of range array index, or is declared but not referenced in the source code.

A DDE is declared in the data dictionary but the corresponding varaible could not be found in the Diab ddump or GNU objdump output file. Check the name for spelling mistakes or add the corresponding variable to the application C code.

1077. (error 1077): line 'number' of 'file name': map variable 'dde name' has no Xaxis or Yaxis specified.

A calibration map specified by a C-style DDE has neither the Xaxis and Yaxis DDEs specified. A 1d calibration map must have the Xaxis specified, a 2d calibration map must have both the Xaxis and Yaxis specified.

1078. (error 1078): line 'number' of 'file name': 'dde name' is not found in the ddump ELF file output, contains an out of range array index, or is declared but not referenced in the source code.

Copyright 2019, Pi Innovo 680 OpenECU error and warning codes

The name for a C-style data dictionary entity wasn't present in the final linked application image and therefore cannot be processed. Check the name for spelling mistakes or add the corresponding variable to the application C code.

1079. (error 1079): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must resolve to a C identifier).

The name for a C-style data dictionary entity doesn't conform to the allowed scheme (as defined in Section 7.1.5.3.2, “DDE naming rules (C-style)”). The name of the DDE must be changed.

1080. (error 1080): line 'number' of 'file name': variable 'dde name' has Lookup entry 'string' but should have one identifier or two separated by a comma.

The Lookup column for DDE 'dde name' has an unexcepted value of 'string'. Instead the Lookup column should have one DDE name or two DDE names separated by a comma.

1081. (error 1081): line 'number' of 'file name': unexpected information at end of line — skipping entire data dictionary.

The tool has found a DDE line containing more information that there are columns. Remove the additional information and tab characters, or declare an additional column in the title line of the DDE file.

1082. (error 1082): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must not start with a digit character).

To provide compatibility with C compilers, C-style DDE names must not start with a digit.

1083. (error 1083): line 'number' of 'file name': 'dde name' is an invalid name for a C-style data dictionary entry (must only use characters 'a' through 'z', 'A' through 'Z', '0' through '9' or '_', '.', '[', ']').

The interface tool accepts a subset of the C lanaguage syntax for variable names, array and structure member access. See Section 7.1.5.3.2, “DDE naming rules (C-style)” for more details.

1085. (error 1085): line 'number' of 'file name': column 'name' is unrecognised — skipping entire data dictionary.

The tool has found a column with a name it does not recognise, i.e., not one of the allowed column names. The only valid column names in a prefix-style data dictionary file are:

Name Value Units Description Type Enums Accuracy Min Max Offset Scale Cref

The only valid column names in a C-style data dictionary file are:

Name Units Description Accuracy Min Max Offset Scale Class Xaxis Yaxis Lookup

1086. (error 1086): line 'number' of 'file name': DDE 'dde name' has Lookup entry 'string' but should have none, one or two identifiers separated by a comma.

Copyright 2019, Pi Innovo 681 OpenECU error and warning codes

The Lookup column for DDE 'dde name' has an unexcepted value of 'string'. Instead the Lookup column should have one DDE name or two DDE names separated by a comma.

1087. (error 1087): line 'number' of 'file name': 'dde name' is a constant but has no value.

The entry is a constant but does not contain a default value, which it must do.

1100. (error 1100) file 'file name': could not open 'ELF-type' output file for reading, 'error message'.

The interface tool could not read the Diab ddump or GNU objdump file named 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

1101. (error 1101): file 'file name': variable with no name attribute in ELF information file at line 'number'.

The interface tool has found an unnamed attribute in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

1102. (error 1102): file 'file name': 'object' with no type attribute in ELF information file at line 'number'.

The interface tool has found a variable or typedef declaration without additional type information in the Diab ddump or GCC objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

1103. (error 1103): file 'file name': referenced ID not found in ELF information file at line 'number'.

The interface tool has found a reference in the ELF information file with no corresponding entry, as if the Diab ddump or GNU objdump file was incomplete. If this error occurs please contact OpenECU technical support.

1104. (error 1104): file 'file name': nested array in ELF information file at line 'number'.

The interface tool has found a nested array reference in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

1105. (error 1105): file 'file name': structure element with unreadable offset in ELF information file at line 'number'.

The interface tool has found a structure member in the Diab ddump or GNU objdump file but could not read the offset information, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

1106. (error 1106): file 'file name': structure element with no offset in ELF information file at line 'number'.

The interface tool has found a structure member that the Diab ddump or GNU objdump file has no offset information for, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

Copyright 2019, Pi Innovo 682 OpenECU error and warning codes

1107. (error 1107): file 'file name': variable with no byte size in ELF information file at line 'number'.

The interface tool has found a variable without size information in the Diab ddump or GNU objdump file, something the tool was not expecting. If this error occurs please contact OpenECU technical support.

1108. (error 1108): file 'file name': DIE with two identically named attributes found.

The interface tool has found two identically named attributes in the contents of the Diab ddump file 'file name'. This is an unexpected condition, please contact OpenECU technical support if this message occurs.

1109. (error 1109): file 'file name': two DIEs with same tag 'name' found in ELF information file.

The interface tool has found two identically named DIEs in the contents of the Diab ddump or GNU objdump file 'file name'. This is an unexpected condition, please contact OpenECU technical support if this message occurs.

1110. (error 1110): auto-generated data dictionary output from the C-API has been fed back in as input; this is disallowed to avoid the possibility of attempting to write a file which is simultaneously being used as input.

The interface tool rejects attempts to read the autogenerated data dictionary file the interface tool itself generates. Instead, the autogenerated data dictionary entities of interest should be copied to a separate data dictionary file and included.

1112. (error 1112): file 'file name': no match for 'dde name' in ELF information file.

The interface tool found an array which was too small or could not find an array element while decoding the 'dde name' DDE. Check that the 'dde name' exists as a C variable and that the variable has not been optimised away by the compiler.

1113. (error 1113): file 'file name': no match for 'dde name' in ELF information file — array bound exceeded.

The interface tool has found a matching C variable for the DDE 'dde name' but one of the array range specifiers in the DDE is outside the bounds of the equivalent array range of the C variable.

1114. (error 1114): file 'file name': unexpected section type 'name' in ELF information file.

The interface tool found an ELF section in the Diab ddump or GNU objdump file it wasn't expecting. If this error occurs, please contact OpenECU technical support.

1115. (error 1115): file 'file name': no debug variables or section information found in ELF information file — is this a Diab 5.5.1.0 (or later) ddump -Dht file?

The interface tool could read the Diab ddump or GNU objdump file but did not find any C variable or ELF section information. Check that the correct file was specified in the command line options.

Copyright 2019, Pi Innovo 683 OpenECU error and warning codes

1116. (error 1116): file 'file name': no match for 'dde name' in ELF information file.

The interface tool could not find information about DDE 'dde name' in the Diab ddump or GNU objdump output file. This may occur if there is no equivilent C variable with the same name as the DDE.

1117. (error 1117): line 'number' of file 'file name': 'dde name' has an invalid number 'number' for the sample rate value.

The interface tool expects the sample rate value to be a natural integer.

1118. (error 1118): line 'number' of file 'file name': the group for 'dde name' cannot contain single quote characters.

The interface tool expects each group name to avoid the use of the single quote character ', to avoid issues with ASAP2 validation by calibration tools.

1119. (error 1119): line 'number' of file 'file name': the group for 'dde name' cannot contain double quote characters.

The interface tool expects each group name to avoid the use of the double quote character ", to avoid issues with ASAP2 validation by calibration tools.

1120. (error 1120): line 'number' of file 'file name': the group for 'dde name' is invalid (group must start with a '/' character).

The interface tool expects each group name to be empty or start with a / character denoting the top of the hierachy. In this case, the group is not empty, change the group string to start with a / character.

1121. (error 1200): line 'number' of file 'file name': there must be no more than 8 DAQ rasters defined for CCP messaging.

The platform software does not support more than 8 DAQ rasters. Reduce the total number of rasters to 8 or less.

1122. (error 1201): line 'number' of file 'file name': the total size of the CCP DAQ rasters must be no more than 254.

The CCP protocol does not support more than 254 ODTs for all of the defined rasters. Reduce the size of each raster to total less than the allowed limit.

1123. (error 1202): line 'number' of file 'file name': the CCP DAQ raster name '%s' must not be repeated.

When generating an ASAP2 file, the interface tool requires that the name of each CCP DAQ raster is unique. This avoids situations where a calibration tool displays the same raster name for different rasters, making the selection of raster ambiguous.

1124. (error 1203): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate not smaller than 5 milliseconds.

The platform software supports CCP DAQ rasters with a base period of 5 milliseconds. Increase the raster rate to be at least 5 milliseconds.

1125. (error 1204): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate not exceeding 10 seconds.

The platform software supports CCP DAQ rasters with a maximum period of 10 seconds. Reduce the raster rate to at least 10 seconds.

Copyright 2019, Pi Innovo 684 OpenECU error and warning codes

1126. (error 1205): line 'number' of file 'file name': the CCP DAQ raster named 'raster-name' must have a rate that is a multiple of 5 milliseconds.

The platform software supports CCP DAQ rasters with a period resolution of 5 milliseconds. Adjust the raster rate to be a multiple of 5 milliseconds.

1127. (error 1206): line 'number' of file 'file name': the CCP DAQ raster named '%s' must have have at least one ODT.

The platform software does supports CCP DAQ rasters with one or more ODTs. Increase the raster size to at least 1.

1128. (warning 1207): line 'number' of file 'file name': the CCP DAQ raster rate '%s' is repeated and may confuse some calibration tools.

Not all calibration tools support multiple CCP DAQ rasters with the same periodic rate (for example, INCA v.5.1.2). Workaround the calibration tool issue by changing the periodic rates of rasters to differ.

2001. (warning 2001): line 'number' of 'file name': 'dde name' has type 'type' which supports at most 'x' digits of display after the decimal point.

The tool has detected that the type of the element can support a certain number of digits after the decimal point, but the DDE accuracy field asks for more digits to be displayed. The tool reduces the number of digits to be displayed after the decimal point to the maximum supported by the type.

2002. (warning 2002): line 'number' of 'file name': 'dde name' has a value less than the minimum specified.

The minimum specified for the DDE is greater than the minimum value given. The minimum field is adjusted to the minimum of the values.

2003. (warning 2003): line 'number' of 'file name': 'dde name' has a minimum greater than the maximum.

The tool was expecting to see a minimum value less than the maximum value but this was not the case.

2004. (warning 2004): line 'number' of 'file name': 'dde name' has a value greater than the maximum specified.

The maximum specified for the DDE is greater than the maximum value given. The maximum field is adjusted to the maximum of the values.

2005. (warning 2005): file 'file name': repeated unit 'units'.

The tool has read the unit 'units' more than once. The redundant copy (or copies) can be removed from the units file.

2006. (warning 2006): file 'file name': empty units file.

A units file is present but it contains no unit definitions (the file contains whitespace or comments only).

2007. (warning 2007): line 'number' of 'file name': the unit 'unit name' for DDE 'dde name' is not in the units file.

The tool has read a DDE with a unit definition that does not match any from the units file. Edit the unit definition for that DDE to match any unit definition in the units file, or extend the units file accordingly.

Copyright 2019, Pi Innovo 685 OpenECU error and warning codes

2008. (warning 2008): file 'file name': found an empty tabbed DDE file.

A tabbed DDE file is present but it contains no DDE definitions (the file contains whitespace or comments only).

2009. (warning 2009): file 'file name': found repeated DDE 'dde name', discarding DDE.

A repeated DDE named 'dde name' was found in file file name. The original DDE is retained and the duplicate is ignored.

2010. (warning 2010): line 'number' of 'file name': variable 'c identifier' occurs at more than one address.

The interface tool has found more than address in memory for the same C variable and does not know which address to use. If this warning occurs please contact OpenECU technical support.

2011. (warning 2011): line 'number' of 'file name': ignoring variable 'dde name' for which no type information was obtained from the ELF information file; this may occur if it is declared but not actually used in source code, or if you specify a containing structure instead of a specific element within it.

The interface tool found a DDE which had no corresponding type information. The DDE information was either derived from a Diab MAP file (which does not contain type information), or the DDE was declared but not used in the source code, or the DDE name refers to a structure rather than a structure member. If a Diab MAP file was used, consider using the Diab ELF file instead, otherwise check the DDE name use in the application source.

2501. Warning (2501): 'dde_name' is an unrecognised map type. Skipping this DDE.

The tool has found a data dictionary entry which appears as if it were a map but does not follow the naming convention specified in Section 7.1.5.2, “DDE naming rules (prefix_style)”.

2502. Warning (2502): 'dde_name' must be a 1xN vector. Skipping this DDE.

The tool has found a data dictionary entry which is an array or a axis DDE but the data for the DDE isn't a vector (as required).

2503. Warning (2503): 'dde_name' must be a MxN matrix. Skipping this DDE.

The tool has found a data dictionary entry which is the z-data for a map but the data for the DDE isn't a 2-D matrix (as required).

2504. Warning (2504): 'dde_name' the x-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector. Skipping this DDE.

The tool has found a data dictionary entry which has a x-axis DDE which isn't a vector (as required).

2505. Warning (2505): 'dde_name' the size of the x-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector (where N > 1). Skipping this DDE.

The tool has found a data dictionary entry for an x-axis with only one element. X-axis DDEs should have at least two elements.

Copyright 2019, Pi Innovo 686 OpenECU error and warning codes

2506. Warning (2506): 'dde_name' the size of the x-axis DDE 'dde_name' differs from the number of columns in the map DDE 'map_dde_name'. Skipping this DDE.

The tool has found a data dictionary entry for an x-axis which does not match the size of the corresponding z-data map DDE.

2507. Warning (2507): 'dde_name' the y-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector. Skipping this DDE.

The tool has found a data dictionary entry which has a y-axis DDE which isn't a vector (as required).

2508. Warning (2508): 'dde_name' the size of the y-axis DDE 'dde_name' for map 'map_dde_name' must be a 1xN vector (where N > 1). Skipping this DDE.

The tool has found a data dictionary entry for a y-axis with only one element. Y-axis DDEs should have at least two elements.

2509. Warning (2509): 'dde_name' the size of the y-axis DDE 'dde_name' differs from the number of columns in the map DDE 'map_dde_name'. Skipping this DDE.

The tool has found a data dictionary entry for a y-axis which does not match the size of the corresponding z-data map DDE. B.1.5. Automatic DDE generation messages

400. (error 400): found internal error while searching for an 'os-native' statement — not found but should be present.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

402. (error 402): while creating automatic adaptive DDE 'dde name' an existing DDE of the same name was found — do not replicate adaptive DDEs in DDE files.

The interface tool has tried to create an automatic adaptive DDE for the corresponding DDE named 'dde name' but found that one is already present. This situation occurs because one of the DDE files contains a definition for a DDE that the interface tool requires — rename the DDE.

403. (error 403): there is no DDE for the adaptive 'adaptive name'.

The interface tool has read an interface file which declares some adaptive data using the adaptive-list statement (see Section 7.1.4.36, “Compound statement: adaptives”) but there is no corresponding DDE for the 'adaptive name'. Update one of the DDE files to include a definition of the adaptive data.

404. (error 404): while creating automatic tune DDE 'dde name' an existing DDE of the same name was found -- do not replicate tune DDEs in DDE files.

The interface tool has tried to create an automatic Tune DDE for the corresponding DDE named 'dde name' but found that one is already present. This situation occurs because one of the DDE files contains a definition for a DDE that the interface tool requires — rename the DDE.

Copyright 2019, Pi Innovo 687 OpenECU error and warning codes

405. (error 405): there is no DDE for the tune 'tune name'.

The interface tool has read an interface file which declares some Tune data using the tune-list statement (see Section 7.1.4.39, “Compound statement: tunes”) but there is no corresponding DDE for the 'tune name'. Update one of the DDE files to include a definition of the adaptive data.

406. (error 406): found internal error — could not find 'named' node.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

407. (error 407): found internal error — could not find 'named' declaration.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs. B.1.6. Code generation messages

950. (error 950): line 'number' of 'file name': from within the 'compound' statement, there is a missing 'assignment' statement.

The interface tool has read an interface specification file and found a compound statement with a missing assignment statement called 'assignment'. In this case, the interface tool is expecting the assignment statement to be present (i.e., the assignment statement is not optional).

950. (error 950): within the 'compound' statement, at least one of these lists of statements must be provided completely (entries marked * are already present):

(error 950): 1. 'list-of-statements'

(error 950): 2. 'list-of-statements'

The interface tool has read an interface specification file and found a compound statement with a missing assignment statement. In this case, the interface tool is expecting the compound statement to contain assignment statements from one of the lists presented (i.e., some assignment statements are not optional).

951. (error 951): within the interface file, there is a missing 'compound' statement.

The interface tool has read an interface specification file and found that the file is missing a compound statement called 'compound'. In this case, the interface tool is expecting the compound statement to be present (i.e., the statement is not optional). Missing assignment statements are marked by the absence of an asterisk.

951. (error 951): within the interface file, at least one of these lists of statements must be provided completely (entries marked * are already present):

(error 951): 1. 'list-of-statements'

(error 951): 2. 'list-of-statements'

The interface tool has read an interface specification file and found a compound statement with a missing assignment statement. In this case, the

Copyright 2019, Pi Innovo 688 OpenECU error and warning codes

interface tool is expecting the compound statement to contain assignment statements from one of the lists presented (i.e., some assignment statements are not optional). Missing assignment statements are marked by the absence of an asterisk.

3090. (error 3090): incorrect declarations in target-ecu statement

The interface tool has not been able to identify the target based on the declarations given in the target-ecu statement. See error text emitted for specific information.

3091. (error 3091): more than one target-ecu statement is present.

The interface tool has found more than one target-ecu compound statement in an interface file, where the tool was expecting only one.

3092. (error 3092): no target-ecu statement specified.

The interface tool has found no target-ecu statement in an interface file, when the tool was expecting one.

3093. (error 3093): missing declarations in target-ecu statement.

The interface tool has found that required declarations were missing from the target-ecu compound statement. See the error text emitted for further details.

3094. (error 3094): multiple declarations in target-ecu statement.

The interface tool has found multiple declarations in the target-ecu compound statement. See the error text emitted for further details.

3095. (error 3095): 'hw-issue-number' outside range [0, 65535].

The interface tool has found a hw-issue-number outside the value range of [0, 65535].

3096. (error 3096): 'hw-option' must be a three-character text string.

The interface tool has found a hw-option text string that was not three characters long.

3101. (error 3101): more than one application statement is present.

The interface tool has found more than one application compound statement in an interface file, where the tool was expected only one.

3102. (error 3102): miscellaneous error in application statements.

This error code is emitted for a variety of issues with application statements. See error text emitted for details of problem identified.

3103. (error 3103): 'version' outside range [0, 65535]

The interface tool has found a major-version, minor-version or subminor- version number outside the value range of [0, 65535].

3121. (error 3121): more than one memory-config statement is present

The interface tool has found a repeated memory-config compound statement in an interface file (the tool expects only one).

Copyright 2019, Pi Innovo 689 OpenECU error and warning codes

3123. (error 3123): memory configuration is not supported on this target

Only certain targets support memory configuration. Please consult Appendix D, Memory configurations for further details.

3131. (error 3131): more than one os-native statement is present.

The interface tool has found a repeated os-native compound statement in an interface file (the tool expects only one).

3141. (error 3141): more than one stack-size statement specified.

The interface tool has found a repeated stack-size statement in an interface file (the tool expects only one).

3142. (error 3142): no stack-size statement specified.

The interface tool has not found the stack-size statement in an interface file (the tool was expecting one).

3143. (error 3143): stack size less than 1024 bytes.

The interface tool has found a stack-size statement specifying less than 1024 bytes (the tool requires at least 1024 bytes to be specified).

3151. (error 3151): miscellaneous task statement error.

The interface tool reports this error code for several different errors relating to OS task declarations. See emitted error text for details of the problem identified.

3152. (error 3152): no task statement specified.

The interface tool has found no tasks specified in an os-native compound statement (the tool expects at least one).

3153. (error 3153): more than 12 tasks specified.

The interface tool has found more than 12 tasks specified in an os-native compound statement (the tool expected less than 12).

3154. (error 3154): task has no specified 'name' statement.

The interface tool has found a task compound statement without a required 'name' statement.

3155. (error 3155): duplicate task name for task 'name' already exists.

The interface tool has found a task named 'name' more than once (all task names must be unique).

3156. (error 3156): an existing task 'name' already has a priority of 'value'.

The interface tool has found a task with a priority of 'value' but the priority value is not unique (all task priority values must be unique).

3157. (error 3157): task rate less than 1 millisecond.

The interface tool has found a task with a period less than one millisecond (the tool does not support task rates less than one millisecond).

3158. (error 3158): task rate greater than 1 hour.

Copyright 2019, Pi Innovo 690 OpenECU error and warning codes

The interface tool has found a task with a period greater than one hour (the tool does not support task rates greater than one hour).

3163. (warning 3163): offset greater than twice period for task.

The interface tool has found a task with an offset (delay before first execution) time that is more than twice the task period. This is allowed but the warning is generated in case the long offset was specified accidentally.

3166. (error 3166): more than one task declared 'tdc-firing'.

The interface tool has found more than one top-dead-centre triggered angular task. Currently only one such task is supported.

3167. (error 3167): tasks with a 'tdc-firing' trigger are only supported by (xxx) targets.

The interface tool has found an angle-triggered task specified for an ECU target which does not yet support angular tasks.

3171. (error 3171): resource has no specified name statement.

The interface tool has found a resource compound statement without a required name statement.

3172. (error 3172): attempt to rename resource 'name'.

The interface tool has found a resource compound statement with a repeated name statement.

3173. (error 3173): resource with name 'name' already exists.

The interface tool has found a resource compound statement with a name statement identical to another resource statement (all resource names must be unique).

3174. (error 3174): task 'name' already present in used-by-task statement.

The interface tool has found a used-by-task statement which repeats a reference to a task (all references must be unique).

3175. (error 3175): task 'name' in used-by-task statement is not declared.

The interface tool has found a used-by-task statement which refers to a task which is not specified.

3181. (error 3181): more than one can-messaging statement is present.

The interface tool has found a repeated can-messaging compound statement (the tool expects to find only one).

3182. (error 3182): number of CAN receive messages is reassigned.

The interface tool has found a repeated number-of-receive-messages statement (the tool expects to find only one).

3183. (error 3183): number of CAN receive messages is outside the range [0,100].

The interface tool has found a number-of-receive-messages statement with a value outside the valid range of [0, 100].

Copyright 2019, Pi Innovo 691 OpenECU error and warning codes

3184. (error 3184): number of CAN transmit messages is outside the range [0,100].

The interface tool has found a number-of-transmit-messages statement with a value outside the valid range of [0, 100].

3191. (error 3191): more than one PGN pdu-datapage statement specified.

The interface tool has found a repeated pdu-datapage statement within a pgn-receive compound statement (the tool expects to see only one).

3201. (error 3201): more than one ccp-messaging statement is present.

The interface tool has found a repeated ccp-messaging statement (the tool expects only one).

3202. (error 3202): miscellaneous CCP-related error.

The interface tool reports this error code for several reasons relating to CAN Calibration Protocol statements. See error text emitted for details of problem.

3203. (error 3203): CCP CRO identifier of 'value' is outside the range [0,2047].

The CRO identifier was specified to be in standard ID mode, and the interface tool has found a cro statement with value outside the valid range.

3204. (error 3204): CCP DTO identifier of 'value' is outside the range [0,2047].

The DTO identifier was specified to be in standard ID mode, and the interface tool has found a dto statement with value outside the valid range.

3205. (error 3205): CCP CRO and DTO identifiers both have the same value of 'value'.

The interface tool has found a cro and dto statement with identical CAN identifier values (the CRO and DTO CAN identifiers must be unique).

3206. (error 3206): CCP station address identifier of 'value' is outside the range [0,255].

The interface tool has found a station-address statement with value outside the valid range.

3207. (error 3207): CCP bus 'value' is outside the range [0,2] supported by target 'name'.

The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

3208. (error 3208): CCP baud rate of 'value' kBps is not supported.

The interface tool has found a baud statement with an unsupported value. See Section 7.1.4.15, “Compound statement: ccp-messaging” for supported baud rates.

3209. (error 3209): more than one cro-ext-id statement specified.

The interface tool has found more than one cro-ext-id statement in the c- api interface file.

3210. (error 3210): more than one dto-ext-id statement specified.

Copyright 2019, Pi Innovo 692 OpenECU error and warning codes

The interface tool has found more than one dto-ext-id statement in the c- api interface file.

3211. (error 3211): CCP CRO identifier of 'value' is outside the range [0,536870911].

The CRO identifier was specified to be in extended ID mode, but the cro statement still specifes a value outside of the 29 bit range. range.

3212. (error 3212): CCP DTO identifier of 'value' is outside the range [0,536870911].

The DTO identifier was specified to be in extended ID mode, but the dto statement still specifes a value outside of the 29 bit range.

3221. (error 3221): more than one j1939-messaging statement is present.

The interface tool has found a repeated j1939-messaging compound statement (the tool expects only one).

3223. (error 3223): J1939 CAN bus 'value' is outside the range [0,2] supported by target 'name'.

The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

3224. (error 3224): J1939 message buffer size 'value' is outside the range [8,1785]")

The interface tool has found a size-of-message-buffer statement with a value outside the valid range.

3225. (error 3225): J1939 number of simultaneous receive messages value of 'value' is outside the range [1,20].

The interface tool has found a num-simultaneous-rx statement with a value outside the valid range.

3226. (error 3226): J1939 number of simultaneous transmit messages value of 'value' is outside the range [1,20].

The interface tool has found a num-simultaneous-tx statement with a value outside the valid range.

3227. (error 3227): J1939 num-rx-tx value of 'value' is outside the range [1,100].

The interface tool has found a num-rx-tx statement with value outside the valid range.

3236. (error 3236): miscellaneous J1939-related error.

The interface tool reports this error code for several different issues related to J1939 declarations. See error text emitted for details of problem.

3241. (error 3241): J1939 node address of 'value' is reserved and cannot be used in the list of DMx nodes.

The interface tool has found the address 254 or 255 in a listen-for-dm1- message or listen-for-dm2-message statement (addresses 254 and 255 are reserved by the J1939 protocol).

Copyright 2019, Pi Innovo 693 OpenECU error and warning codes

3242. (error 3242): J1939 node address of 'value' equals the this-node address.

The interface tool has found a listen-for-dm1-message or listen-for-dm2- message statement which refers to the address of this node (the tool will not listen for its own DM1 and DM2 messages).

3251. (error 3251): more than one J1939 this-node statement is present.

The interface tool has found a repeated this-node statement within a j1939- messaging compound statement (the tool expects only one).

3252. (error 3252): miscellaneous J1939-related error.

The interface tool reports this error code for several different issues related to J1939 declarations. See error text emitted for details of problem.

3253. (error 3253): J1939 node address cannot be 254 or 255.

The interface tool has found a this-node compound statement containing an address statement using a reserved address (valid address range is [0, 253]).

3254. (error 3254): J1939 node industry-group value of 'value' is outside range of [0,7].

The interface tool has found a this-node compound statement containing an industry-group statement with invalid value.

3255. (error 3255): J1939 node vehicle-system-instance value of 'value' is outside range of [0,15].

The interface tool has found a this-node compound statement containing a vehicle-system-instance statement with invalid value.

3256. (error 3256): J1939 node vehicle-system value of 'value' is outside range of [0,127].

The interface tool has found a this-node compound statement containing a vehicle-system statement with invalid value.

3257. (error 3257): J1939 node function value of 'value' is outside range of [0,255].

The interface tool has found a this-node compound statement containing a function statement with invalid value.

3258. (error 3258): J1939 node function-instance value of 'value' is outside range of [0,31].

The interface tool has found a this-node compound statement containing a function-instance statement with invalid value.

3259. (error 3259): J1939 node ecu-instance value of 'value' is outside range of [0,7].

The interface tool has found a this-node compound statement containing an ecu-instance statement with invalid value.

3260. (error 3260): J1939 node manufacturer-code value of 'value' is outside range of [0,2047].

Copyright 2019, Pi Innovo 694 OpenECU error and warning codes

The interface tool has found a this-node compound statement containing a manufacturer-code statement with invalid value.

3261. (error 3261): J1939 node identify-number value of 'value' is outside range of [0,2097151].

The interface tool has found a this-node compound statement containing an identify-number statement with invalid value.

3271. (error 3271): more than one PGN size statement specified.

The interface tool has found a pgn-receive compound statement containing a repeated size statement (the tool expects only one).

3276. (error 3276): J1939 PGN has a size outside the range of [0,1785] bytes.

The interface tool has found a pgn-receive compound statement containing a size statement with an invalid value.

3277. (error 3277): J1939 PGN has a size larger than the J1939 message buffer.

The interface tool has found a pgn-receive compound statement containing a size statement with a value greater than the value specified in the J1939 size-of-message-buffer statement. All J1939 messages must not exceed the size specified in the size-of-message-buffer statement.

3278. (error 3278): duplicate PGN requested information found.

The interface tool has found a more than one pgn-receive compound statement with the same PGN (the tool expects only one).

3291. (error 3291): miscellaneous J1939 PGN-related error.

The interface tool reports this error code for several different issues related to J1939 PGN declarations. See error text emitted for details of problem.

3292. (error 3292): pdu-datapage value of 'value' is outside the range [0,1].

The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-datapage statement with an invalid value.

3293. (error 3293): pdu-format value of 'value' is outside the range [0,255].

The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-format statement with an invalid value.

3294. (error 3294): pdu-specific value of 'value' is outside the range [0,255].

The interface tool has found a pgn-receive or pgn-requested compound statement containing a pdu-specific statement with an invalid value.

3295. (error 3295): J1939 PGN has a PDU format less than 240 and a PDU specific value that is non-zero.

The interface tool has found a pgn-receive or pgn-requested compound statement where the PDU1 format requires the PDU specific to be specified as zero (the library substitutes the destination address automatically).

3296. (error 3296): duplicate PGN receive information found.

Copyright 2019, Pi Innovo 695 OpenECU error and warning codes

The interface tool has found a more than one pgn-requested compound statement with the same PGN (the tool expects only one).

3297. (error 3297): duplicate PID ID found.

The interface tool has found more than one PID with its j1979-8bit-id statement set to the same identifier.

3298. (error 3298): duplicate PID ID found.

The interface tool has found more than one PID with its kwp-8bit-id statement set to the same identifier.

3299. (error 3299): duplicate PID ID found.

The interface tool has found more than one PID with its iso-16bit-id statement set to the same identifier.

3300. (error 3300): duplicate DTE ID 'id' found

The interface tool has found a DTE identifier 'id' more than once (DTE IDs must be unique).

3301. (error 3301): more than one DTC storage statement specified.

The interface tool has found a dtc-data compound statement with a repeated storage statement (the tool expects one).

3302. (error 3302): target 'name' does not support battery backed RAM storage.

The interface tool has found a dtc-data compound statement containing a storage statement which specifies battery backed RAM for a target which does not implement battery backed RAM.

3303. (error 3303): DTCs are not supported for target 'name'.

The interface tool has found a dtc-data compound statement for a target which does not support DTCs.

3304. (error 3304): duplicate DME ID 'id' found

The interface tool has found a DME identifier 'id' more than once (DME IDs must be unique).

3305. (error 3305): undeclared Monitor group ID 'id' used

The interface tool has found that the Monitor group ID 'id' defined for the DTE is not defined (each DTE must be associated with a Monitor that exists).

3311. (error 3311): miscellaneous DTC error.

The interface tool reports this error code for several issues relating to J1939 and ISO-15765 Diagnostic Trouble Codes. See error text emitted for details of problem.

3312. (error 3312): duplicate DTC named 'name' specified.

The interface tool has found a dtc- compound statement containing a name statement specifying an identical name to another object (the tool expects all names to be unique).

Copyright 2019, Pi Innovo 696 OpenECU error and warning codes

3313. (error 3313): DTC uses an undeclared table 'name'.

The interface tool has found a dtc compound statement containing a table statement that refers to an unspecified table.

3314. (error 3314): J1939 DTC SPN value of 'value' is outside the range [0,524287].

The interface tool has found a dtc-j1939 compound statement containing a spn statement with an invalid value.

3315. (error 3315): J1939 DTC FMI value of 'value' is outside the range [0,31].

The interface tool has found a dtc-j1939 compound statement containing a fmi statement with an invalid value.

3316. (error 3316): J1939 DTC CM value of 'value' is outside the range [0,1].

The interface tool has found a dtc-j1939 compound statement containing a cm statement with an invalid value.

3317. (error 3317): duplicate DTE ID 'id' specified

The interface tool has found a DTE identifier 'id' more than once (DTE IDs must be unique).

3318. (error 3318): duplicate DME ID 'id' specified

The interface tool has found a DME identifier 'id' more than once (DME IDs must be unique).

3319. (warning 3319): DTE uses an undefined DME 'id'

The interface tool has found that the DME ID 'id' defined within the DTE is not defined (each DTE should be associated with a DME that exists, otherwise it is orphaned).

3320. (warning 3320): no DTEs have been defined for this DME 'id'

The interface tool has found that the DME ID 'id' has not been associated with any DTE. This is allowed, but a warning is raised to check if it is intentional.

3321. (warning 3321): ISO diagnostics physical address and functional address receive IDs are the same

The interface tool has found that the same ID has been used for the Physical and Functional Rx on ISO-15765 comms. This is currently allowed, but a warning is raised in case this was unintentional.

3341. (error 3341): adaptive adaptive name has already been specified.

The interface tool has found more the same adaptive parameter name listed more than once.

3345. (error 3345): more than one adaptive storage statement specified.

The adaptive storage statement specifies where adaptives should be stored when the ECU is not powered (e.g. flash, battery-backed RAM). Only one such statement is allowed.

3346. (error 3346): target target_name does not support battery backed RAM storage.

Copyright 2019, Pi Innovo 697 OpenECU error and warning codes

The adaptive storage statement specifies where adaptives should be stored when the ECU is not powered (e.g. flash, battery-backed RAM). Here a target ECU has been specified which does not support battery backed RAM storage.

3351. (error 3351): Tunes are not supported for target 'name'.

The interface tool has found a tunes compound statement for a target which does not support Tunes.

3352. (error 3352): no application statement specified.

The interface tool has found no application statement in an interface file, when the tool was expecting one.

3353. (error 3353): no os-native statement specified.

The interface tool has not found the os-native compound statement in an interface file (the tool was expecting one).

3354. (error 3354): task 'name' has no specified 'priority' statement.

The interface tool has found a task compound statement without a required 'priority' statement.

3355. (error 3355): task 'name' has no specified 'period' statement.

The interface tool has found a task compound statement for a periodic task which has no (or zero) repetition time period specified.

3356. (error 3356): task 'name' has a specified 'period' statement.

The interface tool has found a task compound statement for a non-periodic (e.g. angular) task which has a repetition time period specified.

3357. (error 3357): task 'name' has no specified 'function' statement.

The interface tool has found a task compound statement for a task which has no C function specified.

3358. (error 3358): resource 'name' has no specified used-by-task statement.

The interface tool has found a resource compound statement without a required used-by-task statement.

3359. (error 3359): number of CAN transmit messages is reassigned.

The interface tool has found a repeated number-of-transmit-messages statement (the tool expects to find only one).

3360. (error 3360): more than one DTC lamp state priority statement specified.

The interface tool has found a dtc-data compound statement with a repeated dtc-lamp-state-priority statement (the tool expects at most one).

3361. (error 3361): more than one DTC transition previously active to pending statement specified.

The interface tool has found a dtc-data compound statement with a repeated dtc-transition-prev-active-to-pending statement (the tool expects at most one).

Copyright 2019, Pi Innovo 698 OpenECU error and warning codes

3401. (error 3401): PID ID out of range.

The interface tool has found a diagnostic PID with an out of range 16-bit ID number.

3402. (error 3402): ISO diagnostics receive ID is outside the range

The interface tool has found an receive ID beyond permitted range for ISO-15765 (permitted range is [0, 0x7FF] for standard ID and [0, 0x1FFFFFF] for extended ID).

3403. (error 3403): ISO diagnostics physical address receive ID is same as the transmit ID

The interface tool has found that the same ID has been used for the Physical Rx and Tx IDs for ISO-15765 (the receive and transmit IDs have to be different).

3404. (error 3404): ISO diagnostic tx buffer size must be in range [1, 4095]

The interface tool has found that the Tx buffer size defined for ISO-15765 is out of allowed range.

3405. (error 3405): ISO diagnostic rx buffer size must be in range [1, 4095]

The interface tool has found that the Rx buffer size defined for ISO-15765 is out of allowed range.

3406. (error 3406): more than one ISO Diagnostic can-bus statement specified

The interface tool has found a repeated ccp-messaging statement (the tool expects only one).

3407. (error 3407): PID ID out of range.

The interface tool has found a diagnostic PID with an out of range 8-bit ID number.

3408. (error 3408): J1939 dm7-req-buf-size value of 'value' is outside the range [1,10]

The interface tool has found that the DM7 request buffer/ queue size is out of allowed range.

3409. (error 3409): duplicate AECD number error.

The interface tool has found a more than one aecd compound statement with the same AECD number (the tool expects only one).

3410. (error 3410): test map position out of range.

The interface tool has found a test map position outside the permitted range of [1, 64].

3411. (error 3411): test ID is out of range.

The interface tool has found a test ID outside the permitted range of [1, 0xFF].

3412. (error 3412): test map position redefined.

Copyright 2019, Pi Innovo 699 OpenECU error and warning codes

The interface tool has found a test map position that has been assigned to more than one test ID.

3413. (error 3413): DTC time-to-derate value out of range.

The interface tool has found a DTC time-to-derate value outside the permitted range of [0, 225000] seconds.

3414. (error 3414): J1939 Suspect Parameter Number (SPN) out of range.

The interface tool has found a J1939 SPN outside the permitted range of [0, 524287].

3415. (error 3415): J1939 multiframe-priority value out of range.

The interface tool has found the J1939 multiframe-priority value outside the permitted range of [0, 7].

3416. (error 3416): ISO bus 'value' is outside the range [0,2] supported by target 'name'.

The interface tool has found a can-bus statement referring to a CAN bus which isn't implemented by the target.

3421. (error 3421): ISO diagnostic maximum number of UDS dynamically defined identifiers must be in range [0, 255].

3422. (error 3422): ISO diagnostic maximum number of UDS periodic identifiers must be in range [0, 254].

3423. (error 3423): ISO diagnostic periodic ID base period must be in range [20, 65530].

3430. (error 3430): DTC extended data record number 'value' is outside the range [1,239].

The interface tool has found a DTC extended data record number outside of the permitted range of [1,239].

3572. (error 3572): target declaration in target-ecu statement.

The interface tool has found a target declaration in the target-ecu statement for an interface file. The use of target declarations is now deprecated and will become illegal in a future release. Please delete this declaration.

3501. (error 3501): DTE or DME identifier is not defined.

The interface tool has found a dte statement without the required dte-id or a dme statement without the required dme-id statement.

3503. (error 3503): Routine identifier is not defined.

The interface tool has found a routine statement without the required iso-16bit-id statement.

3504. (error 3504): Routine identifier is reserved by the platform.

The interface tool has found a routine statement that has the iso-16bit-id statement set to a routine ID that is reserved by the platform software. Please select a different routine ID.

3505. (error 3505): Duplicate routine ID found.

Copyright 2019, Pi Innovo 700 OpenECU error and warning codes

The interface tool has found more than one UDS service $31 routine with its iso-16bit-id statement set to the same identifier.

3506. (error 3506): Routine data byte length outside of range [0, 4095]

The interface tool has found that the byte length for a UDS service $31 data item is out of allowed range of [0, 4095].

3572. (error 3572): target declaration in target-ecu statement.

The interface tool has found a target declaration in the target-ecu statement for an interface file. The use of target declarations is now deprecated and will become illegal in a future release. Please delete this declaration.

3574. (error 3574): missing hw-part-number declaration in target-ecu statement.

The interface tool has found the hw-part-number declaration to be missing from the target-ecu statement for an interface file. A default hw-part-number as displayed in the warning text emitted has been reconstructed using the target declaration instead. Please note that the use of target declarations is now deprecated and will become illegal in a future release. Please replace this declaration with the correct hw-part-number, hw-issue-number and hw- option declarations instead.

3575. (error 3575): missing hw-issue-number declaration in target-ecu statement.

The interface tool has found the hw-issue-number declaration to be missing from the target-ecu statement for an interface file. A default hw-issue- number as displayed in the warning text emitted has been reconstructed using the target declaration instead. Please note that the use of target declarations is now deprecated and will become illegal in a future release. Please replace this declaration with the correct hw-part-number, hw-issue- number and hw-option declarations instead.

3576. (error 3576): multiple security settings for CCP privilege level

The interface tool has found multiple security statements specifying settings for the same CCP privilege level in the ccp-messaging statement for an interface file. At most one security statement must exist for a CCP privilege level.

3577. (error 3577): parameter 'dde-entry' missing from J1979 freeze frames declaration

The interface tool has found the dde-entry declaration to be missing from the declaration of a J1979 protocol freeze frame.

3578. (error 3578): parameter 'dde-entry' missing from uds snapshot declaration.

The interface tool has found the dde-entry declaration to be missing from the declaration of a UDS protocol freeze frame.

3579. (error 3579): parameter 'dde-entry' missing from J1939 dm4 freeze frame declaration.

The interface tool has found the dde-entry declaration to be missing from the declaration of a J1939 protocol dm4 freeze frame.

Copyright 2019, Pi Innovo 701 OpenECU error and warning codes

3580. (error 3580): type option 'type' unknown, expecting one of: dm4, dm25.

The interface tool has found an invalid type declaration for a J1939 freeze frame.

3581. (error 3581): type option 'type' unknown, expecting one of: snapshot.

The interface tool has found an invalid type declaration for a UDS freeze frame. B.1.7. ASAP2 generation messages

300. (error 300) file 'file name': could not open map file for reading, 'error message'.

The interface tool could not read the mapfile given by 'file name' and the operating system's reason for not being able to do so is given by 'error message'. Correct the reason for failure and try again.

3001. (error 3001) file 'file name': label 'name' is not defined by 'map file' but is required for ASAP2 generation.

The interface tool has read a DDE called 'name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP file called 'map file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern).

3002. (error 3002) file 'file name': label 'name' is not defined by 'file' but is required for ASAP2 generation of DDE 'dde name'.

The interface tool has read a DDE called 'dde name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP or ddump file called 'file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern).

3003. (error 3003): found internal error while creating an ASAP2 entry for DDE 'dde name' — no X-axis DDE 'name' found.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

3004. (error 3004): found internal error while creating an ASAP2 entry for DDE 'dde name' — no Y-axis DDE 'name' found.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

3005. (error 3005): found internal error while creating an ASAP2 entry for DDE 'dde name' — DDE class 'type' is unsupported.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

3006. (error 3006): found internal error while searching for an 'os-native' statement — not found but should be present.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

Copyright 2019, Pi Innovo 702 OpenECU error and warning codes

3007. (error 3007): found internal error while searching for task 'name' required by an ATI shadow table — not found but should be present.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

3008. (error 3008): found internal error while creating a unique ASAP2 identifier for DDE 'dde name' — too many unique conversions.

The interface tool has found in internal error. Please contact OpenECU support if this error occurs.

3009. (warning 3009) line 'number' of 'file name': the DDE name 'dde name' is either too long for an ASAP2 identifier (max 32 characters), or clashes with another identifier, and has been changed to 'short dde name' for ASAP2 file generation.

The interface tool has read a DDE file called 'file name' and at line 'number' has found a DDE called 'dde name' which is too long for an ASAP2 file. The DDE has been changed to 'short dde name' which is guaranteed to be unique and be less than 33 characters long.

3010. (warning 3010) file 'file name': label 'name' is not defined by 'map file' but is required for ASAP2 generation, DDE not added to ASAP2 file.

The interface tool has read a DDE called 'name' from the DDE file called 'file name' but cannot find the address of the DDE in the Diab MAP file called 'map file'. This often occurs because there is no extern C variable with the name 'name' (either because the variable does not exist or because it is not declared extern), or because the DDE file is out of date. The warning does not stop generation of the ASAP2 file, but the DDE will not be added to the ASAP2 file.

3011. (error 3011): found internal error while creating an ASAP2 entry for DDE 'dde name' -- X-axis 'dde' must have at least two elements. (Note unspecified array size in code is currently read as one element.)

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

3012. (error 3012): found internal error while creating an ASAP2 entry for DDE 'dde name' — X-axis DDE 'name' must be 'caxis' Class.

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

3013. (error 3013): found internal error while creating an ASAP2 entry for DDE 'dde name' — Y-axis DDE 'name' must be 'caxis' Class.

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

3014. (error 3014): found internal error while creating an ASAP2 entry for DDE 'dde name' -- Y-axis DDE 'name' must be 1-D array.

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

Copyright 2019, Pi Innovo 703 OpenECU error and warning codes

3015. (error 3015): found internal error while creating an ASAP2 entry for DDE 'dde name' -- Y-axis 'dde' must have at least two elements. (Note unspecified array size in code is currently read as one element.)

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

3016. (error 3016): found internal error while creating an ASAP2 entry for DDE '%s' — Y-axis DDE '%s' must also be in C-style data dictionary

If the calibration map DDE 'dde name' is declared in a C-style data dictionary file then the x-axis DDE 'name' must also be declared in a C-style data dictionary. It is not possible to mix axis and map definitions between prefix and C style data dictionaries.

3017. (error 3017): found internal error while creating an ASAP2 entry for DDE 'dde name' — X-axis DDE 'name' must also be in C-style data dictionary.

If the calibration map DDE 'dde name' is declared in a C-style data dictionary file then the y-axis DDE 'name' must also be declared in a C-style data dictionary. It is not possible to mix axis and map definitions between prefix and C style data dictionaries.

3018. (error 3018): found internal error while creating an ASAP2 entry for DDE 'dde name' -- map array must be array.

The interface tool needs to generate an ASAP2 map definition but has found an internal error.

3019. (error 3019): found internal error while creating an ASAP2 entry for DDE 'dde name' — 2D array but only Xaxis specified.

The interface tool needs to generate an ASAP2 map definition for a two- dimensional calibration map DDE 'dde name' but only one axis has been specified. Both the Xaxis and Yaxis columns must be specified.

3020. (error 3020): found internal error while creating an ASAP2 entry for DDE 'dde name' -- array size incompatible with axis size(s).

The interface tool needs to generate an ASAP2 map definition for a calibration map DDE 'dde name' but the equivalent C variable does not match the size of the map axes. For instance, a map with 4 elements in the x-axis and 10 elements in the y-axis, must have an equivalent C variable with 40 elements.

3021. (warning 3021) file 'file name': one-dimensional array expected for 'dde name'; now treated as such.

A DDE called 'dde name' is expected to be a one dimensional array (for instance, because it's Class column specifies the DDE to be an axis or a string) but the equivalent C variable is not one dimensional (but should be).

3022. (error 3022): file 'file name': label 'dde name' according to 'file' has more than 3 final array dimensions.

The interface tool can generate ASAP2 entities with up to 3 dimensions but no more, because the ASAP2 syntax does not allow further dimensions. However, the interface tool will break up arrays with more than 1 or 2

Copyright 2019, Pi Innovo 704 OpenECU error and warning codes

dimensions into multiple DDEs of smaller dimension. If this error occurs, please contain OpenECU technical support.

3023. (error 3023): C-style data dictionary specified in dde_filename not allowed without ELF information file.

For ASAP2 generation, C-style data dictionaries can only be used if a Diab ddump or GNU objdumb ELF information file file is also specified (not just a map file). Otherwise the tool cannot obtain the types and sizes of the variables detailed in the data dictionary.

3024. (error 3024): found internal error while creating an ASAP2 entry for DDE 'dde name' -- X-axis DDE 'name' must be 1-D array.

The interface tool needs to generate an ASAP2 axis definition for a calibration map named 'dde name' but has found an internal error. If this error occurs, please contact OpenECU technical support.

3025. (warning 3025): string array 'dde name' had zero size, so a default size of 'bytes' has been used, hence it may display incorrectly.

The DDE string 'dde name' has an equivalent C variable in the Diab ddump file with no information about the string's size. The interface tool generates an entry for the DDE but with a size 'bytes' long which probably does not match the actual string length. To avoid this, use an explicit array size in the C declaration.

3026. (error 3026): found internal error while creating an ASAP2 entry for DDE 'dde name' — too many array dimensions for map data.

The interface tool needs to generate an ASAP2 map definition for a calibration map DDE 'dde name' but the equivalent C variable has more dimensions than the calibration map.

3028. (warning 3028): the application name, 'name', contains characters not supported by ASAP2 standards; the application name has been replaced with 'updated name'.

The application name generated in the ASAP2 file contained characters that were unacceptable in accordance to ASAP2 standards. The calibration tool Vector CANape doesn't support use of such ASAP2 files. The C- API interface tool has been updated to generate ASAP2 files containing characters of the application name that are in accordance with the standards.

3332. (error 3332) shadow table references task (task) but that task as not been declared.

The shadow table entry must reference a declared task. This is the task which is to carry out the calibration tool writes. Here a task is referenced which has not been declared.

3333. (error 3333) more than four shadow-table statements are present.

The tool does not currently support more than four shadow table statements.

3334. (warning 3334) shadow table must have number of entries in the range [1, 256].

The number of entries in the shadow table is not within the supported range.

Copyright 2019, Pi Innovo 705 OpenECU error and warning codes B.1.8. ELF to DDE generation messages

4001. (error 4001): C-style data dictionary specified in 'file name' not allowed without ELF ddump output.

The interface tool has been asked to generate a C-style DDE file from the Diab ddump input file but a Diab MAP file has been specified instead. Change from the MAP file to the ddump file. B.1.9. Data type checks between ELF and DDE messages

5001. (warning 5001): the DDE [name] is not defined by [ELF-file] and may be redundant, consider removing from DD file.

The interface tool has identified that a data dictionary entry with a given name was not found in the ELF file. This may indicate that the DDE is no longer required and can be removed from the data dictionary. Or this may indicate that Simulink Coder has not generated a variable for the DDE and a change is necessary to the model or model configuration.

5002. (warning 5002): the automatically added DDE [name] is not defined by [ELF-file], please contact OpenECU technical support.

The interface tool has identified that a data dictionary entry with a given name was not found in the ELF file. The data dictionary entry was automatically added by the C-API tool, and failures of this type are not expected. Please contact OpenECU technical support if this warning occurs.

5003. (warning 5003): the DDE [name] is defined with data type [a] but the ELF uses data type [b].

The interface tool has identified that a data dictionary entry with a given name and given data type a, but that Simulink Coder generated a variable using data type b. This can lead to the calibration tool incorrectly displaying the value of a signal. To remove the warning, change the DDE data type to match that generated by Simulink Coder.

Copyright 2019, Pi Innovo 706 Appendix C. Supporting tools C.1. Introduction

This section provides a quick introduction to the tools that support OpenECU, both supplied by Pi Innovo and those by other companies. The section is intended to be a first step with the tools when used with OpenECU.

For tools that are supplied by other companies, additional details about how to use the tools can be found in their respective manuals. Pi Innovo will not provide technical support in the use of these tools.

The sections on the calibration tools (Section C.3, “ATI Vision”, Section C.5, “Vector CANape”, Section C.4, “ETAS INCA”) and on a free programming tool called FreeCCP (Section C.6, “FreeCCP”) assume that the step1 example application (see Chapter 3, Quick start for details) has been built using the default CCP settings (Table 4.2, “CCP defaults”) and that the user is familiar with the installation of the calibration tool.

Note

On M5xx ECU's (eg. M560, M580), calibration tools must use the A2L file, not the .elf file to commit cal-on-the-fly calibration changes. This is due to the calibration overlay mechanism on the mpc5746 micro-controller. C.2. PiSnoop

Pi Innovo's PiSnoop tool has many functions that are useful in typical OpenECU developments. It offers a cost-effective alternative to traditional calibration tools, but its emphasis is more on software development than calibration. Therefore it presents an interface that is part way to a debugger in terms of watch and memory windows, but typically interacts with the ECU via CCP, just like a calibration tool.

A demo version of PiSnoop is available from our website [http://www.pisnoop.com]) in which all features may be tried out, but with some limitations on the number or duration of operations. This provides a route to getting up and running right away with OpenECU.

PiSnoop is under continual development, so this manual does not attempt to document how to use it with OpenECU in detail as is done for the other tools below. Instead, see the online help that is included in the PiSnoop installation (including the specific OpenECU application note) for up-to-date guidance. In brief however, capabilities include:

• Works with any Vector, Kvaser or PEAK-System (PCAN) CAN interface on Windows XP or higher.

• Loads symbols (parameter names, addresses, types and descriptions) from ASAP2 (.a2l) files...

• ... but can also load symbols from the linker output (.elf) files, giving access to all static C language objects present including arrays, structure elements, pointers and bitfields, without needing data dictionary entries. In Simulink builds, this means Real-Time Workshop structures such as rtDWork and rtB can be explored, making "hidden" block- related values, present in the autocode, available for debug purposes.

• ECU memory access and flash reprogramming via CCP, with seed-key security support and fast DAQ data-logging, which tolerates ECU power cycling.

Copyright 2019, Pi Innovo 707 Supporting tools

• Reloading symbols and/or reprogramming the ECU after rebuilding is a single-click operation.

• Calibration parameter value changes can be uploaded by name to a file, to use for download or flash reprogramming with a different build later.

• Watch, map lookup and raw memory windows to view and edit ECU memory or offline file images.

• CAN traffic generation and monitoring/logging with .dbc file support for named messages and signals.

• ISO 15765-2 (UDS/Keyword Protocol/J1979) and J1939 diagnostic messaging windows.

• UDS/Keyword Protocol can be used as an alternative memory access and flash reprogramming protocol, with seed-key security support.

• ASAP3 support is provided to enable test automation.

• Extensible through plug-in architecture supporting new protocols, hardware interfaces and custom windows. C.2.1. Example Screenshots

This shows how calibration parameters and RAM variables can be accessed and logged together in debugger-style watch windows. Parameters can be loaded from ASAP2 (.a2l) and linker (.elf) files simultaneously. Structures, pointers, bitfields and arrays can be explored:

Debugger-style memory windows can be used to view and edit memory contents. Known symbols loaded from .a2l or .elf files are highlighted when the mouse pointer is placed over their locations:

Further windows are integrated for CAN and diagnostic functions. For example, arbitrary CAN traffic can be generated by hand or using a .dbc file:

Copyright 2019, Pi Innovo 708 Supporting tools

Similarly, CAN traffic can be monitored and logged:

C.3. ATI Vision

ATI Vision by Accurate Technologies is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU. C.3.1. Creating a new project and strategy in ATI Vision

The following instructions assume the user is using a supported version. These instructions were transcribed against a supported version but it may be that these instructions match other versions of the tool.

They also assume that an ATI Vision Hub is used. If another communications device is used, the user will need to deviate from these instructions.

1. Install ATI vision, the installer may reboot your machine. Once windows is restarted, it will detect new USB hardware (assuming the hub is plugged in: if not, plug it in).

Ask windows to install the USB hardware software from the "device software" directory located where you just installed ATI vision, e.g., c:\program files\Accurate Technologies \ati vision\device software.

Start Vision and you will be presented with a window similar to the following:

Copyright 2019, Pi Innovo 709 Supporting tools

2. Next, you must create a project to details how ATI Vision will communicate with the OpenECU device.

Create a new project using the menu option File->New, then select Project.

and save it somewhere on your hard-disk (here, it has been saved using the name "example_project").

Next, add a device by right clicking on the Computer item and selecting "Add Device..."

Copyright 2019, Pi Innovo 710 Supporting tools

Select USB port and in the subsequent dialog, accept all the defaults and select OK.

Next, add a device by right clicking on the USB item and selecting "Add Device..."

Select VISION Network Hub in the subsequent dialog and select OK.

Copyright 2019, Pi Innovo 711 Supporting tools

Accept the default hub name and in the subsequent dialog properties defaults by selecting OK.

Next, add another device by right clicking on the VisionHub item and selecting "Add Device..."

Select a VNI CAN device type, accept the default name and in the subsequent dialog, accept the defaults by selecting OK.

Next, add another device by right clicking on the VNICAN item and selecting "Add Device..."

Copyright 2019, Pi Innovo 712 Supporting tools

Select the CCP Controller Device, accept the default name and in the subsequent dialog, accept the defaults by selecting OK. This has told the Vision tool that you will be communicating to a CCP compatible device over CAN via the Vision Hub connected to the PC via a USB cable.

3. Next, you must create a strategy file to hold both the calibration data and program data. Select File->New, then Strategy File.

The main Vision window will change and you will be presented with the import wizard. Select the ASAP2 description file item.

For the step1 example, select the step1_tool_vision.a2l file from the location where you built it (note that the following diagrams show an older version of the step1 application called step1_r12_g800).

Copyright 2019, Pi Innovo 713 Supporting tools

It is important to keep the "Strategy Presets" text box clear and to tick the "Delete existing data items from before importing" check-box. This ensures that the memory and CCP settings are taken from the ASAP2 file and that subsequent imports of the same strategy will clear out previous ASAP entries before loading the latest.

When using the C-API and C-style data dictionaries the Structure naming selection becomes important as well. Selecting “Names separated with underscores” keeps the names of DDEs as close as possible to the original DDE name.

Click Import to read in the ASAP2 file, then click on the More button.

Copyright 2019, Pi Innovo 714 Supporting tools

Select import memory image, then select Motorola S-record File, then browse and select the step1_image_small.s37 file from the place where you built it.

Select Import, then Finish. The Wizard dialog box now closes.

Note

You must now save this strategy (menu option File->Save) and change back to the project file by clicking on the "example_project" tab at the bottom of the Vision window.

Copyright 2019, Pi Innovo 715 Supporting tools

C.3.2. Downloading an application with an ATI Vision strategy

The following instructions assume the user is using a supported version of ATI Vision. These instructions were transcribed against a supported version but it may be that these instructions match other versions of the tool.

They also assume that an ATI Vision Hub is used. If another communications device is used, the user will need to deviate from these instructions.

1. Add this strategy to the tree list by right clicking on the PCM item and selecting "Add Strategy...", browse to the location where you saved the strategy file and select it.

Copyright 2019, Pi Innovo 716 Supporting tools

This will add two items to the tree view, one for the strategy and one for the calibration data immediately below it.

2. If CCP seed/key security is to be used, copy the relevant DLL(s) into the same location as the strategy file.

3. To try out the connection, go online by selecting the menu option Project->Online.

Copyright 2019, Pi Innovo 717 Supporting tools

The tree view will change to show that each of the devices previously added are communicating correctly:

and brings up a dialog box:

Copyright 2019, Pi Innovo 718 Supporting tools

If any of the devices show a yellow or red mark, then there is a physical disconnection or CCP communications error (e.g., different settings for CCP in the OpenECU device and the application). The dialog box will not pop-up and you will not be able to Flash the device. Go back and check that each of the settings corresponds to physical devices and CCP settings, check that CAN is connected to the correct pins and try again.

To program the OpenECU device with the strategy, select Flash then OK. This brings up a dialog box which shows which memory regions on the OpenECU device to program. Select Start to program the device.

Note

In order to reprogram or Flash the OpenECU device, the OpenECU device must be in reprogramming mode. For details on how to enter reprogramming mode refer to Section 3.3.11, “Program the ECU”

Once programmed, the FEPS must be disconnected (if used) and the OpenECU device power cycled. This reboots the OpenECU and starts to run the application.

4. You can now view ASAP2 entries by creating a screen and adding the application signals and calibrations you wish to see. Select File->New, then Screen File. The main window will change. Right click on the background and select "Add Control".

Copyright 2019, Pi Innovo 719 Supporting tools

For now, we will only look at scalar values by selecting Data List items, but 1-d and 2-d maps are supported, as well as recorders etc..

Select Data List and you will be presented with a dialog box which lists the ASAP2 entries.

Copyright 2019, Pi Innovo 720 Supporting tools

Double click on stp_ect_state and then select OK. You will be presented with the current value of stp_ect_state in real-time.

At this point, you have managed to connect ATI Vision to OpenECU, download the step1 application and view one application signal in real-time. Please refer to the ATI Vision user manual for more details about how to use ATI Vision. C.3.3. Configuring two OpenECUs on the same CAN bus with ATI Vision

When connecting to a single OpenECU for the first time, the tool and OpenECU settings will probably use the default CCP settings (as described in Table 4.2, “CCP defaults”). The example which follows assumes the default CCP settings.

ATI Vision

Strategy A OpenECU A USB CAN CRO: 1785 ATI Hub CRO: 1785 DTO: 1784 DTO: 1784

The above diagram shows ATI Vision with a single strategy using the default CCP settings. A similarly configured OpenECU is connected to ATI Vision via the CAN bus to the Vision Hub, and from the Hub to the PC via a USB cable. Your setup may vary depending on what equipment you have (for instance, you may have two ATI Hubs but the overall concept of configuring the additional OpenECU's remains).

Copyright 2019, Pi Innovo 721 Supporting tools

When a second OpenECU is first required, a second application will be built into a second strategy which must use different CCP settings from the first strategy. The tool settings may follow the example default settings for two OpenECUs.

ATI Vision

OpenECU A

CRO: 1785 Strategy A DTO: 1784 USB CAN CRO: 1785 ATI Hub DTO: 1784 OpenECU B

Strategy B CRO: 1785 DTO: 1784 CRO: 1787 DTO: 1786

The diagram shows ATI Vision with two strategies: strategy A using the default CCP settings (as in the single OpenECU example above); strategy B using different CCP settings. The CCP settings distinguish between the two OpenECUs. Two OpenECUs are connected to the Hub allowing ATI Vision to communicate with both.

As this is the first time the second OpenECU has been connected to the CAN bus, it uses the default CCP settings. When the user selects strategy B in Vision, Vision uses the strategy B CCP CAN identifiers but there is no OpenECU with matching CCP settings. Without any response Vision shows the OpenECU for strategy B as offline.

Follow this procedure to program OpenECU B with strategy B for the first time:

1. Disconnect OpenECU A from the CAN bus. This prevents OpenECU A from interfering with communications to OpenECU B.

2. Right click on strategy B and select Open File. The screen will change.

3. Select File -> Properties and change to the Device Settings tab in the new dialog.

Copyright 2019, Pi Innovo 722 Supporting tools

Change the CRO CAN identifier to 1785 and the DTO CAN identifier to 1784, then select File -> Save.

4. Change back to the Project tab (so you can see both strategy A and strategy B), right click on strategy B and select Reload File. This brings the CRO and DTO changes into strategy B.

Your setup is now configured as:

ATI Vision

OpenECU A

CRO: 1785 Strategy A DTO: 1784 USB CAN CRO: 1785 ATI Hub DTO: 1784 OpenECU B

Strategy B CRO: 1785 DTO: 1784 CRO: 1785 DTO: 1784

If strategy B is selected, ATI Vision will show OpenECU B as online.

5. Reprogram OpenECU B with strategy B (see Section C.3, “ATI Vision” and Section 3.3.11, “Program the ECU” for more).

6. Once reprogrammed, power cycle OpenECU B. ATI Vision will show OpenECU B as offline.

7. Right click on strategy B and select Open File. Select File -> Properties, change to the Device Settings tab in the new dialog, change the CRO CAN identifier to 1787 and the DTO CAN identifier to 1786, then select File -> Save.

8. Change back to the Project tab (so you can see both strategy A and strategy B), right click on strategy B and select Reload File.

Your setup is now configured as:

ATI Vision

OpenECU A

CRO: 1785 Strategy A DTO: 1784 USB CAN CRO: 1785 ATI Hub DTO: 1784 OpenECU B

Strategy B CRO: 1787 DTO: 1786 CRO: 1787 DTO: 1786

9. Reconnect OpenECU A to the CAN bus. Select strategy A to communicate with OpenECU A, or select strategy B to communicate with OpenECU B.

Copyright 2019, Pi Innovo 723 Supporting tools

Note

The above procedure is equally applicable when reprogramming a single OpenECU to new CCP settings. Ensure there is only one OpenECU connected to the CAN bus, build the application with the new CCP settings, import into Vision, adjust the CCP settings in Vision to that of the connected OpenECU, reprogram the OpenECU and reset it, then adjust the CCP settings in Vision to that of the application.

C.3.4. Configuring CCP seed/key security with ATI Vision

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 7.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”.

CCP seed/key security requires that a Win32 DLL is built containing a function which will generate a key value from a seed value supplied by the ECU. The name and function prototype are specified in the ASAP1A and ASAP2 standards to be

BOOL SEEDKEYAPI ASAP1A_CCP_ComputeKeyFromSeed(BYTE *Seed, unsigned short SizeSeed, BYTE *Key, unsigned short MaxSizeKey, unsigned short *SizeKey); // Seed: Pointer to seed data // SizeSeed:Size of seed data (length of ‚Seed‘) // Key: Pointer, where DLL should insert the calculated key data. // MaxSizeKey: Maximum size of ‚Key‘. // SizeKey: Should be set from DLL corresponding to the number of data // inserted to ‚Key‘ (at most ‚MaxSizeKey‘) // Result: The value FALSE (= 0) indicates that the key could not be // calculated from seed data (e.g. ‚MaxSizeKey‘ is too small). // TRUE (!= 0) indicates success of key calculation.

Vision allows differently-named functions to be used, which may be convenient in cases such as supplying a single DLL containing multiple different seed/key algorithms for different strategies). Note though that this may make seed/key DLLs for Vision incompatibile with other calibrations tools which require a single function per DLL with a fixed name per the ASAP standard. C.4. ETAS INCA

INCA by ETAS GmbH is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU.

The following instructions assume the user is using version 5.1.2. These instructions were transcribed against this version but it may be that these instructions match other versions of the tool.

The instructions also assume that ES 580 CAN card is used. If another communications device is used, the user will need to deviate from these instructions.

1. Start INCA and you will be presented with a window similar to the following:

Copyright 2019, Pi Innovo 724 Supporting tools

2. Select the menu option Database->New to create a new database. This database will contain the binary image of the built application and calibration and other items used to calibrate the OpenECU device.

Type in a suitable name: the example here uses example_database and select OK.

Next, select the menu option Edit->Add->ECU Project (a2l) and browse to your built application, e.g., step1_tool_inca.a2l. The example shows an older step1_r12_g800 application.

Copyright 2019, Pi Innovo 725 Supporting tools

Once loaded, the INCA main window updates.

Copyright 2019, Pi Innovo 726 Supporting tools

Next, select the menu option Edit->Add->Workspace and accept the default name, then select the menu option Project->Add Project/Dataset:

and a new dialog appears. Select the project you just added then OK. The main window will have updated to show the project in window 5.

Select the offline item in window 5, then select device->new device

Copyright 2019, Pi Innovo 727 Supporting tools

Select an appropriate CCP compatible device. In this example, the PC running INCA has a ES 580 CAN card attached, so the related CCP item is selected.

3. Next, double click on the workspace item in window 1. If there is an error in the CCP configuration or in the wiring to the OpenECU device, the INCA log window will show that INCA could not communicate with the OpenECU device. If this occurs, check the CCP settings and wiring.

Copyright 2019, Pi Innovo 728 Supporting tools

If the memory pages dialog does not pop-up, the select the menu option Hardware- >Manage memory pages

Select Flash programming, then do it. If this is the first time INCA has been used or if OpenECU was installed without the option to Patch INCA, you will be asked to browse to a ProF configuration file.

Note

The INCA tool makes a distinction between the base calibration (reference page) and a derived calibration (working page). Be sure to download the reference page to start with.

Copyright 2019, Pi Innovo 729 Supporting tools

Select the "Install..." button and browse to the install location of OpenECU, .../ tools_integration/inca_prof and select OK.

This will have installed the INCA ProF configuration file for OpenECU. Select it then OK.

This brings up the ProF settings dialog.

Select Flash strategy and calibration (or Flash strategy, calibration and tunes if using Tunes in your application — the step1 application does not use Tunes), then OK.

Copyright 2019, Pi Innovo 730 Supporting tools

Note

In order to reprogram or Flash the OpenECU device, the OpenECU device must be in reprogramming mode. For details on how to enter reprogramming mode refer to Section 3.3.11, “Program the ECU”.

This brings up the ProF control flow dialog box which shows the progress of programming the OpenECU device.

Press Close when it has finished and Close in the manage memory pages dialog.

4. Next, to view a measurable, select the menu option Variables->Select...

Copyright 2019, Pi Innovo 731 Supporting tools

and from the dialog that pops up, select those signals or calibrations to view. Here, the stp_ect_state signal has been selected and will be updated every 100 milliseconds.

Copyright 2019, Pi Innovo 732 Supporting tools

Select the Configure button, followed by the OK button on the next dialog.

Finally, to display the data of the selected item in real-time, select the menu option Measurement->Start Visualisation. You will be presented with the current value of stp_ect_state in real-time.

Copyright 2019, Pi Innovo 733 Supporting tools

At this point, you have managed to connect ETAS INCA to OpenECU, download the step1 application and view one application signal in real-time. Please refer to the ETAS INCA user manual for more details about how to use INCA.

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 7.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”. However this feature is not officially supported by OpenECU for use with ETAS INCA. As a result this feature has not been formally tested with INCA, and no support will be provided for configuring INCA to support seed/key security. C.5. Vector CANape

CANape by Vector Informatik GmbH is a calibration tool that can communicate to a CCP compliant device. It provides facilities for calibration, data logging and display and can be used with OpenECU.

The following instructions are for version 8.0. Other versions may differ.

The instructions also assume that CANcaseXL is used. If another communications device is used, the user may need to deviate from these instructions.

1. Start CANape and you will be asked to accept a disclaimer. After this you will see the following:

Copyright 2019, Pi Innovo 734 Supporting tools

2. Select 'Create new project' and press 'OK'. You will then be asked for a project name. Enter a suitable name, click 'Next' and then browse to a suitable directory to save the project, click 'Next' and then 'Finish'. You should now see the following:

Select the menu option Device->New from database... and browse to where your model_name_canape.a2l file is located and select Open. If the device is connected correctly and configured with the appropriate baud rate then you should see no errors or warning. The a2l file contains the CAN configuration as set by the model. It also has the relevant information for the flash, cal and RAM locations. CANape will use these values with no further configuration input required from the user.

If CCP seed/key security is required for an operation, the DLL implementing the appropriate key-generation algorithm must be placed in the same directory as the

Copyright 2019, Pi Innovo 735 Supporting tools

CANape project. Note that CCP seed/key security is disabled by default in the model_name_canape.a2l file.

Having set up the project (and CCP security if required), select the menu option Flash->Download file to flash... and browse to your built application, e.g., step1_m460_image_small.hex.

At the bottom left of the window the progress bar should be seen to advance until programming is complete.

Next, select the menu option Measurement->Measurement configuration... and the following window will appear:

Copyright 2019, Pi Innovo 736 Supporting tools

The Simulink model name should be visible in the left hand pane under 'Measurement signals'. Right click on the model name and select 'Insert signal' from the menu that appears. The Database selection window should then appear, listing all of the model signals and calibrateable values.

Copyright 2019, Pi Innovo 737 Supporting tools

Double click on each signal of interest so that their text colour changes to blue. Close both windows and accept changes and you will return to the main window. Now select the menu option Display->Display windows->Numeric window, an empty numeric display will appear. Right click on this numeric display and select 'Insert measurement signal...' the following appears:

Copyright 2019, Pi Innovo 738 Supporting tools

3. Next, right click and select 'Insert signal' on each parameter that you want to monitor in the numeric window

Copyright 2019, Pi Innovo 739 Supporting tools

To access calibration values select the menu option Display->Calibration windows- >Calibration window, then scroll down to find calibration parameters and select the ones that are required.

Copyright 2019, Pi Innovo 740 Supporting tools

At this point, you have managed to connect Vector CANape to OpenECU, downloaded the step1 application and viewed some signals in real-time. Please refer to the Vector CANape user manual for more details about how to use CANape. C.5.1. Configuring CCP seed/key security with Vector CANape

Some manufacturers may enable CCP seed/key security for certain CCP operations, particularly in software which is released to production. Configuring this in the application is discussed in Section 7.1.4.15, “Compound statement: ccp-messaging” and Section 5.16.1.4, “CCP seed/key security”.

CCP seed/key security requires that a Win32 DLL is built containing a function which will generate a key value from a seed value supplied by the ECU. The name and function prototype are specified in the ASAP1A and ASAP2 standards to be

BOOL SEEDKEYAPI ASAP1A_CCP_ComputeKeyFromSeed (BYTE *Seed, unsigned short SizeSeed, BYTE *Key, unsigned short MaxSizeKey, unsigned short *SizeKey); // Seed: Pointer to seed data // SizeSeed:Size of seed data (length of ‚Seed‘) // Key: Pointer, where DLL should insert the calculated key data. // MaxSizeKey: Maximum size of ‚Key‘. // SizeKey: Should be set from DLL corresponding to the number of data // inserted to ‚Key‘ (at most ‚MaxSizeKey‘) // Result: The value FALSE (= 0) indicates that the key could not be // calculated from seed data (e.g. ‚MaxSizeKey‘ is too small). // TRUE (!= 0) indicates success of key calculation.

Some calibration tools allow different function names to be used, but CANape does not. Each seed/key algorithm must therefore be provided in a separate DLL and referenced

Copyright 2019, Pi Innovo 741 Supporting tools

appropriately. Section 4.3.1.1 "CCP Parameters" of the CANape user manual specifies this in more detail. C.6. FreeCCP

FreeCCP is a command line tool which can program an OpenECU with a built application. It requires a Vector or Kvaser CAN card.

This tool is provided free and unsupported by Pi Innovo. Users are permitted to use this software for commercial and non-commercial purposes.

Note

On 64-bit Windows 7 PCs, FreeCCP does not currently work with Vector interfaces, but does with Kvaser interfaces.

Note

FreeCCP is now deprecated, and so may be removed from future releases of OpenECU. Please contact support if you would like a free trial of PiSnoop to get started with OpenECU, even if you intend to migrate to a third-party calibration tool. See also Section C.2, “PiSnoop”.

C.6.1. Programming an OpenECU

To program an OpenECU with a built application using a Kvaser CAN card, issue the following at the command line:

oe_freeccp -kvaser -f _image_small.s37

where is replaced by the name of the application. For instance, with the step1 application for the M670 target, the command to issue would be:

oe_freeccp -kvaser -f step1_m670_image_small.s37

Note

When running from the Windows command line, add the path to the freeccp tool to the system PATH environment variable.

C.6.2. Choosing the CAN card device (Kvaser)

The tool supports using a variety of Kvaser CAN cards. To use this interface use the -kvaser command line option.

oe_freeccp -kvaser -f _image_small.s37

C.6.3. Choosing the CAN card device (Vector)

The tool supports using a variety of Vector CAN cards. The tool defaults to using a CANcardX interface, but can connect to others using the following options: -cancardxl or -pci.

Copyright 2019, Pi Innovo 742 Supporting tools

The options are added to the command for reprogramming, so as an extension to programming an OpenECU device with the step1 application, choosing the AC2 PCI option would be:

oe_freeccp -pci -f step1_image_small.s37

C.6.4. Choosing the CCP settings

Without additional command line parameters, the tool uses the default CCP settings from (Table 4.2, “CCP defaults”. To make the tool use alternative CCP settings, use the following options:

-croid -dtoid -targetid -b

So for instance, if the CCP settings were:

CCP option Setting CRO message identifier 400 DTO message identifier 401 Station address 2 CAN baud rate 500 kBps

then the command to issue to download the step1 application using a Vector CAN card would be:

oe_freeccp -croid 400 -dtoid 401 -targetid 2 -b 500 -f step1_image_small.s37

CCP seed/key security as described in Section 5.16.1.4, “CCP seed/key security” is not supported by FreeCCP. FreeCCP cannot therefore carry out operations for which the currently-running application requires security to be unlocked. This may make it unsuitable for use with production-level software. C.6.5. Checking that the OpenECU device is active

The tool supports a function to determine if it can communicate with an OpenECU device or not, rather than programming the device. This can be used to check the wiring between the OpenECU and CAN card.

To check the CCP connection using a Vector CAN card, issue the command:

oe_freeccp -check

Copyright 2019, Pi Innovo 743 Appendix D. Memory configurations

Some OpenECU targets support different configurations of the ECU's application, calibration and RAM memory sizes, allowing design trade offs to be made whilst developing the application. There are two broad classes of ECUs:

Fleet ECUs Lower-cost that developer ECUs due to the lack of run-time calibration support. These ECUs are intended to be used for fleet trials or production, and are not intended to be used for bench or dyno activities, especially those that require calibration support. Typically, fleet ECUs do not include external RAM.

Developer ECUs Higher-cost that fleet ECUs due to support for run-time calibration. These ECUs are intended to be used for development activities such as dyno cell calibration or HIL based testing. Typically, developer ECUs do include external RAM.

Some configurations support running identical software on fleet and developer units. An application can be built, run and calibrated on a developer ECU, then transfered to a fleet ECU of the same family and type as the developer unit, and run unmodified. An example of this would be memory configuration A for the M220, and memory configuration D for the M560, M680 and M670. The same application, calibration and RAM memory sizes are available with and without run-time calibration support. An application built for M220 memory configuration A will run on both M220 developer and fleet units without modification.

M110

The following memory configurations are available.

Table D.1. Memory configurations supported

Configuration App size Cal size RAM External Run-time (KiB) (KiB) size RAM calibration (KiB) required? supported? A a 512 32 32 N Y B 512 48 16 N Y C 512 16 48 N Y D 512 256 64 N N a If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.

M220, M250, M460, M461

The following memory configurations are available.

Table D.2. Memory configurations supported

Configuration App size Cal size RAM External Run-time (KiB) (KiB) size RAM calibration (KiB) required? supported? A a 512 256 64 N N 512 256 64 Y Y B 512 256 832 Y Y C 640 128 192 Y Y

Copyright 2019, Pi Innovo 744 Memory configurations

Configuration App size Cal size RAM External Run-time (KiB) (KiB) size RAM calibration (KiB) required? supported? D 768 64 768 Y Y a If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.

Most of these configurations require the external RAM available with developer units. If an application using such a memory configuration is loaded onto an ECU with no external tab board RAM available, the ECU will entry reprogramming mode with a flash code of 1-1-7 (repeated resets).

M560, M680, M670

The following memory configurations are available.

Table D.3. Memory configurations supported

Configuration App size Cal size RAM External Run-time (KiB) (KiB) size RAM calibration (KiB) required? supported? A a 3072 128 128 N Y B 3072 64 192 N Y C 3072 192 64 N Y D 3072 512 256 N N 3072 512 256 Y Y a If an OpenECU target that supports memory configuration is loaded with an application in which no such configuration has been specified, then configuration A will be used as the default.

Other targets

No other targets support memory configuration.

Copyright 2019, Pi Innovo 745 Appendix E. ASAP2 compliance

The OpenECU generation of ASAP2 files is against a sub-set of version 1.40 of the standard.

Warning

OpenECU does not adhere to the ASAP2 rule which governs the length of identifiers. OpenECU may generate identifiers with more than 32 characters.

Copyright 2019, Pi Innovo 746 Appendix F. CCP compliance

The OpenECU implementation of CCP is against a sub-set of version 2.1 of the standard and supports the following commands:

Table F.1. Supported CCP commands

CCP command Command Optional Notes value CONNECT 1 Reprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one. SET_MTA 2 Supports one MTA. Addresses must not be extended. DNLOAD 3 UPLOAD 4 START_STOP 6 DISCONNECT 7 Reprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one. START_STOP_ALL 8 yes SET_S_STATUS 12 yes GET_S_STATUS 13 yes BUILD_CKHSUM 14 yes Implements the 16 bit CCITT CRC (shift register initially set to 0xFFFF, non- reflected form). SHORT_UP 15 yes Expects no address extension. Does not change MTA. CLEAR_MEMORY 16 yes GET_SEED 18 yes Not supported before platform version 1.8.6. UNLOCK 19 yes Not supported before platform version 1.8.6. GET_DAQ_SIZE 20 Ignores any attempt to set the DAQ CAN message identifier to anything other than the DTO CAN message identifier. SET_DAQ_PTR 21 WRITE_DAQ 22 EXCHANGE_ID 23 Access to the ECU's type, manufacturing data, and if available, the application defined name. See Section F.1, “EXCHANGE_ID message handling” for details. PROGRAM 24 yes If the length to program is specified as zero, reprogramming code will treat this as a special signal to indicate that programming has finished.

Copyright 2019, Pi Innovo 747 CCP compliance

CCP command Command Optional Notes value GET_CCP_VERSION 27 Returns 2.1. PROGRAM_6 34 yes DNLOAD_6 35 yes

Some older versions of software (prior to platform version 1.6.0, or prior to RPRG version x.6.0) support a larger number of CCP commands. In addition to the commands above, these older versions also supported the following commands:

Table F.2. Supported CCP commands (in older versions of ECUs)

CCP command Command Optional Notes value TEST 5 yes Reprogramming code prior to version 5.0.6 and 105.0.11 assumes a station address of zero or one. GET_ACTV_CAL_PG 9 yes Only one page of calibration is supported. SELECT_CAL_PAGE 17 yes Only one calibration page is supported at a fixed address. MOVE 25 yes DIAG_SERVICE 32 Replied to as "unavailable". ACTION_SERVICE 33 Replied to as "unavailable".

All other commands are replied to as "unknown command". F.1. EXCHANGE_ID message handling

The ASAP1b standard for CCP defines the EXCHANGE_ID message as follows:

Table F.3. Original EXCHANGE_ID message

Position Type Description 0 byte Command Code = EXCHANGE_ID 0x17 1 byte Command Counter = CTR 2... bytes CCP master device ID information (optional and implementation specific)

OpenECU will interpret the master device ID information to determine how to setup the Memory Transfer Address (MTA0) for later uploading.

Table F.4. Modified EXCHANGE_ID message

Position Type Description 0 byte Command Code = EXCHANGE_ID 0x17 1 byte Command Counter = CTR 2..4 bytes Ignored 5..6 byte Manufacturing data key

Copyright 2019, Pi Innovo 748 CCP compliance

Position Type Description See Table F.6, “EXCHANGE_ID manufacturing data key values and binary format” 7 bytes Selection See Table F.5, “EXCHANGE_ID selection values”

The message is processed by the ECU by inspecting the selection in position 7:

Table F.5. EXCHANGE_ID selection values

Value Description 1 If the ECU contains manufacturing data and the manufacturing data key in position 5..6 is valid for the ECU, then set the MTA0 to the address of the manufacturing data in binary format. Valid key values and the structure of the data is defined in Table F.6, “EXCHANGE_ID manufacturing data key values and binary format”. Otherwise, leave MTA0 unmodified and set an appropriate error code in the response message. Note that some older M220, M250, M460 and M461 variants do not contain manufacturing data. 2 If running in application mode then set MTA0 to null terminated ASCII string defined by the application using the C-API tool name application statement. Otherwise, sets MTA0 as if the EXCHANGE_ID selection value were zero. any other value Set MTA0 to the address of a null terminated ASCII string of the ECU family. The string has the form “OpenECU-[name]”. For example, “OpenECU-M220”.

Position 5 (MSB) and 6 (LSB) is interpreted as the manufacturing data identifier:

Table F.6. EXCHANGE_ID manufacturing data key values and binary format

Position a Description b Key = 1, Serial number 0..3 Serial number Key = 2, Date of manufacture The date is composed as (shift) dd:mm:yyyy, where the shift identifies the team involved in the manufacturing process. 0 The team shift at time of manufacture 1 The day of the month of manufacture, range [1, 31] 2 The month of manufacture, range [1, 12] 3..4 The year of manufacture, range [2010, ...] Key = 3, Engineering part number The engineering part number matches the pattern: prefix letter engineering-part-number. For instance, the engineering part number assigned to the M250-000 is '01T068165', where '01' represents the prefix, 'T' represents the letter and '068165' represents the engineering part number. 0 The part number prefix, range [0, 99] 1 The part number letter, represented in ASCII, range [A-Z]

Copyright 2019, Pi Innovo 749 CCP compliance

Position a Description b 2..5 The engineering part number, range [0, 999999] Key = 4, ECU mod and issue numbers The issue level represents a specific design of PCB. Changes to the issue level may have an effect on the software version. The modification level represents what changes were performed to the PCB after manufacturing to correct issue level design mistakes. Changes to the modification level should not have an effect on the software version. 0 The PCB issue level, range [0, 255] 1 The PCB modification level, range [0, 255] Key = 5, Factory part number For instance, the factory part number could be '450FT1034', where '450' represents the part_num[0], 'F' represents the letter[0], 'T' represents the letter[1], and '1034' represents the part_num[1]. 0..1 First number of identifier, range [0, 65535] 2..3 Second number of identifier, range [0, 65535] 4..5 Characters used to separate identifier numbers, represented in ASCII, range [A-Z] Key = 6, Factory part number build type 0..1 The factory part number build type, represented in ASCII, range [A-Z] a All data is arranged in MSB format. b Not all keys are available on all ECUs.

Copyright 2019, Pi Innovo 750 Appendix G. CCP troubleshooting guide

This section describes a troubleshooting procedure for when CCP communications can not be established:

• Section G.2, “No communication between PC and ATI Hub”

• Section G.3, “No communication between PC and OpenECU”

This section explains the symptoms and the solution using examples of a system with an ATI Hub and ATI Vision. Specific issues with ATI products are not addressed in this document as are issues with other system configurations such as ATI's Kvaser and ETAS' INCA, although the overall symptoms and resolutions remain the same.

Note

This guide is provided to help diagnose issues when connecting OpenECU with ATI Vision, and is a reference only. Please direct technical support questions regarding ATI products, to ATI. Pi can supply support for Pi products only.

If at the end of following this guide, the OpenECU module will not communicate to ATI Vision, please get in touch with OpenECU technical support (see Appendix K, Contact information). G.1. Anatomy of an ATI Hub

As a reference to the following troubleshooting guide, this diagram outlines the major interfaces to the ATI Hub. Please refer to the ATI Vision User Guide for further details.

Power switch Power LED Status LEDs USB connector

Front

Back

Power fuse

Power connector 15 pin D-type Communications connector

Copyright 2019, Pi Innovo 751 CCP troubleshooting guide

G.2. No communication between PC and ATI Hub G.2.1. Symptoms

ATI Vision indicates that the Hub and its components are offline. No transmission data rate is shown as no data is communicated. In this case, ATI Vision shows red crosses against “VisionHub”, “VNICAN” and “PCM” while in online mode. The red crosses disappear when while in offline mode.

G.2.2. Possible causes

There are several potential reasons why there are no communications between the computer and the ATI Hub. Also see the Help instructions in ATI Vision's User Guide for further description of how to use the ATI Hub. G.2.2.1. ATI Hub is not powered up/switched on

Troubleshoot

• Check that the “Power LED” on the ATI Hub is illuminated.

Solution

1. Check that the “Power switch” is in the ON position (pointing upwards).

2. Check that the 12V DC is applied on the power connector at the back of the ATI Hub.

3. Check the fuse at the back of the ATI Hub is intact. G.2.2.2. ATI Hub is not connected to the computer correctly

Troubleshoot

• Ensure ATI Hub is powered on (see Section G.2.2, “Possible causes”).

Copyright 2019, Pi Innovo 752 CCP troubleshooting guide

Solution

1. Check that the USB cable between the ATI hub and the computer is connected properly.

2. Ensure that the correct USB driver is installed on the computer (contact ATI Technical Support for more details about the correct USB driver). G.3. No communication between PC and OpenECU G.3.1. Symptoms

ATI Vision indicates that the PCM is offline. A transmission data rate is shown between the computer USB and the Vision Hub. In this case, ATI Vision shows a red cross on “PCM” while in online mode. The red cross disappears and no data transmission rate is reported while in offline mode.

G.3.2. Possible causes

G.3.2.1. OpenECU module is not powered-up

Troubleshoot

• Visually check for the response from actuators that are driven by the OpenECU module (lamps, relays, DC motors, etc.) during power-up. When the observed actuator response is not as expected, then the OpenECU module is not powered up correctly.

• Check that the 5V sensor reference output on the OpenECU module is present. When the reference line voltage does not match the expected 5V, then the module is not powered up correctly.

Copyright 2019, Pi Innovo 753 CCP troubleshooting guide

• Measure the current drawn by the OpenECU module (electrical current into all VPWR input pins). When the total current is less than 250mA, then the module is not powered up correctly.

Solution

1. When fused, check that all fuses are intact.

2. Check that all VPWR pins have a DC voltage supply of 9V to 16V.

3. Check that all PWRGND connections are connected to ground. G.3.2.2. OpenECU module is not connected to the ATI Hub correctly

Troubleshoot

• Ensure OpenECU is powered-up (see Section G.3.2.1, “OpenECU module is not powered-up”).

Solution

1. Remove all devices from the CAN bus except the OpenECU module and the ATI Hub.

Note

When communications are established, then the cause may be in the disconnected device(s). Terminating resistors, different CAN baud rate or clashing CAN message ID's are potential causes. Further investigation will be required but is outside the scope of this trouble shooting guide.

2. Check the 15 pin D-type connector on the back of the ATI Hub if fixed securely.

3. Check that the ATI CAN connections are fitted correctly. CAN-High (white) and CAN- Low (blue) are connected to the corresponding pins of the OpenECU module. G.3.2.3. OpenECU module resets continuously

Troubleshoot

• Ensure OpenECU is powered-up (see Section G.3.2.1, “OpenECU module is not powered-up”).

• Ensure the Hub is connected to the Hub correctly (see Section G.3.2.2, “OpenECU module is not connected to the ATI Hub correctly”).

Solution

1. Power down the OpenECU module.

2. Apply 18V DC to the FEPS input pin of the OpenECU module (i.e. use an external power supply between the FEPS pin and ground).

3. Power up the OpenECU module (powering up with 18V applied to the FEPS pin, forces the OpenECU module to enter reprogramming mode).

4. When communications is established, flash the module with the strategy that is known to be working. Continue with the following steps:

a. Wait for flashing to complete.

Copyright 2019, Pi Innovo 754 CCP troubleshooting guide

b. Remove the 18V DC power from the FEPS input pin of the OpenECU module.

c. Power cycle the module.

Note

Continuous module resets can be caused by a mistake in the strategy model (e.g. divide by zero) or when a model takes too long to run in its allotted time budget (e.g., a 1ms model rate takes longer than 1ms to complete). It is good practice to review the source model for potential causes of the reset.

5. When communications is not established, the OpenECU module is not resetting continuously and the problem is potentially with the CAN configuration (see Section G.3.2.4, “CAN baud rate between OpenECU and ATI disagree” and Section G.3.2.5, “CCP CRO and DTO values do not agree with OpenECU”). G.3.2.4. CAN baud rate between OpenECU and ATI disagree

Troubleshoot

• Ensure OpenECU is powered-up (see Section G.3.2.1, “OpenECU module is not powered-up”).

• Ensure the Hub is connected to the Hub correctly (see Section G.3.2.2, “OpenECU module is not connected to the ATI Hub correctly”).

• Ensure the module does not reset continuously (see Section G.3.2.3, “OpenECU module resets continuously”).

Solution

1. In ATI Vision, right click on “VNICAN” and select the menu option Properties.

2. Select the Settings tab.

3. Select a Bus Frequency of what is expected to match the strategy that is currently flashed onto the module.

Note

When the version of the latest strategy is known, then the bus frequencies of that strategy can be found by opening the strategy in ATI Vision and selecting the menu option File > Properties. The frequency is displayed as “Baudrate” in the Device Settings tab. If the strategy is unknown, then it will be any of the following possible frequencies: 33.333, 50, 62.5, 83.333, 100, 125, 250, 500 or 1000 kBps. Select one at a time until communications are established.

4. When communications is still not established, then the most likely cause is a mismatch of the CRO and DTO vales between the active strategy in the project and the strategy that is currently flashed onto the module. See Section G.3.2.5, “CCP CRO and DTO values do not agree with OpenECU” on how to change CRO and DTO values.

5. When communications is established, flash the module with the strategy that has the new desired bus frequency.

6. Power cycle the module when flashing has completed.

7. In ATI Vision, right click on “VNICAN” and select the menu option Properties.

Copyright 2019, Pi Innovo 755 CCP troubleshooting guide

8. Highlight the Settings tab.

9. Select a “Bus Frequency” of the strategy that is flashed onto the module. G.3.2.5. CCP CRO and DTO values do not agree with OpenECU

Troubleshoot

• Ensure OpenECU is powered-up (see Section G.3.2.1, “OpenECU module is not powered-up”).

• Ensure the Hub is connected to the Hub correctly (see Section G.3.2.2, “OpenECU module is not connected to the ATI Hub correctly”).

• Ensure the module does not reset continuously (see Section G.3.2.3, “OpenECU module resets continuously”).

• Ensure the CAN baud rate is correct (see Section G.3.2.4, “CAN baud rate between OpenECU and ATI disagree”).

Solution

Note

You will need to know the CRO and DTO values of the strategy that was last successfully flashed onto module. These values can either be found in the corresponding MATLAB model or from the corresponding strategy (VST) file. Use steps 2 to 6 below to find out what the existing values are. Because the CRO and DTO can be any CAN identifier number, it will be very difficult to establish communications without knowing the values used in the strategy that is currently flashed onto the modules.

1. Create a copy of the strategy file that needs to be flashed onto the module.

2. Opening it in ATI Vision and selecting the menu option File > Properties.

3. In the Device Settings tab, highlight CRO and press the Edit button. Enter the CRO number of the strategy that is currently flashed onto the module and select the OK.

4. In the Device Settings tab, highlight DTO and press the Edit button. Enter the DTO number of the strategy that is currently flashed onto the module and select the OK.

5. Save the modified strategy file.

6. Attach the modified strategy file to the PCM in ATI Vision and make active.

7. When communications is established, flash the module with the strategy.

8. Power cycle the module when flashing has completed (comms should no longer be established).

9. Attach the version of the strategy file with the original CRO and DTO values to the PCM in ATI Vision and make active. G.3.2.6. CCP seed/key has not been configured, or is using incorrect algorithm(s)

Troubleshoot

• Ensure OpenECU is powered-up (see Section G.3.2.1, “OpenECU module is not powered-up”).

Copyright 2019, Pi Innovo 756 CCP troubleshooting guide

• Ensure the Hub is connected to the Hub correctly (see Section G.3.2.2, “OpenECU module is not connected to the ATI Hub correctly”).

• Ensure the module does not reset continuously (see Section G.3.2.3, “OpenECU module resets continuously”).

• Ensure the CAN baud rate is correct (see Section G.3.2.4, “CAN baud rate between OpenECU and ATI disagree”).

• Ensure the CCP CRO and DTO values are correct (see Section G.3.2.5, “CCP CRO and DTO values do not agree with OpenECU”).

Solution

1. Check the directory where the Vision strategy file is located. If this directory does not contain a DLL file and the strategy is known to require CCP seed/key security, then copy the relevant file to this directory.

2. If the directory contains one or more DLL files but CCP seed/key security is still not available, it is possible that the DLL file in this directory may have the correct name but the wrong algorithm. (It may be the algorithm for a different manufacturer or platform, for example). Locate the correct DLL file(s) providing CCP seed/key security algorithms for this application, and copy the file(s) to this directory.

Copyright 2019, Pi Innovo 757 Appendix H. Crank wheel signal decoding

The crank wheel sensor signal is buffered and processed into a series of digital pulses to the ECU's processor. In turn, the processor detects features of the crank wheel by looking at relative timing between sequential teeth as the wheel accelerates and decelerates. H.1. Variable reluctance signal

The ECU processes a differential VR signal to decode a crank position (and with additional information about a cam wheel, an overall engine position as well).

VR signal (+ve, -ve)

Zero crossing Missing tooth Acceleration represents region center of tooth

Processing the variable reluctance sensor results in a series of digital edges for further signal processing (see Section H.3, “Tooth edge processing”) at the center of a physical tooth. The differential signal is amplified, processed to determine an adaptive threshold used in noise reduction, and then processed to determine zero crossings representing the center of teeth.

Peak threshold adaption

Zero crossing Precision detection differential amplifier

Once the positive differential input signal voltage rises above an adaptive threshold, the zero crossing comparator is armed. Arming the comparator this way provides robust noise immunity to the input VR signal, preventing false triggers from occurring due to a broken tooth or an off-center tooth wheel.

The peak threshold level is set to a third of the peak of the previous cycle of the input VR signal. As the sensor signal peak voltage rises, the adaptive peak threshold voltage also increases by the same ratio. Similarly as the signal peak voltage falls. If the input signal voltage remains lower than the adaptive peak threshold for more than 85ms, an internal watchdog timer drops the threshold level to a default minimum threshold. This ensures pulse recognition recovers even in the presence of intermittent sensor connection.

Copyright 2019, Pi Innovo 758 Crank wheel signal decoding

VR signal (+ve)

Once armed, the zero crossing detection logic generates a digital edge on the falling slope of the positive pair of the VR input. The zero-voltage level of the VR sensor signal corresponds to the center of the gear-tooth and is the most reliable marker for position/angle-sensing applications.

VR signal (+ve)

Processed tooth edge signal

The crank VR input circuitry introduces a phase offset as an artifact of signal filtering. The phase shift causes the digital tooth edge representing the tooth center to occur some time after the actual tooth center. The time between the digital tooth edge and the actual tooth center increases as the frequency of the input signal increases.

Note

Application must take this into account explicitly if required (i.e., the phase shift is typically accommodated implicitly by calibratable lookup tables for general calculations such as spark advance but cylinder balancing and other application strategies may take the phase shift into account explicitly). H.2. Hall-effect signal

Further details to be added in a later release. H.3. Tooth edge processing

Once the VR signal has been converted into a pulse train, each tooth edge is processed by a state machine. Further details about the state machine are given in Section H.4, “Crank decoding states”. Tooth edge processing uses a set of timing comparisons to decode the signal.

Missing tooth region recognition Determining the missing tooth region (the gap) from a variable speed input is achieved by looking at inter-tooth arrival times. With a constant speed wheel, identification of sequential teeth and the gap can be identified by comparing arrival times across a complete revolution. The majority of tooth-to-tooth times will be similar and there will be a single longer time representing the gap.

Copyright 2019, Pi Innovo 759 Crank wheel signal decoding

The scheme used to detect the gap is to compare the duration of the inter-tooth time immediately before the gap (short) to the duration of the gap (long). A timing comparison checks that the ratio of short to long is sufficient to indicate a gap.

Previous tooth edge Tooth edge detected, t-1 detected, t0

Previous tooth edge detected, t-2

Time between consecutive teeth:

∆t = t-1 – t-2 ∆g = t0 – t-1

Missing tooth region confirmed if:

∆g ·ratio-gap-short-long > ∆t

With a constant wheel speed, a value for ratio-gap-short-long slightly larger than one third for a crank wheel with two missing teeth (as shown above) would be sufficient to identify the gap.

With a variable wheel speed, identification of sequential teeth and the gap can be performed in the same fashion, but the ratio limits the detectable acceleration. If there is a tooth-to-tooth acceleration across the gap which causes the ratio test to fail then the gap is not detected. I.e., if the wheel speed has increased above speed-before-gap divided by ratio-gap-short-long then the gap test will fail.

When crank synchronisation has not been found, hard decelerations of the crank wheel between normal teeth could be incorrectly interpreted as a gap using the ratio test. To help avoid false gap detections, the ratio of the gap duration (long) to the immediately following teeth (short) is tested:

Previous tooth edge Tooth edge detected, t-2 detected, t0

Previous tooth edge detected, t-1

Time between consecutive teeth:

∆g = t-1 – t-2 ∆t = t0 – t-1

Missing tooth region confirmed if:

∆g ·ratio-gap-long-short > ∆t

It is still possible that a short single tooth deceleration may be incorrectly interpreted as the gap. To avoid further false positives, the gap is marked as potential, and a revolution of teeth edges is counted before performing a further ratio test. If both tests pass then the gap is confirmed and crank synchronisation declared.

Copyright 2019, Pi Innovo 760 Crank wheel signal decoding

A double ratio test is only required whilst searching for the gap. To keep crank synchronisation a gap must be detected every revolution and a short-long test sufficies. The crank decode logic knows when to apply the test by counting physical teeth between each successful gap ratio test.

Crank synchronisation can be lost in a variety of situations:

• an acceleration across the gap that results in a gap test failure; or

• a noisy crank signal (for instance, a glitchy signal connection, a loose crank sensor, or a generally noisy electrical environment); or

• a malformed crank signal (for instance, a tooth that breaks off); or

• a deceleration such that the next tooth edge is not detected within a reasonable amount of time (for instance, the engine stops and no further teeth edges are detected).

Noise rejection Crank teeth edge processing includes a blanking window to help reject noise that occurs around the zero crossing (can occur at low crank speeds where the signal amplitude is low). The blanking window size is calculated as a ratio of inter-tooth duration, and just as with the gap ratio test, the ratio limits the maximum acceleration possible.

NR timeout Used to reject noisy signal edges

Tooth edge detected, t0

Previous tooth edge detected, t-1

Time for each missing tooth (average):

∆t = t0 – t-1 Noise-rejection timeout:

nr-timeout = t0 + (∆t · ratio-nr)

Maximum speed at next tooth before tooth edge rejected as noise:

speedt1 = speedt0 / ratio-nr

The noise rejection window can be calibrated out by setting the ratio to zero.

Stall detection Crank teeth edge processing includes a timeout after which, if a crank tooth edge has not been detected, the crank wheel is declared stalled. The timeout is calculated as a ratio of the inter-tooth duration, offset by the position of the next expected tooth edge. As is similar with the other ratio tests, the stall-detect ration limits detectable deceleration of the crank wheel.

Copyright 2019, Pi Innovo 761 Crank wheel signal decoding

SD timeout Used to detect crank stall

Tooth edge detected, t0

Previous tooth edge detected, t-1

Time for each missing tooth (average):

∆t = t0 – t-1

Stall-detection timeout:

sd-timeout = t0 + (∆t · (1 + ratio-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (1 + ratio-sd)

The crank stall detection mechanism cannot be calibrated out (in contrast to the noise rejection mechanism).

To better accommodate crank trigger wheels which are positioned such that the gap does not span a portion of the engine cycle that shows the least variability in speed due to firing and compression events, there are specific noise-reject and stall-detect ratios for various teeth (for instance, across the gap, on the first tooth after the gap, etc.).

As described before, these methods are used to find and maintain synchronisation with a crank wheel using a simple state machine. H.4. Crank decoding states

The crank decode functionality is broken down a group of states:

• Initialisation — used to ignore electrical noise generated during initialisation of the electrical system.

• Find crank synchronisation — used to find the missing tooth region when synchronisation was not previously gained, or had been lost

• Keep crank syncrhonisation — used to maintain synchronisation with the crank wheel once synchronisation has been found

Within each group, a series of states decodes the crank signal over time.

Copyright 2019, Pi Innovo 762 Crank wheel signal decoding

During initialisation of ECU

Ignore Skip Found tooth; and crank crank teeth left to skip signal Ignore time teeth expired No teeth left to skip

Find first tooth edge

Tooth edge found

Find second tooth edge

Tooth edge found

Tooth edge timed out timed edge Tooth Find crank synchronisation crank Tooth edge found; and gap gap not found short-long Find

Tooth edge found; and gap found

Confirm gap long-short

Tooth edge found; and gap found

Count teeth

Tooth edge found; and Tooth edge found; and all teeth counted gap confirmed Tooth edge timed out timed edge Tooth

Confirm gap Keep crank synchronisation crank Keep short-long

Copyright 2019, Pi Innovo 763 Crank wheel signal decoding

Ignore-crank-signal Occurs once during initialisation of the ECU, after reset.

The state ignores crank edges for 10 milliseconds, letting any electroincs settle during power up.

Skip-crank-teeth Occurs once the ignore-crank-signal state is complete.

Ignores the first n processed teeth edges, where n is adjustable by the application, letting any electroincs settle during power up.

First-edge Occurs once the skip-crank-teeth state is complete, or loss of crank synchronisation occurred, or the crank signal is declared stalled.

If a tooth edge occurs within first-tooth-timeout milliseconds since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise, the crank signal is declared as stalled. This sets the minimum speed at which the crank decode logic will start to look for crank synchronisation. first-tooth-timeout is adjustable by the application.

Second-edge Occurs if the first-edge state did not timeout.

If a tooth edge occurs within a timeout since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise the crank signal is declared stalled.

SD timeout Used to detect crank stall

Tooth edge Estimated next detected, t0 tooth edge, t1

Previous tooth edge detected, t-1

Time for each missing tooth (average):

∆t = t0 – t-1

Stall-detection timeout:

nr-timeout = t0 + (∆t · (number-of-missing-teeth + 1 + ratio-across-gap-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (number-of-missing-teeth + 1 + ratio-across-gap-sd)

ratio-across-gap-sd is adjustable by the application.

Find-gap-short-long: Occurs if the second-edge state did not timeout; or of the find-gap-short-long state did detect a missing tooth region; or if the confirm-gap-long-short state did not confirm crank synchronisation.

Copyright 2019, Pi Innovo 764 Crank wheel signal decoding

If a tooth edge occurs within a timeout since the last tooth edge then the time of the tooth edge is remembered for later processing. Otherwise the crank signal is declared as stalled.

The state buffers the time of teeth edges in a cyclic fashion, where t0 is the time of the most recent tooth, t-1 is the time of the tooth before t0, and t-2 the time of the tooth before that. The state uses a short-long ratio test to detect the missing tooth region.

SD timeout Used to detect crank stall

Tooth edge Estimated next detected, t0 tooth edge, t1

Previous tooth edge detected, t-1

Time for each missing tooth (average):

∆t = t0 – t-1

Stall-detection timeout:

nr-timeout = t0 + (∆t · (number-of-missing-teeth + 1 + ratio-across-gap-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (number-of-missing-teeth + 1 + ratio-across-gap-sd)

ratio-across-gap-sd is adjustable by the application.

Confirm-gap-long-short Occurs if the search-for-gap-short-long state found the missing tooth region.

If a tooth edge occurs within a window since the last tooth edge then the time of the tooth edge is remembered for later processing (as in state search-for-gap-short-long). Otherwise the crank signal is declared stalled.

The state uses a long-short ratio test to detect the missing tooth region. If positive then crank synchronisation is marked as potential.

Copyright 2019, Pi Innovo 765 Crank wheel signal decoding

NR timeout SD timeout Used to reject Used to detect noisy signal edges crank stall

Previous tooth edge Estimated next detected, t-1 tooth edge, t1

Tooth edge detected, t0

Time for each missing tooth (average):

∆t = (t0 – t-1) / (number-of-missing-teeth + 1) Noise-rejection timeout:

nr-timeout = t0 + (∆t · ratio-after-gap-nr)

Maximum speed at next tooth before tooth edge rejected as noise:

speedt1 = speedt0 / ratio-after-gap-nr

Stall-detection timeout:

sd-timeout = t0 + (∆t · (1 + ratio-after-gap-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (1 + ratio-after-gap-sd)

ratio-after-gap-sd is adjustable by the application.

Count-teeth Occurs if the confirm-gap-long-short state or confirm-gap-short-long state detected the missing tooth region.

If a tooth edge occurs within a timeout since the last tooth edge then the number of teeth since the gap is counted (and an overall crank angle maintained). Otherwise the crank signal is declared stalled.

Copyright 2019, Pi Innovo 766 Crank wheel signal decoding

NR timeout SD timeout Used to reject Used to detect noisy signal edges crank stall

Tooth edge detected, t0

Previous tooth edge Estimated next detected, t-1 tooth edge, t1

Time for each missing tooth (average):

∆t = t0 – t-1 Noise-rejection timeout:

nr-timeout = t0 + (∆t · ratio-normal-gap-nr)

Maximum speed at next tooth before tooth edge rejected as noise:

speedt1 = speedt0 / ratio-normal-gap-nr

Stall-detection timeout:

sd-timeout = t0 + (∆t · (1 + ratio-normal-gap-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (1 + ratio-normal-gap-sd)

ratio-normal-nr and ratio-normal-sd are adjustable by the application.

Confirm-gap-short-long Occurs if the count-teeth state counted the number of physical crank teeth without timeout.

Works as the search-for-gap-short-long state does with the addition of noise rejection.

Copyright 2019, Pi Innovo 767 Crank wheel signal decoding

NR timeout SD timeout Used to reject Used to detect noisy signal edges crank stall

Tooth edge Estimated next detected, t0 tooth edge, t1

Previous tooth edge detected, t-1

Time for each missing tooth (average):

∆t = t0 – t-1 Noise-rejection timeout:

nr-timeout = t0 + (∆t · ratio-across-gap-nr)

Maximum speed at next tooth before tooth edge rejected as noise:

speedt1 = speedt0 / ratio-across-gap-nr

Stall-detection timeout:

nr-timeout = t0 + (∆t · (number-of-missing-teeth + 1 + ratio-across-gap-sd))

Minimum speed at next tooth before stall-detection:

speedt1 = speedt0 / (number-of-missing-teeth + 1 + ratio-across-gap-sd)

ratio-before-gap-nr and ratio-before-gap-sd are adjustable by the application.

Copyright 2019, Pi Innovo 768 Appendix I. Change log I.1.1. Release 3.0.3 (r2019-3)

Release labelled release-3.0.3-r2019-3 from 12 November 2019. This release is marked as general meaning the release has been regression tested and is intended for general use. The following table provides quick access to each of the changes.

Table I.1. Release summary for v3.0.3-r2019-3

Package New features Fixes and improvements Backwards Firmware compatible upgrade C-API No CRs 23947 (F), 23890 (F) Yes Yes, see: 23947 (F) Sim-API No CRs 23947 (F), 23890 (F) Yes Yes, see: 23947 (F) I.1.1.1. Fixes and improvements

Fixes or improvements to existing features with details of why they were previously wrong.

Target ECU

OpenECU software supports a number of ECUs. Each target ECU has differing capabilities across connectors, input/output conditioning circuitry, memory, processors and architectures.

• Added missing status bits supported in $19.

CR 23947 (F), affects Sim-API and C-API

The warning indicator was added previously but the status available mask was not updated.

Note

To enable this functionality, the ECU's firmware must be upgraded to revision 3.0.3-r2019-3 or later. To upgrade the ECU's firmware please contact OpenECU technical support as described in Appendix K, Contact information.

• Changed defaults for short circuit protection.

CR 23890 (F), affects Sim-API and C-API

Reduced fault timer. Reduced fault threshold. Switched to no automatic retry. I.1.1.2. Outstanding issues

• CAN overwrite counter does not increment.

CR 22398 (F), affects Sim-API and C-API

The CAN transmit overwrite counter does not increment when a hardware buffer is overwritten.

Copyright 2019, Pi Innovo 769 Change log

• Error displaying user guide images in the Matlab 2018b help browser

CR 22121 (F), affects Sim-API and C-API

In the Matlab 2018b help browser, pictures in the OpenECU user guide are not displayed.

The OpenECU Simulink User Guide integrates with the Matlab help browser. This is how documentation is displayed when the user clicks on a “Help” button from within an OpenECU Simulink block. In Matlab 2018b, the help browser does not resolve the path to the images folder, so all images are displayed as broken links.

To view the user guide, open a web browser or the pdf files included in the OpenECU platform installation. They can be accessed from the Windows Start menu under “OpenECU Developer Software” or directly from the installation folder. The default location is [OpenECU Install Path] \doc_user\openecu_user_guide_simulink \openecu_user_guide_simulink.html

• Errors integrating with ETAS INCA calibration tool during OpenECU installation

CR 10955 (F), affects Sim-API and C-API

When integrating OpenECU with the ETAS INCA calibration tool during OpenECU installation, there is a problem with part of the installation procedure. Selecting the Integration -> INCA-ProF Integration option when choosing components to install is necessary to generate the target- specific ProF configuration files in the OpenECU installed directory (under tool_integration\inca_prof).

However, when later in the installation process the user is invited to “Choose INCA Updates” (with a list of any currently installed versions of INCA), the user should select "None". This step copies the ProF files into the ETAS INCA installed location, however it does not correctly adjust the paths to those files. This causes errors when attempting to use these ProF files.

Instead the ProF files should be installed directly using the ETAS INCA tool (after installing OpenECU) using the procedure described in the Appendix of the OpenECU User Guide on how to use INCA with OpenECU (under section “Supporting Tools”).

• Manufacturing data retrieval disabled while in reprogramming mode

CR 10386 (F), affects Sim-API and C-API

The firmware is unable to retrieve manufacturing data via an EXCHANGE_ID request while in reprogramming mode. This feature has been temporarily disabled while ECC recovery is enabled in reprogramming mode.

Note

To enable this functionality, the ECU's firmware must be upgraded to revision 3.0.3-r2019-3 or later. To upgrade the ECU's firmware

Copyright 2019, Pi Innovo 770 Change log

please contact OpenECU technical support as described in Appendix K, Contact information.

• J1939 PG transmit and PG receive interfaces do not correctly determine the CAN bus off condition

CR 8754 (W), affects Sim-API and C-API

Both the PG transmit and PG receive interfaces will report an error if the CAN bus is detected as bus-off when the interface runs (as well as other conditions). During testing, it has been shown that the bus-off condition is not detected correctly and thus any bus-off condition does not contribute to the error report. The application must determine the bus-off condition using the CAN status interface rather than relying on the PG transmit and receive interfaces for full error reporting.

• Cannot define a DME without an associated DTE

CR 8752 (W), affects Sim-API and C-API

The ppr_DiagnosticMonitorEntity block to update the numerator, denominator and ratio outputs incorrectly assumes that at least one DTE will be found belonging to that DME. Otherwise it returns an error, and the values for the numerator, denominator and ratio are indeterminate and should not be relied on. As a work around, an application must assign at least one DTE to every DME.

• Application scheduled tasks immediately after software initialisation completes can be delayed by up to 11 milliseconds

CR 8743 (W), affects Sim-API and C-API

Thereafter, the task schedule continues as expected.

• DM30 test result reporting is not currently correct

CR 8630 (W), affects Sim-API

DM30 does not currently report results correctly for DM7 TIDs 248-250. All DM30 results are reported as if TID 247 (return all scaled test results for one SPN) was requested, instead of reporting a single test result. The suggested work around is for single tests to be reported via the generic j1939_PGTransmit block.

• The adaptive blocks do not generate properly on the Real-Time Workshop Embedded Coder target when Global data is placed in a seperate file

CR 8499 (W), affects Sim-API

The default values of adaptive parameters are stored in a defined section of memory in the calibration region. When these calibrations are defined in a seperate file, the compiler does not place them in the proper region of memory, and thus they are disabled. The workaround is to place all global data in the same file as the source file.

• Negative responses to J1979 services not supported for physically addressed requests

CR 8259 (W), affects Sim-API and C-API

Copyright 2019, Pi Innovo 771 Change log

J1979 SEP2010 section 6.2.4.3.7 specifies that if any of services $00 to $0F are not supported, the ECU shall not respond. However, the ECU does give a negative response here for physically addressed requests.

• Negative responses to incorrectly formatted J1979 messages

CR 8259 (W), affects Sim-API and C-API

On certain J1979 ISO 15765-4 services, the ECU generates a negative response to incorrectly formatted request messages in contradiction to the standard. No response is preferred in this situation. This affects services $03, $06, $07 and $0A. See also CR8153.

• Avoiding processor exceptions if NULL dereferenced in customer application during flash erase

CR 8211 (F), affects C-API

See CR 8211 (F) for detail. It is still possible for a bad access to cause an exception which will continue to occur until the flash operation has completed. If it does, a continuous loop is effectively entered until the flash operation is over. If that operation is an erase, it may take long enough for a watchdog exception to take place. Therefore this issue remains open for further action in future to address this scenario. Note however that this type of exception pattern occurs only very rarely even if NULL is repeatedly read during flash operations, so it is now very much less probable that a customer application will cause a reset in the manner described.

• Incorrect flagging of duplicate PGN information

CR 7082 (W), affects Sim-API and C-API

During the build process, checks are performed in case any PGNs have been duplicated. Unfortunately, these checks sometimes flag duplications erroneously.

• Some J1939 functionality does not adhere to the J1939 standard

CR 5786 (W), affects Sim-API and C-API

There are several known issues with the J1939 protocol stack implemented in the OpenECU platform, these are detailed below:

The J1939 feature assumes that it will be running on a fixed address network. Incorrect operation may occur if address claiming is used by other ECUs on the bus.

The feature doesn't implement some timeout periods that are defined in the J1939 specification.

Requests to pause transfers via a CTS message are not honoured.

Requests to re-transmit messages via a CTS message are not honoured.

The feature is unable to handle simultaneous BAM and RTS/CTS sessions from the same source.

Copyright 2019, Pi Innovo 772 Appendix J. Glossary of terms Glossary

ADC Analogue to Digital Converter — a mechanism to read an analogue voltage signal and convert to a digital value.

ASAP2 A standardized description data format for calibration data — for more information refer to ASAM Standards: ASAM MCD 2MC / ASAP2 at the ASAM Web site (http:// www.asam.de).

CAN Controller Area Network — more information can be found on the Bosch web site (http://www.can.bosch.com).

CANdb CAN Database — a CANdb file contains information regarding CAN messages transmitted between CAN nodes in a network. CANdb files (which usually have the file extension .dbc can be edited with tools supplied by Vector CANtech, Inc. (http://www.vector-cantech.com).

CCP CAN Calibration Protocol — for more information refer to ASAM Standards: ASAM MCD: MCD 1a at the ASAM Web site (http://www.asam.de).

CRO Command Receive Object — the CAN identifier of the CCP message, sent by a calibration tool to command the ECU to perform an action.

DTO Data Transmission Object — the CAN identifier of the CCP message, sent by the ECU with the results of a commanded action.

ECU Electronic Control Unit — for instance, an OpenECU device.

KAPWR Keep Alive Power — apply power to this pin while the module is is otherwise powered down to retain the values of any adaptive data or Tunes until the module is next powered up again (see the technical specification for each target for details).

H-Bridge An H-bridge is an electronic circuit which enables a voltage to be applied across a load in either direction. These circuits are used to allow to supply loads such as DC motors forwards and backwards.

Hall Hall Effect Sensor — typical sensor used for cam and shaft position sensing.

HIL Hardware In the Loop — a term used to indicate the replacement of the plant by a simulator (e.g., Pi Innovo's AutoSim — www.piautosim.com [http:// www.piautosim.com]).

J1939 SAE J1939 — a vehicle bus standard used for communications and diagnostics among vehicle components, originally for the heavy duty truck industry in the USA.

Copyright 2019, Pi Innovo 773 Glossary of terms

MIOS Modular Input Output System — a sub-processor of the OpenECU main processor used to encode and decode digital signals.

MISRA The Motor Industry Software Reliability Association produced a set of guidelines for developing vehicle software — for more information refer to Development Guidelines for Vehicle Based Software at the MISRA Web site (http:// www.misra.org.uk).

QADC Queued Analogue to Digital Converted — a sub-processor of the OpenECU main processor used to convert analogue input signals to a quantized digital representation.

PixCal A simplified calibration tool based on Microsoft Excel that requires only a RS232 UART port to communicate with OpenECU. PixCal supports Tunes but not general calibrations and displayables.

PWM Pulse Width Modulation — a digital pulse train, where the ratio of the high time to the low time of a single cycle represents the duty cycle of the PWM signal.

RS232 RS232 is an electrical signalling specification published by the Electronic Industries Association (EIA). It is a standard for serial transmission of data between two devices.

RTOS Real-Time Operating System — a low level piece of software that executes tasks or model iterations in real-time in a periodic fashion.

SIL Safety Integrity Level — the likelihood of a safety related system achieving the safety functions under all the stated conditions within a stated period of time. References to SIL in the OpenECU user manual refer to the MISRA guidelines.

SPI Serial Peripheral Interface — a sub-processor of the OpenECU main processor used to communicate with other devices.

TDC Top Dead Center

TPU Time Processing Unit — a sub-processor of the OpenECU main processor used to encode and decode digital signals.

VRS Variable Reluctance Sensor — typical sensor type for crank, cam or shaft position sensing.

Copyright 2019, Pi Innovo 774 Appendix K. Contact information

If you have questions, or are experiencing issues with OpenECU please see the FAQ website:

website Support.OpenECU.com [http://Support.OpenECU.com]

If you still have questions after searching through the FAQ, or want to discuss sales or proposals, you can contact main office:

Tel +1 734 656 0140

Fax +1 734 656 0141

during normal working hours (Mon to Fri, 0930 to 1700 EST).

Copyright 2019, Pi Innovo 775