GiUCAN

a minimalistic version of BACCAble providing a subset of functionalities: Smart Start and Stop disabling, DPF regeneration warnings, Dashboard info display

View on GitHub

GiUCAN

Demo video

GiUCAN demo

DISCLAIMER

GiUCAN is an experimental project developed solely for educational and research purposes. It is strictly prohibited to use this tool on vehicles operating on public roads or in any manner that may pose a risk to public safety, violate laws or regulations, or cause harm to people or property.

The developer of GiUCAN assumes no liability for any damages, malfunctions, legal issues, or other consequences arising from its use. All responsibility lies with the end user, who assumes full civil, criminal, and legal liability for any misuse.

Do not use this project in real-world vehicle control or autonomous driving applications.

Rationale

I’m contributing to the BACCAble repository, I’m keeping this one strictly target to my needs; the goal is to use it as a learning playground. Please check the amazing BACCAble project!

What you need and how to connect

Premise

Since MY2018 Giulia and Stelvio are equipped with SGW; if you car has SGW you need a bypass.

Hardware

GiUCAN has been developed and tested for FYSETC UCAN so you need:

Connection schema

image

Boards must be powered with 5V, you can get the power from the USB connector below the AC; if your ETM has a free USB HSD connector you can use that one to keep the power connection hidden

DO NOT connect boards to 12V OBD2 pin with a power converter: OBD2 12V is always providing power even when the car is off and in deep sleep mode, GiUCAN relays on ETM powering off USB for shutdown of boards; NO LOW CONSUMPTION MODE HAS BEEN IMPLEMENTED.

Building

Just run build.sh and it will create 3 elf firmware files under dist folder:

By default builds are for Diesel and 7 inch dashboard display

Flashing

You can use dfu-util or STM32CubeProgrammer; connect boards via USB in boot mode by short cutting BO and 3V3 pins then flash the firmware you like via DFU (Erasing & Programming -> USB from the dropdown on the left).

Usage

Once flashed and connected power on your car; after few seconds you’ll see the SNS led on the left active and it means that the SNS has been disabled.

To view messages on the dashboard just keep the cruise control RES button pressed for a couple of seconds, keep it pressed again to hide; you can use cruise control speed joystick to move across dashboard items (1 by 1 or 10 by 10 using “hard press”).

If ETM need to show something it will stay on the dashboard for a little bit ore than a second, then GiUCAN will display the item again.

If a DPF regeneration is about to start and it’s not a “forced” one GiUCAN will fire a sound notification (seat belts alarm) and display the “DPF status” item on the dashboard (even if you haven’t enabled messages by long press of RES button).

Customization

By creating a file named inc/user_config.h you can customize almost any feature or behavior of GiUCAN; please do check the content of inc/config.h as reference

Features and behaviors

Customize items

You can customize what items are displayed, how they are rendered and how they are extracted

take a look at inc/dashboard.h for reference

Patterns

GiUCAN do render messages using snprintf so output is always truncated to DASHBOARD_MESSAGE_MAX_LENGTH

Converters

A converter is defined as

item_type, forV0_return_type, forV0_convert_function_code, forV1_return_type, forV1_convert_function_code

so it defines how first and second value are converted before passing them to snsprintf; they do render to

forV0_return_type item_type_V0Converter(float value)  {return forV0_convert_function_code;}
forV1_return_type item_type_V1Converter(float value)  {return forV1_convert_function_code;}

so for example

X(GEAR_ITEM, char, ((unsigned char)value), bool, false)

renders to

char GEAR_ITEM_V0Converter(float value)  {return ((unsigned char)value);}

bool GEAR_ITEM_V1Converter(float value)  {return false;}

so you might wanna then use it for an item with a pattern like "Current gear: %c" (it’s expecting a char, not a float) and no second value is expected.

Extraction functions

Yuo can extract values from the state or from a CAN response depending on how extractors are defined; a function is defined as

function_name, code

and it renders to

float function_name(GlobalState *s, uint8_t *r) { return code; }

you can the extract a float from s or r or both; for example

X(extractTempCommon, ((float)(((A(r) * 256) + B(r))) * 0.02f) - 40.0f)

renders to

float extractTempCommon(GlobalState *s, uint8_t *r) { return ((float)(((A(r) * 256) + B(r))) * 0.02f) - 40.0f; }

(GiUCAN does provide defines for A, B, C and D to facilitate the extraction of bytes 4,5,6 and 7 of r)

also for example

X(extractBoardUptime, (((float)s->board.now) / 60000.0f))                      \

renders to

float extractBoardUptime(GlobalState *s, uint8_t *r) { return (((float)s->board.now) / 60000.0f); }

Extractors

Every item that can display values need extractors for first and second optional value; extractors are defined as

item_type,
hasV0,
forV0_needsQuery,
forV0_query_reqId,
forV0_query_reqData,
forV0_extraction_function
hasV1,
forV1_needsQuery,
forV1_query_reqId,
forV1_query_reqData,
forV1_extraction_function

and the renders to CarValueExtractors; they defines if a value needs a query, what are query request id, request data and reply id and what function to use to extract the value from state or response (see Extraction functions)

for example

X(UPTIME_ITEM, true, true, 0x18DA10F1, 0x03221009, extractCarUptime, true, false, 0, 0, extractBoardUptime)

renders to:

static CarValueExtractors UPTIME_ITEM_extractors = {
    .hasV0 = true,
    .forV0 = {
        .needsQuery = true,
        .query = {
            .reqId = 0x18DA10F1,
            .reqData = SWAP_ENDIAN32(0x03221009),
            .replyId = REQ_RES_ID_CONVERSION(0x18DA10F1),
        },
        .extract = extractCarUptime,
    },
    .hasV1 = true,
    .forV1 = {
        .needsQuery = false,
        .query = {
            .reqId = 0,
            .reqData = SWAP_ENDIAN32(0),
            .replyId = REQ_RES_ID_CONVERSION(0)
        },
        .extract = extractBoardUptime,
    }};

GiUCAN will use extractors to send queries - if needed - the consume the response and extract first and second float values using extraction functions (noop_extract is provided in the codebase for convenience).

user config examples

Take a look at danardi78/Alfaromeo-Giulia-Stelvio-PIDs for all known PIDs