{"id":23709499,"url":"https://github.com/shpegun60/cansolver","last_synced_at":"2026-02-06T06:30:18.324Z","repository":{"id":269229409,"uuid":"906789943","full_name":"shpegun60/CanSolver","owner":"shpegun60","description":"Can/FDCan prescalar finder class ","archived":false,"fork":false,"pushed_at":"2024-12-24T20:28:45.000Z","size":11545,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-30T18:56:14.606Z","etag":null,"topics":["5-algoritms","bit-timing-calculator","can","fdcan"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shpegun60.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-21T22:57:52.000Z","updated_at":"2024-12-24T20:28:48.000Z","dependencies_parsed_at":"2024-12-22T00:27:13.771Z","dependency_job_id":null,"html_url":"https://github.com/shpegun60/CanSolver","commit_stats":null,"previous_names":["shpegun60/cansolver"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shpegun60%2FCanSolver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shpegun60%2FCanSolver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shpegun60%2FCanSolver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shpegun60%2FCanSolver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shpegun60","download_url":"https://codeload.github.com/shpegun60/CanSolver/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239793069,"owners_count":19697893,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["5-algoritms","bit-timing-calculator","can","fdcan"],"created_at":"2024-12-30T18:56:30.495Z","updated_at":"2026-02-06T06:30:18.241Z","avatar_url":"https://github.com/shpegun60.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Sites for calculation Can/FDCan Prescalars\n* [Bit Timing Calculator for CAN FD :: kvaser](https://kvaser.com/support/calculators/can-fd-bit-timing-calculator/)\n* [CAN Bus Bit Timing Calculator :: kvaser](https://kvaser.com/support/calculators/bit-timing-calculator/)\n* [CAN Bit Time Calculation :: bittiming](http://www.bittiming.can-wiki.info/)\n* [STM32G4 FDCAN :: Create by : phryniszak](https://phryniszak.github.io/stm32g-fdcan/)\n\nAll algorithms is tested on those site`s\n## Algoritms\n* **calulate0** - Brute Force Method - The most difficult method!!!! Use only when all methods have failed\n* [calculate1](https://github.com/phryniszak/stm32g-fdcan)\n* [calculate2](https://github.com/waszil/can_bit_timing_calculator/tree/master)\n* [calculate3](https://github.com/rhyttr/SocketCAN/blob/master/can-utils/can-calc-bit-timing.c)\n* [calculate4](https://github.com/shpegun60/MCP251XFD/blob/master/Core/MCP251XFD/MCP251XFD.c)\n\n## Benchmark\n* **calulate0** -   16777216\n* **calculate1** -  1912\n* **calculate2** -  32768\n* **calculate3** -  39066\n* **calculate4** -  511\n\n\n1) This test shows how many calculations were performed by different algorithms with the same input data.\n2) **calculate4_can** - This method is based on **calculate4** that is, in terms of speed it is the same. \"Benchmark = calculate4 = 511\"\n3) **calculate4_fdcan** - This method is called twice **calculate4**, meaning it calculates the divisors for the head speed and the data separately. \"Benchmark = calculate4 * 2 = 511 * 2 = 1022\"\n\n\n## Arguments for enable code parts:\n * **Qt in .pro file**: DEFINES += CANSOLVER_TEST=1 CANSOLVER_PRINT=1 CANSOLVER_MINIMUM=0\n * **Eclipse**: need add preprocessor variables to: compiler settings/preprocessor CANSOLVER_TEST=1 CANSOLVER_PRINT=1 CANSOLVER_MINIMUM=0\n * **CMake**: add_definitions(-DCANSOLVER_PRINT=1 -DCANSOLVER_TEST=1 -DCANSOLVER_MINIMUM=0)\n * **clang**: g++ -DCANSOLVER_PRINT=1 -DCANSOLVER_TEST=1 -DCANSOLVER_MINIMUM=0\n * **Microcontroller**: nothing to add, all hard function is disabled\n\n\n\n```cpp\n\n  struct Result {\n        u32 bitrate;             // result bit rate [bit/sec]\n        u32 prescaler;           // The clock prescaler value used for generating the CAN timing.\n        u32 tq_per_bit;          // Number of Time Quanta (TQ) per bit in the CAN bit timing.\n        u32 tBS1;                // Time Segment 1 (in TQ), which includes Propagation and Phase Segment 1.\n        u32 tBS2;                // Time Segment 2 (in TQ), used for Phase Segment 2.\n        u32 sync_jump_width;     // Synchronization Jump Width (SJW) in TQ, defining the maximum adjustment for resynchronization.\n        float sample_point;      // The sample point location as a percentage [%] of the bit period.\n        float freq_diff;         // The frequency deviation [%] between the calculated and desired bit rate.\n        bool solutionFinded;\t // Solution finded indicator (only the best structure)\n\n        // Class method for comparison\n        bool operator==(const Result\u0026 other) const {\n            // Compare all fields to determine equality between two results.\n            return std::tie(prescaler, tq_per_bit, tBS1, tBS2, sync_jump_width, sample_point, freq_diff) ==\n                   std::tie(other.prescaler, other.tq_per_bit, other.tBS1, other.tBS2, other.sync_jump_width, other.sample_point, other.freq_diff);\n        }\n    };\n\n\n    struct Input {\n        u32 clock;               \t\t// The FDCAN peripheral's input clock frequency in Hz.\n        u32 clock_divider;      \t\t// Divider applied to the input clock to determine the CAN clock frequency.\n        u32 rate;               \t\t// Desired nominal bit rate in bits per second (bps).\n        float sampling_point_min;       // Minimum allowed sampling point percentage [%] (0–100).\n        float sampling_point_max;  \t\t// Maximum allowed sampling point percentage [%] (0–100).\n\n        u32 prescaler_min;              // Minimum value of the prescaler for clock division.\n        u32 prescaler_max;              // Maximum value of the prescaler for clock division.\n\n        u32 time_seg1_min;              // Minimum duration of Time Segment 1 in Time Quanta (TQ).\n        u32 time_seg1_max;              // Maximum duration of Time Segment 1 in Time Quanta (TQ).\n\n        u32 time_seg2_min;              // Minimum duration of Time Segment 2 in Time Quanta (TQ).\n        u32 time_seg2_max;              // Maximum duration of Time Segment 2 in Time Quanta (TQ).\n\n        u32 sjw_min;                    // Minimum Synchronization Jump Width (SJW) in Time Quanta (TQ).\n        u32 sjw_max;                    // Maximum Synchronization Jump Width (SJW) in Time Quanta (TQ).\n\n        float baudrate_tolerance = 1.0f; // Allowed tolerance for the deviation of the actual bit rate from the desired rate, in percent.\n    };\n\n    /*\n     * Brute Force Method - The most difficult method!!!! Use only when all methods have failed\n     * Estimated cost = (prescaler_max - prescaler_min) * (time_seg1_max - time_seg1_min) * (time_seg2_max - time_seg2_min)\n     * From Shpegun60\n     */\n    const Result\u0026 calculate0(const Input\u0026 in);\n\n  /*\n     * Estimated cost = (prescaler_max - prescaler_min) * (sampling_point_min - sampling_point_max) / 0.1  --\u003e FAST\n\t * from https://github.com/phryniszak/stm32g-fdcan\n\t */\n    const Result\u0026 calculate1(const Input\u0026 in);          \t// Computes all possible CAN timing configurations based on the input parameters.\n\n    /*\n\t * Estimated cost = (time_seg1_max - time_seg1_min) * (time_seg2_max - time_seg2_min)\n\t *\n\t * from https://github.com/waszil/can_bit_timing_calculator/tree/master\n\t */\n    const Result\u0026 calculate2(const Input\u0026 in);\t\t\t// Computes all possible CAN timing configurations based on the input parameters.\n\n    /*\n     * Estimated cost = ???\n     * from https://github.com/rhyttr/SocketCAN/blob/master/can-utils/can-calc-bit-timing.c\n\t */\n    const Result\u0026 calculate3(const Input\u0026 in);\t\t\t// Computes all possible CAN timing configurations based on the input parameters.\n\n    /*\n     * Estimated cost = ??? ULTRA - FAST\n     * from https://github.com/shpegun60/MCP251XFD/blob/master/Core/MCP251XFD/MCP251XFD.c\n     */\n    const Result\u0026 calculate4(const Input \u0026in);\n\n    /*\n     * Methods for microcontrollers (based on calculate4)\n     */\n    inline static Result calculate4_can(const Input \u0026head);\n    inline static std::array\u003cResult, 2\u003e calculate4_fdcan(const Input \u0026head, const Input \u0026data);\n```\n## Test\n\n```cpp\nvoid CanSolver::test()\n{\n    CanSolver nom;\n    CanSolver::Input nominal {\n        100000000, // clock\n        1,        // clock_divider\n        1000000,  // rate\n        75,       // sampling_point_min\n        80,       // sampling_point_max\n        1,        // prescaler_min\n        512,      // prescaler_max\n        1,        // time_seg1_min\n        256,      // time_seg1_max\n        1,        // time_seg2_min\n        128,      // time_seg2_max\n        1,        // sjw_min\n        128,      // sjw_max\n        0.1f      // baudrate_tolerance\n    };\n\n    // CanSolver::Input nominal {\n    //     100000000, // clock\n    //     1,        // clock_divider\n    //     2500000,  // rate\n    //     75,       // sampling_point_min\n    //     80,       // sampling_point_max\n    //     1,        // prescaler_min\n    //     32,      // prescaler_max\n    //     1,        // time_seg1_min\n    //     32,      // time_seg1_max\n    //     1,        // time_seg2_min\n    //     16,      // time_seg2_max\n    //     1,        // sjw_min\n    //     16,      // sjw_max\n    //     0.1f      // baudrate_tolerance\n    // };\n\n\n    {\n        nom.calculate0(nominal);\n        nom.remove_duplicates();\n        nom.sort();\n        std::cout \u003c\u003c \"Results for Brute Force Method:\\n\";\n        nom.print_results();\n        std::cout \u003c\u003c \"Benchmark: \" \u003c\u003c nom.getBenchmark() \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    {\n        nom.calculate1(nominal);\n        nom.remove_duplicates();\n        nom.sort();\n        std::cout \u003c\u003c \"Results for First Method:\\n\";\n        nom.print_results();\n        std::cout \u003c\u003c \"Benchmark: \" \u003c\u003c nom.getBenchmark() \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    {\n        nom.calculate2(nominal);\n        nom.remove_duplicates();\n        nom.sort();\n        std::cout \u003c\u003c \"Results for Second Algititm:\\n\";\n        nom.print_results();\n        std::cout \u003c\u003c \"Benchmark: \" \u003c\u003c nom.getBenchmark() \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    {\n        nom.calculate3(nominal);\n        nom.remove_duplicates();\n        nom.sort();\n        std::cout \u003c\u003c \"Results for Third Algititm:\\n\";\n        nom.print_results();\n        std::cout \u003c\u003c \"Benchmark: \" \u003c\u003c nom.getBenchmark() \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    {\n        nom.calculate4(nominal);\n        nom.remove_duplicates();\n        nom.sort();\n        std::cout \u003c\u003c \"Results for Four Algititm:\\n\";\n        nom.print_results();\n        std::cout \u003c\u003c \"Benchmark: \" \u003c\u003c nom.getBenchmark() \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    {\n        std::cout \u003c\u003c \"Results for Simple CAN:\\n\";\n        CanSolver can;\n        auto res = CanSolver::calculate4_can(nominal);\n        can.print_results(res);\n\n        std::cout \u003c\u003c \"\\nPassed: \"\u003c\u003c (nom.getBest() == res)  \u003c\u003c \"\\n\\n\";\n    }\n\n    {\n        std::cout \u003c\u003c \"Results for FDCAN:\\n\";\n        CanSolver can;\n        auto res = CanSolver::calculate4_fdcan(nominal, nominal);\n        can.print_results(res[0]);\n        can.print_results(res[1]);\n\n        std::cout \u003c\u003c \"\\nHead Passed: \"\u003c\u003c (nom.getBest() == res[0])  \u003c\u003c \"\\n\";\n        std::cout \u003c\u003c \"Data Passed: \"\u003c\u003c (nom.getBest() == res[1])  \u003c\u003c \"\\n\\n\";\n    }\n\n}\n```\n\n## Output:\n```\nResults for Brute Force Method:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n    1 |        25 |       4 |        2 |        1 |     1 |         75 |      0 \n    1 |         5 |      20 |       14 |        5 |     5 |         75 |      0 \n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n    1 |         4 |      25 |       18 |        6 |     6 |         76 |      0 \n    1 |         2 |      50 |       37 |       12 |    12 |         76 |      0 \n    1 |         1 |     100 |       75 |       24 |    24 |         76 |      0\n    1 |         1 |     100 |       76 |       23 |    23 |         77 |      0\n    1 |         2 |      50 |       38 |       11 |    11 |         78 |      0\n    1 |         1 |     100 |       77 |       22 |    22 |         78 |      0\n    1 |         1 |     100 |       78 |       21 |    21 |         79 |      0\n    1 |        20 |       5 |        3 |        1 |     1 |         80 |      0\n    1 |        10 |      10 |        7 |        2 |     2 |         80 |      0 \n    1 |         5 |      20 |       15 |        4 |     4 |         80 |      0 \n    1 |         4 |      25 |       19 |        5 |     5 |         80 |      0 \n    1 |         2 |      50 |       39 |       10 |    10 |         80 |      0 \n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\n------\nThe best:\n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n\nBenchmark: 16777216\n\nResults for First Method:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n    1 |        25 |       4 |        2 |        1 |     1 |         75 |      0 \n    1 |         5 |      20 |       14 |        5 |     5 |         75 |      0\n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0\n    1 |         4 |      25 |       18 |        6 |     6 |         76 |      0\n    1 |         2 |      50 |       37 |       12 |    12 |         76 |      0\n    1 |         1 |     100 |       75 |       24 |    24 |         76 |      0\n    1 |         1 |     100 |       76 |       23 |    23 |         77 |      0\n    1 |         2 |      50 |       38 |       11 |    11 |         78 |      0\n    1 |         1 |     100 |       77 |       22 |    22 |         78 |      0\n    1 |         1 |     100 |       78 |       21 |    21 |         79 |      0\n    1 |        20 |       5 |        3 |        1 |     1 |         80 |      0\n    1 |        10 |      10 |        7 |        2 |     2 |         80 |      0\n    1 |         5 |      20 |       15 |        4 |     4 |         80 |      0\n    1 |         4 |      25 |       19 |        5 |     5 |         80 |      0\n    1 |         2 |      50 |       39 |       10 |    10 |         80 |      0 \n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\n------\nThe best:\n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n\nBenchmark: 1912\n\nResults for Second Algititm:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n    1 |        25 |       4 |        2 |        1 |     1 |         75 |      0 \n    1 |         5 |      20 |       14 |        5 |     5 |         75 |      0 \n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n    1 |         4 |      25 |       18 |        6 |     6 |         76 |      0\n    1 |         2 |      50 |       37 |       12 |    12 |         76 |      0\n    1 |         1 |     100 |       75 |       24 |    24 |         76 |      0 \n    1 |         1 |     100 |       76 |       23 |    23 |         77 |      0 \n    1 |         2 |      50 |       38 |       11 |    11 |         78 |      0 \n    1 |         1 |     100 |       77 |       22 |    22 |         78 |      0 \n    1 |         1 |     100 |       78 |       21 |    21 |79 |      0\n    1 |        20 |       5 |        3 |        1 |     1 |         80 |      0 \n    1 |        10 |      10 |        7 |        2 |     2 |         80 |      0 \n    1 |         5 |      20 |       15 |        4 |     4 |         80 |      0 \n    1 |         4 |      25 |       19 |        5 |     5 |         80 |      0 \n    1 |         2 |      50 |       39 |       10 |    10 |         80 |      0 \n    1 |         1 |100 |       79 |       20 |    20 |         80 |      0\n\n------\nThe best:\n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n\nBenchmark: 32768\n\nResults for Third Algititm:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n    1 |        25 |       4 |        2 |        1 |     1 |         75 |      0 \n    1 |         5 |      20 |       14 |        5 |     5 |         75 |      0 \n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0 \n    1 |         4 |      25 |       18 |        6 |     6 |         76 |      0 \n    1 |         2 |      50 |       37 |       12 |    12 |         76 |      0 \n    1 |         1 |     100 |       75 |       24 |    24 |         76 |      0 \n    1 |         1 |     100 |       76 |       23 |    23 |         77 |      0 \n    1 |         2 |      50 |       38 |       11 |    11 |         78 |      0 \n    1 |         1 |     100 |       77 |       22 |    22 |         78 |      0 \n    1 |         1 |     100 |       78 |       21 |    21 |         79 |      0\n    1 |        20 |       5 |        3 |        1 |     1 |         80 |      0 \n    1 |        10 |      10 |        7 |        2 |     2 |         80 |      0 \n    1 |         5 |      20 |       15 |        4 |     4 |         80 |      0 \n    1 |         4 |      25 |       19 |        5 |     5 |         80 |      0 \n    1 |         2 |      50 |       39 |       10 |    10 |         80 |      0 \n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\n------\nThe best:\n    1 |         1 |     100 |       74 |       25 |    25 |         75 |      0\n\nBenchmark: 39066\n\nResults for Four Algititm:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n    1 |        25 |       4 |        2 |        1 |     1 |         75 |      0 \n    1 |        20 |       5 |        3 |        1 |     1 |         80 |      0 \n    1 |        10 |      10 |        7 |        2 |     2 |         80 |      0 \n    1 |         5 |      20 |       15 |        4 |     4 |         80 |      0 \n    1 |         4 |      25 |       19 |        5 |     5 |         80 |      0 \n    1 |         2 |      50 |       39 |       10 |    10 |         80 |      0 \n    1 |         1 |  100 |       79 |       20 |    20 |         80 |      0\n\n------\nThe best:\n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\nBenchmark: 511\n\nResults for Simple CAN:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n\n------\nThe best:\n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\n\nPassed: 1\n\nResults for FDCAN:\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n\n------\nThe best:\n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\nRate[Mb]| Prescaler | TQ/bit | TimeSeg1 | TimeSeg2 | SJW  | SampleP[%] | Diff[%]\n------------------------------------------------------------------------------- \n\n------\nThe best:\n    1 |         1 |     100 |       79 |       20 |    20 |         80 |      0 \n\n\nHead Passed: 1\nData Passed: 1\n\n\nProcess exited with code: 0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshpegun60%2Fcansolver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshpegun60%2Fcansolver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshpegun60%2Fcansolver/lists"}