From 323a91df6fc1ada141a8bc98ead1c2108f93dd7d Mon Sep 17 00:00:00 2001 From: MykolaKovalyk Date: Fri, 16 Aug 2024 15:15:20 +0300 Subject: [PATCH 1/2] Add first pipeline check --- .github/.gitignore | 1 - .github/actions/avr_setup/action.yml | 18 +++ .github/actions/get_changed_files/action.yml | 13 +++ .github/workflows/Lab_01_CI.yml | 37 ------ .github/workflows/lab-validation.yml | 114 +++++++++++++++++++ 5 files changed, 145 insertions(+), 38 deletions(-) delete mode 100644 .github/.gitignore create mode 100644 .github/actions/avr_setup/action.yml create mode 100644 .github/actions/get_changed_files/action.yml delete mode 100644 .github/workflows/Lab_01_CI.yml create mode 100644 .github/workflows/lab-validation.yml diff --git a/.github/.gitignore b/.github/.gitignore deleted file mode 100644 index 8b13789..0000000 --- a/.github/.gitignore +++ /dev/null @@ -1 +0,0 @@ - diff --git a/.github/actions/avr_setup/action.yml b/.github/actions/avr_setup/action.yml new file mode 100644 index 0000000..3b92db0 --- /dev/null +++ b/.github/actions/avr_setup/action.yml @@ -0,0 +1,18 @@ +name: "Get changed files list" +description: "Setup Node with caching for dependencies" +runs: + using: "composite" + steps: + - name: Set up Arduino CLI + uses: arduino/setup-arduino-cli@v2 + + - name: Install platform + run: | + arduino-cli core update-index + arduino-cli core install ${{ env.platform }} + shell: bash + + - name: Install popular libs + run: | + arduino-cli lib install LiquidCrystal + shell: bash \ No newline at end of file diff --git a/.github/actions/get_changed_files/action.yml b/.github/actions/get_changed_files/action.yml new file mode 100644 index 0000000..ecf73ac --- /dev/null +++ b/.github/actions/get_changed_files/action.yml @@ -0,0 +1,13 @@ +name: "Get changed files list" +description: "Setup Node with caching for dependencies" +runs: + using: "composite" + steps: + - name: Get changed files list + id: get_changed_files + run: | + echo "Changed files:" + git diff --name-only ${{ github.event.pull_request.base.sha }} > changed_files.txt + cat changed_files.txt + echo "The list is saved to changed_files.txt" + shell: bash \ No newline at end of file diff --git a/.github/workflows/Lab_01_CI.yml b/.github/workflows/Lab_01_CI.yml deleted file mode 100644 index 985573b..0000000 --- a/.github/workflows/Lab_01_CI.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Cheking of compile Arduino sketch for AVR/AtMega and ESP8266 - -on: - push: - branches: [ main, master ] - pull_request: - branches: [ main, master ] - -jobs: - test-matrix: - strategy: - matrix: - arduino-platform: - - "arduino:avr" - - "esp8266:esp8266" - include: - - arduino-platform: "arduino:avr" - fqbn: "arduino:avr:mega" - - arduino-platform: "esp8266:esp8266" - fqbn: "esp8266:esp8266:generic" - - runs-on: ubuntu-22.04 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Arduino CLI - uses: arduino/setup-arduino-cli@v2 - - - name: Install platform - run: | - arduino-cli core update-index - arduino-cli core install ${{ matrix.arduino-platform }} - - - name: Compile Sketch - run: arduino-cli compile --fqbn ${{ matrix.fqbn }} ./mc_labs/mc_lab_01/*.ino diff --git a/.github/workflows/lab-validation.yml b/.github/workflows/lab-validation.yml new file mode 100644 index 0000000..059343b --- /dev/null +++ b/.github/workflows/lab-validation.yml @@ -0,0 +1,114 @@ +name: Cheking of compile Arduino sketch for AVR/AtMega + +on: + pull_request: + branches: [main, master] + +env: + platform: "arduino:avr" + fqbn_master: "arduino:avr:mega" + COMMIT_COUNT: $(( ${{ github.event_name == 'pull_request' && github.event.pull_request.commits || 0 }} + 1 )) + +jobs: + handle_bad_branch_name: + runs-on: ubuntu-22.04 + if: (contains(github.head_ref, 'mc_lab_1') || contains(github.head_ref, 'mc_lab_2') || contains(github.head_ref, 'mc_lab_3') || contains(github.head_ref, 'mc_lab_4') || contains(github.head_ref, 'mc_lab_5') || contains(github.head_ref, 'mc_lab_6') || contains(github.head_ref, 'mc_lab_7')) == false + steps: + - name: Fail the build + run: | + echo "The branch name is not correct. It should contain 'mc_lab_' prefix" + exit 1 + build_labs_1_to_4: + runs-on: ubuntu-22.04 + if: contains(github.head_ref, 'mc_lab_1') || contains(github.head_ref, 'mc_lab_2') || contains(github.head_ref, 'mc_lab_3') || contains(github.head_ref, 'mc_lab_4') + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: ${{ env.COMMIT_COUNT }} + + - name: Get changed files list + uses: ./.github/actions/get_changed_files + + - name: Set up Arduino CLI + uses: ./.github/actions/avr_setup + + - name: Compile Sketch + run: arduino-cli compile --fqbn ${{ env.fqbn_master }} $(grep -E '\.ino$' changed_files.txt | xargs) + build_lab_5: + runs-on: ubuntu-22.04 + if: contains(github.head_ref, 'mc_lab_5') + env: + fqbn_slave: "arduino:avr:nano" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: ${{ env.COMMIT_COUNT }} + + - name: Get changed files list + uses: ./.github/actions/get_changed_files + + - name: Get master folder + run: | + cat changed_files.txt | xargs dirname | grep 'master' | grep -m 1 -vE '/(.*master.*|.*slave.*)/' > master_project.txt + echo "Master project:" + cat master_project.txt + + - name: Get slave folders + run: | + cat changed_files.txt | xargs dirname | grep 'slave' | grep -vE '/(.*master.*|.*slave.*)/' > slave_projects.txt + echo "Slave projects:" + cat slave_projects.txt + + - name: Check if there is at least one master and one slave project + run: | + if [ ! -s master_project.txt ] || [ ! -s slave_projects.txt ]; then + echo "There is no master or slave project" + exit 1 + fi + + - name: Set up Arduino CLI + uses: ./.github/actions/avr_setup + + - name: Compile master + run: while read master_folder; do arduino-cli compile --fqbn ${{ env.fqbn_master }} $master_folder/*.ino; done < master_project.txt + + - name: Compile slaves + run: while read slave_folder; do arduino-cli compile --fqbn ${{ env.fqbn_slave }} $slave_folder/*.ino; done < slave_projects.txt + build_lab_6: + runs-on: ubuntu-22.04 + if: contains(github.head_ref, 'mc_lab_6') + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: ${{ env.COMMIT_COUNT }} + + - name: It just passes + run: echo "It just passes. It's too complex" + build_lab_7: + runs-on: ubuntu-22.04 + if: contains(github.head_ref, 'mc_lab_7') + env: + register-bindings: "m2560def.inc" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: ${{ env.COMMIT_COUNT }} + + - name: Get changed files list + uses: ./.github/actions/get_changed_files + + - name: Setup AVRA Assembler + run: | + git clone https://github.com/Ro5bert/avra.git + cd avra + sudo make install + + - name: Preprocess sketch - append register bindings to the top of the file + run: printf ".include \"${{ env.register-bindings }}\"\n\n" | cat - $(grep -m 1 -E '\.(asm|S)$' changed_files.txt | xargs) > pipeline_main_assembly_source_file.asm + + - name: Compile Sketch + run: avra pipeline_main_assembly_source_file.asm From fa1c2d8a7f75a91bbf12b3bf0e636864077cd3b5 Mon Sep 17 00:00:00 2001 From: MykolaKovalyk Date: Sat, 17 Aug 2024 03:39:31 +0300 Subject: [PATCH 2/2] Add example code for lab 2 --- mc_labs/mc_lab_02/lab2-mko/lab2-mko.ino | 74 ++++++++++++++++++++++++ mc_labs/mc_lab_02/lab2-mko/lab2.pdsprj | Bin 0 -> 21781 bytes 2 files changed, 74 insertions(+) create mode 100644 mc_labs/mc_lab_02/lab2-mko/lab2-mko.ino create mode 100644 mc_labs/mc_lab_02/lab2-mko/lab2.pdsprj diff --git a/mc_labs/mc_lab_02/lab2-mko/lab2-mko.ino b/mc_labs/mc_lab_02/lab2-mko/lab2-mko.ino new file mode 100644 index 0000000..be37762 --- /dev/null +++ b/mc_labs/mc_lab_02/lab2-mko/lab2-mko.ino @@ -0,0 +1,74 @@ +const unsigned char BUTTON_0_PIN = 49; +const unsigned char BUTTON_1_PIN = 47; + +const unsigned char LED_PINS[] = { 62, 63, 64, 65, 66, 67, 68, 69 }; +const unsigned int DELAY = 800; + +void setup() { + for (int i = 0; i < 8; i++) { + pinMode(LED_PINS[i], OUTPUT); + digitalWrite(LED_PINS[i], LOW); + } + + pinMode(BUTTON_0_PIN, INPUT); + digitalWrite(BUTTON_0_PIN, HIGH); + + pinMode(BUTTON_1_PIN, INPUT); + digitalWrite(BUTTON_1_PIN, HIGH); + + Serial.begin(9600); +} + + +unsigned char currentIteration = 0; +unsigned char currentMode = 0; +void bleep_sequential() { + digitalWrite(LED_PINS[currentIteration], HIGH); + delay(DELAY); + digitalWrite(LED_PINS[currentIteration], LOW); + currentIteration = (currentIteration + 1) % 8; +} + +void bleep_two_converge() { + digitalWrite(LED_PINS[currentIteration], HIGH); + digitalWrite(LED_PINS[7 - currentIteration], HIGH); + delay(DELAY); + digitalWrite(LED_PINS[currentIteration], LOW); + digitalWrite(LED_PINS[7 - currentIteration], LOW); + currentIteration = (currentIteration + 1) % 4; +} + + + +void loop() { + int inByte = -1; + if (Serial.available()) + inByte = Serial.read(); + + if (currentMode == 0) { + if (inByte == 0xA1) + currentMode = 1; + else if (inByte == 0xB1) + currentMode = 2; + } + + if (currentMode == 1) + bleep_sequential(); + else if (currentMode == 2) + bleep_two_converge(); + + if (currentIteration == 0) + currentMode = 0; + + + if (digitalRead(BUTTON_0_PIN) == LOW) + { + Serial.write(0xA1); + delay(1000); + } + if (digitalRead(BUTTON_1_PIN) == LOW) + { + Serial.write(0xB1); + delay(1000); + } +} diff --git a/mc_labs/mc_lab_02/lab2-mko/lab2.pdsprj b/mc_labs/mc_lab_02/lab2-mko/lab2.pdsprj new file mode 100644 index 0000000000000000000000000000000000000000..de5e2e82645f5cf254aa8d5708abfd53ef5c801f GIT binary patch literal 21781 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 literal 0 HcmV?d00001