Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
31db0c9
feat: implement circular linked list optimization for ADC ISR
FredM67 Oct 10, 2025
fbf0f20
refactor: move ADC optimization code near ISR function
FredM67 Oct 10, 2025
b5ebc77
Optimize DC offset filtering with left-aligned ADC and EMA
FredM67 Oct 15, 2025
28fac46
style: normalize else brace placement in ADC_vect ISR
FredM67 Oct 15, 2025
f97a700
refactor: generalize initializeArray template; update docs and versio…
FredM67 Oct 16, 2025
9730106
feat: optimize ISR with assembly multiplication and fix ADMUX timing
FredM67 Oct 17, 2025
c98f332
style: align inline comment spacing for instP >>= 12 in processCurren…
FredM67 Oct 17, 2025
a0e925b
style: correct V^2 scaling comments and normalize TODO spacing
FredM67 Oct 17, 2025
53316e3
Optimize V² accumulation with uint32_t and add comprehensive tests
FredM67 Oct 17, 2025
8e74f11
style: normalize spacing and formatting in voltage accumulation tests
FredM67 Oct 17, 2025
b31d367
Merge branch 'main' into 121-suggestions-1-2
FredM67 Oct 17, 2025
7086e8d
fix: add inline uint16_t prototypes for processVoltageRawSample and p…
FredM67 Oct 17, 2025
b22cde3
Merge branch '121-suggestions-1-2' of github.com:FredM67/PVRouter-3-p…
FredM67 Oct 17, 2025
5d20297
perf: pre-shift ADC samples to 14-bit before S16x16 multiplies; adjus…
FredM67 Oct 22, 2025
cd32cb1
Merge branch 'main' into 121-suggestions-1-2
FredM67 Dec 26, 2025
955f4d5
fix: update ADMUX at end of ADC ISR to meet ATmega328P timing (#126)
FredM67 Dec 26, 2025
8828c27
chore: implement two-branch workflow (main + dev) (#134)
FredM67 Dec 27, 2025
564dcab
docs: add detailed daily and release workflow instructions (#135)
FredM67 Dec 27, 2025
75b1d7b
fix: remove broken image links from CONTRIBUTING.md (#136)
FredM67 Dec 27, 2025
20c385b
Merge branch 'dev' into 121-suggestions-1-2
FredM67 Dec 27, 2025
3f1b174
test: add DC offset filter unit tests with old/new comparison
FredM67 Jan 29, 2026
1357843
test: add power and RMS calculation comparison tests
FredM67 Jan 30, 2026
da9fa68
test: add realistic load variation tests for old/new comparison
FredM67 Jan 30, 2026
efbe83d
test: extend current amplitudes to ADC limit (~505)
FredM67 Jan 30, 2026
a23abc9
test: add statistics output to power/RMS comparison tests
FredM67 Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repos:
- id: no-commit-to-branch
args:
- --branch=main
- --branch=dev
- id: end-of-file-fixer
exclude: ^(.*/)?\.vscode/|\.drawio$
- id: trailing-whitespace
Expand Down
69 changes: 64 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approacha

In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.

Use the table of contents icon <img src="./assets/images/table-of-contents.png" width="25" height="25" /> on the top left corner of this document to get to a specific section of this guide quickly.

## New contributor guide

To get an overview of the project, read the [README](README.md). Here are some resources to help you get started with open source contributions:
Expand All @@ -18,6 +16,69 @@ To get an overview of the project, read the [README](README.md). Here are some r
- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)


## Branching Strategy

This project uses a two-branch workflow:

| Branch | Purpose | Description |
|--------|---------|-------------|
| `main` | Stable releases | Production-ready code that users download (default branch) |
| `dev` | Development | Active development and testing |

> **Note:** Direct commits to `main` and `dev` are blocked by pre-commit hooks. Always work in feature branches.

### Daily Development Workflow

**Starting a new feature:**

```bash
# Switch to dev and update
git checkout dev
git pull origin dev

# Create feature branch
git checkout -b feature/my-feature-name
```

**Working on your feature:**

```bash
# Make changes, commit as usual
git add .
git commit -m "feat: description of changes"

# Push your feature branch
git push -u origin feature/my-feature-name
```

**Creating a Pull Request:**

```bash
# Create PR targeting dev branch
gh pr create --base dev --title "feat: my feature"

# Or use GitHub UI and change base branch from 'main' to 'dev'
```

### Release Workflow

**When ready to release stable code to users:**

```bash
# Switch to main branch
git checkout main
git pull origin main

# Merge dev into main
git merge dev

# Tag the release
git tag v1.x.x
git push origin main --tags
```

After merging to `main`, users will get the latest stable release when they clone or download the repository.

## Getting started

To navigate our codebase with confidence, see [the introduction to working in the docs repository](/contributing/working-in-docs-repository.md) :confetti_ball:. For more information on how we write our markdown files, see [the GitHub Markdown reference](contributing/content-markup-reference.md).
Expand All @@ -40,8 +101,6 @@ Scan through our [existing issues](https://github.com/github/docs/issues) to fin

Click **Make a contribution** at the bottom of any docs page to make small changes such as a typo, sentence fix, or a broken link. This takes you to the `.md` file where you can make your changes and [create a pull request](#pull-request) for a review.

<img src="./assets/images/contribution_cta.png" width="300" height="150" />

#### Make changes in a codespace

For more information about using a codespace for working on GitHub documentation, see "[Working in a codespace](https://github.com/github/docs/blob/main/contributing/codespace.md)."
Expand Down Expand Up @@ -125,7 +184,7 @@ If you need to commit without running hooks (not recommended):
git commit --no-verify
```

> **Note:** The `no-commit-to-branch` hook prevents direct commits to `main`. Create a feature branch for your changes.
> **Note:** The `no-commit-to-branch` hook prevents direct commits to `main` and `dev`. Always create a feature branch for your changes (typically branching from `dev`).

### Commit your update

Expand Down
167 changes: 167 additions & 0 deletions Mk2_3phase_RFdatalog_temp/mult_asm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
* @file mult_asm.h
* @author Based on florentbr's suggestions and avrfreertos optimizations
* @brief Assembly-optimized multiplication functions for AVR microcontrollers
* @version 0.1
* @date 2025-10-09
*
* @copyright Copyright (c) 2025
*
* This file contains highly optimized assembly multiplication functions for
* time-critical operations on AVR microcontrollers. These functions eliminate
* the overhead of GCC's library calls for 16/32-bit multiplications.
*
* Based on:
* - florentbr's optimization suggestions for PVRouter
* - avrfreertos multiplication optimizations by feilipu
* - OpenMusicLabs AVR assembly techniques
*/

#ifndef MULT_ASM_H
#define MULT_ASM_H

#include <stdint.h>

/**
* @brief Optimized 16×16→32 signed multiplication with assembly
*
* This function performs a signed 16-bit × 16-bit multiplication returning
* a 32-bit result using hand-optimized AVR assembly. It's significantly
* faster than GCC's library multiplication functions.
*
* @param result Reference to int32_t variable to store the result
* @param a First 16-bit signed value
* @param b Second 16-bit signed value
*
* @note On AVR: ~15-20 cycles vs ~50+ cycles for library calls
* @note Fallback available for non-AVR platforms
* @note Based on avrfreertos and OpenMusicLabs techniques
* @note Function provides type checking and debugging support
*
* @ingroup TimeCritical
*/
static inline __attribute__((always_inline)) void multS16x16_to32(int32_t& result, int16_t a, int16_t b)
{
#ifdef __AVR__
asm volatile(
"clr r26 \n\t" // Clear temporary register
"mul %A1, %A2 \n\t" // a_lo * b_lo
"movw %A0, r0 \n\t" // Store low 16 bits
"muls %B1, %B2 \n\t" // a_hi * b_hi (signed)
"movw %C0, r0 \n\t" // Store high 16 bits
"mulsu %B1, %A2 \n\t" // a_hi * b_lo (signed*unsigned)
"sbc %D0, r26 \n\t" // Handle sign extension
"add %B0, r0 \n\t" // Add partial result
"adc %C0, r1 \n\t"
"adc %D0, r26 \n\t"
"mulsu %B2, %A1 \n\t" // b_hi * a_lo (signed*unsigned)
"sbc %D0, r26 \n\t" // Handle sign extension
"add %B0, r0 \n\t" // Add partial result
"adc %C0, r1 \n\t"
"adc %D0, r26 \n\t"
"clr r1 \n\t" // Restore r1 to zero
: "=&r"(result)
: "a"(a), "a"(b)
: "r26");
#else
result = static_cast< int32_t >(a) * b;
#endif
}

static inline __attribute__((always_inline)) void multU16x16_to32(uint32_t& result, uint16_t a, uint16_t b)
{
#ifdef __AVR__
asm volatile(
"clr r26 \n\t"
"mul %A1, %A2 \n\t"
"movw %A0, r0 \n\t"
"mul %B1, %B2 \n\t"
"movw %C0, r0 \n\t"
"mul %B2, %A1 \n\t"
"add %B0, r0 \n\t"
"adc %C0, r1 \n\t"
"adc %D0, r26 \n\t"
"mul %B1, %A2 \n\t"
"add %B0, r0 \n\t"
"adc %C0, r1 \n\t"
"adc %D0, r26 \n\t"
"clr r1 \n\t"
: "=&r"(result)
: "a"(a), "a"(b)
: "r26");
#else
result = static_cast< uint32_t >(a) * b;
#endif
}

/**
* @brief Optimized 16×8→16 signed multiplication with Q8 fractional
*
* This function performs a signed 16-bit × unsigned 8-bit Q8 fractional
* multiplication with rounding, returning a 16-bit result. The 8-bit value
* is treated as a fraction (Q8 format: 8 fractional bits).
*
* @param result Reference to int16_t variable to store the result
* @param value 16-bit signed value
* @param fraction 8-bit unsigned fraction (Q8 format: 0.0 to 0.996)
*
* @note On AVR: ~9 cycles with built-in rounding
* @note Q8 format: fraction = 256 * actual_fraction
* @note Example: fraction=128 represents 0.5, fraction=64 represents 0.25
* @note Based on avrfreertos and OpenMusicLabs techniques
* @note Function provides type checking and debugging support
*
* @ingroup TimeCritical
*/
static inline __attribute__((always_inline)) void mult16x8_q8(int16_t& result, int16_t value, uint8_t fraction)
{
#ifdef __AVR__
asm volatile(
"mulsu %B[val], %[frac] \n\t" // value_hi * fraction (signed*unsigned)
"movw %A[ret], r0 \n\t" // Store result
"mul %A[val], %[frac] \n\t" // value_lo * fraction
"lsl r0 \n\t" // Shift for rounding
"adc %A[ret], r1 \n\t" // Add with carry (rounding)
"clr r1 \n\t" // Restore r1 to zero
"adc %B[ret], r1 \n\t" // Propagate carry
: [ret] "=&r"(result)
: [val] "a"(value), [frac] "a"(fraction));
#else
result = static_cast< int16_t >((static_cast< int32_t >(value) * fraction + 0x80) >> 8);
#endif
}

/**
* @brief Convert floating-point fraction to Q8 format
*
* Helper function to convert a floating-point fraction (0.0 to 1.0)
* to the Q8 format used by mult16x8_q8().
*
* @param frac Floating-point fraction (0.0 to 1.0)
* @return Q8 format value (0 to 255)
*
* @note This is typically used at compile time with constexpr
* @note Example: float_to_q8(0.5) returns 128
*/
constexpr uint8_t float_to_q8(float frac)
{
return static_cast< uint8_t >(frac * 256.0f + 0.5f);
}

/**
* @brief Convert Q8 format back to floating-point
*
* Helper function to convert Q8 format back to floating-point
* for debugging and testing purposes.
*
* @param q8_val Q8 format value (0 to 255)
* @return Floating-point fraction (0.0 to ~1.0)
*
* @note Primarily for testing and debugging
*/
constexpr float q8_to_float(uint8_t q8_val)
{
return static_cast< float >(q8_val) / 256.0f;
}

#endif /* MULT_ASM_H */
Loading
Loading